Merge branch 'master' into master

pull/4783/head
Kim Kulling 2023-04-28 11:04:09 +02:00 committed by GitHub
commit 54a9cb9839
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
520 changed files with 52938 additions and 3810 deletions

View File

@ -57,3 +57,13 @@ jobs:
- name: test
run: cd build/bin && ./unit
shell: bash
job3:
name: printf-sanitizer
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: run scan_printf script
run: ./scripts/scan_printf.sh
shell: bash

View File

@ -138,7 +138,7 @@ IF (WIN32)
ELSE()
OPTION( ASSIMP_BUILD_ZLIB
"Build your own zlib"
OFF
ON
)
ENDIF()

128
CODE_OF_CONDUCT.md 100644
View File

@ -0,0 +1,128 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.

View File

@ -1,6 +1,8 @@
Open Asset Import Library (assimp)
==================================
A library to import and export various 3d-model-formats including scene-post-processing to generate missing render data.
Open Asset Import Library is a library to load various 3d file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export.
### Current project status ###
[![Financial Contributors on Open Collective](https://opencollective.com/assimp/all/badge.svg?label=financial+contributors)](https://opencollective.com/assimp)
![C/C++ CI](https://github.com/assimp/assimp/workflows/C/C++%20CI/badge.svg)
@ -14,7 +16,6 @@ A library to import and export various 3d-model-formats including scene-post-pro
[![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Average time to resolve an issue")
[![Percentage of issues still open](http://isitmaintained.com/badge/open/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Percentage of issues still open")
[![Total alerts](https://img.shields.io/lgtm/alerts/g/assimp/assimp.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/assimp/assimp/alerts/)
<br>
APIs are provided for C and C++. There are various bindings to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS.
@ -23,15 +24,19 @@ Additionally, assimp features various __mesh post processing tools__: normals an
### Latest Doc's ###
Please check the latest documents at [Asset-Importer-Lib-Doc](https://assimp-docs.readthedocs.io/en/latest/).
### Get involved ###
This is the development repo containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [Github Assimp Releases](https://github.com/assimp/assimp/releases).
<br>
You find a bug in the docs? Use [Doc-Repo](https://github.com/assimp/assimp-docs).
<br>
Please check our Wiki as well: https://github.com/assimp/assimp/wiki
### Prebuild binaries ###
Please check our [Itchi Projectspace](https://kimkulling.itch.io/the-asset-importer-lib)
If you want to check our Model-Database, use the following repo: https://github.com/assimp/assimp-mdb
### Communities ###
- Ask a question at [The Assimp-Discussion Board](https://github.com/assimp/assimp/discussions)
- Ask on [Assimp-Community on Reddit](https://www.reddit.com/r/Assimp/)
- Ask on [StackOverflow with the assimp-tag](http://stackoverflow.com/questions/tagged/assimp?sort=newest).
- Nothing has worked? File a question or an issue-report at [The Assimp-Issue Tracker](https://github.com/assimp/assimp/issues)
And we also have a Gitter-channel:Gitter [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)<br>
#### Supported file formats ####
You can find the complete list of supported file-formats [here](https://github.com/assimp/assimp/blob/master/doc/Fileformats.md)
@ -66,28 +71,18 @@ Open Asset Import Library is implemented in C++. The directory structure looks l
/port Ports to other languages and scripts to maintain those.
/test Unit- and regression tests, test suite of models
/tools Tools (old assimp viewer, command line `assimp`)
/samples A small number of samples to illustrate possible
use cases for Assimp
/samples A small number of samples to illustrate possible use-cases for Assimp
The source code is organized in the following way:
code/Common The base implementation for importers and the infrastructure
code/CApi Special implementations which are only used for the C-API
code/Geometry A collection of geometry tools
code/Material The material system
code/PBR An exporter for physical based models
code/PostProcessing The post-processing steps
code/AssetLib/<FormatName> Implementation for import and export for the format
### Where to get help ###
To find our documentation, visit [our website](https://assimp.org/) or check out [Wiki](https://github.com/assimp/assimp/wiki)
If the docs don't solve your problem, you can:
- Ask on [StackOverflow with the assimp-tag](http://stackoverflow.com/questions/tagged/assimp?sort=newest).
- Ask on [Assimp-Community on Reddit](https://www.reddit.com/r/Assimp/)
- Ask a question at [The Assimp-Discussion Board](https://github.com/assimp/assimp/discussions)
- Nothing has worked? File a question or an issue-report at [The Assimp-Issue Tracker](https://github.com/assimp/assimp/issues)
Open Asset Import Library is a library to load various 3d file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export.
And we also have a Gitter-channel:Gitter [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)<br>
### Contributing ###
Contributions to assimp are highly appreciated. The easiest way to get involved is to submit
a pull request with your changes against the main repository's `master` branch.

View File

@ -266,8 +266,15 @@ void Discreet3DSImporter::ParseMainChunk() {
};
ASSIMP_3DS_END_CHUNK();
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code-return"
#endif
// recursively continue processing this hierarchy level
return ParseMainChunk();
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
}
// ------------------------------------------------------------------------------------------------

View File

@ -68,7 +68,7 @@ using namespace D3DS;
class Discreet3DSImporter : public BaseImporter {
public:
Discreet3DSImporter();
~Discreet3DSImporter();
~Discreet3DSImporter() override;
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.

View File

@ -93,7 +93,7 @@ public:
// empty
}
~EmbeddedTexture() = default;
~EmbeddedTexture() override = default;
ResourceType getType() const override {
return ResourceType::RT_EmbeddedTexture2D;
@ -110,7 +110,7 @@ public:
// empty
}
~Texture2DGroup() = default;
~Texture2DGroup() override = default;
ResourceType getType() const override {
return ResourceType::RT_Texture2DGroup;
@ -127,7 +127,7 @@ public:
// empty
}
~BaseMaterials() = default;
~BaseMaterials() override = default;
ResourceType getType() const override {
return ResourceType::RT_BaseMaterials;
@ -152,7 +152,7 @@ public:
// empty
}
~Object() = default;
~Object() override = default;
ResourceType getType() const override {
return ResourceType::RT_Object;

View File

@ -282,11 +282,11 @@ public:
bool Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const;
bool Find_ConvertedNode(const std::string &pID, NodeArray &nodeArray, aiNode **pNode) const;
bool Find_ConvertedMaterial(const std::string &pID, const SPP_Material **pConvertedMaterial) const;
void Throw_CloseNotFound(const std::string &nodeName);
void Throw_IncorrectAttr(const std::string &nodeName, const std::string &pAttrName);
void Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &pAttrName);
void Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription);
void Throw_ID_NotFound(const std::string &pID) const;
AI_WONT_RETURN void Throw_CloseNotFound(const std::string &nodeName) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Throw_IncorrectAttr(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Throw_ID_NotFound(const std::string &pID) const AI_WONT_RETURN_SUFFIX;
void XML_CheckNode_MustHaveChildren(pugi::xml_node &node);
bool XML_SearchNode(const std::string &nodeName);
void ParseHelper_FixTruncatedFloatString(const char *pInStr, std::string &pOutString);

View File

@ -815,6 +815,7 @@ nl_clean_loop:
for (; next_it != nodeArray.end(); ++next_it) {
if ((*next_it)->FindNode((*nl_it)->mName) != nullptr) {
// if current top node(nl_it) found in another top node then erase it from node_list and restart search loop.
// FIXME: this leaks memory on test models test8.amf and test9.amf
nodeArray.erase(nl_it);
goto nl_clean_loop;

View File

@ -304,7 +304,6 @@ void Parser::Parse() {
}
AI_ASE_HANDLE_TOP_LEVEL_SECTION();
}
return;
}
// ------------------------------------------------------------------------------------------------
@ -734,7 +733,6 @@ void Parser::ParseLV3MapBlock(Texture &map) {
}
AI_ASE_HANDLE_SECTION("3", "*MAP_XXXXXX");
}
return;
}
// ------------------------------------------------------------------------------------------------
@ -859,7 +857,6 @@ void Parser::ParseLV1ObjectBlock(ASE::BaseNode &node) {
}
AI_ASE_HANDLE_TOP_LEVEL_SECTION();
}
return;
}
// ------------------------------------------------------------------------------------------------
@ -883,7 +880,6 @@ void Parser::ParseLV2CameraSettingsBlock(ASE::Camera &camera) {
}
AI_ASE_HANDLE_SECTION("2", "CAMERA_SETTINGS");
}
return;
}
// ------------------------------------------------------------------------------------------------
@ -1189,7 +1185,6 @@ void Parser::ParseLV2NodeTransformBlock(ASE::BaseNode &mesh) {
}
AI_ASE_HANDLE_SECTION("2", "*NODE_TM");
}
return;
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV2MeshBlock(ASE::Mesh &mesh) {
@ -1310,7 +1305,6 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh &mesh) {
}
AI_ASE_HANDLE_SECTION("2", "*MESH");
}
return;
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV3MeshWeightsBlock(ASE::Mesh &mesh) {
@ -1344,7 +1338,6 @@ void Parser::ParseLV3MeshWeightsBlock(ASE::Mesh &mesh) {
}
AI_ASE_HANDLE_SECTION("3", "*MESH_WEIGHTS");
}
return;
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV4MeshBones(unsigned int iNumBones, ASE::Mesh &mesh) {
@ -1414,7 +1407,6 @@ void Parser::ParseLV4MeshBonesVertices(unsigned int iNumVertices, ASE::Mesh &mes
}
AI_ASE_HANDLE_SECTION("4", "*MESH_BONE_VERTEX");
}
return;
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV3MeshVertexListBlock(
@ -1443,7 +1435,6 @@ void Parser::ParseLV3MeshVertexListBlock(
}
AI_ASE_HANDLE_SECTION("3", "*MESH_VERTEX_LIST");
}
return;
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV3MeshFaceListBlock(unsigned int iNumFaces, ASE::Mesh &mesh) {
@ -1470,7 +1461,6 @@ void Parser::ParseLV3MeshFaceListBlock(unsigned int iNumFaces, ASE::Mesh &mesh)
}
AI_ASE_HANDLE_SECTION("3", "*MESH_FACE_LIST");
}
return;
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV3MeshTListBlock(unsigned int iNumVertices,
@ -1503,7 +1493,6 @@ void Parser::ParseLV3MeshTListBlock(unsigned int iNumVertices,
}
AI_ASE_HANDLE_SECTION("3", "*MESH_TVERT_LIST");
}
return;
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV3MeshTFaceListBlock(unsigned int iNumFaces,
@ -1532,7 +1521,6 @@ void Parser::ParseLV3MeshTFaceListBlock(unsigned int iNumFaces,
}
AI_ASE_HANDLE_SECTION("3", "*MESH_TFACE_LIST");
}
return;
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh &mesh) {
@ -1567,7 +1555,6 @@ void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh &mesh) {
}
AI_ASE_HANDLE_SECTION("3", "*MESH_MAPPING_CHANNEL");
}
return;
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV3MeshCListBlock(unsigned int iNumVertices, ASE::Mesh &mesh) {
@ -1595,7 +1582,6 @@ void Parser::ParseLV3MeshCListBlock(unsigned int iNumVertices, ASE::Mesh &mesh)
}
AI_ASE_HANDLE_SECTION("3", "*MESH_CVERTEX_LIST");
}
return;
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV3MeshCFaceListBlock(unsigned int iNumFaces, ASE::Mesh &mesh) {
@ -1623,7 +1609,6 @@ void Parser::ParseLV3MeshCFaceListBlock(unsigned int iNumFaces, ASE::Mesh &mesh)
}
AI_ASE_HANDLE_SECTION("3", "*MESH_CFACE_LIST");
}
return;
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh &sMesh) {
@ -1681,7 +1666,6 @@ void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh &sMesh) {
}
AI_ASE_HANDLE_SECTION("3", "*MESH_NORMALS");
}
return;
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV4MeshFace(ASE::Face &out) {

View File

@ -7,7 +7,7 @@ For details, see http://sourceforge.net/projects/libb64
#include "cencode.h" // changed from <B64/cencode.h>
const int CHARS_PER_LINE = 72;
static const int CHARS_PER_LINE = 72;
#ifdef _MSC_VER
#pragma warning(push)

View File

@ -418,7 +418,6 @@ void B3DImporter::ReadTRIS(int v0) {
ASSIMP_LOG_ERROR("Bad triangle index: i0=", i0, ", i1=", i1, ", i2=", i2);
#endif
Fail("Bad triangle index");
continue;
}
face->mNumIndices = 3;
face->mIndices = new unsigned[3];

View File

@ -96,7 +96,8 @@ struct CustomDataTypeDescription {
* other (like CD_ORCO, ...) uses arrays of rawtypes or even arrays of Structures
* use a special readfunction for that cases
*/
std::array<CustomDataTypeDescription, CD_NUMTYPES> customDataTypeDescriptions = { { DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MVert),
static std::array<CustomDataTypeDescription, CD_NUMTYPES> customDataTypeDescriptions = { {
DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MVert),
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MEdge),

View File

@ -569,7 +569,7 @@ void Structure ::Convert<MVert>(
const FileDatabase &db) const {
ReadFieldArray<ErrorPolicy_Fail>(dest.co, "co", db);
ReadFieldArray<ErrorPolicy_Fail>(dest.no, "no", db);
ReadFieldArray<ErrorPolicy_Warn>(dest.no, "no", db);
ReadField<ErrorPolicy_Igno>(dest.flag, "flag", db);
//ReadField<ErrorPolicy_Warn>(dest.mat_nr,"mat_nr",db);
ReadField<ErrorPolicy_Igno>(dest.bweight, "bweight", db);

View File

@ -1855,7 +1855,6 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
default:
// LineStrip is not supported due to expected index unmangling
throw DeadlyImportError("Unsupported primitive type.");
break;
}
// store the face size to later reconstruct the face from

View File

@ -139,6 +139,7 @@ size_t Offset(const char* begin, const char* cursor) {
}
// ------------------------------------------------------------------------------------------------
AI_WONT_RETURN void TokenizeError(const std::string& message, const char* begin, const char* cursor) AI_WONT_RETURN_SUFFIX;
void TokenizeError(const std::string& message, const char* begin, const char* cursor) {
TokenizeError(message, Offset(begin, cursor));
}

View File

@ -421,6 +421,8 @@ void FBXConverter::ConvertCamera(const Camera &cam, const std::string &orig_name
out_camera->mAspect = cam.AspectWidth() / cam.AspectHeight();
// NOTE: Camera mPosition, mLookAt and mUp must be set to default here.
// All transformations to the camera will be handled by its node in the scenegraph.
out_camera->mPosition = aiVector3D(0.0f);
out_camera->mLookAt = aiVector3D(1.0f, 0.0f, 0.0f);
out_camera->mUp = aiVector3D(0.0f, 1.0f, 0.0f);
@ -640,7 +642,7 @@ void FBXConverter::GetRotationMatrix(Model::RotOrder mode, const aiVector3D &rot
bool FBXConverter::NeedsComplexTransformationChain(const Model &model) {
const PropertyTable &props = model.Props();
const auto zero_epsilon = ai_epsilon;
const auto zero_epsilon = Math::getEpsilon<ai_real>();
const aiVector3D all_ones(1.0f, 1.0f, 1.0f);
for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
const TransformationComp comp = static_cast<TransformationComp>(i);
@ -873,8 +875,12 @@ void FBXConverter::SetupNodeMetadata(const Model &model, aiNode &nd) {
data->Set(index++, prop.first, interpretedBool->Value());
} else if (const TypedProperty<int> *interpretedInt = prop.second->As<TypedProperty<int>>()) {
data->Set(index++, prop.first, interpretedInt->Value());
} else if (const TypedProperty<uint32_t> *interpretedUInt = prop.second->As<TypedProperty<uint32_t>>()) {
data->Set(index++, prop.first, interpretedUInt->Value());
} else if (const TypedProperty<uint64_t> *interpretedUint64 = prop.second->As<TypedProperty<uint64_t>>()) {
data->Set(index++, prop.first, interpretedUint64->Value());
} else if (const TypedProperty<int64_t> *interpretedint64 = prop.second->As<TypedProperty<int64_t>>()) {
data->Set(index++, prop.first, interpretedint64->Value());
} else if (const TypedProperty<float> *interpretedFloat = prop.second->As<TypedProperty<float>>()) {
data->Set(index++, prop.first, interpretedFloat->Value());
} else if (const TypedProperty<std::string> *interpretedString = prop.second->As<TypedProperty<std::string>>()) {
@ -1176,15 +1182,23 @@ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, c
std::vector<aiAnimMesh *> animMeshes;
for (const BlendShape *blendShape : mesh.GetBlendShapes()) {
for (const BlendShapeChannel *blendShapeChannel : blendShape->BlendShapeChannels()) {
const std::vector<const ShapeGeometry *> &shapeGeometries = blendShapeChannel->GetShapeGeometries();
for (size_t i = 0; i < shapeGeometries.size(); i++) {
const auto& shapeGeometries = blendShapeChannel->GetShapeGeometries();
for (const ShapeGeometry *shapeGeometry : shapeGeometries) {
aiAnimMesh *animMesh = aiCreateAnimMesh(out_mesh);
const ShapeGeometry *shapeGeometry = shapeGeometries.at(i);
const std::vector<aiVector3D> &curVertices = shapeGeometry->GetVertices();
const std::vector<aiVector3D> &curNormals = shapeGeometry->GetNormals();
const std::vector<unsigned int> &curIndices = shapeGeometry->GetIndices();
const auto &curVertices = shapeGeometry->GetVertices();
const auto &curNormals = shapeGeometry->GetNormals();
const auto &curIndices = shapeGeometry->GetIndices();
//losing channel name if using shapeGeometry->Name()
animMesh->mName.Set(FixAnimMeshName(blendShapeChannel->Name()));
// if blendShapeChannel Name is empty or don't have a ".", add geoMetryName;
auto aniName = FixAnimMeshName(blendShapeChannel->Name());
auto geoMetryName = FixAnimMeshName(shapeGeometry->Name());
if (aniName.empty()) {
aniName = geoMetryName;
}
else if (aniName.find('.') == aniName.npos) {
aniName += "." + geoMetryName;
}
animMesh->mName.Set(aniName);
for (size_t j = 0; j < curIndices.size(); j++) {
const unsigned int curIndex = curIndices.at(j);
aiVector3D vertex = curVertices.at(j);
@ -1406,13 +1420,12 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co
std::vector<aiAnimMesh *> animMeshes;
for (const BlendShape *blendShape : mesh.GetBlendShapes()) {
for (const BlendShapeChannel *blendShapeChannel : blendShape->BlendShapeChannels()) {
const std::vector<const ShapeGeometry *> &shapeGeometries = blendShapeChannel->GetShapeGeometries();
for (size_t i = 0; i < shapeGeometries.size(); i++) {
const auto& shapeGeometries = blendShapeChannel->GetShapeGeometries();
for (const ShapeGeometry *shapeGeometry : shapeGeometries) {
aiAnimMesh *animMesh = aiCreateAnimMesh(out_mesh);
const ShapeGeometry *shapeGeometry = shapeGeometries.at(i);
const std::vector<aiVector3D> &curVertices = shapeGeometry->GetVertices();
const std::vector<aiVector3D> &curNormals = shapeGeometry->GetNormals();
const std::vector<unsigned int> &curIndices = shapeGeometry->GetIndices();
const auto& curVertices = shapeGeometry->GetVertices();
const auto& curNormals = shapeGeometry->GetNormals();
const auto& curIndices = shapeGeometry->GetIndices();
animMesh->mName.Set(FixAnimMeshName(shapeGeometry->Name()));
for (size_t j = 0; j < curIndices.size(); j++) {
unsigned int curIndex = curIndices.at(j);

View File

@ -154,8 +154,10 @@ BlendShape::BlendShape(uint64_t id, const Element& element, const Document& doc,
for (const Connection* con : conns) {
const BlendShapeChannel* const bspc = ProcessSimpleConnection<BlendShapeChannel>(*con, false, "BlendShapeChannel -> BlendShape", element);
if (bspc) {
blendShapeChannels.push_back(bspc);
continue;
auto pr = blendShapeChannels.insert(bspc);
if (!pr.second) {
FBXImporter::LogWarn("there is the same blendShapeChannel id ", bspc->ID());
}
}
}
}
@ -179,8 +181,10 @@ BlendShapeChannel::BlendShapeChannel(uint64_t id, const Element& element, const
for (const Connection* con : conns) {
const ShapeGeometry* const sg = ProcessSimpleConnection<ShapeGeometry>(*con, false, "Shape -> BlendShapeChannel", element);
if (sg) {
shapeGeometries.push_back(sg);
continue;
auto pr = shapeGeometries.insert(sg);
if (!pr.second) {
FBXImporter::LogWarn("there is the same shapeGeometrie id ", sg->ID());
}
}
}
}

View File

@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define INCLUDED_AI_FBX_DOCUMENT_H
#include <numeric>
#include <unordered_set>
#include <stdint.h>
#include <assimp/mesh.h>
#include "FBXProperties.h"
@ -855,14 +856,14 @@ public:
return fullWeights;
}
const std::vector<const ShapeGeometry*>& GetShapeGeometries() const {
const std::unordered_set<const ShapeGeometry*>& GetShapeGeometries() const {
return shapeGeometries;
}
private:
float percent;
WeightArray fullWeights;
std::vector<const ShapeGeometry*> shapeGeometries;
std::unordered_set<const ShapeGeometry*> shapeGeometries;
};
/** DOM class for BlendShape deformers */
@ -872,12 +873,12 @@ public:
virtual ~BlendShape();
const std::vector<const BlendShapeChannel*>& BlendShapeChannels() const {
const std::unordered_set<const BlendShapeChannel*>& BlendShapeChannels() const {
return blendShapeChannels;
}
private:
std::vector<const BlendShapeChannel*> blendShapeChannels;
std::unordered_set<const BlendShapeChannel*> blendShapeChannels;
};
/** DOM class for skin deformer clusters (aka sub-deformers) */

View File

@ -138,20 +138,6 @@ Material::Material(uint64_t id, const Element& element, const Document& doc, con
// ------------------------------------------------------------------------------------------------
Material::~Material() = default;
aiVector2D uvTrans;
aiVector2D uvScaling;
ai_real uvRotation;
std::string type;
std::string relativeFileName;
std::string fileName;
std::string alphaSource;
std::shared_ptr<const PropertyTable> props;
unsigned int crop[4]{};
const Video* media;
// ------------------------------------------------------------------------------------------------
Texture::Texture(uint64_t id, const Element& element, const Document& doc, const std::string& name) :
Object(id,element,name),

View File

@ -69,13 +69,16 @@ Geometry::Geometry(uint64_t id, const Element& element, const std::string& name,
}
const BlendShape* const bsp = ProcessSimpleConnection<BlendShape>(*con, false, "BlendShape -> Geometry", element);
if (bsp) {
blendShapes.push_back(bsp);
auto pr = blendShapes.insert(bsp);
if (!pr.second) {
FBXImporter::LogWarn("there is the same blendShape id ", bsp->ID());
}
}
}
}
// ------------------------------------------------------------------------------------------------
const std::vector<const BlendShape*>& Geometry::GetBlendShapes() const {
const std::unordered_set<const BlendShape*>& Geometry::GetBlendShapes() const {
return blendShapes;
}

View File

@ -62,7 +62,7 @@ public:
/// @param name The name instance
/// @param doc The document instance
Geometry( uint64_t id, const Element& element, const std::string& name, const Document& doc );
/// @brief The class destructor, default.
virtual ~Geometry() = default;
@ -72,11 +72,12 @@ public:
/// @brief Get the BlendShape attached to this geometry or nullptr
/// @return The blendshape arrays.
const std::vector<const BlendShape*>& GetBlendShapes() const;
const std::unordered_set<const BlendShape*>& GetBlendShapes() const;
private:
const Skin* skin;
std::vector<const BlendShape*> blendShapes;
std::unordered_set<const BlendShape*> blendShapes;
};
typedef std::vector<int> MatIndexArray;
@ -112,7 +113,7 @@ public:
/// @return The binomal vector.
const std::vector<aiVector3D>& GetBinormals() const;
/// @brief Return list of faces - each entry denotes a face and specifies how many vertices it has.
/// @brief Return list of faces - each entry denotes a face and specifies how many vertices it has.
/// Vertices are taken from the vertex data arrays in sequential order.
/// @return The face indices vector.
const std::vector<unsigned int>& GetFaceIndexCounts() const;

View File

@ -88,6 +88,7 @@ namespace {
// ------------------------------------------------------------------------------------------------
AI_WONT_RETURN void ParseError(const std::string& message, TokenPtr token) AI_WONT_RETURN_SUFFIX;
void ParseError(const std::string& message, TokenPtr token)
{
if(token) {
@ -188,15 +189,19 @@ Scope::Scope(Parser& parser,bool topLevel)
ParseError("unexpected content: empty string.");
}
elements.insert(ElementMap::value_type(str,new_Element(*n,parser)));
auto *element = new_Element(*n, parser);
// Element() should stop at the next Key token (or right after a Close token)
n = parser.CurrentToken();
if (n == nullptr) {
if (topLevel) {
elements.insert(ElementMap::value_type(str, element));
return;
}
ParseError("unexpected end of file",parser.LastToken());
delete element;
} else {
elements.insert(ElementMap::value_type(str, element));
}
}
}

View File

@ -86,7 +86,7 @@ protected:
// -------------------------------------------------------------------
/** Import a HMP4 file
*/
void InternReadFile_HMP4();
AI_WONT_RETURN void InternReadFile_HMP4() AI_WONT_RETURN_SUFFIX;
// -------------------------------------------------------------------
/** Import a HMP5 file

View File

@ -65,7 +65,6 @@ void LWOImporter::LoadLWOBFile()
if (mFileBuffer + head.length > end)
{
throw DeadlyImportError("LWOB: Invalid chunk length");
break;
}
uint8_t* const next = mFileBuffer+head.length;
switch (head.type)

View File

@ -178,7 +178,7 @@ void LWOImporter::InternReadFile(const std::string &pFile,
mLayers->push_back(Layer());
mCurLayer = &mLayers->back();
mCurLayer->mName = "<LWODefault>";
mCurLayer->mIndex = (uint16_t) -1;
mCurLayer->mIndex = 1;
// old lightwave file format (prior to v6)
mIsLWO2 = false;
@ -398,14 +398,6 @@ void LWOImporter::InternReadFile(const std::string &pFile,
pvVC[w]++;
}
#if 0
// process vertex weights. We can't properly reconstruct the whole skeleton for now,
// but we can create dummy bones for all weight channels which we have.
for (unsigned int w = 0; w < layer.mWeightChannels.size();++w)
{
}
#endif
face.mIndices[q] = vert;
}
pf->mIndices = face.mIndices;
@ -429,7 +421,7 @@ void LWOImporter::InternReadFile(const std::string &pFile,
// Generate nodes to render the mesh. Store the source layer in the mParent member of the nodes
unsigned int num = static_cast<unsigned int>(apcMeshes.size() - meshStart);
if (layer.mName != "<LWODefault>" || num > 0) {
aiNode *pcNode = new aiNode();
std::unique_ptr<aiNode> pcNode(new aiNode());
pcNode->mName.Set(layer.mName);
pcNode->mParent = (aiNode *)&layer;
pcNode->mNumMeshes = num;
@ -439,7 +431,8 @@ void LWOImporter::InternReadFile(const std::string &pFile,
for (unsigned int p = 0; p < pcNode->mNumMeshes; ++p)
pcNode->mMeshes[p] = p + meshStart;
}
apcNodes[layer.mIndex] = pcNode;
ASSIMP_LOG_DEBUG("insert apcNode for layer ", layer.mIndex, " \"", layer.mName, "\"");
apcNodes[layer.mIndex] = pcNode.release();
}
}
@ -572,40 +565,64 @@ void LWOImporter::GenerateNodeGraph(std::map<uint16_t, aiNode *> &apcNodes) {
aiNode *root = mScene->mRootNode = new aiNode();
root->mName.Set("<LWORoot>");
//Set parent of all children, inserting pivots
std::map<uint16_t, aiNode *> mapPivot;
for (auto itapcNodes = apcNodes.begin(); itapcNodes != apcNodes.end(); ++itapcNodes) {
//Get the parent index
LWO::Layer *nodeLayer = (LWO::Layer *)(itapcNodes->second->mParent);
uint16_t parentIndex = nodeLayer->mParent;
//Create pivot node, store it into the pivot map, and set the parent as the pivot
aiNode *pivotNode = new aiNode();
pivotNode->mName.Set("Pivot-" + std::string(itapcNodes->second->mName.data));
itapcNodes->second->mParent = pivotNode;
//Look for the parent node to attach the pivot to
if (apcNodes.find(parentIndex) != apcNodes.end()) {
pivotNode->mParent = apcNodes[parentIndex];
} else {
//If not, attach to the root node
pivotNode->mParent = root;
}
//Set the node and the pivot node transformation
itapcNodes->second->mTransformation.a4 = -nodeLayer->mPivot.x;
itapcNodes->second->mTransformation.b4 = -nodeLayer->mPivot.y;
itapcNodes->second->mTransformation.c4 = -nodeLayer->mPivot.z;
pivotNode->mTransformation.a4 = nodeLayer->mPivot.x;
pivotNode->mTransformation.b4 = nodeLayer->mPivot.y;
pivotNode->mTransformation.c4 = nodeLayer->mPivot.z;
mapPivot[-(itapcNodes->first + 2)] = pivotNode;
ASSIMP_LOG_DEBUG("apcNodes initial size: ", apcNodes.size());
if (!apcNodes.empty()) {
ASSIMP_LOG_DEBUG("first apcNode is: ", apcNodes.begin()->first, " \"", apcNodes.begin()->second->mName.C_Str(), "\"");
}
//Merge pivot map into node map
for (auto itMapPivot = mapPivot.begin(); itMapPivot != mapPivot.end(); ++itMapPivot) {
apcNodes[itMapPivot->first] = itMapPivot->second;
//Set parent of all children, inserting pivots
{
std::map<uint16_t, aiNode *> mapPivot;
for (auto itapcNodes = apcNodes.begin(); itapcNodes != apcNodes.end(); ++itapcNodes) {
//Get the parent index
LWO::Layer *nodeLayer = (LWO::Layer *)(itapcNodes->second->mParent);
uint16_t parentIndex = nodeLayer->mParent;
//Create pivot node, store it into the pivot map, and set the parent as the pivot
std::unique_ptr<aiNode> pivotNode(new aiNode());
pivotNode->mName.Set("Pivot-" + std::string(itapcNodes->second->mName.data));
itapcNodes->second->mParent = pivotNode.get();
//Look for the parent node to attach the pivot to
if (apcNodes.find(parentIndex) != apcNodes.end()) {
pivotNode->mParent = apcNodes[parentIndex];
} else {
//If not, attach to the root node
pivotNode->mParent = root;
}
//Set the node and the pivot node transformation
itapcNodes->second->mTransformation.a4 = -nodeLayer->mPivot.x;
itapcNodes->second->mTransformation.b4 = -nodeLayer->mPivot.y;
itapcNodes->second->mTransformation.c4 = -nodeLayer->mPivot.z;
pivotNode->mTransformation.a4 = nodeLayer->mPivot.x;
pivotNode->mTransformation.b4 = nodeLayer->mPivot.y;
pivotNode->mTransformation.c4 = nodeLayer->mPivot.z;
uint16_t pivotNodeId = static_cast<uint16_t>(-(itapcNodes->first + 2));
ASSIMP_LOG_DEBUG("insert pivot node: ", pivotNodeId);
auto oldNodeIt = mapPivot.find(pivotNodeId);
if (oldNodeIt != mapPivot.end()) {
ASSIMP_LOG_ERROR("attempted to insert pivot node which already exists in pivot map ", pivotNodeId, " \"", pivotNode->mName.C_Str(), "\"");
} else {
mapPivot.emplace(pivotNodeId, pivotNode.release());
}
}
ASSIMP_LOG_DEBUG("pivot nodes: ", mapPivot.size());
//Merge pivot map into node map
for (auto itMapPivot = mapPivot.begin(); itMapPivot != mapPivot.end();) {
uint16_t pivotNodeId = itMapPivot->first;
auto oldApcNodeIt = apcNodes.find(pivotNodeId);
if (oldApcNodeIt != apcNodes.end()) {
ASSIMP_LOG_ERROR("attempted to insert pivot node which already exists in apc nodes ", pivotNodeId, " \"", itMapPivot->second->mName.C_Str(), "\"");
} else {
apcNodes.emplace(pivotNodeId, itMapPivot->second);
}
itMapPivot->second = nullptr;
itMapPivot = mapPivot.erase(itMapPivot);
}
ASSIMP_LOG_DEBUG("total nodes: ", apcNodes.size());
}
//Set children of all parents
@ -627,8 +644,15 @@ void LWOImporter::GenerateNodeGraph(std::map<uint16_t, aiNode *> &apcNodes) {
}
}
if (!mScene->mRootNode->mNumChildren)
if (!mScene->mRootNode->mNumChildren) {
ASSIMP_LOG_DEBUG("All apcNodes:");
for (auto nodeIt = apcNodes.begin(); nodeIt != apcNodes.end(); ) {
ASSIMP_LOG_DEBUG("Node ", nodeIt->first, " \"", nodeIt->second->mName.C_Str(), "\"");
nodeIt->second = nullptr;
nodeIt = apcNodes.erase(nodeIt);
}
throw DeadlyImportError("LWO: Unable to build a valid node graph");
}
// Remove a single root node with no meshes assigned to it ...
if (1 == mScene->mRootNode->mNumChildren) {
@ -1462,7 +1486,6 @@ void LWOImporter::LoadLWO2File() {
if (mFileBuffer + head.length > end) {
throw DeadlyImportError("LWO2: Chunk length points behind the file");
break;
}
uint8_t *const next = mFileBuffer + head.length;
mFileBuffer += bufOffset;

View File

@ -345,7 +345,7 @@ void LWOImporter::ConvertMaterial(const LWO::Surface &surf, aiMaterial *pcMat) {
// (the diffuse value is just a scaling factor)
// If a diffuse texture is set, we set this value to 1.0
clr = (b && false ? aiColor3D(1.0, 1.0, 1.0) : surf.mColor);
clr = (b ? aiColor3D(1.0, 1.0, 1.0) : surf.mColor);
clr.r *= surf.mDiffuseValue;
clr.g *= surf.mDiffuseValue;
clr.b *= surf.mDiffuseValue;

View File

@ -365,9 +365,7 @@ public:
static void ReportWarning (const char* warn, unsigned int line);
void ReportError (const char* error) {
return ReportError(error, lineNumber);
}
AI_WONT_RETURN void ReportError (const char* error) AI_WONT_RETURN_SUFFIX;
void ReportWarning (const char* warn) {
return ReportWarning(warn, lineNumber);
@ -404,6 +402,9 @@ private:
unsigned int lineNumber;
};
inline void MD5Parser::ReportError(const char* error) {
ReportError(error, lineNumber);
}
// -------------------------------------------------------------------
inline bool MD5Parser::SkipLine(const char* in, const char** out) {
++lineNumber;

View File

@ -470,14 +470,16 @@ void HL1MDLLoader::read_bones() {
temp_bones_.resize(header_->numbones);
// Create the main 'bones' node that will contain all MDL root bones.
aiNode *bones_node = new aiNode(AI_MDL_HL1_NODE_BONES);
rootnode_children_.push_back(bones_node);
bones_node->mNumChildren = static_cast<unsigned int>(header_->numbones);
bones_node->mChildren = new aiNode *[bones_node->mNumChildren];
// Store roots bones IDs temporarily.
std::vector<int> roots;
// Create bone matrices in local space.
for (int i = 0; i < header_->numbones; ++i) {
aiNode *bone_node = temp_bones_[i].node = bones_node->mChildren[i] = new aiNode(unique_bones_names[i]);
aiNode *bone_node = temp_bones_[i].node = new aiNode(unique_bones_names[i]);
aiVector3D angles(pbone[i].value[3], pbone[i].value[4], pbone[i].value[5]);
temp_bones_[i].absolute_transform = bone_node->mTransformation =
@ -485,9 +487,11 @@ void HL1MDLLoader::read_bones() {
aiVector3D(pbone[i].value[0], pbone[i].value[1], pbone[i].value[2]));
if (pbone[i].parent == -1) {
bone_node->mParent = scene_->mRootNode;
bone_node->mParent = bones_node;
roots.push_back(i); // This bone has no parent. Add it to the roots list.
} else {
bone_node->mParent = bones_node->mChildren[pbone[i].parent];
bone_node->mParent = temp_bones_[pbone[i].parent].node;
temp_bones_[pbone[i].parent].children.push_back(i); // Add this bone to the parent bone's children list.
temp_bones_[i].absolute_transform =
temp_bones_[pbone[i].parent].absolute_transform * bone_node->mTransformation;
@ -496,6 +500,36 @@ void HL1MDLLoader::read_bones() {
temp_bones_[i].offset_matrix = temp_bones_[i].absolute_transform;
temp_bones_[i].offset_matrix.Inverse();
}
// Allocate memory for each MDL root bone.
bones_node->mNumChildren = static_cast<unsigned int>(roots.size());
bones_node->mChildren = new aiNode *[bones_node->mNumChildren];
// Build all bones children hierarchy starting from each MDL root bone.
for (size_t i = 0; i < roots.size(); ++i)
{
const TempBone &root_bone = temp_bones_[roots[i]];
bones_node->mChildren[i] = root_bone.node;
build_bone_children_hierarchy(root_bone);
}
}
void HL1MDLLoader::build_bone_children_hierarchy(const TempBone &bone)
{
if (bone.children.empty())
return;
aiNode* bone_node = bone.node;
bone_node->mNumChildren = static_cast<unsigned int>(bone.children.size());
bone_node->mChildren = new aiNode *[bone_node->mNumChildren];
// Build each child bone's hierarchy recursively.
for (size_t i = 0; i < bone.children.size(); ++i)
{
const TempBone &child_bone = temp_bones_[bone.children[i]];
bone_node->mChildren[i] = child_bone.node;
build_bone_children_hierarchy(child_bone);
}
}
// ------------------------------------------------------------------------------------------------

View File

@ -143,6 +143,14 @@ private:
*/
static bool get_num_blend_controllers(const int num_blend_animations, int &num_blend_controllers);
/**
* \brief Build a bone's node children hierarchy.
*
* \param[in] bone The bone for which we must build all children hierarchy.
*/
struct TempBone;
void build_bone_children_hierarchy(const TempBone& bone);
/** Output scene to be filled */
aiScene *scene_;
@ -198,11 +206,13 @@ private:
TempBone() :
node(nullptr),
absolute_transform(),
offset_matrix() {}
offset_matrix(),
children() {}
aiNode *node;
aiMatrix4x4 absolute_transform;
aiMatrix4x4 offset_matrix;
std::vector<int> children; // Bone children
};
std::vector<TempBone> temp_bones_;

View File

@ -139,7 +139,7 @@ protected:
// -------------------------------------------------------------------
/** Import a CS:S/HL2 MDL file (not fully implemented)
*/
void InternReadFile_HL2( );
AI_WONT_RETURN void InternReadFile_HL2( ) AI_WONT_RETURN_SUFFIX;
// -------------------------------------------------------------------
/** Check whether a given position is inside the valid range

View File

@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <iostream>
#include <fstream>
#include <memory>
#include <assimp/types.h>
#include "MMDCpp14.h"
namespace pmx
@ -730,7 +731,7 @@ namespace pmx
std::unique_ptr<PmxAncherRigidBody []> anchers;
int pin_vertex_count;
std::unique_ptr<int []> pin_vertices;
void Read(std::istream *stream, PmxSetting *setting);
AI_WONT_RETURN void Read(std::istream *stream, PmxSetting *setting) AI_WONT_RETURN_SUFFIX;
};
class PmxModel

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2023, assimp team
All rights reserved.
@ -84,7 +84,6 @@ ObjFileImporter::ObjFileImporter() :
// Destructor.
ObjFileImporter::~ObjFileImporter() {
delete m_pRootObject;
m_pRootObject = nullptr;
}
// ------------------------------------------------------------------------------------------------
@ -270,7 +269,7 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model *pModel, const ObjFile
for (size_t i = 0; i < pObject->m_Meshes.size(); ++i) {
unsigned int meshId = pObject->m_Meshes[i];
aiMesh *pMesh = createTopology(pModel, pObject, meshId);
if (pMesh) {
if (pMesh != nullptr) {
if (pMesh->mNumFaces > 0) {
MeshArray.push_back(pMesh);
} else {
@ -324,14 +323,13 @@ aiMesh *ObjFileImporter::createTopology(const ObjFile::Model *pModel, const ObjF
return nullptr;
}
std::unique_ptr<aiMesh> pMesh(new aiMesh);
aiMesh *pMesh = new aiMesh;
if (!pObjMesh->m_name.empty()) {
pMesh->mName.Set(pObjMesh->m_name);
}
for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) {
const ObjFile::Face *inp = pObjMesh->m_Faces[index];
//ai_assert(nullptr != inp);
if (inp->mPrimitiveType == aiPrimitiveType_LINE) {
pMesh->mNumFaces += static_cast<unsigned int>(inp->m_vertices.size() - 1);
@ -387,9 +385,9 @@ aiMesh *ObjFileImporter::createTopology(const ObjFile::Model *pModel, const ObjF
}
// Create mesh vertices
createVertexArray(pModel, pData, meshIndex, pMesh.get(), uiIdxCount);
createVertexArray(pModel, pData, meshIndex, pMesh, uiIdxCount);
return pMesh.release();
return pMesh;
}
// ------------------------------------------------------------------------------------------------

View File

@ -236,7 +236,7 @@ void ObjFileParser::parseFile(IOStreamBuffer<char> &streamBuffer) {
getNameNoSpace(m_DataIt, m_DataItEnd, name);
insideCstype = name == "cstype";
goto pf_skip_line;
} break;
}
default: {
pf_skip_line:

View File

@ -57,7 +57,7 @@ namespace Assimp {
namespace Ogre {
//AI_WONT_RETURN void ThrowAttibuteError(const XmlParser *reader, const std::string &name, const std::string &error = "") AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void ThrowAttibuteError(const std::string &nodeName, const std::string &name, const std::string &error) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void ThrowAttibuteError(const std::string &nodeName, const std::string &name, const std::string &error) {
if (!error.empty()) {
throw DeadlyImportError(error, " in node '", nodeName, "' and attribute '", name, "'");
@ -128,7 +128,6 @@ bool OgreXmlSerializer::ReadAttribute<bool>(XmlNode &xmlNode, const char *name)
}
ThrowAttibuteError(xmlNode.name(), name, "Boolean value is expected to be 'true' or 'false', encountered '" + value + "'");
return false;
}
// Mesh XML constants
@ -490,7 +489,7 @@ bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml *me
OgreXmlSerializer serializer(xmlParser.get());
XmlNode root = xmlParser->getRootNode();
if (std::string(root.name()) != nnSkeleton) {
printf("\nSkeleton is not a valid root: %s\n", root.name());
ASSIMP_LOG_VERBOSE_DEBUG("nSkeleton is not a valid root: ", root.name(), ".");
for (auto &a : root.children()) {
if (std::string(a.name()) == nnSkeleton) {
root = a;

View File

@ -460,14 +460,12 @@ void OpenGEXImporter::handleMetricNode(DDLNode *node, aiScene * /*pScene*/) {
void OpenGEXImporter::handleNameNode(DDLNode *node, aiScene * /*pScene*/) {
if (nullptr == m_currentNode) {
throw DeadlyImportError("No current node for name.");
return;
}
Value *val(node->getValue());
if (nullptr != val) {
if (Value::ValueType::ddl_string != val->m_type) {
throw DeadlyImportError("OpenGEX: invalid data type for value in node name.");
return;
}
const std::string name(val->getString());
@ -508,7 +506,6 @@ static void getRefNames(DDLNode *node, std::vector<std::string> &names) {
void OpenGEXImporter::handleObjectRefNode(DDLNode *node, aiScene * /*pScene*/) {
if (nullptr == m_currentNode) {
throw DeadlyImportError("No parent node for name.");
return;
}
std::vector<std::string> objRefNames;
@ -532,7 +529,6 @@ void OpenGEXImporter::handleObjectRefNode(DDLNode *node, aiScene * /*pScene*/) {
void OpenGEXImporter::handleMaterialRefNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
if (nullptr == m_currentNode) {
throw DeadlyImportError("No parent node for name.");
return;
}
std::vector<std::string> matRefNames;
@ -672,14 +668,12 @@ static void setMatrix(aiNode *node, DataArrayList *transformData) {
void OpenGEXImporter::handleTransformNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
if (nullptr == m_currentNode) {
throw DeadlyImportError("No parent node for name.");
return;
}
DataArrayList *transformData(node->getDataArrayList());
if (nullptr != transformData) {
if (transformData->m_numItems != 16) {
throw DeadlyImportError("Invalid number of data for transform matrix.");
return;
}
setMatrix(m_currentNode, transformData);
}
@ -835,7 +829,6 @@ static void copyColor4DArray(size_t numItems, DataArrayList *vaList, aiColor4D *
void OpenGEXImporter::handleVertexArrayNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
if (nullptr == node) {
throw DeadlyImportError("No parent node for name.");
return;
}
Property *prop = node->getProperties();
@ -876,12 +869,10 @@ void OpenGEXImporter::handleVertexArrayNode(ODDLParser::DDLNode *node, aiScene *
void OpenGEXImporter::handleIndexArrayNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
if (nullptr == node) {
throw DeadlyImportError("No parent node for name.");
return;
}
if (nullptr == m_currentMesh) {
throw DeadlyImportError("No current mesh for index data found.");
return;
}
DataArrayList *vaList = node->getDataArrayList();

View File

@ -382,11 +382,10 @@ void Q3DImporter::InternReadFile(const std::string &pFile,
// TODO
goto outer;
} break;
}
default:
throw DeadlyImportError("Quick3D: Unknown chunk");
break;
};
}
outer:

View File

@ -58,7 +58,7 @@ namespace Assimp {
class RAWImporter : public BaseImporter {
public:
RAWImporter();
~RAWImporter();
~RAWImporter() override;
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.

View File

@ -85,7 +85,7 @@ static const aiImporterDesc desc = {
struct SIBChunk {
uint32_t Tag;
uint32_t Size;
} PACK_STRUCT;
};
enum {
POS,

View File

@ -56,7 +56,7 @@ namespace Assimp {
class UnrealImporter : public BaseImporter {
public:
UnrealImporter();
~UnrealImporter();
~UnrealImporter() override;
// -------------------------------------------------------------------
/** @brief Returns whether we can handle the format of the given file

View File

@ -839,7 +839,6 @@ void XFileParser::ParseDataObjectAnimationKey(AnimBone *pAnimBone) {
default:
ThrowException("Unknown key type ", keyType, " in animation.");
break;
} // end switch
// key separator

View File

@ -55,6 +55,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
namespace Assimp {
AI_WONT_RETURN inline void Throw_ArgOutOfRange(const std::string &argument) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN inline void Throw_CloseNotFound(const std::string &node) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN inline void Throw_ConvertFail_Str2ArrF(const std::string &nodeName, const std::string &pAttrValue) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN inline void Throw_ConvertFail_Str2ArrD(const std::string &nodeName, const std::string &pAttrValue) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN inline void Throw_ConvertFail_Str2ArrB(const std::string &nodeName, const std::string &pAttrValue) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN inline void Throw_ConvertFail_Str2ArrI(const std::string &nodeName, const std::string &pAttrValue) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN inline void Throw_DEF_And_USE(const std::string &nodeName) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN inline void Throw_IncorrectAttr(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN inline void Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN inline void Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN inline void Throw_TagCountIncorrect(const std::string &pNode) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN inline void Throw_USE_NotFound(const std::string &nodeName, const std::string &pAttrValue) AI_WONT_RETURN_SUFFIX;
inline void Throw_ArgOutOfRange(const std::string &argument) {
throw DeadlyImportError("Argument value is out of range for: \"" + argument + "\".");

View File

@ -513,21 +513,22 @@ struct Camera : public Object {
};
Type type;
struct Perspective {
float aspectRatio; //!<The floating - point aspect ratio of the field of view. (0 = undefined = use the canvas one)
float yfov; //!<The floating - point vertical field of view in radians. (required)
float zfar; //!<The floating - point distance to the far clipping plane. (required)
float znear; //!< The floating - point distance to the near clipping plane. (required)
};
struct Ortographic {
float xmag; //! The floating-point horizontal magnification of the view. (required)
float ymag; //! The floating-point vertical magnification of the view. (required)
float zfar; //! The floating-point distance to the far clipping plane. (required)
float znear; //! The floating-point distance to the near clipping plane. (required)
};
union {
struct {
float aspectRatio; //!<The floating - point aspect ratio of the field of view. (0 = undefined = use the canvas one)
float yfov; //!<The floating - point vertical field of view in radians. (required)
float zfar; //!<The floating - point distance to the far clipping plane. (required)
float znear; //!< The floating - point distance to the near clipping plane. (required)
} perspective;
struct {
float xmag; //! The floating-point horizontal magnification of the view. (required)
float ymag; //! The floating-point vertical magnification of the view. (required)
float zfar; //! The floating-point distance to the far clipping plane. (required)
float znear; //! The floating-point distance to the near clipping plane. (required)
} ortographic;
struct Perspective perspective;
struct Ortographic ortographic;
};
Camera() = default;

View File

@ -483,7 +483,7 @@ private:
public:
Buffer();
~Buffer();
~Buffer() override;
void Read(Value &obj, Asset &r);
@ -565,7 +565,7 @@ struct Accessor : public Object {
inline size_t GetMaxByteSize();
template <class T>
void ExtractData(T *&outData);
size_t ExtractData(T *&outData, const std::vector<unsigned int> *remappingIndices = nullptr);
void WriteData(size_t count, const void *src_buffer, size_t src_stride);
void WriteSparseValues(size_t count, const void *src_data, size_t src_dataStride);

View File

@ -962,14 +962,15 @@ inline size_t Accessor::GetMaxByteSize() {
}
template <class T>
void Accessor::ExtractData(T *&outData) {
size_t Accessor::ExtractData(T *&outData, const std::vector<unsigned int> *remappingIndices) {
uint8_t *data = GetPointer();
if (!data) {
throw DeadlyImportError("GLTF2: data is null when extracting data from ", getContextForErrorMessages(id, name));
}
const size_t usedCount = (remappingIndices != nullptr) ? remappingIndices->size() : count;
const size_t elemSize = GetElementSize();
const size_t totalSize = elemSize * count;
const size_t totalSize = elemSize * usedCount;
const size_t stride = GetStride();
@ -980,18 +981,31 @@ void Accessor::ExtractData(T *&outData) {
}
const size_t maxSize = GetMaxByteSize();
if (count * stride > maxSize) {
throw DeadlyImportError("GLTF: count*stride ", (count * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
}
outData = new T[count];
if (stride == elemSize && targetElemSize == elemSize) {
memcpy(outData, data, totalSize);
} else {
for (size_t i = 0; i < count; ++i) {
memcpy(outData + i, data + i * stride, elemSize);
outData = new T[usedCount];
if (remappingIndices != nullptr) {
const unsigned int maxIndex = static_cast<unsigned int>(maxSize / stride - 1);
for (size_t i = 0; i < usedCount; ++i) {
size_t srcIdx = (*remappingIndices)[i];
if (srcIdx > maxIndex) {
throw DeadlyImportError("GLTF: index*stride ", (srcIdx * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
}
memcpy(outData + i, data + srcIdx * stride, elemSize);
}
} else { // non-indexed cases
if (usedCount * stride > maxSize) {
throw DeadlyImportError("GLTF: count*stride ", (usedCount * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
}
if (stride == elemSize && targetElemSize == elemSize) {
memcpy(outData, data, totalSize);
} else {
for (size_t i = 0; i < usedCount; ++i) {
memcpy(outData + i, data + i * stride, elemSize);
}
}
}
return usedCount;
}
inline void Accessor::WriteData(size_t _count, const void *src_buffer, size_t src_stride) {

View File

@ -453,6 +453,11 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
unsigned int k = 0;
meshOffsets.clear();
std::vector<unsigned int> usedVertexIndices;
std::vector<unsigned int> reverseMappingIndices;
std::vector<unsigned int> indexBuffer;
for (unsigned int m = 0; m < r.meshes.Size(); ++m) {
Mesh &mesh = r.meshes[m];
@ -462,6 +467,50 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
for (unsigned int p = 0; p < mesh.primitives.size(); ++p) {
Mesh::Primitive &prim = mesh.primitives[p];
Mesh::Primitive::Attributes &attr = prim.attributes;
// Find out the maximum number of vertices:
size_t numAllVertices = 0;
if (!attr.position.empty() && attr.position[0]) {
numAllVertices = attr.position[0]->count;
}
// Extract used vertices:
bool useIndexBuffer = prim.indices;
std::vector<unsigned int>* vertexRemappingTable = nullptr;
if (useIndexBuffer) {
size_t count = prim.indices->count;
indexBuffer.resize(count);
usedVertexIndices.clear();
reverseMappingIndices.clear();
usedVertexIndices.reserve(count / 3); // this is a very rough heuristic to reduce re-allocations
vertexRemappingTable = &usedVertexIndices;
Accessor::Indexer data = prim.indices->GetIndexer();
if (!data.IsValid()) {
throw DeadlyImportError("GLTF: Invalid accessor without data in mesh ", getContextForErrorMessages(mesh.id, mesh.name));
}
// Build the vertex remapping table and the modified index buffer (used later instead of the original one)
// In case no index buffer is used, the original vertex arrays are being used so no remapping is required in the first place.
const unsigned int unusedIndex = ~0u;
for (unsigned int i = 0; i < count; ++i) {
unsigned int index = data.GetUInt(i);
if (index >= numAllVertices) {
// Out-of-range indices will be filtered out when adding the faces and then lead to a warning. At this stage, we just keep them.
indexBuffer[i] = index;
continue;
}
if (index >= reverseMappingIndices.size()) {
reverseMappingIndices.resize(index + 1, unusedIndex);
}
if (reverseMappingIndices[index] == unusedIndex) {
reverseMappingIndices[index] = static_cast<unsigned int>(usedVertexIndices.size());
usedVertexIndices.push_back(index);
}
indexBuffer[i] = reverseMappingIndices[index];
}
}
aiMesh *aim = new aiMesh();
meshes.push_back(std::unique_ptr<aiMesh>(aim));
@ -491,28 +540,25 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
break;
}
Mesh::Primitive::Attributes &attr = prim.attributes;
if (!attr.position.empty() && attr.position[0]) {
aim->mNumVertices = static_cast<unsigned int>(attr.position[0]->count);
attr.position[0]->ExtractData(aim->mVertices);
aim->mNumVertices = static_cast<unsigned int>(attr.position[0]->ExtractData(aim->mVertices, vertexRemappingTable));
}
if (!attr.normal.empty() && attr.normal[0]) {
if (attr.normal[0]->count != aim->mNumVertices) {
if (attr.normal[0]->count != numAllVertices) {
DefaultLogger::get()->warn("Normal count in mesh \"", mesh.name, "\" does not match the vertex count, normals ignored.");
} else {
attr.normal[0]->ExtractData(aim->mNormals);
attr.normal[0]->ExtractData(aim->mNormals, vertexRemappingTable);
// only extract tangents if normals are present
if (!attr.tangent.empty() && attr.tangent[0]) {
if (attr.tangent[0]->count != aim->mNumVertices) {
if (attr.tangent[0]->count != numAllVertices) {
DefaultLogger::get()->warn("Tangent count in mesh \"", mesh.name, "\" does not match the vertex count, tangents ignored.");
} else {
// generate bitangents from normals and tangents according to spec
Tangent *tangents = nullptr;
attr.tangent[0]->ExtractData(tangents);
attr.tangent[0]->ExtractData(tangents, vertexRemappingTable);
aim->mTangents = new aiVector3D[aim->mNumVertices];
aim->mBitangents = new aiVector3D[aim->mNumVertices];
@ -529,7 +575,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
}
for (size_t c = 0; c < attr.color.size() && c < AI_MAX_NUMBER_OF_COLOR_SETS; ++c) {
if (attr.color[c]->count != aim->mNumVertices) {
if (attr.color[c]->count != numAllVertices) {
DefaultLogger::get()->warn("Color stream size in mesh \"", mesh.name,
"\" does not match the vertex count");
continue;
@ -537,7 +583,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
auto componentType = attr.color[c]->componentType;
if (componentType == glTF2::ComponentType_FLOAT) {
attr.color[c]->ExtractData(aim->mColors[c]);
attr.color[c]->ExtractData(aim->mColors[c], vertexRemappingTable);
} else {
if (componentType == glTF2::ComponentType_UNSIGNED_BYTE) {
aim->mColors[c] = GetVertexColorsForType<unsigned char>(attr.color[c]);
@ -552,13 +598,13 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
continue;
}
if (attr.texcoord[tc]->count != aim->mNumVertices) {
if (attr.texcoord[tc]->count != numAllVertices) {
DefaultLogger::get()->warn("Texcoord stream size in mesh \"", mesh.name,
"\" does not match the vertex count");
continue;
}
attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc]);
attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc], vertexRemappingTable);
aim->mNumUVComponents[tc] = attr.texcoord[tc]->GetNumComponents();
aiVector3D *values = aim->mTextureCoords[tc];
@ -583,11 +629,11 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
Mesh::Primitive::Target &target = targets[i];
if (needPositions) {
if (target.position[0]->count != aim->mNumVertices) {
if (target.position[0]->count != numAllVertices) {
ASSIMP_LOG_WARN("Positions of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count");
} else {
aiVector3D *positionDiff = nullptr;
target.position[0]->ExtractData(positionDiff);
target.position[0]->ExtractData(positionDiff, vertexRemappingTable);
for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; vertexId++) {
aiAnimMesh.mVertices[vertexId] += positionDiff[vertexId];
}
@ -595,11 +641,11 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
}
}
if (needNormals) {
if (target.normal[0]->count != aim->mNumVertices) {
if (target.normal[0]->count != numAllVertices) {
ASSIMP_LOG_WARN("Normals of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count");
} else {
aiVector3D *normalDiff = nullptr;
target.normal[0]->ExtractData(normalDiff);
target.normal[0]->ExtractData(normalDiff, vertexRemappingTable);
for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; vertexId++) {
aiAnimMesh.mNormals[vertexId] += normalDiff[vertexId];
}
@ -610,14 +656,14 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
if (!aiAnimMesh.HasNormals()) {
// prevent nullptr access to aiAnimMesh.mNormals below when no normals are available
ASSIMP_LOG_WARN("Bitangents of target ", i, " in mesh \"", mesh.name, "\" can't be computed, because mesh has no normals.");
} else if (target.tangent[0]->count != aim->mNumVertices) {
} else if (target.tangent[0]->count != numAllVertices) {
ASSIMP_LOG_WARN("Tangents of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count");
} else {
Tangent *tangent = nullptr;
attr.tangent[0]->ExtractData(tangent);
attr.tangent[0]->ExtractData(tangent, vertexRemappingTable);
aiVector3D *tangentDiff = nullptr;
target.tangent[0]->ExtractData(tangentDiff);
target.tangent[0]->ExtractData(tangentDiff, vertexRemappingTable);
for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; ++vertexId) {
tangent[vertexId].xyz += tangentDiff[vertexId];
@ -641,20 +687,15 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
aiFace *facePtr = nullptr;
size_t nFaces = 0;
if (prim.indices) {
size_t count = prim.indices->count;
Accessor::Indexer data = prim.indices->GetIndexer();
if (!data.IsValid()) {
throw DeadlyImportError("GLTF: Invalid accessor without data in mesh ", getContextForErrorMessages(mesh.id, mesh.name));
}
if (useIndexBuffer) {
size_t count = indexBuffer.size();
switch (prim.mode) {
case PrimitiveMode_POINTS: {
nFaces = count;
facePtr = faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; ++i) {
SetFaceAndAdvance1(facePtr, aim->mNumVertices, data.GetUInt(i));
SetFaceAndAdvance1(facePtr, aim->mNumVertices, indexBuffer[i]);
}
break;
}
@ -667,7 +708,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
}
facePtr = faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 2) {
SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(i), data.GetUInt(i + 1));
SetFaceAndAdvance2(facePtr, aim->mNumVertices, indexBuffer[i], indexBuffer[i + 1]);
}
break;
}
@ -676,12 +717,12 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
case PrimitiveMode_LINE_STRIP: {
nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0);
facePtr = faces = new aiFace[nFaces];
SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(0), data.GetUInt(1));
SetFaceAndAdvance2(facePtr, aim->mNumVertices, indexBuffer[0], indexBuffer[1]);
for (unsigned int i = 2; i < count; ++i) {
SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(i - 1), data.GetUInt(i));
SetFaceAndAdvance2(facePtr, aim->mNumVertices, indexBuffer[i - 1], indexBuffer[i]);
}
if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop
SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(static_cast<int>(count) - 1), faces[0].mIndices[0]);
SetFaceAndAdvance2(facePtr, aim->mNumVertices, indexBuffer[static_cast<int>(count) - 1], faces[0].mIndices[0]);
}
break;
}
@ -694,7 +735,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
}
facePtr = faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 3) {
SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2));
SetFaceAndAdvance3(facePtr, aim->mNumVertices, indexBuffer[i], indexBuffer[i + 1], indexBuffer[i + 2]);
}
break;
}
@ -705,10 +746,10 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
// The ordering is to ensure that the triangles are all drawn with the same orientation
if ((i + 1) % 2 == 0) {
// For even n, vertices n + 1, n, and n + 2 define triangle n
SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(i + 1), data.GetUInt(i), data.GetUInt(i + 2));
SetFaceAndAdvance3(facePtr, aim->mNumVertices, indexBuffer[i + 1], indexBuffer[i], indexBuffer[i + 2]);
} else {
// For odd n, vertices n, n+1, and n+2 define triangle n
SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2));
SetFaceAndAdvance3(facePtr, aim->mNumVertices, indexBuffer[i], indexBuffer[i + 1], indexBuffer[i + 2]);
}
}
break;
@ -716,9 +757,9 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
case PrimitiveMode_TRIANGLE_FAN:
nFaces = count - 2;
facePtr = faces = new aiFace[nFaces];
SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(0), data.GetUInt(1), data.GetUInt(2));
SetFaceAndAdvance3(facePtr, aim->mNumVertices, indexBuffer[0], indexBuffer[1], indexBuffer[2]);
for (unsigned int i = 1; i < nFaces; ++i) {
SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(0), data.GetUInt(i + 1), data.GetUInt(i + 2));
SetFaceAndAdvance3(facePtr, aim->mNumVertices, indexBuffer[0], indexBuffer[i + 1], indexBuffer[i + 2]);
}
break;
}
@ -1172,11 +1213,6 @@ aiNode *ImportNode(aiScene *pScene, glTF2::Asset &r, std::vector<unsigned int> &
if (node.camera) {
pScene->mCameras[node.camera.GetIndex()]->mName = ainode->mName;
if (node.translation.isPresent) {
aiVector3D trans;
CopyValue(node.translation.value, trans);
pScene->mCameras[node.camera.GetIndex()]->mPosition = trans;
}
}
if (node.light) {

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -47,14 +45,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp {
// ------------------------------------------------------------------------------------------------
CIOStreamWrapper::~CIOStreamWrapper() {
/* Various places depend on this destructor to close the file */
if (mFile) {
// Various places depend on this destructor to close the file
if (mFile != nullptr) {
mIO->mFileSystem->CloseProc(mIO->mFileSystem, mFile);
}
}
// ...................................................................
// ------------------------------------------------------------------------------------------------
size_t CIOStreamWrapper::Read(void *pvBuffer,
size_t pSize,
size_t pCount) {
@ -62,7 +62,7 @@ size_t CIOStreamWrapper::Read(void *pvBuffer,
return mFile->ReadProc(mFile, (char *)pvBuffer, pSize, pCount);
}
// ...................................................................
// ------------------------------------------------------------------------------------------------
size_t CIOStreamWrapper::Write(const void *pvBuffer,
size_t pSize,
size_t pCount) {
@ -70,23 +70,23 @@ size_t CIOStreamWrapper::Write(const void *pvBuffer,
return mFile->WriteProc(mFile, (const char *)pvBuffer, pSize, pCount);
}
// ...................................................................
// ------------------------------------------------------------------------------------------------
aiReturn CIOStreamWrapper::Seek(size_t pOffset,
aiOrigin pOrigin) {
return mFile->SeekProc(mFile, pOffset, pOrigin);
}
// ...................................................................
// ------------------------------------------------------------------------------------------------
size_t CIOStreamWrapper::Tell() const {
return mFile->TellProc(mFile);
}
// ...................................................................
// ------------------------------------------------------------------------------------------------
size_t CIOStreamWrapper::FileSize() const {
return mFile->FileSizeProc(mFile);
}
// ...................................................................
// ------------------------------------------------------------------------------------------------
void CIOStreamWrapper::Flush() {
return mFile->FlushProc(mFile);
}

View File

@ -47,48 +47,59 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/cfileio.h>
#include <assimp/IOStream.hpp>
#include <assimp/IOSystem.hpp>
#include <assimp/ai_assert.h>
namespace Assimp {
class CIOSystemWrapper;
// ------------------------------------------------------------------------------------------------
// Custom IOStream implementation for the C-API
class CIOStreamWrapper : public IOStream {
/// @brief Custom IOStream implementation for the C-API-
// ------------------------------------------------------------------------------------------------
class CIOStreamWrapper final : public IOStream {
public:
explicit CIOStreamWrapper(aiFile *pFile, CIOSystemWrapper *io) :
mFile(pFile),
mIO(io) {}
~CIOStreamWrapper(void);
size_t Read(void *pvBuffer, size_t pSize, size_t pCount);
size_t Write(const void *pvBuffer, size_t pSize, size_t pCount);
aiReturn Seek(size_t pOffset, aiOrigin pOrigin);
size_t Tell(void) const;
size_t FileSize() const;
void Flush();
explicit CIOStreamWrapper(aiFile *pFile, CIOSystemWrapper *io);
~CIOStreamWrapper() override;
size_t Read(void *pvBuffer, size_t pSize, size_t pCount) override;
size_t Write(const void *pvBuffer, size_t pSize, size_t pCount) override;
aiReturn Seek(size_t pOffset, aiOrigin pOrigin) override;
size_t Tell(void) const override;
size_t FileSize() const override;
void Flush() override;
private:
aiFile *mFile;
CIOSystemWrapper *mIO;
};
class CIOSystemWrapper : public IOSystem {
inline CIOStreamWrapper::CIOStreamWrapper(aiFile *pFile, CIOSystemWrapper *io) :
mFile(pFile),
mIO(io) {
ai_assert(io != nullptr);
}
// ------------------------------------------------------------------------------------------------
/// @brief Custom IO-System wrapper implementation for the C-API.
// ------------------------------------------------------------------------------------------------
class CIOSystemWrapper final : public IOSystem {
friend class CIOStreamWrapper;
public:
explicit CIOSystemWrapper(aiFileIO *pFile) :
mFileSystem(pFile) {}
bool Exists(const char *pFile) const;
char getOsSeparator() const;
IOStream *Open(const char *pFile, const char *pMode = "rb");
void Close(IOStream *pFile);
explicit CIOSystemWrapper(aiFileIO *pFile);
~CIOSystemWrapper() override = default;
bool Exists(const char *pFile) const override;
char getOsSeparator() const override;
IOStream *Open(const char *pFile, const char *pMode = "rb") override;
void Close(IOStream *pFile) override;
private:
aiFileIO *mFileSystem;
};
inline CIOSystemWrapper::CIOSystemWrapper(aiFileIO *pFile) : mFileSystem(pFile) {
ai_assert(pFile != nullptr);
}
} // namespace Assimp
#endif
#endif // AI_CIOSYSTEM_H_INCLUDED

View File

@ -218,6 +218,12 @@ SET( CApi_SRCS
)
SOURCE_GROUP(CApi FILES ${CApi_SRCS})
SET(Geometry_SRCS
Geometry/GeometryUtils.h
Geometry/GeometryUtils.cpp
)
SOURCE_GROUP(Geometry FILES ${Geometry_SRCS})
SET( STEPParser_SRCS
AssetLib/STEPParser/STEPFileReader.h
AssetLib/STEPParser/STEPFileReader.cpp
@ -1129,6 +1135,7 @@ SET( assimp_src
${Core_SRCS}
${CApi_SRCS}
${Common_SRCS}
${Geometry_SRCS}
${Logging_SRCS}
${Exporter_SRCS}
${PostProcessing_SRCS}
@ -1188,7 +1195,64 @@ TARGET_USE_COMMON_OUTPUT_DIRECTORY(assimp)
IF (ASSIMP_WARNINGS_AS_ERRORS)
MESSAGE(STATUS "Treating all warnings as errors (for assimp library only)")
IF (MSVC)
TARGET_COMPILE_OPTIONS(assimp PRIVATE /W4 /WX)
IF(CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) # clang-cl
TARGET_COMPILE_OPTIONS(assimp PRIVATE -Wall -Werror
-Wno-unused-function
-Wno-microsoft-enum-value
-Wno-switch-enum
-Wno-covered-switch-default
-Wno-reserved-identifier
-Wno-c++98-compat-pedantic
-Wno-c++98-compat
-Wno-documentation
-Wno-documentation-unknown-command
-Wno-deprecated-dynamic-exception-spec
-Wno-undef
-Wno-suggest-destructor-override
-Wno-suggest-override
-Wno-zero-as-null-pointer-constant
-Wno-global-constructors
-Wno-exit-time-destructors
-Wno-extra-semi-stmt
-Wno-missing-prototypes
-Wno-old-style-cast
-Wno-cast-align
-Wno-cast-qual
-Wno-float-equal
-Wno-implicit-int-float-conversion
-Wno-sign-conversion
-Wno-implicit-float-conversion
-Wno-implicit-int-conversion
-Wno-float-conversion
-Wno-double-promotion
-Wno-unused-macros
-Wno-disabled-macro-expansion
-Wno-shadow-field
-Wno-shadow
-Wno-language-extension-token
-Wno-header-hygiene
-Wno-tautological-value-range-compare
-Wno-tautological-type-limit-compare
-Wno-missing-noreturn
-Wno-missing-variable-declarations
-Wno-extra-semi
-Wno-nonportable-system-include-path
-Wno-undefined-reinterpret-cast
-Wno-shift-sign-overflow
-Wno-deprecated-copy-with-user-provided-dtor
-Wno-deprecated-copy-with-dtor
-Wno-deprecated
-Wno-format-nonliteral
-Wno-comma
-Wno-implicit-fallthrough
-Wno-unused-template
-Wno-undefined-func-template
-Wno-declaration-after-statement
)
ELSE()
TARGET_COMPILE_OPTIONS(assimp PRIVATE /W4 /WX)
ENDIF()
ELSE()
TARGET_COMPILE_OPTIONS(assimp PRIVATE -Wall -Werror)
ENDIF()

View File

@ -214,7 +214,12 @@ void GetImporterInstanceList(std::vector<BaseImporter *> &out) {
// Some importers may be unimplemented or otherwise unsuitable for general use
// in their current state. Devs can set ASSIMP_ENABLE_DEV_IMPORTERS in their
// local environment to enable them, otherwise they're left out of the registry.
#if defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP
// not supported under uwp
const char *envStr = std::getenv("ASSIMP_ENABLE_DEV_IMPORTERS");
#else
const char *envStr = { "0" };
#endif
bool devImportersEnabled = envStr && strcmp(envStr, "0");
// Ensure no unused var warnings if all uses are #ifndef'd away below:
@ -377,9 +382,6 @@ void GetImporterInstanceList(std::vector<BaseImporter *> &out) {
#ifndef ASSIMP_BUILD_NO_IQM_IMPORTER
out.push_back(new IQMImporter());
#endif
//#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER
// out.push_back(new StepFile::StepFileImporter());
//#endif
}
/** will delete all registered importers. */

View File

@ -74,26 +74,8 @@ inline bool OnLeftSideOfLine2D(const T& p0, const T& p1,const T& p2) {
* both aiVector3D and aiVector2D, but generally ignores the third coordinate.*/
template <typename T>
inline bool PointInTriangle2D(const T& p0, const T& p1,const T& p2, const T& pp) {
// Point in triangle test using baryzentric coordinates
const aiVector2D v0 = p1 - p0;
const aiVector2D v1 = p2 - p0;
const aiVector2D v2 = pp - p0;
double dot00 = v0 * v0;
double dot11 = v1 * v1;
const double dot01 = v0 * v1;
const double dot02 = v0 * v2;
const double dot12 = v1 * v2;
const double denom = dot00 * dot11 - dot01 * dot01;
if (denom == 0.0) {
return false;
}
const double invDenom = 1.0 / denom;
dot11 = (dot11 * dot02 - dot01 * dot12) * invDenom;
dot00 = (dot00 * dot12 - dot01 * dot02) * invDenom;
return (dot11 > 0) && (dot00 > 0) && (dot11 + dot00 < 1);
// pp should be left side of the three triangle side, by ccw arrow
return OnLeftSideOfLine2D(p0, p1, pp) && OnLeftSideOfLine2D(p1, p2, pp) && OnLeftSideOfLine2D(p2, p0, pp);
}

View File

@ -50,7 +50,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stdio.h>
#include <unordered_map>
using namespace Assimp;
void mydummy() {}
#ifdef _MSC_VER
@ -78,7 +81,7 @@ public:
};
typedef std::vector<unsigned int> UIntVector;
typedef std::map<uint64_t, Edge> EdgeMap;
typedef std::unordered_map<uint64_t, Edge> EdgeMap;
// ---------------------------------------------------------------------------
// Hashing function to derive an index into an #EdgeMap from two given

View File

@ -68,7 +68,7 @@ class ZipFile : public IOStream {
public:
std::string m_Filename;
virtual ~ZipFile();
virtual ~ZipFile() override;
// IOStream interface
size_t Read(void *pvBuffer, size_t pSize, size_t pCount) override;

View File

@ -1,17 +1,14 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
----------------------------------------------------------------------
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
with or without modification, are permitted provided that the
following conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
@ -38,55 +35,45 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
----------------------------------------------------------------------
*/
#ifndef ASSIMP_SAMPLES_SHARED_CODE_UTFCONVERTER_H
#define ASSIMP_SAMPLES_SHARED_CODE_UTFCONVERTER_H
#include "GeometryUtils.h"
#include <string>
#include <locale>
#include <codecvt>
#include <assimp/vector3.h>
namespace AssimpSamples {
namespace SharedCode {
namespace Assimp {
// Used to convert between multibyte and unicode strings.
class UTFConverter {
using UTFConverterImpl = std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>;
public:
UTFConverter(const char* s) :
s_(s),
ws_(impl_.from_bytes(s)) {
}
UTFConverter(const wchar_t* s) :
s_(impl_.to_bytes(s)),
ws_(s) {
}
UTFConverter(const std::string& s) :
s_(s),
ws_(impl_.from_bytes(s)) {
}
UTFConverter(const std::wstring& s) :
s_(impl_.to_bytes(s)),
ws_(s) {
}
inline const char* c_str() const {
return s_.c_str();
}
inline const std::string& str() const {
return s_;
}
inline const wchar_t* c_wstr() const {
return ws_.c_str();
}
private:
static UTFConverterImpl impl_;
std::string s_;
std::wstring ws_;
};
}
ai_real GeometryUtils::heron( ai_real a, ai_real b, ai_real c ) {
ai_real s = (a + b + c) / 2;
ai_real area = pow((s * ( s - a ) * ( s - b ) * ( s - c ) ), (ai_real)0.5 );
return area;
}
#endif // ASSIMP_SAMPLES_SHARED_CODE_UTFCONVERTER_H
ai_real GeometryUtils::distance3D( const aiVector3D &vA, aiVector3D &vB ) {
const ai_real lx = ( vB.x - vA.x );
const ai_real ly = ( vB.y - vA.y );
const ai_real lz = ( vB.z - vA.z );
ai_real a = lx*lx + ly*ly + lz*lz;
ai_real d = pow( a, (ai_real)0.5 );
return d;
}
ai_real GeometryUtils::calculateAreaOfTriangle( const aiFace& face, aiMesh* mesh ) {
ai_real area = 0;
aiVector3D vA( mesh->mVertices[ face.mIndices[ 0 ] ] );
aiVector3D vB( mesh->mVertices[ face.mIndices[ 1 ] ] );
aiVector3D vC( mesh->mVertices[ face.mIndices[ 2 ] ] );
ai_real a( distance3D( vA, vB ) );
ai_real b( distance3D( vB, vC ) );
ai_real c( distance3D( vC, vA ) );
area = heron( a, b, c );
return area;
}
} // namespace Assimp

View File

@ -1,17 +1,14 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
----------------------------------------------------------------------
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
with or without modification, are permitted provided that the
following conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
@ -38,15 +35,33 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
----------------------------------------------------------------------
*/
#include "UTFConverter.h"
#include <assimp/types.h>
#include <assimp/mesh.h>
namespace AssimpSamples {
namespace SharedCode {
namespace Assimp {
typename UTFConverter::UTFConverterImpl UTFConverter::impl_;
// ---------------------------------------------------------------------------
/// @brief This helper class supports some basic geometry algorithms.
// ---------------------------------------------------------------------------
class GeometryUtils {
public:
static ai_real heron( ai_real a, ai_real b, ai_real c );
/// @brief Will compute the distance between 2 3D-vectors
/// @param vA Vector a.
/// @param vB Vector b.
/// @return The distance.
static ai_real distance3D( const aiVector3D &vA, aiVector3D &vB );
}
}
/// @brief Will calculate the area of a triangle described by a aiFace.
/// @param face The face
/// @param mesh The mesh containing the face
/// @return The area.
static ai_real calculateAreaOfTriangle( const aiFace& face, aiMesh* mesh );
};
} // namespace Assimp

View File

@ -60,10 +60,6 @@ CalcTangentsProcess::CalcTangentsProcess() :
// nothing to do here
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
CalcTangentsProcess::~CalcTangentsProcess() = default;
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool CalcTangentsProcess::IsActive(unsigned int pFlags) const {

View File

@ -59,14 +59,11 @@ namespace Assimp
* because the joining of vertices also considers tangents and bitangents for
* uniqueness.
*/
class ASSIMP_API_WINONLY CalcTangentsProcess : public BaseProcess
{
class ASSIMP_API_WINONLY CalcTangentsProcess : public BaseProcess {
public:
CalcTangentsProcess();
~CalcTangentsProcess();
~CalcTangentsProcess() override = default;
public:
// -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag.
* @param pFlags The processing flags the importer was called with.
@ -74,24 +71,21 @@ public:
* @return true if the process is present in this flag fields,
* false if not.
*/
bool IsActive( unsigned int pFlags) const;
bool IsActive( unsigned int pFlags) const override;
// -------------------------------------------------------------------
/** Called prior to ExecuteOnScene().
* The function is a request to the process to update its configuration
* basing on the Importer's configuration property list.
*/
void SetupProperties(const Importer* pImp);
void SetupProperties(const Importer* pImp) override;
// setter for configMaxAngle
inline void SetMaxSmoothAngle(float f)
{
void SetMaxSmoothAngle(float f) {
configMaxAngle =f;
}
protected:
// -------------------------------------------------------------------
/** Calculates tangents and bitangents for a specific mesh.
* @param pMesh The mesh to process.
@ -103,10 +97,9 @@ protected:
/** Executes the post processing step on the given imported data.
* @param pScene The imported data to work at.
*/
void Execute( aiScene* pScene);
void Execute( aiScene* pScene) override;
private:
/** Configuration option: maximum smoothing angle, in radians*/
float configMaxAngle;
unsigned int configSourceUV;

View File

@ -57,14 +57,6 @@ namespace {
const static ai_real angle_epsilon = ai_real( 0.95 );
}
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
ComputeUVMappingProcess::ComputeUVMappingProcess() = default;
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
ComputeUVMappingProcess::~ComputeUVMappingProcess() = default;
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool ComputeUVMappingProcess::IsActive( unsigned int pFlags) const

View File

@ -59,13 +59,10 @@ namespace Assimp {
/** ComputeUVMappingProcess - converts special mappings, such as spherical,
* cylindrical or boxed to proper UV coordinates for rendering.
*/
class ComputeUVMappingProcess : public BaseProcess
{
public:
ComputeUVMappingProcess();
~ComputeUVMappingProcess();
class ComputeUVMappingProcess : public BaseProcess {
public:
ComputeUVMappingProcess() = default;
~ComputeUVMappingProcess() override = default;
// -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag field.
@ -73,14 +70,14 @@ public:
* combination of #aiPostProcessSteps.
* @return true if the process is present in this flag fields, false if not.
*/
bool IsActive( unsigned int pFlags) const;
bool IsActive( unsigned int pFlags) const override;
// -------------------------------------------------------------------
/** Executes the post processing step on the given imported data.
* At the moment a process is not supposed to fail.
* @param pScene The imported data to work at.
*/
void Execute( aiScene* pScene);
void Execute( aiScene* pScene) override;
protected:
@ -125,8 +122,7 @@ protected:
private:
// temporary structure to describe a mapping
struct MappingInfo
{
struct MappingInfo {
explicit MappingInfo(aiTextureMapping _type)
: type (_type)
, axis (0.f,1.f,0.f)
@ -137,8 +133,7 @@ private:
aiVector3D axis;
unsigned int uv;
bool operator== (const MappingInfo& other)
{
bool operator== (const MappingInfo& other) {
return type == other.type && axis == other.axis;
}
};

View File

@ -79,14 +79,6 @@ void flipUVs(aiMeshType *pMesh) {
} // namespace
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
MakeLeftHandedProcess::MakeLeftHandedProcess() = default;
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
MakeLeftHandedProcess::~MakeLeftHandedProcess() = default;
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool MakeLeftHandedProcess::IsActive(unsigned int pFlags) const {
@ -121,6 +113,12 @@ void MakeLeftHandedProcess::Execute(aiScene *pScene) {
ProcessAnimation(nodeAnim);
}
}
// process the cameras accordingly
for( unsigned int a = 0; a < pScene->mNumCameras; ++a)
{
ProcessCamera(pScene->mCameras[a]);
}
ASSIMP_LOG_DEBUG("MakeLeftHandedProcess finished");
}
@ -239,6 +237,13 @@ void MakeLeftHandedProcess::ProcessAnimation(aiNodeAnim *pAnim) {
}
}
// ------------------------------------------------------------------------------------------------
// Converts a single camera to left handed coordinates.
void MakeLeftHandedProcess::ProcessCamera( aiCamera* pCam)
{
pCam->mLookAt = 2.0f * pCam->mPosition - pCam->mLookAt;
}
#endif // !! ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS
#ifndef ASSIMP_BUILD_NO_FLIPUVS_PROCESS
// # FlipUVsProcess
@ -305,14 +310,6 @@ void FlipUVsProcess::ProcessMesh(aiMesh *pMesh) {
#ifndef ASSIMP_BUILD_NO_FLIPWINDING_PROCESS
// # FlipWindingOrderProcess
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
FlipWindingOrderProcess::FlipWindingOrderProcess() = default;
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
FlipWindingOrderProcess::~FlipWindingOrderProcess() = default;
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool FlipWindingOrderProcess::IsActive(unsigned int pFlags) const {

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -59,6 +58,7 @@ struct aiMesh;
struct aiNodeAnim;
struct aiNode;
struct aiMaterial;
struct aiCamera;
namespace Assimp {
@ -72,22 +72,18 @@ namespace Assimp {
*
* @note RH-LH and LH-RH is the same, so this class can be used for both
*/
class MakeLeftHandedProcess : public BaseProcess
{
class MakeLeftHandedProcess : public BaseProcess {
public:
MakeLeftHandedProcess();
~MakeLeftHandedProcess();
MakeLeftHandedProcess() = default;
~MakeLeftHandedProcess() override = default;
// -------------------------------------------------------------------
bool IsActive( unsigned int pFlags) const;
bool IsActive( unsigned int pFlags) const override;
// -------------------------------------------------------------------
void Execute( aiScene* pScene);
void Execute( aiScene* pScene) override;
protected:
// -------------------------------------------------------------------
/** Recursively converts a node and all of its children
*/
@ -114,30 +110,36 @@ protected:
* @param pAnim The bone animation to transform
*/
void ProcessAnimation( aiNodeAnim* pAnim);
// -------------------------------------------------------------------
/** Converts a single camera to left handed coordinates.
* The camera viewing direction is inverted by reflecting mLookAt
* across mPosition.
* @param pCam The camera to convert
*/
void ProcessCamera( aiCamera* pCam);
};
// ---------------------------------------------------------------------------
/** Postprocessing step to flip the face order of the imported data
*/
class FlipWindingOrderProcess : public BaseProcess
{
class FlipWindingOrderProcess : public BaseProcess {
friend class Importer;
public:
/** Constructor to be privately used by Importer */
FlipWindingOrderProcess();
FlipWindingOrderProcess() = default;
/** Destructor, private as well */
~FlipWindingOrderProcess();
~FlipWindingOrderProcess() override = default;
// -------------------------------------------------------------------
bool IsActive( unsigned int pFlags) const;
bool IsActive( unsigned int pFlags) const override;
// -------------------------------------------------------------------
void Execute( aiScene* pScene);
void Execute( aiScene* pScene) override;
public:
/** Some other types of post-processing require winding order flips */
static void ProcessMesh( aiMesh* pMesh);
};

View File

@ -43,42 +43,26 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/// @file DeboneProcess.cpp
/** Implementation of the DeboneProcess post processing step */
// internal headers of the post-processing framework
#include "ProcessHelper.h"
#include "DeboneProcess.h"
#include <stdio.h>
using namespace Assimp;
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
DeboneProcess::DeboneProcess()
{
mNumBones = 0;
mNumBonesCanDoWithout = 0;
mThreshold = AI_DEBONE_THRESHOLD;
mAllOrNone = false;
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
DeboneProcess::~DeboneProcess() = default;
DeboneProcess::DeboneProcess() : mNumBones(0), mNumBonesCanDoWithout(0), mThreshold(AI_DEBONE_THRESHOLD), mAllOrNone(false) {}
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool DeboneProcess::IsActive( unsigned int pFlags) const
{
bool DeboneProcess::IsActive( unsigned int pFlags) const {
return (pFlags & aiProcess_Debone) != 0;
}
// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
void DeboneProcess::SetupProperties(const Importer* pImp)
{
void DeboneProcess::SetupProperties(const Importer* pImp) {
// get the current value of the property
mAllOrNone = pImp->GetPropertyInteger(AI_CONFIG_PP_DB_ALL_OR_NONE,0)?true:false;
mThreshold = pImp->GetPropertyFloat(AI_CONFIG_PP_DB_THRESHOLD,AI_DEBONE_THRESHOLD);
@ -86,8 +70,7 @@ void DeboneProcess::SetupProperties(const Importer* pImp)
// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
void DeboneProcess::Execute( aiScene* pScene)
{
void DeboneProcess::Execute( aiScene* pScene) {
ASSIMP_LOG_DEBUG("DeboneProcess begin");
if(!pScene->mNumMeshes) {
@ -117,10 +100,8 @@ void DeboneProcess::Execute( aiScene* pScene)
// build a new array of meshes for the scene
std::vector<aiMesh*> meshes;
for(unsigned int a=0;a<pScene->mNumMeshes;a++)
{
for (unsigned int a=0;a<pScene->mNumMeshes; ++a) {
aiMesh* srcMesh = pScene->mMeshes[a];
std::vector<std::pair<aiMesh*,const aiBone*> > newMeshes;
if(splitList[a]) {
@ -150,8 +131,7 @@ void DeboneProcess::Execute( aiScene* pScene)
// and destroy the source mesh. It should be completely contained inside the new submeshes
delete srcMesh;
}
else {
} else {
// Mesh is kept unchanged - store it's new place in the mesh array
mSubMeshIndices[a].emplace_back(static_cast<unsigned int>(meshes.size()), (aiNode *)nullptr);
meshes.push_back(srcMesh);
@ -173,8 +153,7 @@ void DeboneProcess::Execute( aiScene* pScene)
// ------------------------------------------------------------------------------------------------
// Counts bones total/removable in a given mesh.
bool DeboneProcess::ConsiderMesh(const aiMesh* pMesh)
{
bool DeboneProcess::ConsiderMesh(const aiMesh* pMesh) {
if(!pMesh->HasBones()) {
return false;
}
@ -193,25 +172,23 @@ bool DeboneProcess::ConsiderMesh(const aiMesh* pMesh)
for(unsigned int i=0;i<pMesh->mNumBones;i++) {
for(unsigned int j=0;j<pMesh->mBones[i]->mNumWeights;j++) {
float w = pMesh->mBones[i]->mWeights[j].mWeight;
if(w==0.0f) {
if (w == 0.0f) {
continue;
}
unsigned int vid = pMesh->mBones[i]->mWeights[j].mVertexId;
if(w>=mThreshold) {
if(vertexBones[vid]!=cUnowned) {
if(vertexBones[vid]==i) //double entry
{
if (w >= mThreshold) {
if (vertexBones[vid] != cUnowned) {
//double entry
if(vertexBones[vid]==i) {
ASSIMP_LOG_WARN("Encountered double entry in bone weights");
}
else //TODO: track attraction in order to break tie
{
} else {
//TODO: track attraction in order to break tie
vertexBones[vid] = cCoowned;
}
}
else vertexBones[vid] = i;
} else {
vertexBones[vid] = i;
}
}
if(!isBoneNecessary[i]) {
@ -227,13 +204,16 @@ bool DeboneProcess::ConsiderMesh(const aiMesh* pMesh)
if(isInterstitialRequired) {
for(unsigned int i=0;i<pMesh->mNumFaces;i++) {
unsigned int v = vertexBones[pMesh->mFaces[i].mIndices[0]];
for(unsigned int j=1;j<pMesh->mFaces[i].mNumIndices;j++) {
for (unsigned int j=1;j<pMesh->mFaces[i].mNumIndices;j++) {
unsigned int w = vertexBones[pMesh->mFaces[i].mIndices[j]];
if(v!=w) {
if(v<pMesh->mNumBones) isBoneNecessary[v] = true;
if(w<pMesh->mNumBones) isBoneNecessary[w] = true;
if (v != w) {
if(v<pMesh->mNumBones) {
isBoneNecessary[v] = true;
}
if (w<pMesh->mNumBones) {
isBoneNecessary[w] = true;
}
}
}
}
@ -252,8 +232,7 @@ bool DeboneProcess::ConsiderMesh(const aiMesh* pMesh)
// ------------------------------------------------------------------------------------------------
// Splits the given mesh by bone count.
void DeboneProcess::SplitMesh( const aiMesh* pMesh, std::vector< std::pair< aiMesh*,const aiBone* > >& poNewMeshes) const
{
void DeboneProcess::SplitMesh( const aiMesh* pMesh, std::vector< std::pair< aiMesh*,const aiBone* > >& poNewMeshes) const {
// same deal here as ConsiderMesh basically
std::vector<bool> isBoneNecessary(pMesh->mNumBones,false);
@ -371,8 +350,7 @@ void DeboneProcess::SplitMesh( const aiMesh* pMesh, std::vector< std::pair< aiMe
// ------------------------------------------------------------------------------------------------
// Recursively updates the node's mesh list to account for the changed mesh list
void DeboneProcess::UpdateNode(aiNode* pNode) const
{
void DeboneProcess::UpdateNode(aiNode* pNode) const {
// rebuild the node's mesh index list
std::vector<unsigned int> newMeshList;
@ -430,8 +408,7 @@ void DeboneProcess::UpdateNode(aiNode* pNode) const
// ------------------------------------------------------------------------------------------------
// Apply the node transformation to a mesh
void DeboneProcess::ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat)const
{
void DeboneProcess::ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat)const {
// Check whether we need to transform the coordinates at all
if (!mat.IsIdentity()) {

View File

@ -70,7 +70,7 @@ namespace Assimp {
class DeboneProcess : public BaseProcess {
public:
DeboneProcess();
~DeboneProcess();
~DeboneProcess() override = default;
// -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag.
@ -79,14 +79,14 @@ public:
* @return true if the process is present in this flag fields,
* false if not.
*/
bool IsActive( unsigned int pFlags) const;
bool IsActive( unsigned int pFlags) const override;
// -------------------------------------------------------------------
/** Called prior to ExecuteOnScene().
* The function is a request to the process to update its configuration
* basing on the Importer's configuration property list.
*/
void SetupProperties(const Importer* pImp);
void SetupProperties(const Importer* pImp) override;
protected:
// -------------------------------------------------------------------
@ -94,7 +94,7 @@ protected:
* At the moment a process is not supposed to fail.
* @param pScene The imported data to work at.
*/
void Execute( aiScene* pScene);
void Execute( aiScene* pScene) override;
// -------------------------------------------------------------------
/** Counts bones total/removable in a given mesh.

View File

@ -54,14 +54,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp;
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
DropFaceNormalsProcess::DropFaceNormalsProcess() = default;
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
DropFaceNormalsProcess::~DropFaceNormalsProcess() = default;
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool DropFaceNormalsProcess::IsActive( unsigned int pFlags) const {

View File

@ -55,8 +55,8 @@ namespace Assimp {
*/
class ASSIMP_API_WINONLY DropFaceNormalsProcess : public BaseProcess {
public:
DropFaceNormalsProcess();
~DropFaceNormalsProcess();
DropFaceNormalsProcess() = default;
~DropFaceNormalsProcess() override = default;
// -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag field.
@ -64,15 +64,14 @@ public:
* combination of #aiPostProcessSteps.
* @return true if the process is present in this flag fields, false if not.
*/
bool IsActive( unsigned int pFlags) const;
bool IsActive( unsigned int pFlags) const override;
// -------------------------------------------------------------------
/** Executes the post processing step on the given imported data.
* At the moment a process is not supposed to fail.
* @param pScene The imported data to work at.
*/
void Execute( aiScene* pScene);
void Execute( aiScene* pScene) override;
private:
bool DropMeshFaceNormals(aiMesh* pcMesh);

View File

@ -49,10 +49,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp;
EmbedTexturesProcess::EmbedTexturesProcess() = default;
EmbedTexturesProcess::~EmbedTexturesProcess() = default;
bool EmbedTexturesProcess::IsActive(unsigned int pFlags) const {
return (pFlags & aiProcess_EmbedTextures) != 0;
}

View File

@ -62,19 +62,19 @@ namespace Assimp {
class ASSIMP_API EmbedTexturesProcess : public BaseProcess {
public:
/// The default class constructor.
EmbedTexturesProcess();
EmbedTexturesProcess() = default;
/// The class destructor.
virtual ~EmbedTexturesProcess();
~EmbedTexturesProcess() override = default;
/// Overwritten, @see BaseProcess
virtual bool IsActive(unsigned int pFlags) const;
bool IsActive(unsigned int pFlags) const override;
/// Overwritten, @see BaseProcess
virtual void SetupProperties(const Importer* pImp);
void SetupProperties(const Importer* pImp) override;
/// Overwritten, @see BaseProcess
virtual void Execute(aiScene* pScene);
virtual void Execute(aiScene* pScene) override;
private:
// Resolve the path and add the file content to the scene as a texture.

View File

@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "ProcessHelper.h"
#include "FindDegenerates.h"
#include "Geometry/GeometryUtils.h"
#include <assimp/Exceptional.h>
@ -63,10 +64,6 @@ FindDegeneratesProcess::FindDegeneratesProcess() :
// empty
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
FindDegeneratesProcess::~FindDegeneratesProcess() = default;
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool FindDegeneratesProcess::IsActive( unsigned int pFlags) const {
@ -132,37 +129,6 @@ static void updateSceneGraph(aiNode* pNode, const std::unordered_map<unsigned in
}
}
static ai_real heron( ai_real a, ai_real b, ai_real c ) {
ai_real s = (a + b + c) / 2;
ai_real area = pow((s * ( s - a ) * ( s - b ) * ( s - c ) ), (ai_real)0.5 );
return area;
}
static ai_real distance3D( const aiVector3D &vA, aiVector3D &vB ) {
const ai_real lx = ( vB.x - vA.x );
const ai_real ly = ( vB.y - vA.y );
const ai_real lz = ( vB.z - vA.z );
ai_real a = lx*lx + ly*ly + lz*lz;
ai_real d = pow( a, (ai_real)0.5 );
return d;
}
static ai_real calculateAreaOfTriangle( const aiFace& face, aiMesh* mesh ) {
ai_real area = 0;
aiVector3D vA( mesh->mVertices[ face.mIndices[ 0 ] ] );
aiVector3D vB( mesh->mVertices[ face.mIndices[ 1 ] ] );
aiVector3D vC( mesh->mVertices[ face.mIndices[ 2 ] ] );
ai_real a( distance3D( vA, vB ) );
ai_real b( distance3D( vB, vC ) );
ai_real c( distance3D( vC, vA ) );
area = heron( a, b, c );
return area;
}
// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported mesh
bool FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
@ -218,7 +184,7 @@ bool FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
if ( mConfigCheckAreaOfTriangle ) {
if ( face.mNumIndices == 3 ) {
ai_real area = calculateAreaOfTriangle( face, mesh );
ai_real area = GeometryUtils::calculateAreaOfTriangle( face, mesh );
if (area < ai_epsilon) {
if ( mConfigRemoveDegenerates ) {
remove_me[ a ] = true;

View File

@ -59,19 +59,19 @@ namespace Assimp {
class ASSIMP_API FindDegeneratesProcess : public BaseProcess {
public:
FindDegeneratesProcess();
~FindDegeneratesProcess();
~FindDegeneratesProcess() override = default;
// -------------------------------------------------------------------
// Check whether step is active
bool IsActive( unsigned int pFlags) const;
bool IsActive( unsigned int pFlags) const override;
// -------------------------------------------------------------------
// Execute step on a given scene
void Execute( aiScene* pScene);
void Execute( aiScene* pScene) override;
// -------------------------------------------------------------------
// Setup import settings
void SetupProperties(const Importer* pImp);
void SetupProperties(const Importer* pImp) override;
// -------------------------------------------------------------------
// Execute step on a given mesh
@ -105,23 +105,19 @@ private:
bool mConfigCheckAreaOfTriangle;
};
inline
void FindDegeneratesProcess::EnableInstantRemoval(bool enabled) {
inline void FindDegeneratesProcess::EnableInstantRemoval(bool enabled) {
mConfigRemoveDegenerates = enabled;
}
inline
bool FindDegeneratesProcess::IsInstantRemoval() const {
inline bool FindDegeneratesProcess::IsInstantRemoval() const {
return mConfigRemoveDegenerates;
}
inline
void FindDegeneratesProcess::EnableAreaCheck( bool enabled ) {
inline void FindDegeneratesProcess::EnableAreaCheck( bool enabled ) {
mConfigCheckAreaOfTriangle = enabled;
}
inline
bool FindDegeneratesProcess::isAreaCheckEnabled() const {
inline bool FindDegeneratesProcess::isAreaCheckEnabled() const {
return mConfigCheckAreaOfTriangle;
}

View File

@ -58,10 +58,6 @@ FindInstancesProcess::FindInstancesProcess()
: configSpeedFlag (false)
{}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
FindInstancesProcess::~FindInstancesProcess() = default;
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool FindInstancesProcess::IsActive( unsigned int pFlags) const

View File

@ -50,7 +50,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "PostProcessing/ProcessHelper.h"
class FindInstancesProcessTest;
namespace Assimp {
namespace Assimp {
// -------------------------------------------------------------------------------
/** @brief Get a pseudo(!)-hash representing a mesh.
@ -60,8 +61,7 @@ namespace Assimp {
* @param in Input mesh
* @return Hash.
*/
inline
uint64_t GetMeshHash(aiMesh* in) {
inline uint64_t GetMeshHash(aiMesh* in) {
ai_assert(nullptr != in);
// ... get an unique value representing the vertex format of the mesh
@ -83,8 +83,7 @@ uint64_t GetMeshHash(aiMesh* in) {
* @param e Epsilon
* @return true if the arrays are identical
*/
inline
bool CompareArrays(const aiVector3D* first, const aiVector3D* second,
inline bool CompareArrays(const aiVector3D* first, const aiVector3D* second,
unsigned int size, float e) {
for (const aiVector3D* end = first+size; first != end; ++first,++second) {
if ( (*first - *second).SquareLength() >= e)
@ -107,31 +106,27 @@ inline bool CompareArrays(const aiColor4D* first, const aiColor4D* second,
// ---------------------------------------------------------------------------
/** @brief A post-processing steps to search for instanced meshes
*/
class FindInstancesProcess : public BaseProcess
{
class FindInstancesProcess : public BaseProcess {
public:
FindInstancesProcess();
~FindInstancesProcess();
~FindInstancesProcess() override = default;
public:
// -------------------------------------------------------------------
// Check whether step is active in given flags combination
bool IsActive( unsigned int pFlags) const;
bool IsActive( unsigned int pFlags) const override;
// -------------------------------------------------------------------
// Execute step on a given scene
void Execute( aiScene* pScene);
void Execute( aiScene* pScene) override;
// -------------------------------------------------------------------
// Setup properties prior to executing the process
void SetupProperties(const Importer* pImp);
void SetupProperties(const Importer* pImp) override;
private:
bool configSpeedFlag;
}; // ! end class FindInstancesProcess
} // ! end namespace Assimp
#endif // !! AI_FINDINSTANCES_H_INC

View File

@ -60,10 +60,6 @@ FindInvalidDataProcess::FindInvalidDataProcess() :
// nothing to do here
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
FindInvalidDataProcess::~FindInvalidDataProcess() = default;
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool FindInvalidDataProcess::IsActive(unsigned int pFlags) const {

View File

@ -64,35 +64,37 @@ namespace Assimp {
* which have zero normal vectors. */
class ASSIMP_API FindInvalidDataProcess : public BaseProcess {
public:
// -------------------------------------------------------------------
/// The default class constructor / destructor.
FindInvalidDataProcess();
~FindInvalidDataProcess();
~FindInvalidDataProcess() override = default;
// -------------------------------------------------------------------
//
bool IsActive(unsigned int pFlags) const;
/// Returns active state.
bool IsActive(unsigned int pFlags) const override;
// -------------------------------------------------------------------
// Setup import settings
void SetupProperties(const Importer *pImp);
/// Setup import settings
void SetupProperties(const Importer *pImp) override;
// -------------------------------------------------------------------
// Run the step
void Execute(aiScene *pScene);
/// Run the step
void Execute(aiScene *pScene) override;
// -------------------------------------------------------------------
/** Executes the post-processing step on the given mesh
* @param pMesh The mesh to process.
* @return 0 - nothing, 1 - removed sth, 2 - please delete me */
/// Executes the post-processing step on the given mesh
/// @param pMesh The mesh to process.
/// @return 0 - nothing, 1 - removed sth, 2 - please delete me */
int ProcessMesh(aiMesh *pMesh);
// -------------------------------------------------------------------
/** Executes the post-processing step on the given animation
* @param anim The animation to process. */
/// Executes the post-processing step on the given animation
/// @param anim The animation to process. */
void ProcessAnimation(aiAnimation *anim);
// -------------------------------------------------------------------
/** Executes the post-processing step on the given anim channel
* @param anim The animation channel to process.*/
/// Executes the post-processing step on the given anim channel
/// @param anim The animation channel to process.*/
void ProcessAnimationChannel(aiNodeAnim *anim);
private:

View File

@ -56,26 +56,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp;
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
FixInfacingNormalsProcess::FixInfacingNormalsProcess() = default;
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
FixInfacingNormalsProcess::~FixInfacingNormalsProcess() = default;
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool FixInfacingNormalsProcess::IsActive( unsigned int pFlags) const
{
bool FixInfacingNormalsProcess::IsActive( unsigned int pFlags) const {
return (pFlags & aiProcess_FixInfacingNormals) != 0;
}
// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
void FixInfacingNormalsProcess::Execute( aiScene* pScene)
{
void FixInfacingNormalsProcess::Execute( aiScene* pScene) {
ASSIMP_LOG_DEBUG("FixInfacingNormalsProcess begin");
bool bHas( false );

View File

@ -49,8 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct aiMesh;
namespace Assimp
{
namespace Assimp {
// ---------------------------------------------------------------------------
/** The FixInfacingNormalsProcess tries to determine whether the normal
@ -59,8 +58,10 @@ namespace Assimp
*/
class FixInfacingNormalsProcess : public BaseProcess {
public:
FixInfacingNormalsProcess();
~FixInfacingNormalsProcess();
// -------------------------------------------------------------------
/// The default class constructor / destructor.
FixInfacingNormalsProcess() = default;
~FixInfacingNormalsProcess() override = default;
// -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag field.
@ -68,14 +69,14 @@ public:
* combination of #aiPostProcessSteps.
* @return true if the process is present in this flag fields, false if not.
*/
bool IsActive( unsigned int pFlags) const;
bool IsActive( unsigned int pFlags) const override;
// -------------------------------------------------------------------
/** Executes the post processing step on the given imported data.
* At the moment a process is not supposed to fail.
* @param pScene The imported data to work at.
*/
void Execute( aiScene* pScene);
void Execute( aiScene* pScene) override;
protected:

View File

@ -48,10 +48,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp {
GenBoundingBoxesProcess::GenBoundingBoxesProcess() = default;
GenBoundingBoxesProcess::~GenBoundingBoxesProcess() = default;
bool GenBoundingBoxesProcess::IsActive(unsigned int pFlags) const {
return 0 != ( pFlags & aiProcess_GenBoundingBoxes );
}

View File

@ -19,7 +19,7 @@ conditions are met:
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
s
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
@ -54,18 +54,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp {
/** Post-processing process to find axis-aligned bounding volumes for amm meshes
* used in a scene
/**
* @brief Post-processing process to find axis-aligned bounding volumes for amm meshes
* used in a scene.
*/
class ASSIMP_API GenBoundingBoxesProcess : public BaseProcess {
public:
/// The class constructor.
GenBoundingBoxesProcess();
/// The class destructor.
~GenBoundingBoxesProcess();
/// Will return true, if aiProcess_GenBoundingBoxes is defined.
// -------------------------------------------------------------------
/// The default class constructor / destructor.
GenBoundingBoxesProcess() = default;
~GenBoundingBoxesProcess() override = default;
// -------------------------------------------------------------------
/// @brief Will return true, if aiProcess_GenBoundingBoxes is defined.
bool IsActive(unsigned int pFlags) const override;
/// The execution callback.
// -------------------------------------------------------------------
/// @brief The execution callback.
void Execute(aiScene* pScene) override;
};

View File

@ -54,14 +54,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp;
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
GenFaceNormalsProcess::GenFaceNormalsProcess() = default;
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
GenFaceNormalsProcess::~GenFaceNormalsProcess() = default;
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool GenFaceNormalsProcess::IsActive(unsigned int pFlags) const {

View File

@ -47,35 +47,33 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "Common/BaseProcess.h"
#include <assimp/mesh.h>
namespace Assimp
{
namespace Assimp {
// ---------------------------------------------------------------------------
/** The GenFaceNormalsProcess computes face normals for all faces of all meshes
*/
class ASSIMP_API_WINONLY GenFaceNormalsProcess : public BaseProcess
{
/**
* @brief The GenFaceNormalsProcess computes face normals for all faces of all meshes
*/
class ASSIMP_API_WINONLY GenFaceNormalsProcess : public BaseProcess {
public:
// -------------------------------------------------------------------
/// The default class constructor / destructor.
GenFaceNormalsProcess() = default;
~GenFaceNormalsProcess() override = default;
GenFaceNormalsProcess();
~GenFaceNormalsProcess();
public:
// -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag field.
* @param pFlags The processing flags the importer was called with. A bitwise
* combination of #aiPostProcessSteps.
* @return true if the process is present in this flag fields, false if not.
*/
bool IsActive( unsigned int pFlags) const;
bool IsActive( unsigned int pFlags) const override;
// -------------------------------------------------------------------
/** Executes the post processing step on the given imported data.
* At the moment a process is not supposed to fail.
* @param pScene The imported data to work at.
*/
void Execute( aiScene* pScene);
void Execute( aiScene* pScene) override;
private:
bool GenMeshFaceNormals(aiMesh* pcMesh);

View File

@ -60,10 +60,6 @@ GenVertexNormalsProcess::GenVertexNormalsProcess() :
// empty
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
GenVertexNormalsProcess::~GenVertexNormalsProcess() = default;
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool GenVertexNormalsProcess::IsActive(unsigned int pFlags) const {
@ -109,10 +105,10 @@ void GenVertexNormalsProcess::Execute(aiScene *pScene) {
// Executes the post processing step on the given imported data.
bool GenVertexNormalsProcess::GenMeshVertexNormals(aiMesh *pMesh, unsigned int meshIndex) {
if (nullptr != pMesh->mNormals) {
if (force_)
delete[] pMesh->mNormals;
else
if (!force_) {
return false;
}
delete[] pMesh->mNormals;
}
// If the mesh consists of lines and/or points but not of
@ -144,8 +140,9 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals(aiMesh *pMesh, unsigned int m
const aiVector3D *pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices - 1]];
// Boolean XOR - if either but not both of these flags is set, then the winding order has
// changed and the cross product to calculate the normal needs to be reversed
if (flippedWindingOrder_ != leftHanded_)
if (flippedWindingOrder_ != leftHanded_) {
std::swap(pV2, pV3);
}
const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).NormalizeSafe();
for (unsigned int i = 0; i < face.mNumIndices; ++i) {

View File

@ -60,8 +60,10 @@ namespace Assimp {
*/
class ASSIMP_API GenVertexNormalsProcess : public BaseProcess {
public:
// -------------------------------------------------------------------
/// The default class constructor / destructor.
GenVertexNormalsProcess();
~GenVertexNormalsProcess();
~GenVertexNormalsProcess() override = default;
// -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag.
@ -70,22 +72,21 @@ public:
* @return true if the process is present in this flag fields,
* false if not.
*/
bool IsActive( unsigned int pFlags) const;
bool IsActive( unsigned int pFlags) const override;
// -------------------------------------------------------------------
/** Called prior to ExecuteOnScene().
* The function is a request to the process to update its configuration
* basing on the Importer's configuration property list.
*/
void SetupProperties(const Importer* pImp);
void SetupProperties(const Importer* pImp) override;
// -------------------------------------------------------------------
/** Executes the post processing step on the given imported data.
* At the moment a process is not supposed to fail.
* @param pScene The imported data to work at.
*/
void Execute( aiScene* pScene);
void Execute( aiScene* pScene) override;
// setter for configMaxAngle
inline void SetMaxSmoothAngle(ai_real f) {

View File

@ -68,10 +68,6 @@ ImproveCacheLocalityProcess::ImproveCacheLocalityProcess()
// empty
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
ImproveCacheLocalityProcess::~ImproveCacheLocalityProcess() = default;
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool ImproveCacheLocalityProcess::IsActive( unsigned int pFlags) const {

View File

@ -51,8 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct aiMesh;
namespace Assimp
{
namespace Assimp {
// ---------------------------------------------------------------------------
/** The ImproveCacheLocalityProcess reorders all faces for improved vertex
@ -61,26 +60,24 @@ namespace Assimp
*
* @note This step expects triagulated input data.
*/
class ImproveCacheLocalityProcess : public BaseProcess
{
class ImproveCacheLocalityProcess : public BaseProcess {
public:
// -------------------------------------------------------------------
/// The default class constructor / destructor.
ImproveCacheLocalityProcess();
~ImproveCacheLocalityProcess();
public:
~ImproveCacheLocalityProcess() override = default;
// -------------------------------------------------------------------
// Check whether the pp step is active
bool IsActive( unsigned int pFlags) const;
bool IsActive( unsigned int pFlags) const override;
// -------------------------------------------------------------------
// Executes the pp step on a given scene
void Execute( aiScene* pScene);
void Execute( aiScene* pScene) override;
// -------------------------------------------------------------------
// Configures the pp step
void SetupProperties(const Importer* pImp);
void SetupProperties(const Importer* pImp) override;
protected:
// -------------------------------------------------------------------

View File

@ -51,8 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct aiMesh;
namespace Assimp
{
namespace Assimp {
// ---------------------------------------------------------------------------
/** The JoinVerticesProcess unites identical vertices in all imported meshes.
@ -65,12 +64,9 @@ namespace Assimp
class ASSIMP_API JoinVerticesProcess : public BaseProcess {
public:
// -------------------------------------------------------------------
/// @brief The default class constructor.
JoinVerticesProcess() = default;
// -------------------------------------------------------------------
/// @brief The default class destructor.
~JoinVerticesProcess() = default;
/// The default class constructor / destructor.
JoinVerticesProcess() = default;
~JoinVerticesProcess() override = default;
// -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag field.
@ -78,14 +74,14 @@ public:
* combination of #aiPostProcessSteps.
* @return true if the process is present in this flag fields, false if not.
*/
bool IsActive( unsigned int pFlags) const;
bool IsActive( unsigned int pFlags) const override;
// -------------------------------------------------------------------
/** Executes the post processing step on the given imported data.
* At the moment a process is not supposed to fail.
* @param pScene The imported data to work at.
*/
void Execute( aiScene* pScene);
void Execute( aiScene* pScene) override;
// -------------------------------------------------------------------
/** Unites identical vertices in the given mesh.

View File

@ -53,11 +53,9 @@ namespace Assimp {
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
LimitBoneWeightsProcess::LimitBoneWeightsProcess() : mMaxWeights(AI_LMW_MAX_WEIGHTS) {}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
LimitBoneWeightsProcess::~LimitBoneWeightsProcess() = default;
LimitBoneWeightsProcess::LimitBoneWeightsProcess() : mMaxWeights(AI_LMW_MAX_WEIGHTS) {
// empty
}
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.

View File

@ -74,8 +74,10 @@ namespace Assimp {
*/
class ASSIMP_API LimitBoneWeightsProcess : public BaseProcess {
public:
// -------------------------------------------------------------------
/// The default class constructor / destructor.
LimitBoneWeightsProcess();
~LimitBoneWeightsProcess();
~LimitBoneWeightsProcess() override = default;
// -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag.
@ -84,27 +86,27 @@ public:
* @return true if the process is present in this flag fields,
* false if not.
*/
bool IsActive( unsigned int pFlags) const;
bool IsActive( unsigned int pFlags) const override;
// -------------------------------------------------------------------
/** Called prior to ExecuteOnScene().
* The function is a request to the process to update its configuration
* basing on the Importer's configuration property list.
*/
void SetupProperties(const Importer* pImp);
// -------------------------------------------------------------------
/** Limits the bone weight count for all vertices in the given mesh.
* @param pMesh The mesh to process.
*/
void ProcessMesh( aiMesh* pMesh);
void SetupProperties(const Importer* pImp) override;
// -------------------------------------------------------------------
/** Executes the post processing step on the given imported data.
* At the moment a process is not supposed to fail.
* @param pScene The imported data to work at.
*/
void Execute( aiScene* pScene);
void Execute( aiScene* pScene) override;
// -------------------------------------------------------------------
/** Limits the bone weight count for all vertices in the given mesh.
* @param pMesh The mesh to process.
*/
void ProcessMesh( aiMesh* pMesh);
// -------------------------------------------------------------------
/** Describes a bone weight on a vertex */

View File

@ -49,10 +49,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp;
// ------------------------------------------------------------------------------------------------
MakeVerboseFormatProcess::MakeVerboseFormatProcess() = default;
// ------------------------------------------------------------------------------------------------
MakeVerboseFormatProcess::~MakeVerboseFormatProcess() = default;
// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
void MakeVerboseFormatProcess::Execute(aiScene *pScene) {

View File

@ -66,22 +66,19 @@ namespace Assimp {
* The step has been added because it was required by the viewer, however
* it has been moved to the main library since others might find it
* useful, too. */
class ASSIMP_API_WINONLY MakeVerboseFormatProcess : public BaseProcess
{
public:
MakeVerboseFormatProcess();
~MakeVerboseFormatProcess();
class ASSIMP_API_WINONLY MakeVerboseFormatProcess : public BaseProcess {
public:
// -------------------------------------------------------------------
/// The default class constructor / destructor.
MakeVerboseFormatProcess() = default;
~MakeVerboseFormatProcess() override = default;
// -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag field.
* @param pFlags The processing flags the importer was called with. A bitwise
* combination of #aiPostProcessSteps.
* @return true if the process is present in this flag fields, false if not */
bool IsActive( unsigned int /*pFlags*/ ) const
bool IsActive( unsigned int /*pFlags*/ ) const override
{
// NOTE: There is no direct flag that corresponds to
// this postprocess step.
@ -92,7 +89,7 @@ public:
/** Executes the post processing step on the given imported data.
* At the moment a process is not supposed to fail.
* @param pScene The imported data to work at. */
void Execute( aiScene* pScene);
void Execute( aiScene* pScene) override;
public:

View File

@ -78,10 +78,6 @@ OptimizeGraphProcess::OptimizeGraphProcess() :
// empty
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
OptimizeGraphProcess::~OptimizeGraphProcess() = default;
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool OptimizeGraphProcess::IsActive(unsigned int pFlags) const {

View File

@ -71,8 +71,10 @@ namespace Assimp {
*/
class OptimizeGraphProcess : public BaseProcess {
public:
// -------------------------------------------------------------------
/// The default class constructor / destructor.
OptimizeGraphProcess();
~OptimizeGraphProcess();
~OptimizeGraphProcess() override = default;
// -------------------------------------------------------------------
bool IsActive( unsigned int pFlags) const override;

View File

@ -69,10 +69,6 @@ OptimizeMeshesProcess::OptimizeMeshesProcess()
// empty
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
OptimizeMeshesProcess::~OptimizeMeshesProcess() = default;
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool OptimizeMeshesProcess::IsActive( unsigned int pFlags) const

View File

@ -68,11 +68,10 @@ namespace Assimp {
*/
class OptimizeMeshesProcess : public BaseProcess {
public:
/// @brief The class constructor.
// -------------------------------------------------------------------
/// The default class constructor / destructor.
OptimizeMeshesProcess();
/// @brief The class destructor.
~OptimizeMeshesProcess();
~OptimizeMeshesProcess() override = default;
/** @brief Internal utility to store additional mesh info
*/
@ -94,16 +93,14 @@ public:
unsigned int output_id;
};
public:
// -------------------------------------------------------------------
bool IsActive( unsigned int pFlags) const;
bool IsActive( unsigned int pFlags) const override;
// -------------------------------------------------------------------
void Execute( aiScene* pScene);
void Execute( aiScene* pScene) override;
// -------------------------------------------------------------------
void SetupProperties(const Importer* pImp);
void SetupProperties(const Importer* pImp) override;
// -------------------------------------------------------------------
/** @brief Specify whether you want meshes with different

View File

@ -68,10 +68,6 @@ PretransformVertices::PretransformVertices() :
// empty
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
PretransformVertices::~PretransformVertices() = default;
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool PretransformVertices::IsActive(unsigned int pFlags) const {
@ -581,7 +577,7 @@ void PretransformVertices::Execute(aiScene *pScene) {
// multiply all properties of the camera with the absolute
// transformation of the corresponding node
cam->mPosition = nd->mTransformation * cam->mPosition;
cam->mLookAt = aiMatrix3x3(nd->mTransformation) * cam->mLookAt;
cam->mLookAt = nd->mTransformation * cam->mLookAt;
cam->mUp = aiMatrix3x3(nd->mTransformation) * cam->mUp;
}

View File

@ -68,8 +68,10 @@ namespace Assimp {
*/
class ASSIMP_API PretransformVertices : public BaseProcess {
public:
// -------------------------------------------------------------------
/// The default class constructor / destructor.
PretransformVertices();
~PretransformVertices();
~PretransformVertices() override = default;
// -------------------------------------------------------------------
// Check whether step is active

View File

@ -62,10 +62,6 @@ RemoveRedundantMatsProcess::RemoveRedundantMatsProcess()
// nothing to do here
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
RemoveRedundantMatsProcess::~RemoveRedundantMatsProcess() = default;
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool RemoveRedundantMatsProcess::IsActive( unsigned int pFlags) const

View File

@ -59,23 +59,22 @@ namespace Assimp {
*/
class ASSIMP_API RemoveRedundantMatsProcess : public BaseProcess {
public:
/// The default class constructor.
// -------------------------------------------------------------------
/// The default class constructor / destructor.
RemoveRedundantMatsProcess();
/// The class destructor.
~RemoveRedundantMatsProcess();
~RemoveRedundantMatsProcess() override = default;
// -------------------------------------------------------------------
// Check whether step is active
bool IsActive( unsigned int pFlags) const;
bool IsActive( unsigned int pFlags) const override;
// -------------------------------------------------------------------
// Execute step on a given scene
void Execute( aiScene* pScene);
void Execute( aiScene* pScene) override;
// -------------------------------------------------------------------
// Setup import settings
void SetupProperties(const Importer* pImp);
void SetupProperties(const Importer* pImp) override;
// -------------------------------------------------------------------
/** @brief Set list of fixed (inmutable) materials

View File

@ -56,10 +56,6 @@ using namespace Assimp;
RemoveVCProcess::RemoveVCProcess() :
configDeleteFlags(), mScene() {}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
RemoveVCProcess::~RemoveVCProcess() = default;
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool RemoveVCProcess::IsActive(unsigned int pFlags) const {

View File

@ -58,11 +58,10 @@ namespace Assimp {
*/
class ASSIMP_API RemoveVCProcess : public BaseProcess {
public:
/// The default class constructor.
// -------------------------------------------------------------------
/// The default class constructor / destructor.
RemoveVCProcess();
/// The class destructor.
~RemoveVCProcess();
~RemoveVCProcess() override = default;
// -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag field.
@ -70,37 +69,35 @@ public:
* combination of #aiPostProcessSteps.
* @return true if the process is present in this flag fields, false if not.
*/
bool IsActive( unsigned int pFlags) const;
bool IsActive( unsigned int pFlags) const override;
// -------------------------------------------------------------------
/** Executes the post processing step on the given imported data.
* At the moment a process is not supposed to fail.
* @param pScene The imported data to work at.
*/
void Execute( aiScene* pScene);
void Execute( aiScene* pScene) override;
// -------------------------------------------------------------------
/** Called prior to ExecuteOnScene().
* The function is a request to the process to update its configuration
* basing on the Importer's configuration property list.
*/
virtual void SetupProperties(const Importer* pImp);
virtual void SetupProperties(const Importer* pImp) override;
// -------------------------------------------------------------------
/** Manually setup the configuration flags for the step
*
* @param Bitwise combination of the #aiComponent enumerated values.
*/
void SetDeleteFlags(unsigned int f)
{
void SetDeleteFlags(unsigned int f) {
configDeleteFlags = f;
}
// -------------------------------------------------------------------
/** Query the current configuration.
*/
unsigned int GetDeleteFlags() const
{
unsigned int GetDeleteFlags() const {
return configDeleteFlags;
}

View File

@ -47,25 +47,27 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp {
ScaleProcess::ScaleProcess()
: BaseProcess()
, mScale( AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT ) {
// ------------------------------------------------------------------------------------------------
ScaleProcess::ScaleProcess() : BaseProcess(), mScale( AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT ) {
// empty
}
ScaleProcess::~ScaleProcess() = default;
// ------------------------------------------------------------------------------------------------
void ScaleProcess::setScale( ai_real scale ) {
mScale = scale;
}
// ------------------------------------------------------------------------------------------------
ai_real ScaleProcess::getScale() const {
return mScale;
}
// ------------------------------------------------------------------------------------------------
bool ScaleProcess::IsActive( unsigned int pFlags ) const {
return ( pFlags & aiProcess_GlobalScale ) != 0;
}
// ------------------------------------------------------------------------------------------------
void ScaleProcess::SetupProperties( const Importer* pImp ) {
// User scaling
mScale = pImp->GetPropertyFloat( AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY, 1.0f );
@ -78,6 +80,7 @@ void ScaleProcess::SetupProperties( const Importer* pImp ) {
mScale *= importerScale;
}
// ------------------------------------------------------------------------------------------------
void ScaleProcess::Execute( aiScene* pScene ) {
if(mScale == 1.0f) {
return; // nothing to scale
@ -96,37 +99,30 @@ void ScaleProcess::Execute( aiScene* pScene ) {
}
// Process animations and update position transform to new unit system
for( unsigned int animationID = 0; animationID < pScene->mNumAnimations; animationID++ )
{
for( unsigned int animationID = 0; animationID < pScene->mNumAnimations; animationID++ ) {
aiAnimation* animation = pScene->mAnimations[animationID];
for( unsigned int animationChannel = 0; animationChannel < animation->mNumChannels; animationChannel++)
{
for( unsigned int animationChannel = 0; animationChannel < animation->mNumChannels; animationChannel++) {
aiNodeAnim* anim = animation->mChannels[animationChannel];
for( unsigned int posKey = 0; posKey < anim->mNumPositionKeys; posKey++)
{
for( unsigned int posKey = 0; posKey < anim->mNumPositionKeys; posKey++) {
aiVectorKey& vectorKey = anim->mPositionKeys[posKey];
vectorKey.mValue *= mScale;
}
}
}
for( unsigned int meshID = 0; meshID < pScene->mNumMeshes; meshID++)
{
for( unsigned int meshID = 0; meshID < pScene->mNumMeshes; meshID++) {
aiMesh *mesh = pScene->mMeshes[meshID];
// Reconstruct mesh vertices to the new unit system
for( unsigned int vertexID = 0; vertexID < mesh->mNumVertices; vertexID++)
{
for( unsigned int vertexID = 0; vertexID < mesh->mNumVertices; vertexID++) {
aiVector3D& vertex = mesh->mVertices[vertexID];
vertex *= mScale;
}
// bone placement / scaling
for( unsigned int boneID = 0; boneID < mesh->mNumBones; boneID++)
{
for( unsigned int boneID = 0; boneID < mesh->mNumBones; boneID++) {
// Reconstruct matrix by transform rather than by scale
// This prevent scale values being changed which can
// be meaningful in some cases
@ -152,12 +148,10 @@ void ScaleProcess::Execute( aiScene* pScene ) {
// animation mesh processing
// convert by position rather than scale.
for( unsigned int animMeshID = 0; animMeshID < mesh->mNumAnimMeshes; animMeshID++)
{
for( unsigned int animMeshID = 0; animMeshID < mesh->mNumAnimMeshes; animMeshID++) {
aiAnimMesh * animMesh = mesh->mAnimMeshes[animMeshID];
for( unsigned int vertexID = 0; vertexID < animMesh->mNumVertices; vertexID++)
{
for( unsigned int vertexID = 0; vertexID < animMesh->mNumVertices; vertexID++) {
aiVector3D& vertex = animMesh->mVertices[vertexID];
vertex *= mScale;
}
@ -167,16 +161,17 @@ void ScaleProcess::Execute( aiScene* pScene ) {
traverseNodes( pScene->mRootNode );
}
// ------------------------------------------------------------------------------------------------
void ScaleProcess::traverseNodes( aiNode *node, unsigned int nested_node_id ) {
applyScaling( node );
for( size_t i = 0; i < node->mNumChildren; i++)
{
for( size_t i = 0; i < node->mNumChildren; i++) {
// recurse into the tree until we are done!
traverseNodes( node->mChildren[i], nested_node_id+1 );
}
}
// ------------------------------------------------------------------------------------------------
void ScaleProcess::applyScaling( aiNode *currentNode ) {
if ( nullptr != currentNode ) {
// Reconstruct matrix by transform rather than by scale

Some files were not shown because too many files have changed in this diff Show More