From 456b54988a686dfdfbbf7f58ba328884a6901cc3 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 11 Nov 2020 19:38:42 +0100 Subject: [PATCH] closes https://github.com/assimp/assimp/issues/1044: set default value in case of light intensity envelopes- --- code/AssetLib/FBX/FBXImporter.cpp | 32 +- code/AssetLib/FBX/FBXImporter.h | 19 +- code/AssetLib/FBX/FBXMeshGeometry.cpp | 495 +++--- code/AssetLib/FBX/FBXParser.cpp | 793 +++++----- code/AssetLib/IFC/IFCUtil.cpp | 418 +++--- code/Common/Importer.cpp | 500 +++--- code/Common/Importer.h | 99 +- code/Common/PolyTools.h | 115 +- code/PostProcessing/TriangulateProcess.cpp | 319 ++-- test/CMakeLists.txt | 1 + test/unit/utProfiler.cpp | 2 - tools/assimp_view/AnimEvaluator.h | 6 +- tools/assimp_view/Display.cpp | 1587 +++++++++----------- tools/assimp_view/SceneAnimator.h | 27 +- 14 files changed, 2039 insertions(+), 2374 deletions(-) diff --git a/code/AssetLib/FBX/FBXImporter.cpp b/code/AssetLib/FBX/FBXImporter.cpp index a097568a5..2faf533d1 100644 --- a/code/AssetLib/FBX/FBXImporter.cpp +++ b/code/AssetLib/FBX/FBXImporter.cpp @@ -123,20 +123,20 @@ const aiImporterDesc *FBXImporter::GetInfo() const { // ------------------------------------------------------------------------------------------------ // Setup configuration properties for the loader void FBXImporter::SetupProperties(const Importer *pImp) { - settings.readAllLayers = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS, true); - settings.readAllMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_MATERIALS, false); - settings.readMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_MATERIALS, true); - settings.readTextures = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_TEXTURES, true); - settings.readCameras = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_CAMERAS, true); - settings.readLights = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_LIGHTS, true); - settings.readAnimations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ANIMATIONS, true); - settings.readWeights = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_WEIGHTS, true); - settings.strictMode = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_STRICT_MODE, false); - settings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true); - settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true); - settings.useLegacyEmbeddedTextureNaming = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING, false); - settings.removeEmptyBones = pImp->GetPropertyBool(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true); - settings.convertToMeters = pImp->GetPropertyBool(AI_CONFIG_FBX_CONVERT_TO_M, false); + mSettings.readAllLayers = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS, true); + mSettings.readAllMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_MATERIALS, false); + mSettings.readMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_MATERIALS, true); + mSettings.readTextures = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_TEXTURES, true); + mSettings.readCameras = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_CAMERAS, true); + mSettings.readLights = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_LIGHTS, true); + mSettings.readAnimations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ANIMATIONS, true); + mSettings.readWeights = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_WEIGHTS, true); + mSettings.strictMode = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_STRICT_MODE, false); + mSettings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true); + mSettings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true); + mSettings.useLegacyEmbeddedTextureNaming = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING, false); + mSettings.removeEmptyBones = pImp->GetPropertyBool(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true); + mSettings.convertToMeters = pImp->GetPropertyBool(AI_CONFIG_FBX_CONVERT_TO_M, false); } // ------------------------------------------------------------------------------------------------ @@ -181,10 +181,10 @@ void FBXImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy Parser parser(tokens, is_binary); // take the raw parse-tree and convert it to a FBX DOM - Document doc(parser, settings); + Document doc(parser, mSettings); // convert the FBX DOM to aiScene - ConvertToAssimpScene(pScene, doc, settings.removeEmptyBones); + ConvertToAssimpScene(pScene, doc, mSettings.removeEmptyBones); // size relative to cm float size_relative_to_cm = doc.GlobalSettings().UnitScaleFactor(); diff --git a/code/AssetLib/FBX/FBXImporter.h b/code/AssetLib/FBX/FBXImporter.h index 7a9fc4b74..34517c7f2 100644 --- a/code/AssetLib/FBX/FBXImporter.h +++ b/code/AssetLib/FBX/FBXImporter.h @@ -70,27 +70,16 @@ typedef class basic_formatter, std::allocator class FBXImporter : public BaseImporter, public LogFunctions { public: FBXImporter(); - virtual ~FBXImporter(); - - // -------------------- - bool CanRead(const std::string &pFile, - IOSystem *pIOHandler, - bool checkSig) const; + ~FBXImporter() override; + bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const; protected: - // -------------------- const aiImporterDesc *GetInfo() const; - - // -------------------- void SetupProperties(const Importer *pImp); - - // -------------------- - void InternReadFile(const std::string &pFile, - aiScene *pScene, - IOSystem *pIOHandler); + void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler); private: - FBX::ImportSettings settings; + FBX::ImportSettings mSettings; }; // !class FBXImporter } // end of namespace Assimp diff --git a/code/AssetLib/FBX/FBXMeshGeometry.cpp b/code/AssetLib/FBX/FBXMeshGeometry.cpp index da96934d6..6d82bd6a1 100644 --- a/code/AssetLib/FBX/FBXMeshGeometry.cpp +++ b/code/AssetLib/FBX/FBXMeshGeometry.cpp @@ -48,12 +48,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include -#include "FBXMeshGeometry.h" #include "FBXDocument.h" -#include "FBXImporter.h" -#include "FBXImportSettings.h" #include "FBXDocumentUtil.h" - +#include "FBXImportSettings.h" +#include "FBXImporter.h" +#include "FBXMeshGeometry.h" namespace Assimp { namespace FBX { @@ -61,17 +60,15 @@ namespace FBX { using namespace Util; // ------------------------------------------------------------------------------------------------ -Geometry::Geometry(uint64_t id, const Element& element, const std::string& name, const Document& doc) - : Object(id, element, name) - , skin() -{ - const std::vector& conns = doc.GetConnectionsByDestinationSequenced(ID(),"Deformer"); - for(const Connection* con : conns) { - const Skin* const sk = ProcessSimpleConnection(*con, false, "Skin -> Geometry", element); - if(sk) { +Geometry::Geometry(uint64_t id, const Element &element, const std::string &name, const Document &doc) : + Object(id, element, name), skin() { + const std::vector &conns = doc.GetConnectionsByDestinationSequenced(ID(), "Deformer"); + for (const Connection *con : conns) { + const Skin *const sk = ProcessSimpleConnection(*con, false, "Skin -> Geometry", element); + if (sk) { skin = sk; } - const BlendShape* const bsp = ProcessSimpleConnection(*con, false, "BlendShape -> Geometry", element); + const BlendShape *const bsp = ProcessSimpleConnection(*con, false, "BlendShape -> Geometry", element); if (bsp) { blendShapes.push_back(bsp); } @@ -79,48 +76,46 @@ Geometry::Geometry(uint64_t id, const Element& element, const std::string& name, } // ------------------------------------------------------------------------------------------------ -Geometry::~Geometry() -{ +Geometry::~Geometry() { // empty } // ------------------------------------------------------------------------------------------------ -const std::vector& Geometry::GetBlendShapes() const { +const std::vector &Geometry::GetBlendShapes() const { return blendShapes; } // ------------------------------------------------------------------------------------------------ -const Skin* Geometry::DeformerSkin() const { +const Skin *Geometry::DeformerSkin() const { return skin; } // ------------------------------------------------------------------------------------------------ -MeshGeometry::MeshGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc) -: Geometry(id, element,name, doc) -{ - const Scope* sc = element.Compound(); +MeshGeometry::MeshGeometry(uint64_t id, const Element &element, const std::string &name, const Document &doc) : + Geometry(id, element, name, doc) { + const Scope *sc = element.Compound(); if (!sc) { DOMError("failed to read Geometry object (class: Mesh), no data scope found"); } // must have Mesh elements: - const Element& Vertices = GetRequiredElement(*sc,"Vertices",&element); - const Element& PolygonVertexIndex = GetRequiredElement(*sc,"PolygonVertexIndex",&element); + const Element &Vertices = GetRequiredElement(*sc, "Vertices", &element); + const Element &PolygonVertexIndex = GetRequiredElement(*sc, "PolygonVertexIndex", &element); // optional Mesh elements: - const ElementCollection& Layer = sc->GetCollection("Layer"); + const ElementCollection &Layer = sc->GetCollection("Layer"); std::vector tempVerts; - ParseVectorDataArray(tempVerts,Vertices); + ParseVectorDataArray(tempVerts, Vertices); - if(tempVerts.empty()) { + if (tempVerts.empty()) { FBXImporter::LogWarn("encountered mesh with no vertices"); } std::vector tempFaces; - ParseVectorDataArray(tempFaces,PolygonVertexIndex); + ParseVectorDataArray(tempFaces, PolygonVertexIndex); - if(tempFaces.empty()) { + if (tempFaces.empty()) { FBXImporter::LogWarn("encountered mesh with no faces"); } @@ -128,7 +123,7 @@ MeshGeometry::MeshGeometry(uint64_t id, const Element& element, const std::strin m_faces.reserve(tempFaces.size() / 3); m_mapping_offsets.resize(tempVerts.size()); - m_mapping_counts.resize(tempVerts.size(),0); + m_mapping_counts.resize(tempVerts.size(), 0); m_mappings.resize(tempFaces.size()); const size_t vertex_count = tempVerts.size(); @@ -136,10 +131,10 @@ MeshGeometry::MeshGeometry(uint64_t id, const Element& element, const std::strin // generate output vertices, computing an adjacency table to // preserve the mapping from fbx indices to *this* indexing. unsigned int count = 0; - for(int index : tempFaces) { + for (int index : tempFaces) { const int absi = index < 0 ? (-index - 1) : index; - if(static_cast(absi) >= vertex_count) { - DOMError("polygon vertex index out of range",&PolygonVertexIndex); + if (static_cast(absi) >= vertex_count) { + DOMError("polygon vertex index out of range", &PolygonVertexIndex); } m_vertices.push_back(tempVerts[absi]); @@ -162,7 +157,7 @@ MeshGeometry::MeshGeometry(uint64_t id, const Element& element, const std::strin } cursor = 0; - for(int index : tempFaces) { + for (int index : tempFaces) { const int absi = index < 0 ? (-index - 1) : index; m_mappings[m_mapping_offsets[absi] + m_mapping_counts[absi]++] = cursor++; } @@ -172,19 +167,18 @@ MeshGeometry::MeshGeometry(uint64_t id, const Element& element, const std::strin // if settings.readAllLayers is false: // * read only the layer with index 0, but warn about any further layers for (ElementMap::const_iterator it = Layer.first; it != Layer.second; ++it) { - const TokenList& tokens = (*it).second->Tokens(); + const TokenList &tokens = (*it).second->Tokens(); - const char* err; + const char *err; const int index = ParseTokenAsInt(*tokens[0], err); - if(err) { - DOMError(err,&element); + if (err) { + DOMError(err, &element); } - if(doc.Settings().readAllLayers || index == 0) { - const Scope& layer = GetRequiredScope(*(*it).second); + if (doc.Settings().readAllLayers || index == 0) { + const Scope &layer = GetRequiredScope(*(*it).second); ReadLayer(layer); - } - else { + } else { FBXImporter::LogWarn("ignoring additional geometry layers"); } } @@ -196,151 +190,142 @@ MeshGeometry::~MeshGeometry() { } // ------------------------------------------------------------------------------------------------ -const std::vector& MeshGeometry::GetVertices() const { +const std::vector &MeshGeometry::GetVertices() const { return m_vertices; } // ------------------------------------------------------------------------------------------------ -const std::vector& MeshGeometry::GetNormals() const { +const std::vector &MeshGeometry::GetNormals() const { return m_normals; } // ------------------------------------------------------------------------------------------------ -const std::vector& MeshGeometry::GetTangents() const { +const std::vector &MeshGeometry::GetTangents() const { return m_tangents; } // ------------------------------------------------------------------------------------------------ -const std::vector& MeshGeometry::GetBinormals() const { +const std::vector &MeshGeometry::GetBinormals() const { return m_binormals; } // ------------------------------------------------------------------------------------------------ -const std::vector& MeshGeometry::GetFaceIndexCounts() const { +const std::vector &MeshGeometry::GetFaceIndexCounts() const { return m_faces; } // ------------------------------------------------------------------------------------------------ -const std::vector& MeshGeometry::GetTextureCoords( unsigned int index ) const { +const std::vector &MeshGeometry::GetTextureCoords(unsigned int index) const { static const std::vector empty; - return index >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? empty : m_uvs[ index ]; + return index >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? empty : m_uvs[index]; } -std::string MeshGeometry::GetTextureCoordChannelName( unsigned int index ) const { - return index >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? "" : m_uvNames[ index ]; +std::string MeshGeometry::GetTextureCoordChannelName(unsigned int index) const { + return index >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? "" : m_uvNames[index]; } -const std::vector& MeshGeometry::GetVertexColors( unsigned int index ) const { +const std::vector &MeshGeometry::GetVertexColors(unsigned int index) const { static const std::vector empty; - return index >= AI_MAX_NUMBER_OF_COLOR_SETS ? empty : m_colors[ index ]; + return index >= AI_MAX_NUMBER_OF_COLOR_SETS ? empty : m_colors[index]; } -const MatIndexArray& MeshGeometry::GetMaterialIndices() const { +const MatIndexArray &MeshGeometry::GetMaterialIndices() const { return m_materials; } // ------------------------------------------------------------------------------------------------ -const unsigned int* MeshGeometry::ToOutputVertexIndex( unsigned int in_index, unsigned int& count ) const { - if ( in_index >= m_mapping_counts.size() ) { +const unsigned int *MeshGeometry::ToOutputVertexIndex(unsigned int in_index, unsigned int &count) const { + if (in_index >= m_mapping_counts.size()) { return nullptr; } - ai_assert( m_mapping_counts.size() == m_mapping_offsets.size() ); - count = m_mapping_counts[ in_index ]; + ai_assert(m_mapping_counts.size() == m_mapping_offsets.size()); + count = m_mapping_counts[in_index]; - ai_assert( m_mapping_offsets[ in_index ] + count <= m_mappings.size() ); + ai_assert(m_mapping_offsets[in_index] + count <= m_mappings.size()); - return &m_mappings[ m_mapping_offsets[ in_index ] ]; + return &m_mappings[m_mapping_offsets[in_index]]; } // ------------------------------------------------------------------------------------------------ -unsigned int MeshGeometry::FaceForVertexIndex( unsigned int in_index ) const { - ai_assert( in_index < m_vertices.size() ); +unsigned int MeshGeometry::FaceForVertexIndex(unsigned int in_index) const { + ai_assert(in_index < m_vertices.size()); // in the current conversion pattern this will only be needed if // weights are present, so no need to always pre-compute this table - if ( m_facesVertexStartIndices.empty() ) { - m_facesVertexStartIndices.resize( m_faces.size() + 1, 0 ); + if (m_facesVertexStartIndices.empty()) { + m_facesVertexStartIndices.resize(m_faces.size() + 1, 0); - std::partial_sum( m_faces.begin(), m_faces.end(), m_facesVertexStartIndices.begin() + 1 ); + std::partial_sum(m_faces.begin(), m_faces.end(), m_facesVertexStartIndices.begin() + 1); m_facesVertexStartIndices.pop_back(); } - ai_assert( m_facesVertexStartIndices.size() == m_faces.size() ); + ai_assert(m_facesVertexStartIndices.size() == m_faces.size()); const std::vector::iterator it = std::upper_bound( - m_facesVertexStartIndices.begin(), - m_facesVertexStartIndices.end(), - in_index - ); + m_facesVertexStartIndices.begin(), + m_facesVertexStartIndices.end(), + in_index); - return static_cast< unsigned int >( std::distance( m_facesVertexStartIndices.begin(), it - 1 ) ); + return static_cast(std::distance(m_facesVertexStartIndices.begin(), it - 1)); } // ------------------------------------------------------------------------------------------------ -void MeshGeometry::ReadLayer(const Scope& layer) -{ - const ElementCollection& LayerElement = layer.GetCollection("LayerElement"); +void MeshGeometry::ReadLayer(const Scope &layer) { + const ElementCollection &LayerElement = layer.GetCollection("LayerElement"); for (ElementMap::const_iterator eit = LayerElement.first; eit != LayerElement.second; ++eit) { - const Scope& elayer = GetRequiredScope(*(*eit).second); + const Scope &elayer = GetRequiredScope(*(*eit).second); ReadLayerElement(elayer); } } - // ------------------------------------------------------------------------------------------------ -void MeshGeometry::ReadLayerElement(const Scope& layerElement) -{ - const Element& Type = GetRequiredElement(layerElement,"Type"); - const Element& TypedIndex = GetRequiredElement(layerElement,"TypedIndex"); +void MeshGeometry::ReadLayerElement(const Scope &layerElement) { + const Element &Type = GetRequiredElement(layerElement, "Type"); + const Element &TypedIndex = GetRequiredElement(layerElement, "TypedIndex"); - const std::string& type = ParseTokenAsString(GetRequiredToken(Type,0)); - const int typedIndex = ParseTokenAsInt(GetRequiredToken(TypedIndex,0)); + const std::string &type = ParseTokenAsString(GetRequiredToken(Type, 0)); + const int typedIndex = ParseTokenAsInt(GetRequiredToken(TypedIndex, 0)); - const Scope& top = GetRequiredScope(element); + const Scope &top = GetRequiredScope(element); const ElementCollection candidates = top.GetCollection(type); for (ElementMap::const_iterator it = candidates.first; it != candidates.second; ++it) { - const int index = ParseTokenAsInt(GetRequiredToken(*(*it).second,0)); - if(index == typedIndex) { - ReadVertexData(type,typedIndex,GetRequiredScope(*(*it).second)); + const int index = ParseTokenAsInt(GetRequiredToken(*(*it).second, 0)); + if (index == typedIndex) { + ReadVertexData(type, typedIndex, GetRequiredScope(*(*it).second)); return; } } FBXImporter::LogError(Formatter::format("failed to resolve vertex layer element: ") - << type << ", index: " << typedIndex); + << type << ", index: " << typedIndex); } // ------------------------------------------------------------------------------------------------ -void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scope& source) -{ - const std::string& MappingInformationType = ParseTokenAsString(GetRequiredToken( - GetRequiredElement(source,"MappingInformationType"),0) - ); +void MeshGeometry::ReadVertexData(const std::string &type, int index, const Scope &source) { + const std::string &MappingInformationType = ParseTokenAsString(GetRequiredToken( + GetRequiredElement(source, "MappingInformationType"), 0)); - const std::string& ReferenceInformationType = ParseTokenAsString(GetRequiredToken( - GetRequiredElement(source,"ReferenceInformationType"),0) - ); + const std::string &ReferenceInformationType = ParseTokenAsString(GetRequiredToken( + GetRequiredElement(source, "ReferenceInformationType"), 0)); if (type == "LayerElementUV") { - if(index >= AI_MAX_NUMBER_OF_TEXTURECOORDS) { + if (index >= AI_MAX_NUMBER_OF_TEXTURECOORDS) { FBXImporter::LogError(Formatter::format("ignoring UV layer, maximum number of UV channels exceeded: ") - << index << " (limit is " << AI_MAX_NUMBER_OF_TEXTURECOORDS << ")" ); + << index << " (limit is " << AI_MAX_NUMBER_OF_TEXTURECOORDS << ")"); return; } - const Element* Name = source["Name"]; + const Element *Name = source["Name"]; m_uvNames[index] = ""; - if(Name) { - m_uvNames[index] = ParseTokenAsString(GetRequiredToken(*Name,0)); + if (Name) { + m_uvNames[index] = ParseTokenAsString(GetRequiredToken(*Name, 0)); } - ReadVertexDataUV(m_uvs[index],source, - MappingInformationType, - ReferenceInformationType - ); - } - else if (type == "LayerElementMaterial") { + ReadVertexDataUV(m_uvs[index], source, + MappingInformationType, + ReferenceInformationType); + } else if (type == "LayerElementMaterial") { if (m_materials.size() > 0) { FBXImporter::LogError("ignoring additional material layer"); return; @@ -348,10 +333,9 @@ void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scop std::vector temp_materials; - ReadVertexDataMaterials(temp_materials,source, - MappingInformationType, - ReferenceInformationType - ); + ReadVertexDataMaterials(temp_materials, source, + MappingInformationType, + ReferenceInformationType); // sometimes, there will be only negative entries. Drop the material // layer in such a case (I guess it means a default material should @@ -359,58 +343,50 @@ void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scop // avoids losing the material if there are more material layers // coming of which at least one contains actual data (did observe // that with one test file). - const size_t count_neg = std::count_if(temp_materials.begin(),temp_materials.end(),[](int n) { return n < 0; }); - if(count_neg == temp_materials.size()) { + const size_t count_neg = std::count_if(temp_materials.begin(), temp_materials.end(), [](int n) { return n < 0; }); + if (count_neg == temp_materials.size()) { FBXImporter::LogWarn("ignoring dummy material layer (all entries -1)"); return; } std::swap(temp_materials, m_materials); - } - else if (type == "LayerElementNormal") { + } else if (type == "LayerElementNormal") { if (m_normals.size() > 0) { FBXImporter::LogError("ignoring additional normal layer"); return; } - ReadVertexDataNormals(m_normals,source, - MappingInformationType, - ReferenceInformationType - ); - } - else if (type == "LayerElementTangent") { + ReadVertexDataNormals(m_normals, source, + MappingInformationType, + ReferenceInformationType); + } else if (type == "LayerElementTangent") { if (m_tangents.size() > 0) { FBXImporter::LogError("ignoring additional tangent layer"); return; } - ReadVertexDataTangents(m_tangents,source, - MappingInformationType, - ReferenceInformationType - ); - } - else if (type == "LayerElementBinormal") { + ReadVertexDataTangents(m_tangents, source, + MappingInformationType, + ReferenceInformationType); + } else if (type == "LayerElementBinormal") { if (m_binormals.size() > 0) { FBXImporter::LogError("ignoring additional binormal layer"); return; } - ReadVertexDataBinormals(m_binormals,source, - MappingInformationType, - ReferenceInformationType - ); - } - else if (type == "LayerElementColor") { - if(index >= AI_MAX_NUMBER_OF_COLOR_SETS) { + ReadVertexDataBinormals(m_binormals, source, + MappingInformationType, + ReferenceInformationType); + } else if (type == "LayerElementColor") { + if (index >= AI_MAX_NUMBER_OF_COLOR_SETS) { FBXImporter::LogError(Formatter::format("ignoring vertex color layer, maximum number of color sets exceeded: ") - << index << " (limit is " << AI_MAX_NUMBER_OF_COLOR_SETS << ")" ); + << index << " (limit is " << AI_MAX_NUMBER_OF_COLOR_SETS << ")"); return; } - ReadVertexDataColors(m_colors[index],source, - MappingInformationType, - ReferenceInformationType - ); + ReadVertexDataColors(m_colors[index], source, + MappingInformationType, + ReferenceInformationType); } } @@ -419,21 +395,20 @@ void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scop // output is in polygon vertex order. This logic is used for reading normals, UVs, colors, // tangents .. template -void ResolveVertexDataArray(std::vector& data_out, const Scope& source, - const std::string& MappingInformationType, - const std::string& ReferenceInformationType, - const char* dataElementName, - const char* indexDataElementName, - size_t vertex_count, - const std::vector& mapping_counts, - const std::vector& mapping_offsets, - const std::vector& mappings) -{ +void ResolveVertexDataArray(std::vector &data_out, const Scope &source, + const std::string &MappingInformationType, + const std::string &ReferenceInformationType, + const char *dataElementName, + const char *indexDataElementName, + size_t vertex_count, + const std::vector &mapping_counts, + const std::vector &mapping_offsets, + const std::vector &mappings) { bool isDirect = ReferenceInformationType == "Direct"; bool isIndexToDirect = ReferenceInformationType == "IndexToDirect"; // fall-back to direct data if there is no index data element - if ( isIndexToDirect && !HasElement( source, indexDataElementName ) ) { + if (isIndexToDirect && !HasElement(source, indexDataElementName)) { isDirect = true; isIndexToDirect = false; } @@ -461,13 +436,12 @@ void ResolveVertexDataArray(std::vector& data_out, const Scope& source, data_out[mappings[j]] = tempData[i]; } } - } - else if (MappingInformationType == "ByVertice" && isIndexToDirect) { - std::vector tempData; - ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName)); + } else if (MappingInformationType == "ByVertice" && isIndexToDirect) { + std::vector tempData; + ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName)); std::vector uvIndices; - ParseVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName)); + ParseVectorDataArray(uvIndices, GetRequiredElement(source, indexDataElementName)); if (uvIndices.size() != vertex_count) { FBXImporter::LogError(Formatter::format("length of input data unexpected for ByVertice mapping: ") @@ -481,32 +455,29 @@ void ResolveVertexDataArray(std::vector& data_out, const Scope& source, const unsigned int istart = mapping_offsets[i], iend = istart + mapping_counts[i]; for (unsigned int j = istart; j < iend; ++j) { - if (static_cast(uvIndices[i]) >= tempData.size()) { - DOMError("index out of range",&GetRequiredElement(source,indexDataElementName)); + if (static_cast(uvIndices[i]) >= tempData.size()) { + DOMError("index out of range", &GetRequiredElement(source, indexDataElementName)); } - data_out[mappings[j]] = tempData[uvIndices[i]]; + data_out[mappings[j]] = tempData[uvIndices[i]]; } } - } - else if (MappingInformationType == "ByPolygonVertex" && isDirect) { - std::vector tempData; - ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName)); + } else if (MappingInformationType == "ByPolygonVertex" && isDirect) { + std::vector tempData; + ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName)); - if (tempData.size() != vertex_count) { + if (tempData.size() != vertex_count) { FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygon mapping: ") - << tempData.size() << ", expected " << vertex_count - ); + << tempData.size() << ", expected " << vertex_count); return; } - data_out.swap(tempData); - } - else if (MappingInformationType == "ByPolygonVertex" && isIndexToDirect) { - std::vector tempData; - ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName)); + data_out.swap(tempData); + } else if (MappingInformationType == "ByPolygonVertex" && isIndexToDirect) { + std::vector tempData; + ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName)); std::vector uvIndices; - ParseVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName)); + ParseVectorDataArray(uvIndices, GetRequiredElement(source, indexDataElementName)); if (uvIndices.size() != vertex_count) { FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygonVertex mapping: ") @@ -518,120 +489,111 @@ void ResolveVertexDataArray(std::vector& data_out, const Scope& source, const T empty; unsigned int next = 0; - for(int i : uvIndices) { - if ( -1 == i ) { - data_out[ next++ ] = empty; + for (int i : uvIndices) { + if (-1 == i) { + data_out[next++] = empty; continue; } if (static_cast(i) >= tempData.size()) { - DOMError("index out of range",&GetRequiredElement(source,indexDataElementName)); + DOMError("index out of range", &GetRequiredElement(source, indexDataElementName)); } - data_out[next++] = tempData[i]; + data_out[next++] = tempData[i]; } - } - else { + } else { FBXImporter::LogError(Formatter::format("ignoring vertex data channel, access type not implemented: ") - << MappingInformationType << "," << ReferenceInformationType); + << MappingInformationType << "," << ReferenceInformationType); } } // ------------------------------------------------------------------------------------------------ -void MeshGeometry::ReadVertexDataNormals(std::vector& normals_out, const Scope& source, - const std::string& MappingInformationType, - const std::string& ReferenceInformationType) -{ - ResolveVertexDataArray(normals_out,source,MappingInformationType,ReferenceInformationType, - "Normals", - "NormalsIndex", - m_vertices.size(), - m_mapping_counts, - m_mapping_offsets, - m_mappings); +void MeshGeometry::ReadVertexDataNormals(std::vector &normals_out, const Scope &source, + const std::string &MappingInformationType, + const std::string &ReferenceInformationType) { + ResolveVertexDataArray(normals_out, source, MappingInformationType, ReferenceInformationType, + "Normals", + "NormalsIndex", + m_vertices.size(), + m_mapping_counts, + m_mapping_offsets, + m_mappings); } // ------------------------------------------------------------------------------------------------ -void MeshGeometry::ReadVertexDataUV(std::vector& uv_out, const Scope& source, - const std::string& MappingInformationType, - const std::string& ReferenceInformationType) -{ - ResolveVertexDataArray(uv_out,source,MappingInformationType,ReferenceInformationType, - "UV", - "UVIndex", - m_vertices.size(), - m_mapping_counts, - m_mapping_offsets, - m_mappings); +void MeshGeometry::ReadVertexDataUV(std::vector &uv_out, const Scope &source, + const std::string &MappingInformationType, + const std::string &ReferenceInformationType) { + ResolveVertexDataArray(uv_out, source, MappingInformationType, ReferenceInformationType, + "UV", + "UVIndex", + m_vertices.size(), + m_mapping_counts, + m_mapping_offsets, + m_mappings); } // ------------------------------------------------------------------------------------------------ -void MeshGeometry::ReadVertexDataColors(std::vector& colors_out, const Scope& source, - const std::string& MappingInformationType, - const std::string& ReferenceInformationType) -{ - ResolveVertexDataArray(colors_out,source,MappingInformationType,ReferenceInformationType, - "Colors", - "ColorIndex", - m_vertices.size(), - m_mapping_counts, - m_mapping_offsets, - m_mappings); +void MeshGeometry::ReadVertexDataColors(std::vector &colors_out, const Scope &source, + const std::string &MappingInformationType, + const std::string &ReferenceInformationType) { + ResolveVertexDataArray(colors_out, source, MappingInformationType, ReferenceInformationType, + "Colors", + "ColorIndex", + m_vertices.size(), + m_mapping_counts, + m_mapping_offsets, + m_mappings); } // ------------------------------------------------------------------------------------------------ static const char *TangentIndexToken = "TangentIndex"; static const char *TangentsIndexToken = "TangentsIndex"; -void MeshGeometry::ReadVertexDataTangents(std::vector& tangents_out, const Scope& source, - const std::string& MappingInformationType, - const std::string& ReferenceInformationType) -{ - const char * str = source.Elements().count( "Tangents" ) > 0 ? "Tangents" : "Tangent"; - const char * strIdx = source.Elements().count( "Tangents" ) > 0 ? TangentsIndexToken : TangentIndexToken; - ResolveVertexDataArray(tangents_out,source,MappingInformationType,ReferenceInformationType, - str, - strIdx, - m_vertices.size(), - m_mapping_counts, - m_mapping_offsets, - m_mappings); +void MeshGeometry::ReadVertexDataTangents(std::vector &tangents_out, const Scope &source, + const std::string &MappingInformationType, + const std::string &ReferenceInformationType) { + const char *str = source.Elements().count("Tangents") > 0 ? "Tangents" : "Tangent"; + const char *strIdx = source.Elements().count("Tangents") > 0 ? TangentsIndexToken : TangentIndexToken; + ResolveVertexDataArray(tangents_out, source, MappingInformationType, ReferenceInformationType, + str, + strIdx, + m_vertices.size(), + m_mapping_counts, + m_mapping_offsets, + m_mappings); } // ------------------------------------------------------------------------------------------------ static const std::string BinormalIndexToken = "BinormalIndex"; static const std::string BinormalsIndexToken = "BinormalsIndex"; -void MeshGeometry::ReadVertexDataBinormals(std::vector& binormals_out, const Scope& source, - const std::string& MappingInformationType, - const std::string& ReferenceInformationType) -{ - const char * str = source.Elements().count( "Binormals" ) > 0 ? "Binormals" : "Binormal"; - const char * strIdx = source.Elements().count( "Binormals" ) > 0 ? BinormalsIndexToken.c_str() : BinormalIndexToken.c_str(); - ResolveVertexDataArray(binormals_out,source,MappingInformationType,ReferenceInformationType, - str, - strIdx, - m_vertices.size(), - m_mapping_counts, - m_mapping_offsets, - m_mappings); +void MeshGeometry::ReadVertexDataBinormals(std::vector &binormals_out, const Scope &source, + const std::string &MappingInformationType, + const std::string &ReferenceInformationType) { + const char *str = source.Elements().count("Binormals") > 0 ? "Binormals" : "Binormal"; + const char *strIdx = source.Elements().count("Binormals") > 0 ? BinormalsIndexToken.c_str() : BinormalIndexToken.c_str(); + ResolveVertexDataArray(binormals_out, source, MappingInformationType, ReferenceInformationType, + str, + strIdx, + m_vertices.size(), + m_mapping_counts, + m_mapping_offsets, + m_mappings); } - // ------------------------------------------------------------------------------------------------ -void MeshGeometry::ReadVertexDataMaterials(std::vector& materials_out, const Scope& source, - const std::string& MappingInformationType, - const std::string& ReferenceInformationType) -{ +void MeshGeometry::ReadVertexDataMaterials(std::vector &materials_out, const Scope &source, + const std::string &MappingInformationType, + const std::string &ReferenceInformationType) { const size_t face_count = m_faces.size(); - if( 0 == face_count ) - { + if (0 == face_count) { return; } - + // materials are handled separately. First of all, they are assigned per-face // and not per polyvert. Secondly, ReferenceInformationType=IndexToDirect // has a slightly different meaning for materials. - ParseVectorDataArray(materials_out,GetRequiredElement(source,"Materials")); + ParseVectorDataArray(materials_out, GetRequiredElement(source, "Materials")); if (MappingInformationType == "AllSame") { // easy - same material for all faces @@ -648,27 +610,26 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector& materials_out, cons } else if (MappingInformationType == "ByPolygon" && ReferenceInformationType == "IndexToDirect") { materials_out.resize(face_count); - if(materials_out.size() != face_count) { + if (materials_out.size() != face_count) { FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygon mapping: ") - << materials_out.size() << ", expected " << face_count - ); + << materials_out.size() << ", expected " << face_count); return; } } else { FBXImporter::LogError(Formatter::format("ignoring material assignments, access type not implemented: ") - << MappingInformationType << "," << ReferenceInformationType); + << MappingInformationType << "," << ReferenceInformationType); } } // ------------------------------------------------------------------------------------------------ -ShapeGeometry::ShapeGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc) -: Geometry(id, element, name, doc) { +ShapeGeometry::ShapeGeometry(uint64_t id, const Element &element, const std::string &name, const Document &doc) : + Geometry(id, element, name, doc) { const Scope *sc = element.Compound(); if (nullptr == sc) { DOMError("failed to read Geometry object (class: Shape), no data scope found"); } - const Element& Indexes = GetRequiredElement(*sc, "Indexes", &element); - const Element& Normals = GetRequiredElement(*sc, "Normals", &element); - const Element& Vertices = GetRequiredElement(*sc, "Vertices", &element); + const Element &Indexes = GetRequiredElement(*sc, "Indexes", &element); + const Element &Normals = GetRequiredElement(*sc, "Normals", &element); + const Element &Vertices = GetRequiredElement(*sc, "Vertices", &element); ParseVectorDataArray(m_indices, Indexes); ParseVectorDataArray(m_vertices, Vertices); ParseVectorDataArray(m_normals, Normals); @@ -679,27 +640,26 @@ ShapeGeometry::~ShapeGeometry() { // empty } // ------------------------------------------------------------------------------------------------ -const std::vector& ShapeGeometry::GetVertices() const { +const std::vector &ShapeGeometry::GetVertices() const { return m_vertices; } // ------------------------------------------------------------------------------------------------ -const std::vector& ShapeGeometry::GetNormals() const { +const std::vector &ShapeGeometry::GetNormals() const { return m_normals; } // ------------------------------------------------------------------------------------------------ -const std::vector& ShapeGeometry::GetIndices() const { +const std::vector &ShapeGeometry::GetIndices() const { return m_indices; } // ------------------------------------------------------------------------------------------------ -LineGeometry::LineGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc) - : Geometry(id, element, name, doc) -{ - const Scope* sc = element.Compound(); +LineGeometry::LineGeometry(uint64_t id, const Element &element, const std::string &name, const Document &doc) : + Geometry(id, element, name, doc) { + const Scope *sc = element.Compound(); if (!sc) { DOMError("failed to read Geometry object (class: Line), no data scope found"); } - const Element& Points = GetRequiredElement(*sc, "Points", &element); - const Element& PointsIndex = GetRequiredElement(*sc, "PointsIndex", &element); + const Element &Points = GetRequiredElement(*sc, "Points", &element); + const Element &PointsIndex = GetRequiredElement(*sc, "PointsIndex", &element); ParseVectorDataArray(m_vertices, Points); ParseVectorDataArray(m_indices, PointsIndex); } @@ -709,14 +669,13 @@ LineGeometry::~LineGeometry() { // empty } // ------------------------------------------------------------------------------------------------ -const std::vector& LineGeometry::GetVertices() const { +const std::vector &LineGeometry::GetVertices() const { return m_vertices; } // ------------------------------------------------------------------------------------------------ -const std::vector& LineGeometry::GetIndices() const { +const std::vector &LineGeometry::GetIndices() const { return m_indices; } -} // !FBX -} // !Assimp +} // namespace FBX +} // namespace Assimp #endif - diff --git a/code/AssetLib/FBX/FBXParser.cpp b/code/AssetLib/FBX/FBXParser.cpp index f93f69d4d..c7efea39a 100644 --- a/code/AssetLib/FBX/FBXParser.cpp +++ b/code/AssetLib/FBX/FBXParser.cpp @@ -47,18 +47,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef ASSIMP_BUILD_NO_FBX_IMPORTER #ifdef ASSIMP_BUILD_NO_OWN_ZLIB -# include +#include #else -# include "../contrib/zlib/zlib.h" +#include "../contrib/zlib/zlib.h" #endif -#include "FBXTokenizer.h" #include "FBXParser.h" +#include "FBXTokenizer.h" #include "FBXUtil.h" +#include #include #include -#include #include #include @@ -68,81 +68,76 @@ using namespace Assimp::FBX; namespace { - // ------------------------------------------------------------------------------------------------ - // signal parse error, this is always unrecoverable. Throws DeadlyImportError. - AI_WONT_RETURN void ParseError(const std::string& message, const Token& token) AI_WONT_RETURN_SUFFIX; - AI_WONT_RETURN void ParseError(const std::string& message, const Token& token) - { - throw DeadlyImportError("FBX-Parser", Util::GetTokenText(&token), message); - } - - // ------------------------------------------------------------------------------------------------ - AI_WONT_RETURN void ParseError(const std::string &message, const Element *element = nullptr) AI_WONT_RETURN_SUFFIX; - AI_WONT_RETURN void ParseError(const std::string& message, const Element* element) - { - if(element) { - ParseError(message,element->KeyToken()); - } - throw DeadlyImportError("FBX-Parser ", message); - } - - - // ------------------------------------------------------------------------------------------------ - void ParseError(const std::string& message, TokenPtr token) - { - if(token) { - ParseError(message, *token); - } - ParseError(message); - } - - // Initially, we did reinterpret_cast, breaking strict aliasing rules. - // This actually caused trouble on Android, so let's be safe this time. - // https://github.com/assimp/assimp/issues/24 - template - T SafeParse(const char* data, const char* end) { - // Actual size validation happens during Tokenization so - // this is valid as an assertion. - (void)(end); - ai_assert(static_cast(end - data) >= sizeof(T)); - T result = static_cast(0); - ::memcpy(&result, data, sizeof(T)); - return result; - } +// ------------------------------------------------------------------------------------------------ +// signal parse error, this is always unrecoverable. Throws DeadlyImportError. +AI_WONT_RETURN void ParseError(const std::string &message, const Token &token) AI_WONT_RETURN_SUFFIX; +AI_WONT_RETURN void ParseError(const std::string &message, const Token &token) { + throw DeadlyImportError("FBX-Parser", Util::GetTokenText(&token), message); } +// ------------------------------------------------------------------------------------------------ +AI_WONT_RETURN void ParseError(const std::string &message, const Element *element = nullptr) AI_WONT_RETURN_SUFFIX; +AI_WONT_RETURN void ParseError(const std::string &message, const Element *element) { + if (element) { + ParseError(message, element->KeyToken()); + } + throw DeadlyImportError("FBX-Parser ", message); +} + +// ------------------------------------------------------------------------------------------------ +void ParseError(const std::string &message, TokenPtr token) { + if (token) { + ParseError(message, *token); + } + ParseError(message); +} + +// Initially, we did reinterpret_cast, breaking strict aliasing rules. +// This actually caused trouble on Android, so let's be safe this time. +// https://github.com/assimp/assimp/issues/24 +template +T SafeParse(const char *data, const char *end) { + // Actual size validation happens during Tokenization so + // this is valid as an assertion. + (void)(end); + ai_assert(static_cast(end - data) >= sizeof(T)); + T result = static_cast(0); + ::memcpy(&result, data, sizeof(T)); + return result; +} +} // namespace + namespace Assimp { namespace FBX { // ------------------------------------------------------------------------------------------------ -Element::Element(const Token& key_token, Parser& parser) -: key_token(key_token) -{ +Element::Element(const Token &key_token, Parser &parser) : + key_token(key_token) { TokenPtr n = nullptr; do { n = parser.AdvanceToNextToken(); - if(!n) { - ParseError("unexpected end of file, expected closing bracket",parser.LastToken()); + if (!n) { + ParseError("unexpected end of file, expected closing bracket", parser.LastToken()); } if (n->Type() == TokenType_DATA) { tokens.push_back(n); - TokenPtr prev = n; + TokenPtr prev = n; n = parser.AdvanceToNextToken(); - if(!n) { - ParseError("unexpected end of file, expected bracket, comma or key",parser.LastToken()); + if (!n) { + ParseError("unexpected end of file, expected bracket, comma or key", parser.LastToken()); } - const TokenType ty = n->Type(); + const TokenType ty = n->Type(); - // some exporters are missing a comma on the next line - if (ty == TokenType_DATA && prev->Type() == TokenType_DATA && (n->Line() == prev->Line() + 1)) { - tokens.push_back(n); - continue; - } + // some exporters are missing a comma on the next line + if (ty == TokenType_DATA && prev->Type() == TokenType_DATA && (n->Line() == prev->Line() + 1)) { + tokens.push_back(n); + continue; + } if (ty != TokenType_OPEN_BRACKET && ty != TokenType_CLOSE_BRACKET && ty != TokenType_COMMA && ty != TokenType_KEY) { - ParseError("unexpected token; expected bracket, comma or key",n); + ParseError("unexpected token; expected bracket, comma or key", n); } } @@ -154,29 +149,26 @@ Element::Element(const Token& key_token, Parser& parser) ai_assert(n); if (n->Type() != TokenType_CLOSE_BRACKET) { - ParseError("expected closing bracket",n); + ParseError("expected closing bracket", n); } parser.AdvanceToNextToken(); return; } - } - while(n->Type() != TokenType_KEY && n->Type() != TokenType_CLOSE_BRACKET); + } while (n->Type() != TokenType_KEY && n->Type() != TokenType_CLOSE_BRACKET); } // ------------------------------------------------------------------------------------------------ -Element::~Element() -{ - // no need to delete tokens, they are owned by the parser +Element::~Element() { + // no need to delete tokens, they are owned by the parser } // ------------------------------------------------------------------------------------------------ -Scope::Scope(Parser& parser,bool topLevel) -{ - if(!topLevel) { +Scope::Scope(Parser &parser, bool topLevel) { + if (!topLevel) { TokenPtr t = parser.CurrentToken(); if (t->Type() != TokenType_OPEN_BRACKET) { - ParseError("expected open bracket",t); + ParseError("expected open bracket", t); } } @@ -186,13 +178,13 @@ Scope::Scope(Parser& parser,bool topLevel) } // note: empty scopes are allowed - while(n->Type() != TokenType_CLOSE_BRACKET) { + while (n->Type() != TokenType_CLOSE_BRACKET) { if (n->Type() != TokenType_KEY) { - ParseError("unexpected token, expected TOK_KEY",n); + ParseError("unexpected token, expected TOK_KEY", n); } - const std::string& str = n->StringContents(); - elements.insert(ElementMap::value_type(str,new_Element(*n,parser))); + const std::string &str = n->StringContents(); + elements.insert(ElementMap::value_type(str, new_Element(*n, parser))); // Element() should stop at the next Key token (or right after a Close token) n = parser.CurrentToken(); @@ -200,40 +192,32 @@ Scope::Scope(Parser& parser,bool topLevel) if (topLevel) { return; } - ParseError("unexpected end of file",parser.LastToken()); + ParseError("unexpected end of file", parser.LastToken()); } } } // ------------------------------------------------------------------------------------------------ -Scope::~Scope() -{ - for(ElementMap::value_type& v : elements) { +Scope::~Scope() { + for (ElementMap::value_type &v : elements) { delete v.second; } } // ------------------------------------------------------------------------------------------------ -Parser::Parser (const TokenList& tokens, bool is_binary) -: tokens(tokens) -, last() -, current() -, cursor(tokens.begin()) -, is_binary(is_binary) -{ +Parser::Parser(const TokenList &tokens, bool is_binary) : + tokens(tokens), last(), current(), cursor(tokens.begin()), is_binary(is_binary) { ASSIMP_LOG_DEBUG("Parsing FBX tokens"); - root.reset(new Scope(*this,true)); + root.reset(new Scope(*this, true)); } // ------------------------------------------------------------------------------------------------ -Parser::~Parser() -{ +Parser::~Parser() { // empty } // ------------------------------------------------------------------------------------------------ -TokenPtr Parser::AdvanceToNextToken() -{ +TokenPtr Parser::AdvanceToNextToken() { last = current; if (cursor == tokens.end()) { current = nullptr; @@ -244,20 +228,17 @@ TokenPtr Parser::AdvanceToNextToken() } // ------------------------------------------------------------------------------------------------ -TokenPtr Parser::CurrentToken() const -{ +TokenPtr Parser::CurrentToken() const { return current; } // ------------------------------------------------------------------------------------------------ -TokenPtr Parser::LastToken() const -{ +TokenPtr Parser::LastToken() const { return last; } // ------------------------------------------------------------------------------------------------ -uint64_t ParseTokenAsID(const Token& t, const char*& err_out) -{ +uint64_t ParseTokenAsID(const Token &t, const char *&err_out) { err_out = nullptr; if (t.Type() != TokenType_DATA) { @@ -265,15 +246,14 @@ uint64_t ParseTokenAsID(const Token& t, const char*& err_out) return 0L; } - if(t.IsBinary()) - { - const char* data = t.begin(); + if (t.IsBinary()) { + const char *data = t.begin(); if (data[0] != 'L') { err_out = "failed to parse ID, unexpected data type, expected L(ong) (binary)"; return 0L; } - BE_NCONST uint64_t id = SafeParse(data+1, t.end()); + BE_NCONST uint64_t id = SafeParse(data + 1, t.end()); AI_SWAP8(id); return id; } @@ -282,8 +262,8 @@ uint64_t ParseTokenAsID(const Token& t, const char*& err_out) unsigned int length = static_cast(t.end() - t.begin()); ai_assert(length > 0); - const char* out = nullptr; - const uint64_t id = strtoul10_64(t.begin(),&out,&length); + const char *out = nullptr; + const uint64_t id = strtoul10_64(t.begin(), &out, &length); if (out > t.end()) { err_out = "failed to parse ID (text)"; return 0L; @@ -293,8 +273,7 @@ uint64_t ParseTokenAsID(const Token& t, const char*& err_out) } // ------------------------------------------------------------------------------------------------ -size_t ParseTokenAsDim(const Token& t, const char*& err_out) -{ +size_t ParseTokenAsDim(const Token &t, const char *&err_out) { // same as ID parsing, except there is a trailing asterisk err_out = nullptr; @@ -303,33 +282,32 @@ size_t ParseTokenAsDim(const Token& t, const char*& err_out) return 0; } - if(t.IsBinary()) - { - const char* data = t.begin(); + if (t.IsBinary()) { + const char *data = t.begin(); if (data[0] != 'L') { err_out = "failed to parse ID, unexpected data type, expected L(ong) (binary)"; return 0; } - BE_NCONST uint64_t id = SafeParse(data+1, t.end()); + BE_NCONST uint64_t id = SafeParse(data + 1, t.end()); AI_SWAP8(id); return static_cast(id); } - if(*t.begin() != '*') { + if (*t.begin() != '*') { err_out = "expected asterisk before array dimension"; return 0; } // XXX: should use size_t here unsigned int length = static_cast(t.end() - t.begin()); - if(length == 0) { + if (length == 0) { err_out = "expected valid integer number after asterisk"; return 0; } - const char* out = nullptr; - const size_t id = static_cast(strtoul10_64(t.begin() + 1,&out,&length)); + const char *out = nullptr; + const size_t id = static_cast(strtoul10_64(t.begin() + 1, &out, &length)); if (out > t.end()) { err_out = "failed to parse ID"; return 0; @@ -338,10 +316,8 @@ size_t ParseTokenAsDim(const Token& t, const char*& err_out) return id; } - // ------------------------------------------------------------------------------------------------ -float ParseTokenAsFloat(const Token& t, const char*& err_out) -{ +float ParseTokenAsFloat(const Token &t, const char *&err_out) { err_out = nullptr; if (t.Type() != TokenType_DATA) { @@ -349,19 +325,17 @@ float ParseTokenAsFloat(const Token& t, const char*& err_out) return 0.0f; } - if(t.IsBinary()) - { - const char* data = t.begin(); + if (t.IsBinary()) { + const char *data = t.begin(); if (data[0] != 'F' && data[0] != 'D') { err_out = "failed to parse F(loat) or D(ouble), unexpected data type (binary)"; return 0.0f; } if (data[0] == 'F') { - return SafeParse(data+1, t.end()); - } - else { - return static_cast( SafeParse(data+1, t.end()) ); + return SafeParse(data + 1, t.end()); + } else { + return static_cast(SafeParse(data + 1, t.end())); } } @@ -369,22 +343,20 @@ float ParseTokenAsFloat(const Token& t, const char*& err_out) // first - next in the fbx token stream comes ',', // which fast_atof could interpret as decimal point. #define MAX_FLOAT_LENGTH 31 - const size_t length = static_cast(t.end()-t.begin()); + const size_t length = static_cast(t.end() - t.begin()); if (length > MAX_FLOAT_LENGTH) { return 0.f; } char temp[MAX_FLOAT_LENGTH + 1]; std::copy(t.begin(), t.end(), temp); - temp[std::min(static_cast(MAX_FLOAT_LENGTH),length)] = '\0'; + temp[std::min(static_cast(MAX_FLOAT_LENGTH), length)] = '\0'; return fast_atof(temp); } - // ------------------------------------------------------------------------------------------------ -int ParseTokenAsInt(const Token& t, const char*& err_out) -{ +int ParseTokenAsInt(const Token &t, const char *&err_out) { err_out = nullptr; if (t.Type() != TokenType_DATA) { @@ -392,23 +364,22 @@ int ParseTokenAsInt(const Token& t, const char*& err_out) return 0; } - if(t.IsBinary()) - { - const char* data = t.begin(); + if (t.IsBinary()) { + const char *data = t.begin(); if (data[0] != 'I') { err_out = "failed to parse I(nt), unexpected data type (binary)"; return 0; } - BE_NCONST int32_t ival = SafeParse(data+1, t.end()); + BE_NCONST int32_t ival = SafeParse(data + 1, t.end()); AI_SWAP4(ival); return static_cast(ival); } ai_assert(static_cast(t.end() - t.begin()) > 0); - const char* out; - const int intval = strtol10(t.begin(),&out); + const char *out; + const int intval = strtol10(t.begin(), &out); if (out != t.end()) { err_out = "failed to parse ID"; return 0; @@ -417,10 +388,8 @@ int ParseTokenAsInt(const Token& t, const char*& err_out) return intval; } - // ------------------------------------------------------------------------------------------------ -int64_t ParseTokenAsInt64(const Token& t, const char*& err_out) -{ +int64_t ParseTokenAsInt64(const Token &t, const char *&err_out) { err_out = nullptr; if (t.Type() != TokenType_DATA) { @@ -428,9 +397,8 @@ int64_t ParseTokenAsInt64(const Token& t, const char*& err_out) return 0L; } - if (t.IsBinary()) - { - const char* data = t.begin(); + if (t.IsBinary()) { + const char *data = t.begin(); if (data[0] != 'L') { err_out = "failed to parse Int64, unexpected data type"; return 0L; @@ -445,7 +413,7 @@ int64_t ParseTokenAsInt64(const Token& t, const char*& err_out) unsigned int length = static_cast(t.end() - t.begin()); ai_assert(length > 0); - const char* out = nullptr; + const char *out = nullptr; const int64_t id = strtol10_64(t.begin(), &out, &length); if (out > t.end()) { err_out = "failed to parse Int64 (text)"; @@ -456,8 +424,7 @@ int64_t ParseTokenAsInt64(const Token& t, const char*& err_out) } // ------------------------------------------------------------------------------------------------ -std::string ParseTokenAsString(const Token& t, const char*& err_out) -{ +std::string ParseTokenAsString(const Token &t, const char *&err_out) { err_out = nullptr; if (t.Type() != TokenType_DATA) { @@ -465,16 +432,15 @@ std::string ParseTokenAsString(const Token& t, const char*& err_out) return ""; } - if(t.IsBinary()) - { - const char* data = t.begin(); + if (t.IsBinary()) { + const char *data = t.begin(); if (data[0] != 'S') { err_out = "failed to parse S(tring), unexpected data type (binary)"; return ""; } // read string length - BE_NCONST int32_t len = SafeParse(data+1, t.end()); + BE_NCONST int32_t len = SafeParse(data + 1, t.end()); AI_SWAP4(len); ai_assert(t.end() - data == 5 + len); @@ -482,50 +448,46 @@ std::string ParseTokenAsString(const Token& t, const char*& err_out) } const size_t length = static_cast(t.end() - t.begin()); - if(length < 2) { + if (length < 2) { err_out = "token is too short to hold a string"; return ""; } - const char* s = t.begin(), *e = t.end() - 1; + const char *s = t.begin(), *e = t.end() - 1; if (*s != '\"' || *e != '\"') { err_out = "expected double quoted string"; return ""; } - return std::string(s+1,length-2); + return std::string(s + 1, length - 2); } - namespace { // ------------------------------------------------------------------------------------------------ // read the type code and element count of a binary data array and stop there -void ReadBinaryDataArrayHead(const char*& data, const char* end, char& type, uint32_t& count, - const Element& el) -{ - if (static_cast(end-data) < 5) { - ParseError("binary data array is too short, need five (5) bytes for type signature and element count",&el); +void ReadBinaryDataArrayHead(const char *&data, const char *end, char &type, uint32_t &count, + const Element &el) { + if (static_cast(end - data) < 5) { + ParseError("binary data array is too short, need five (5) bytes for type signature and element count", &el); } // data type type = *data; // read number of elements - BE_NCONST uint32_t len = SafeParse(data+1, end); + BE_NCONST uint32_t len = SafeParse(data + 1, end); AI_SWAP4(len); count = len; data += 5; } - // ------------------------------------------------------------------------------------------------ // read binary data array, assume cursor points to the 'compression mode' field (i.e. behind the header) -void ReadBinaryDataArray(char type, uint32_t count, const char*& data, const char* end, - std::vector& buff, - const Element& /*el*/) -{ +void ReadBinaryDataArray(char type, uint32_t count, const char *&data, const char *end, + std::vector &buff, + const Element & /*el*/) { BE_NCONST uint32_t encmode = SafeParse(data, end); AI_SWAP4(encmode); data += 4; @@ -539,51 +501,49 @@ void ReadBinaryDataArray(char type, uint32_t count, const char*& data, const cha // determine the length of the uncompressed data by looking at the type signature uint32_t stride = 0; - switch(type) - { - case 'f': - case 'i': - stride = 4; - break; + switch (type) { + case 'f': + case 'i': + stride = 4; + break; - case 'd': - case 'l': - stride = 8; - break; + case 'd': + case 'l': + stride = 8; + break; - default: - ai_assert(false); + default: + ai_assert(false); }; const uint32_t full_length = stride * count; buff.resize(full_length); - if(encmode == 0) { + if (encmode == 0) { ai_assert(full_length == comp_len); // plain data, no compression std::copy(data, end, buff.begin()); - } - else if(encmode == 1) { + } else if (encmode == 1) { // zlib/deflate, next comes ZIP head (0x78 0x01) // see http://www.ietf.org/rfc/rfc1950.txt z_stream zstream; zstream.opaque = Z_NULL; zstream.zalloc = Z_NULL; - zstream.zfree = Z_NULL; + zstream.zfree = Z_NULL; zstream.data_type = Z_BINARY; // http://hewgill.com/journal/entries/349-how-to-decompress-gzip-stream-with-zlib - if(Z_OK != inflateInit(&zstream)) { + if (Z_OK != inflateInit(&zstream)) { ParseError("failure initializing zlib"); } - zstream.next_in = reinterpret_cast( const_cast(data) ); - zstream.avail_in = comp_len; + zstream.next_in = reinterpret_cast(const_cast(data)); + zstream.avail_in = comp_len; zstream.avail_out = static_cast(buff.size()); - zstream.next_out = reinterpret_cast(&*buff.begin()); + zstream.next_out = reinterpret_cast(&*buff.begin()); const int ret = inflate(&zstream, Z_FINISH); if (ret != Z_STREAM_END && ret != Z_OK) { @@ -604,37 +564,35 @@ void ReadBinaryDataArray(char type, uint32_t count, const char*& data, const cha ai_assert(data == end); } -} // !anon - +} // namespace // ------------------------------------------------------------------------------------------------ // read an array of float3 tuples -void ParseVectorDataArray(std::vector& out, const Element& el) -{ - out.resize( 0 ); +void ParseVectorDataArray(std::vector &out, const Element &el) { + out.resize(0); - const TokenList& tok = el.Tokens(); - if(tok.empty()) { - ParseError("unexpected empty element",&el); + const TokenList &tok = el.Tokens(); + if (tok.empty()) { + ParseError("unexpected empty element", &el); } - if(tok[0]->IsBinary()) { - const char* data = tok[0]->begin(), *end = tok[0]->end(); + if (tok[0]->IsBinary()) { + const char *data = tok[0]->begin(), *end = tok[0]->end(); char type; uint32_t count; ReadBinaryDataArrayHead(data, end, type, count, el); - if(count % 3 != 0) { - ParseError("number of floats is not a multiple of three (3) (binary)",&el); + if (count % 3 != 0) { + ParseError("number of floats is not a multiple of three (3) (binary)", &el); } - if(!count) { + if (!count) { return; } if (type != 'd' && type != 'f') { - ParseError("expected float or double array (binary)",&el); + ParseError("expected float or double array (binary)", &el); } std::vector buff; @@ -647,11 +605,11 @@ void ParseVectorDataArray(std::vector& out, const Element& el) out.reserve(count3); if (type == 'd') { - const double* d = reinterpret_cast(&buff[0]); + const double *d = reinterpret_cast(&buff[0]); for (unsigned int i = 0; i < count3; ++i, d += 3) { out.push_back(aiVector3D(static_cast(d[0]), - static_cast(d[1]), - static_cast(d[2]))); + static_cast(d[1]), + static_cast(d[2]))); } // for debugging /*for ( size_t i = 0; i < out.size(); i++ ) { @@ -660,11 +618,10 @@ void ParseVectorDataArray(std::vector& out, const Element& el) stream << " vec3.x = " << vec3.x << " vec3.y = " << vec3.y << " vec3.z = " << vec3.z << std::endl; DefaultLogger::get()->info( stream.str() ); }*/ - } - else if (type == 'f') { - const float* f = reinterpret_cast(&buff[0]); + } else if (type == 'f') { + const float *f = reinterpret_cast(&buff[0]); for (unsigned int i = 0; i < count3; ++i, f += 3) { - out.push_back(aiVector3D(f[0],f[1],f[2])); + out.push_back(aiVector3D(f[0], f[1], f[2])); } } @@ -678,13 +635,13 @@ void ParseVectorDataArray(std::vector& out, const Element& el) // crash since assimp handles this case properly. out.reserve(dim); - const Scope& scope = GetRequiredScope(el); - const Element& a = GetRequiredElement(scope,"a",&el); + const Scope &scope = GetRequiredScope(el); + const Element &a = GetRequiredElement(scope, "a", &el); if (a.Tokens().size() % 3 != 0) { - ParseError("number of floats is not a multiple of three (3)",&el); + ParseError("number of floats is not a multiple of three (3)", &el); } - for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) { + for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end;) { aiVector3D v; v.x = ParseTokenAsFloat(**it++); v.y = ParseTokenAsFloat(**it++); @@ -694,34 +651,32 @@ void ParseVectorDataArray(std::vector& out, const Element& el) } } - // ------------------------------------------------------------------------------------------------ // read an array of color4 tuples -void ParseVectorDataArray(std::vector& out, const Element& el) -{ - out.resize( 0 ); - const TokenList& tok = el.Tokens(); - if(tok.empty()) { - ParseError("unexpected empty element",&el); +void ParseVectorDataArray(std::vector &out, const Element &el) { + out.resize(0); + const TokenList &tok = el.Tokens(); + if (tok.empty()) { + ParseError("unexpected empty element", &el); } - if(tok[0]->IsBinary()) { - const char* data = tok[0]->begin(), *end = tok[0]->end(); + if (tok[0]->IsBinary()) { + const char *data = tok[0]->begin(), *end = tok[0]->end(); char type; uint32_t count; ReadBinaryDataArrayHead(data, end, type, count, el); - if(count % 4 != 0) { - ParseError("number of floats is not a multiple of four (4) (binary)",&el); + if (count % 4 != 0) { + ParseError("number of floats is not a multiple of four (4) (binary)", &el); } - if(!count) { + if (!count) { return; } if (type != 'd' && type != 'f') { - ParseError("expected float or double array (binary)",&el); + ParseError("expected float or double array (binary)", &el); } std::vector buff; @@ -734,18 +689,17 @@ void ParseVectorDataArray(std::vector& out, const Element& el) out.reserve(count4); if (type == 'd') { - const double* d = reinterpret_cast(&buff[0]); + const double *d = reinterpret_cast(&buff[0]); for (unsigned int i = 0; i < count4; ++i, d += 4) { out.push_back(aiColor4D(static_cast(d[0]), - static_cast(d[1]), - static_cast(d[2]), - static_cast(d[3]))); + static_cast(d[1]), + static_cast(d[2]), + static_cast(d[3]))); } - } - else if (type == 'f') { - const float* f = reinterpret_cast(&buff[0]); + } else if (type == 'f') { + const float *f = reinterpret_cast(&buff[0]); for (unsigned int i = 0; i < count4; ++i, f += 4) { - out.push_back(aiColor4D(f[0],f[1],f[2],f[3])); + out.push_back(aiColor4D(f[0], f[1], f[2], f[3])); } } return; @@ -756,13 +710,13 @@ void ParseVectorDataArray(std::vector& out, const Element& el) // see notes in ParseVectorDataArray() above out.reserve(dim); - const Scope& scope = GetRequiredScope(el); - const Element& a = GetRequiredElement(scope,"a",&el); + const Scope &scope = GetRequiredScope(el); + const Element &a = GetRequiredElement(scope, "a", &el); if (a.Tokens().size() % 4 != 0) { - ParseError("number of floats is not a multiple of four (4)",&el); + ParseError("number of floats is not a multiple of four (4)", &el); } - for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) { + for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end;) { aiColor4D v; v.r = ParseTokenAsFloat(**it++); v.g = ParseTokenAsFloat(**it++); @@ -773,34 +727,32 @@ void ParseVectorDataArray(std::vector& out, const Element& el) } } - // ------------------------------------------------------------------------------------------------ // read an array of float2 tuples -void ParseVectorDataArray(std::vector& out, const Element& el) -{ - out.resize( 0 ); - const TokenList& tok = el.Tokens(); - if(tok.empty()) { - ParseError("unexpected empty element",&el); +void ParseVectorDataArray(std::vector &out, const Element &el) { + out.resize(0); + const TokenList &tok = el.Tokens(); + if (tok.empty()) { + ParseError("unexpected empty element", &el); } - if(tok[0]->IsBinary()) { - const char* data = tok[0]->begin(), *end = tok[0]->end(); + if (tok[0]->IsBinary()) { + const char *data = tok[0]->begin(), *end = tok[0]->end(); char type; uint32_t count; ReadBinaryDataArrayHead(data, end, type, count, el); - if(count % 2 != 0) { - ParseError("number of floats is not a multiple of two (2) (binary)",&el); + if (count % 2 != 0) { + ParseError("number of floats is not a multiple of two (2) (binary)", &el); } - if(!count) { + if (!count) { return; } if (type != 'd' && type != 'f') { - ParseError("expected float or double array (binary)",&el); + ParseError("expected float or double array (binary)", &el); } std::vector buff; @@ -813,16 +765,15 @@ void ParseVectorDataArray(std::vector& out, const Element& el) out.reserve(count2); if (type == 'd') { - const double* d = reinterpret_cast(&buff[0]); + const double *d = reinterpret_cast(&buff[0]); for (unsigned int i = 0; i < count2; ++i, d += 2) { out.push_back(aiVector2D(static_cast(d[0]), - static_cast(d[1]))); + static_cast(d[1]))); } - } - else if (type == 'f') { - const float* f = reinterpret_cast(&buff[0]); + } else if (type == 'f') { + const float *f = reinterpret_cast(&buff[0]); for (unsigned int i = 0; i < count2; ++i, f += 2) { - out.push_back(aiVector2D(f[0],f[1])); + out.push_back(aiVector2D(f[0], f[1])); } } @@ -834,13 +785,13 @@ void ParseVectorDataArray(std::vector& out, const Element& el) // see notes in ParseVectorDataArray() above out.reserve(dim); - const Scope& scope = GetRequiredScope(el); - const Element& a = GetRequiredElement(scope,"a",&el); + const Scope &scope = GetRequiredScope(el); + const Element &a = GetRequiredElement(scope, "a", &el); if (a.Tokens().size() % 2 != 0) { - ParseError("number of floats is not a multiple of two (2)",&el); + ParseError("number of floats is not a multiple of two (2)", &el); } - for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) { + for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end;) { aiVector2D v; v.x = ParseTokenAsFloat(**it++); v.y = ParseTokenAsFloat(**it++); @@ -849,30 +800,28 @@ void ParseVectorDataArray(std::vector& out, const Element& el) } } - // ------------------------------------------------------------------------------------------------ // read an array of ints -void ParseVectorDataArray(std::vector& out, const Element& el) -{ - out.resize( 0 ); - const TokenList& tok = el.Tokens(); - if(tok.empty()) { - ParseError("unexpected empty element",&el); +void ParseVectorDataArray(std::vector &out, const Element &el) { + out.resize(0); + const TokenList &tok = el.Tokens(); + if (tok.empty()) { + ParseError("unexpected empty element", &el); } - if(tok[0]->IsBinary()) { - const char* data = tok[0]->begin(), *end = tok[0]->end(); + if (tok[0]->IsBinary()) { + const char *data = tok[0]->begin(), *end = tok[0]->end(); char type; uint32_t count; ReadBinaryDataArrayHead(data, end, type, count, el); - if(!count) { + if (!count) { return; } if (type != 'i') { - ParseError("expected int array (binary)",&el); + ParseError("expected int array (binary)", &el); } std::vector buff; @@ -883,7 +832,7 @@ void ParseVectorDataArray(std::vector& out, const Element& el) out.reserve(count); - const int32_t* ip = reinterpret_cast(&buff[0]); + const int32_t *ip = reinterpret_cast(&buff[0]); for (unsigned int i = 0; i < count; ++i, ++ip) { BE_NCONST int32_t val = *ip; AI_SWAP4(val); @@ -898,39 +847,37 @@ void ParseVectorDataArray(std::vector& out, const Element& el) // see notes in ParseVectorDataArray() out.reserve(dim); - const Scope& scope = GetRequiredScope(el); - const Element& a = GetRequiredElement(scope,"a",&el); + const Scope &scope = GetRequiredScope(el); + const Element &a = GetRequiredElement(scope, "a", &el); - for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) { + for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end;) { const int ival = ParseTokenAsInt(**it++); out.push_back(ival); } } - // ------------------------------------------------------------------------------------------------ // read an array of floats -void ParseVectorDataArray(std::vector& out, const Element& el) -{ - out.resize( 0 ); - const TokenList& tok = el.Tokens(); - if(tok.empty()) { - ParseError("unexpected empty element",&el); +void ParseVectorDataArray(std::vector &out, const Element &el) { + out.resize(0); + const TokenList &tok = el.Tokens(); + if (tok.empty()) { + ParseError("unexpected empty element", &el); } - if(tok[0]->IsBinary()) { - const char* data = tok[0]->begin(), *end = tok[0]->end(); + if (tok[0]->IsBinary()) { + const char *data = tok[0]->begin(), *end = tok[0]->end(); char type; uint32_t count; ReadBinaryDataArrayHead(data, end, type, count, el); - if(!count) { + if (!count) { return; } if (type != 'd' && type != 'f') { - ParseError("expected float or double array (binary)",&el); + ParseError("expected float or double array (binary)", &el); } std::vector buff; @@ -940,13 +887,12 @@ void ParseVectorDataArray(std::vector& out, const Element& el) ai_assert(buff.size() == count * (type == 'd' ? 8 : 4)); if (type == 'd') { - const double* d = reinterpret_cast(&buff[0]); + const double *d = reinterpret_cast(&buff[0]); for (unsigned int i = 0; i < count; ++i, ++d) { out.push_back(static_cast(*d)); } - } - else if (type == 'f') { - const float* f = reinterpret_cast(&buff[0]); + } else if (type == 'f') { + const float *f = reinterpret_cast(&buff[0]); for (unsigned int i = 0; i < count; ++i, ++f) { out.push_back(*f); } @@ -960,10 +906,10 @@ void ParseVectorDataArray(std::vector& out, const Element& el) // see notes in ParseVectorDataArray() out.reserve(dim); - const Scope& scope = GetRequiredScope(el); - const Element& a = GetRequiredElement(scope,"a",&el); + const Scope &scope = GetRequiredScope(el); + const Element &a = GetRequiredElement(scope, "a", &el); - for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) { + for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end;) { const float ival = ParseTokenAsFloat(**it++); out.push_back(ival); } @@ -971,27 +917,26 @@ void ParseVectorDataArray(std::vector& out, const Element& el) // ------------------------------------------------------------------------------------------------ // read an array of uints -void ParseVectorDataArray(std::vector& out, const Element& el) -{ - out.resize( 0 ); - const TokenList& tok = el.Tokens(); - if(tok.empty()) { - ParseError("unexpected empty element",&el); +void ParseVectorDataArray(std::vector &out, const Element &el) { + out.resize(0); + const TokenList &tok = el.Tokens(); + if (tok.empty()) { + ParseError("unexpected empty element", &el); } - if(tok[0]->IsBinary()) { - const char* data = tok[0]->begin(), *end = tok[0]->end(); + if (tok[0]->IsBinary()) { + const char *data = tok[0]->begin(), *end = tok[0]->end(); char type; uint32_t count; ReadBinaryDataArrayHead(data, end, type, count, el); - if(!count) { + if (!count) { return; } if (type != 'i') { - ParseError("expected (u)int array (binary)",&el); + ParseError("expected (u)int array (binary)", &el); } std::vector buff; @@ -1002,10 +947,10 @@ void ParseVectorDataArray(std::vector& out, const Element& el) out.reserve(count); - const int32_t* ip = reinterpret_cast(&buff[0]); + const int32_t *ip = reinterpret_cast(&buff[0]); for (unsigned int i = 0; i < count; ++i, ++ip) { BE_NCONST int32_t val = *ip; - if(val < 0) { + if (val < 0) { ParseError("encountered negative integer index (binary)"); } @@ -1021,89 +966,29 @@ void ParseVectorDataArray(std::vector& out, const Element& el) // see notes in ParseVectorDataArray() out.reserve(dim); - const Scope& scope = GetRequiredScope(el); - const Element& a = GetRequiredElement(scope,"a",&el); + const Scope &scope = GetRequiredScope(el); + const Element &a = GetRequiredElement(scope, "a", &el); - for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) { + for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end;) { const int ival = ParseTokenAsInt(**it++); - if(ival < 0) { + if (ival < 0) { ParseError("encountered negative integer index"); } out.push_back(static_cast(ival)); } } - // ------------------------------------------------------------------------------------------------ // read an array of uint64_ts -void ParseVectorDataArray(std::vector& out, const Element& el) -{ - out.resize( 0 ); - const TokenList& tok = el.Tokens(); - if(tok.empty()) { - ParseError("unexpected empty element",&el); - } - - if(tok[0]->IsBinary()) { - const char* data = tok[0]->begin(), *end = tok[0]->end(); - - char type; - uint32_t count; - ReadBinaryDataArrayHead(data, end, type, count, el); - - if(!count) { - return; - } - - if (type != 'l') { - ParseError("expected long array (binary)",&el); - } - - std::vector buff; - ReadBinaryDataArray(type, count, data, end, buff, el); - - ai_assert(data == end); - ai_assert(buff.size() == count * 8); - - out.reserve(count); - - const uint64_t* ip = reinterpret_cast(&buff[0]); - for (unsigned int i = 0; i < count; ++i, ++ip) { - BE_NCONST uint64_t val = *ip; - AI_SWAP8(val); - out.push_back(val); - } - - return; - } - - const size_t dim = ParseTokenAsDim(*tok[0]); - - // see notes in ParseVectorDataArray() - out.reserve(dim); - - const Scope& scope = GetRequiredScope(el); - const Element& a = GetRequiredElement(scope,"a",&el); - - for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) { - const uint64_t ival = ParseTokenAsID(**it++); - - out.push_back(ival); - } -} - -// ------------------------------------------------------------------------------------------------ -// read an array of int64_ts -void ParseVectorDataArray(std::vector& out, const Element& el) -{ - out.resize( 0 ); - const TokenList& tok = el.Tokens(); +void ParseVectorDataArray(std::vector &out, const Element &el) { + out.resize(0); + const TokenList &tok = el.Tokens(); if (tok.empty()) { ParseError("unexpected empty element", &el); } if (tok[0]->IsBinary()) { - const char* data = tok[0]->begin(), *end = tok[0]->end(); + const char *data = tok[0]->begin(), *end = tok[0]->end(); char type; uint32_t count; @@ -1125,7 +1010,64 @@ void ParseVectorDataArray(std::vector& out, const Element& el) out.reserve(count); - const int64_t* ip = reinterpret_cast(&buff[0]); + const uint64_t *ip = reinterpret_cast(&buff[0]); + for (unsigned int i = 0; i < count; ++i, ++ip) { + BE_NCONST uint64_t val = *ip; + AI_SWAP8(val); + out.push_back(val); + } + + return; + } + + const size_t dim = ParseTokenAsDim(*tok[0]); + + // see notes in ParseVectorDataArray() + out.reserve(dim); + + const Scope &scope = GetRequiredScope(el); + const Element &a = GetRequiredElement(scope, "a", &el); + + for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end;) { + const uint64_t ival = ParseTokenAsID(**it++); + + out.push_back(ival); + } +} + +// ------------------------------------------------------------------------------------------------ +// read an array of int64_ts +void ParseVectorDataArray(std::vector &out, const Element &el) { + out.resize(0); + const TokenList &tok = el.Tokens(); + if (tok.empty()) { + ParseError("unexpected empty element", &el); + } + + if (tok[0]->IsBinary()) { + const char *data = tok[0]->begin(), *end = tok[0]->end(); + + char type; + uint32_t count; + ReadBinaryDataArrayHead(data, end, type, count, el); + + if (!count) { + return; + } + + if (type != 'l') { + ParseError("expected long array (binary)", &el); + } + + std::vector buff; + ReadBinaryDataArray(type, count, data, end, buff, el); + + ai_assert(data == end); + ai_assert(buff.size() == count * 8); + + out.reserve(count); + + const int64_t *ip = reinterpret_cast(&buff[0]); for (unsigned int i = 0; i < count; ++i, ++ip) { BE_NCONST int64_t val = *ip; AI_SWAP8(val); @@ -1140,8 +1082,8 @@ void ParseVectorDataArray(std::vector& out, const Element& el) // see notes in ParseVectorDataArray() out.reserve(dim); - const Scope& scope = GetRequiredScope(el); - const Element& a = GetRequiredElement(scope, "a", &el); + const Scope &scope = GetRequiredScope(el); + const Element &a = GetRequiredElement(scope, "a", &el); for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end;) { const int64_t ival = ParseTokenAsInt64(**it++); @@ -1151,18 +1093,16 @@ void ParseVectorDataArray(std::vector& out, const Element& el) } // ------------------------------------------------------------------------------------------------ -aiMatrix4x4 ReadMatrix(const Element& element) -{ +aiMatrix4x4 ReadMatrix(const Element &element) { std::vector values; - ParseVectorDataArray(values,element); + ParseVectorDataArray(values, element); - if(values.size() != 16) { + if (values.size() != 16) { ParseError("expected 16 matrix elements"); } aiMatrix4x4 result; - result.a1 = values[0]; result.a2 = values[1]; result.a3 = values[2]; @@ -1187,22 +1127,20 @@ aiMatrix4x4 ReadMatrix(const Element& element) return result; } - // ------------------------------------------------------------------------------------------------ // wrapper around ParseTokenAsString() with ParseError handling -std::string ParseTokenAsString(const Token& t) -{ - const char* err; - const std::string& i = ParseTokenAsString(t,err); - if(err) { - ParseError(err,t); +std::string ParseTokenAsString(const Token &t) { + const char *err; + const std::string &i = ParseTokenAsString(t, err); + if (err) { + ParseError(err, t); } return i; } -bool HasElement( const Scope& sc, const std::string& index ) { - const Element* el = sc[ index ]; - if ( nullptr == el ) { +bool HasElement(const Scope &sc, const std::string &index) { + const Element *el = sc[index]; + if (nullptr == el) { return false; } @@ -1211,97 +1149,84 @@ bool HasElement( const Scope& sc, const std::string& index ) { // ------------------------------------------------------------------------------------------------ // extract a required element from a scope, abort if the element cannot be found -const Element& GetRequiredElement(const Scope& sc, const std::string& index, const Element* element /*= nullptr*/) -{ - const Element* el = sc[index]; - if(!el) { - ParseError("did not find required element \"" + index + "\"",element); +const Element &GetRequiredElement(const Scope &sc, const std::string &index, const Element *element /*= nullptr*/) { + const Element *el = sc[index]; + if (!el) { + ParseError("did not find required element \"" + index + "\"", element); } return *el; } - // ------------------------------------------------------------------------------------------------ // extract required compound scope -const Scope& GetRequiredScope(const Element& el) -{ - const Scope* const s = el.Compound(); - if(!s) { - ParseError("expected compound scope",&el); +const Scope &GetRequiredScope(const Element &el) { + const Scope *const s = el.Compound(); + if (!s) { + ParseError("expected compound scope", &el); } return *s; } - // ------------------------------------------------------------------------------------------------ // get token at a particular index -const Token& GetRequiredToken(const Element& el, unsigned int index) -{ - const TokenList& t = el.Tokens(); - if(index >= t.size()) { - ParseError(Formatter::format( "missing token at index " ) << index,&el); +const Token &GetRequiredToken(const Element &el, unsigned int index) { + const TokenList &t = el.Tokens(); + if (index >= t.size()) { + ParseError(Formatter::format("missing token at index ") << index, &el); } return *t[index]; } - // ------------------------------------------------------------------------------------------------ // wrapper around ParseTokenAsID() with ParseError handling -uint64_t ParseTokenAsID(const Token& t) -{ - const char* err; - const uint64_t i = ParseTokenAsID(t,err); - if(err) { - ParseError(err,t); +uint64_t ParseTokenAsID(const Token &t) { + const char *err; + const uint64_t i = ParseTokenAsID(t, err); + if (err) { + ParseError(err, t); } return i; } - // ------------------------------------------------------------------------------------------------ // wrapper around ParseTokenAsDim() with ParseError handling -size_t ParseTokenAsDim(const Token& t) -{ - const char* err; - const size_t i = ParseTokenAsDim(t,err); - if(err) { - ParseError(err,t); +size_t ParseTokenAsDim(const Token &t) { + const char *err; + const size_t i = ParseTokenAsDim(t, err); + if (err) { + ParseError(err, t); } return i; } - // ------------------------------------------------------------------------------------------------ // wrapper around ParseTokenAsFloat() with ParseError handling -float ParseTokenAsFloat(const Token& t) -{ - const char* err; - const float i = ParseTokenAsFloat(t,err); - if(err) { - ParseError(err,t); +float ParseTokenAsFloat(const Token &t) { + const char *err; + const float i = ParseTokenAsFloat(t, err); + if (err) { + ParseError(err, t); } return i; } // ------------------------------------------------------------------------------------------------ // wrapper around ParseTokenAsInt() with ParseError handling -int ParseTokenAsInt(const Token& t) -{ - const char* err; - const int i = ParseTokenAsInt(t,err); - if(err) { - ParseError(err,t); +int ParseTokenAsInt(const Token &t) { + const char *err; + const int i = ParseTokenAsInt(t, err); + if (err) { + ParseError(err, t); } return i; } // ------------------------------------------------------------------------------------------------ // wrapper around ParseTokenAsInt64() with ParseError handling -int64_t ParseTokenAsInt64(const Token& t) -{ - const char* err; +int64_t ParseTokenAsInt64(const Token &t) { + const char *err; const int64_t i = ParseTokenAsInt64(t, err); if (err) { ParseError(err, t); @@ -1309,7 +1234,7 @@ int64_t ParseTokenAsInt64(const Token& t) return i; } -} // !FBX -} // !Assimp +} // namespace FBX +} // namespace Assimp #endif diff --git a/code/AssetLib/IFC/IFCUtil.cpp b/code/AssetLib/IFC/IFCUtil.cpp index e1a733828..ffd0d680e 100644 --- a/code/AssetLib/IFC/IFCUtil.cpp +++ b/code/AssetLib/IFC/IFCUtil.cpp @@ -55,20 +55,19 @@ namespace Assimp { namespace IFC { // ------------------------------------------------------------------------------------------------ -void TempOpening::Transform(const IfcMatrix4& mat) { - if(profileMesh) { +void TempOpening::Transform(const IfcMatrix4 &mat) { + if (profileMesh) { profileMesh->Transform(mat); } - if(profileMesh2D) { + if (profileMesh2D) { profileMesh2D->Transform(mat); } extrusionDir *= IfcMatrix3(mat); } // ------------------------------------------------------------------------------------------------ -aiMesh* TempMesh::ToMesh() -{ - ai_assert(mVerts.size() == std::accumulate(mVertcnt.begin(),mVertcnt.end(),size_t(0))); +aiMesh *TempMesh::ToMesh() { + ai_assert(mVerts.size() == std::accumulate(mVertcnt.begin(), mVertcnt.end(), size_t(0))); if (mVerts.empty()) { return nullptr; @@ -79,14 +78,14 @@ aiMesh* TempMesh::ToMesh() // copy vertices mesh->mNumVertices = static_cast(mVerts.size()); mesh->mVertices = new aiVector3D[mesh->mNumVertices]; - std::copy(mVerts.begin(),mVerts.end(),mesh->mVertices); + std::copy(mVerts.begin(), mVerts.end(), mesh->mVertices); // and build up faces mesh->mNumFaces = static_cast(mVertcnt.size()); mesh->mFaces = new aiFace[mesh->mNumFaces]; - for(unsigned int i = 0,n=0, acc = 0; i < mesh->mNumFaces; ++n) { - aiFace& f = mesh->mFaces[i]; + for (unsigned int i = 0, n = 0, acc = 0; i < mesh->mNumFaces; ++n) { + aiFace &f = mesh->mFaces[i]; if (!mVertcnt[n]) { --mesh->mNumFaces; continue; @@ -94,7 +93,7 @@ aiMesh* TempMesh::ToMesh() f.mNumIndices = mVertcnt[n]; f.mIndices = new unsigned int[f.mNumIndices]; - for(unsigned int a = 0; a < f.mNumIndices; ++a) { + for (unsigned int a = 0; a < f.mNumIndices; ++a) { f.mIndices[a] = acc++; } @@ -105,36 +104,31 @@ aiMesh* TempMesh::ToMesh() } // ------------------------------------------------------------------------------------------------ -void TempMesh::Clear() -{ +void TempMesh::Clear() { mVerts.clear(); mVertcnt.clear(); } // ------------------------------------------------------------------------------------------------ -void TempMesh::Transform(const IfcMatrix4& mat) -{ - for(IfcVector3& v : mVerts) { +void TempMesh::Transform(const IfcMatrix4 &mat) { + for (IfcVector3 &v : mVerts) { v *= mat; } } // ------------------------------------------------------------------------------ -IfcVector3 TempMesh::Center() const -{ - return (mVerts.size() == 0) ? IfcVector3(0.0f, 0.0f, 0.0f) : (std::accumulate(mVerts.begin(),mVerts.end(),IfcVector3()) / static_cast(mVerts.size())); +IfcVector3 TempMesh::Center() const { + return (mVerts.size() == 0) ? IfcVector3(0.0f, 0.0f, 0.0f) : (std::accumulate(mVerts.begin(), mVerts.end(), IfcVector3()) / static_cast(mVerts.size())); } // ------------------------------------------------------------------------------------------------ -void TempMesh::Append(const TempMesh& other) -{ - mVerts.insert(mVerts.end(),other.mVerts.begin(),other.mVerts.end()); - mVertcnt.insert(mVertcnt.end(),other.mVertcnt.begin(),other.mVertcnt.end()); +void TempMesh::Append(const TempMesh &other) { + mVerts.insert(mVerts.end(), other.mVerts.begin(), other.mVerts.end()); + mVertcnt.insert(mVertcnt.end(), other.mVertcnt.begin(), other.mVertcnt.end()); } // ------------------------------------------------------------------------------------------------ -void TempMesh::RemoveDegenerates() -{ +void TempMesh::RemoveDegenerates() { // The strategy is simple: walk the mesh and compute normals using // Newell's algorithm. The length of the normals gives the area // of the polygons, which is close to zero for lines. @@ -161,52 +155,48 @@ void TempMesh::RemoveDegenerates() ++it; } - if(drop) { + if (drop) { IFCImporter::LogVerboseDebug("removing degenerate faces"); } } // ------------------------------------------------------------------------------------------------ -IfcVector3 TempMesh::ComputePolygonNormal(const IfcVector3* vtcs, size_t cnt, bool normalize) -{ - std::vector temp((cnt+2)*3); - for( size_t vofs = 0, i = 0; vofs < cnt; ++vofs ) - { - const IfcVector3& v = vtcs[vofs]; +IfcVector3 TempMesh::ComputePolygonNormal(const IfcVector3 *vtcs, size_t cnt, bool normalize) { + const size_t Capa = cnt + 2; + std::vector temp((Capa)*3); + for (size_t vofs = 0, i = 0; vofs < cnt; ++vofs) { + const IfcVector3 &v = vtcs[vofs]; temp[i++] = v.x; temp[i++] = v.y; temp[i++] = v.z; } IfcVector3 nor; - NewellNormal<3, 3, 3>(nor, static_cast(cnt), &temp[0], &temp[1], &temp[2]); + NewellNormal<3, 3, 3>(nor, static_cast(cnt), &temp[0], &temp[1], &temp[2], Capa); return normalize ? nor.Normalize() : nor; } // ------------------------------------------------------------------------------------------------ -void TempMesh::ComputePolygonNormals(std::vector& normals, - bool normalize, - size_t ofs) const -{ +void TempMesh::ComputePolygonNormals(std::vector &normals, bool normalize, size_t ofs) const { size_t max_vcount = 0; - std::vector::const_iterator begin = mVertcnt.begin()+ofs, end = mVertcnt.end(), iit; - for(iit = begin; iit != end; ++iit) { - max_vcount = std::max(max_vcount,static_cast(*iit)); + std::vector::const_iterator begin = mVertcnt.begin() + ofs, end = mVertcnt.end(), iit; + for (iit = begin; iit != end; ++iit) { + max_vcount = std::max(max_vcount, static_cast(*iit)); } - - std::vector temp((max_vcount+2)*4); - normals.reserve( normals.size() + mVertcnt.size()-ofs ); + const size_t Capa = max_vcount + 2; + std::vector temp(Capa * 4); + normals.reserve(normals.size() + mVertcnt.size() - ofs); // `NewellNormal()` currently has a relatively strange interface and need to // re-structure things a bit to meet them. - size_t vidx = std::accumulate(mVertcnt.begin(),begin,0); - for(iit = begin; iit != end; vidx += *iit++) { + size_t vidx = std::accumulate(mVertcnt.begin(), begin, 0); + for (iit = begin; iit != end; vidx += *iit++) { if (!*iit) { normals.push_back(IfcVector3()); continue; } - for(size_t vofs = 0, cnt = 0; vofs < *iit; ++vofs) { - const IfcVector3& v = mVerts[vidx+vofs]; + for (size_t vofs = 0, cnt = 0; vofs < *iit; ++vofs) { + const IfcVector3 &v = mVerts[vidx + vofs]; temp[cnt++] = v.x; temp[cnt++] = v.y; temp[cnt++] = v.z; @@ -217,11 +207,11 @@ void TempMesh::ComputePolygonNormals(std::vector& normals, } normals.push_back(IfcVector3()); - NewellNormal<4,4,4>(normals.back(),*iit,&temp[0],&temp[1],&temp[2]); + NewellNormal<4, 4, 4>(normals.back(), *iit, &temp[0], &temp[1], &temp[2], Capa); } - if(normalize) { - for(IfcVector3& n : normals) { + if (normalize) { + for (IfcVector3 &n : normals) { n.Normalize(); } } @@ -229,62 +219,55 @@ void TempMesh::ComputePolygonNormals(std::vector& normals, // ------------------------------------------------------------------------------------------------ // Compute the normal of the last polygon in the given mesh -IfcVector3 TempMesh::ComputeLastPolygonNormal(bool normalize) const -{ +IfcVector3 TempMesh::ComputeLastPolygonNormal(bool normalize) const { return ComputePolygonNormal(&mVerts[mVerts.size() - mVertcnt.back()], mVertcnt.back(), normalize); } -struct CompareVector -{ - bool operator () (const IfcVector3& a, const IfcVector3& b) const - { +struct CompareVector { + bool operator()(const IfcVector3 &a, const IfcVector3 &b) const { IfcVector3 d = a - b; IfcFloat eps = 1e-6; return d.x < -eps || (std::abs(d.x) < eps && d.y < -eps) || (std::abs(d.x) < eps && std::abs(d.y) < eps && d.z < -eps); } }; -struct FindVector -{ +struct FindVector { IfcVector3 v; - FindVector(const IfcVector3& p) : v(p) { } - bool operator () (const IfcVector3& p) { return FuzzyVectorCompare(1e-6)(p, v); } + FindVector(const IfcVector3 &p) : + v(p) {} + bool operator()(const IfcVector3 &p) { return FuzzyVectorCompare(1e-6)(p, v); } }; // ------------------------------------------------------------------------------------------------ -void TempMesh::FixupFaceOrientation() -{ +void TempMesh::FixupFaceOrientation() { const IfcVector3 vavg = Center(); // create a list of start indices for all faces to allow random access to faces std::vector faceStartIndices(mVertcnt.size()); - for( size_t i = 0, a = 0; a < mVertcnt.size(); i += mVertcnt[a], ++a ) + for (size_t i = 0, a = 0; a < mVertcnt.size(); i += mVertcnt[a], ++a) faceStartIndices[a] = i; // list all faces on a vertex std::map, CompareVector> facesByVertex; - for( size_t a = 0; a < mVertcnt.size(); ++a ) - { - for( size_t b = 0; b < mVertcnt[a]; ++b ) + for (size_t a = 0; a < mVertcnt.size(); ++a) { + for (size_t b = 0; b < mVertcnt[a]; ++b) facesByVertex[mVerts[faceStartIndices[a] + b]].push_back(a); } // determine neighbourhood for all polys std::vector neighbour(mVerts.size(), SIZE_MAX); std::vector tempIntersect(10); - for( size_t a = 0; a < mVertcnt.size(); ++a ) - { - for( size_t b = 0; b < mVertcnt[a]; ++b ) - { + for (size_t a = 0; a < mVertcnt.size(); ++a) { + for (size_t b = 0; b < mVertcnt[a]; ++b) { size_t ib = faceStartIndices[a] + b, nib = faceStartIndices[a] + (b + 1) % mVertcnt[a]; - const std::vector& facesOnB = facesByVertex[mVerts[ib]]; - const std::vector& facesOnNB = facesByVertex[mVerts[nib]]; + const std::vector &facesOnB = facesByVertex[mVerts[ib]]; + const std::vector &facesOnNB = facesByVertex[mVerts[nib]]; // there should be exactly one or two faces which appear in both lists. Our face and the other side std::vector::iterator sectstart = tempIntersect.begin(); std::vector::iterator sectend = std::set_intersection( - facesOnB.begin(), facesOnB.end(), facesOnNB.begin(), facesOnNB.end(), sectstart); + facesOnB.begin(), facesOnB.end(), facesOnNB.begin(), facesOnNB.end(), sectstart); - if( std::distance(sectstart, sectend) != 2 ) + if (std::distance(sectstart, sectend) != 2) continue; - if( *sectstart == a ) + if (*sectstart == a) ++sectstart; neighbour[ib] = *sectstart; } @@ -294,30 +277,31 @@ void TempMesh::FixupFaceOrientation() // facing outwards. So we reverse this face to point outwards in relation to the center. Then we adapt neighbouring // faces to have the same winding until all faces have been tested. std::vector faceDone(mVertcnt.size(), false); - while( std::count(faceDone.begin(), faceDone.end(), false) != 0 ) - { + while (std::count(faceDone.begin(), faceDone.end(), false) != 0) { // find the farthest of the remaining faces size_t farthestIndex = SIZE_MAX; IfcFloat farthestDistance = -1.0; - for( size_t a = 0; a < mVertcnt.size(); ++a ) - { - if( faceDone[a] ) + for (size_t a = 0; a < mVertcnt.size(); ++a) { + if (faceDone[a]) continue; IfcVector3 faceCenter = std::accumulate(mVerts.begin() + faceStartIndices[a], - mVerts.begin() + faceStartIndices[a] + mVertcnt[a], IfcVector3(0.0)) / IfcFloat(mVertcnt[a]); + mVerts.begin() + faceStartIndices[a] + mVertcnt[a], IfcVector3(0.0)) / + IfcFloat(mVertcnt[a]); IfcFloat dst = (faceCenter - vavg).SquareLength(); - if( dst > farthestDistance ) { farthestDistance = dst; farthestIndex = a; } + if (dst > farthestDistance) { + farthestDistance = dst; + farthestIndex = a; + } } // calculate its normal and reverse the poly if its facing towards the mesh center IfcVector3 farthestNormal = ComputePolygonNormal(mVerts.data() + faceStartIndices[farthestIndex], mVertcnt[farthestIndex]); IfcVector3 farthestCenter = std::accumulate(mVerts.begin() + faceStartIndices[farthestIndex], - mVerts.begin() + faceStartIndices[farthestIndex] + mVertcnt[farthestIndex], IfcVector3(0.0)) - / IfcFloat(mVertcnt[farthestIndex]); + mVerts.begin() + faceStartIndices[farthestIndex] + mVertcnt[farthestIndex], IfcVector3(0.0)) / + IfcFloat(mVertcnt[farthestIndex]); // We accept a bit of negative orientation without reversing. In case of doubt, prefer the orientation given in // the file. - if( (farthestNormal * (farthestCenter - vavg).Normalize()) < -0.4 ) - { + if ((farthestNormal * (farthestCenter - vavg).Normalize()) < -0.4) { size_t fsi = faceStartIndices[farthestIndex], fvc = mVertcnt[farthestIndex]; std::reverse(mVerts.begin() + fsi, mVerts.begin() + fsi + fvc); std::reverse(neighbour.begin() + fsi, neighbour.begin() + fsi + fvc); @@ -326,7 +310,7 @@ void TempMesh::FixupFaceOrientation() // Before: points A - B - C - D with edge neighbour p - q - r - s // After: points D - C - B - A, reversed neighbours are s - r - q - p, but the should be // r q p s - for( size_t a = 0; a < fvc - 1; ++a ) + for (size_t a = 0; a < fvc - 1; ++a) std::swap(neighbour[fsi + a], neighbour[fsi + a + 1]); } faceDone[farthestIndex] = true; @@ -334,21 +318,19 @@ void TempMesh::FixupFaceOrientation() todo.push_back(farthestIndex); // go over its neighbour faces recursively and adapt their winding order to match the farthest face - while( !todo.empty() ) - { + while (!todo.empty()) { size_t tdf = todo.back(); size_t vsi = faceStartIndices[tdf], vc = mVertcnt[tdf]; todo.pop_back(); // check its neighbours - for( size_t a = 0; a < vc; ++a ) - { + for (size_t a = 0; a < vc; ++a) { // ignore neighbours if we already checked them size_t nbi = neighbour[vsi + a]; - if( nbi == SIZE_MAX || faceDone[nbi] ) + if (nbi == SIZE_MAX || faceDone[nbi]) continue; - const IfcVector3& vp = mVerts[vsi + a]; + const IfcVector3 &vp = mVerts[vsi + a]; size_t nbvsi = faceStartIndices[nbi], nbvc = mVertcnt[nbi]; std::vector::iterator it = std::find_if(mVerts.begin() + nbvsi, mVerts.begin() + nbvsi + nbvc, FindVector(vp)); ai_assert(it != mVerts.begin() + nbvsi + nbvc); @@ -358,8 +340,7 @@ void TempMesh::FixupFaceOrientation() // to reverse the neighbour nb_vidx = (nb_vidx + 1) % nbvc; size_t oursideidx = (a + 1) % vc; - if( FuzzyVectorCompare(1e-6)(mVerts[vsi + oursideidx], mVerts[nbvsi + nb_vidx]) ) - { + if (FuzzyVectorCompare(1e-6)(mVerts[vsi + oursideidx], mVerts[nbvsi + nb_vidx])) { std::reverse(mVerts.begin() + nbvsi, mVerts.begin() + nbvsi + nbvc); std::reverse(neighbour.begin() + nbvsi, neighbour.begin() + nbvsi + nbvc); for (size_t aa = 0; aa < nbvc - 1; ++aa) { @@ -381,17 +362,16 @@ void TempMesh::FixupFaceOrientation() void TempMesh::RemoveAdjacentDuplicates() { bool drop = false; std::vector::iterator base = mVerts.begin(); - for(unsigned int& cnt : mVertcnt) { - if (cnt < 2){ + for (unsigned int &cnt : mVertcnt) { + if (cnt < 2) { base += cnt; continue; } - IfcVector3 vmin,vmax; - ArrayBounds(&*base, cnt ,vmin,vmax); + IfcVector3 vmin, vmax; + ArrayBounds(&*base, cnt, vmin, vmax); - - const IfcFloat epsilon = (vmax-vmin).SquareLength() / static_cast(1e9); + const IfcFloat epsilon = (vmax - vmin).SquareLength() / static_cast(1e9); //const IfcFloat dotepsilon = 1e-9; //// look for vertices that lie directly on the line between their predecessor and their @@ -419,153 +399,127 @@ void TempMesh::RemoveAdjacentDuplicates() { // drop any identical, adjacent vertices. this pass will collect the dropouts // of the previous pass as a side-effect. FuzzyVectorCompare fz(epsilon); - std::vector::iterator end = base+cnt, e = std::unique( base, end, fz ); + std::vector::iterator end = base + cnt, e = std::unique(base, end, fz); if (e != end) { cnt -= static_cast(std::distance(e, end)); - mVerts.erase(e,end); - drop = true; + mVerts.erase(e, end); + drop = true; } // check front and back vertices for this polygon - if (cnt > 1 && fz(*base,*(base+cnt-1))) { - mVerts.erase(base+ --cnt); - drop = true; + if (cnt > 1 && fz(*base, *(base + cnt - 1))) { + mVerts.erase(base + --cnt); + drop = true; } // removing adjacent duplicates shouldn't erase everything :-) - ai_assert(cnt>0); + ai_assert(cnt > 0); base += cnt; } - if(drop) { + if (drop) { IFCImporter::LogVerboseDebug("removing duplicate vertices"); } } // ------------------------------------------------------------------------------------------------ -void TempMesh::Swap(TempMesh& other) -{ +void TempMesh::Swap(TempMesh &other) { mVertcnt.swap(other.mVertcnt); mVerts.swap(other.mVerts); } // ------------------------------------------------------------------------------------------------ -bool IsTrue(const ::Assimp::STEP::EXPRESS::BOOLEAN& in) -{ +bool IsTrue(const ::Assimp::STEP::EXPRESS::BOOLEAN &in) { return (std::string)in == "TRUE" || (std::string)in == "T"; } // ------------------------------------------------------------------------------------------------ -IfcFloat ConvertSIPrefix(const std::string& prefix) -{ +IfcFloat ConvertSIPrefix(const std::string &prefix) { if (prefix == "EXA") { return 1e18f; - } - else if (prefix == "PETA") { + } else if (prefix == "PETA") { return 1e15f; - } - else if (prefix == "TERA") { + } else if (prefix == "TERA") { return 1e12f; - } - else if (prefix == "GIGA") { + } else if (prefix == "GIGA") { return 1e9f; - } - else if (prefix == "MEGA") { + } else if (prefix == "MEGA") { return 1e6f; - } - else if (prefix == "KILO") { + } else if (prefix == "KILO") { return 1e3f; - } - else if (prefix == "HECTO") { + } else if (prefix == "HECTO") { return 1e2f; - } - else if (prefix == "DECA") { + } else if (prefix == "DECA") { return 1e-0f; - } - else if (prefix == "DECI") { + } else if (prefix == "DECI") { return 1e-1f; - } - else if (prefix == "CENTI") { + } else if (prefix == "CENTI") { return 1e-2f; - } - else if (prefix == "MILLI") { + } else if (prefix == "MILLI") { return 1e-3f; - } - else if (prefix == "MICRO") { + } else if (prefix == "MICRO") { return 1e-6f; - } - else if (prefix == "NANO") { + } else if (prefix == "NANO") { return 1e-9f; - } - else if (prefix == "PICO") { + } else if (prefix == "PICO") { return 1e-12f; - } - else if (prefix == "FEMTO") { + } else if (prefix == "FEMTO") { return 1e-15f; - } - else if (prefix == "ATTO") { + } else if (prefix == "ATTO") { return 1e-18f; - } - else { + } else { IFCImporter::LogError("Unrecognized SI prefix: " + prefix); return 1; } } // ------------------------------------------------------------------------------------------------ -void ConvertColor(aiColor4D& out, const Schema_2x3::IfcColourRgb& in) -{ - out.r = static_cast( in.Red ); - out.g = static_cast( in.Green ); - out.b = static_cast( in.Blue ); - out.a = static_cast( 1.f ); +void ConvertColor(aiColor4D &out, const Schema_2x3::IfcColourRgb &in) { + out.r = static_cast(in.Red); + out.g = static_cast(in.Green); + out.b = static_cast(in.Blue); + out.a = static_cast(1.f); } // ------------------------------------------------------------------------------------------------ -void ConvertColor(aiColor4D& out, const Schema_2x3::IfcColourOrFactor& in,ConversionData& conv,const aiColor4D* base) -{ - if (const ::Assimp::STEP::EXPRESS::REAL* const r = in.ToPtr<::Assimp::STEP::EXPRESS::REAL>()) { +void ConvertColor(aiColor4D &out, const Schema_2x3::IfcColourOrFactor &in, ConversionData &conv, const aiColor4D *base) { + if (const ::Assimp::STEP::EXPRESS::REAL *const r = in.ToPtr<::Assimp::STEP::EXPRESS::REAL>()) { out.r = out.g = out.b = static_cast(*r); - if(base) { - out.r *= static_cast( base->r ); - out.g *= static_cast( base->g ); - out.b *= static_cast( base->b ); - out.a = static_cast( base->a ); - } - else out.a = 1.0; - } - else if (const Schema_2x3::IfcColourRgb* const rgb = in.ResolveSelectPtr(conv.db)) { - ConvertColor(out,*rgb); - } - else { + if (base) { + out.r *= static_cast(base->r); + out.g *= static_cast(base->g); + out.b *= static_cast(base->b); + out.a = static_cast(base->a); + } else + out.a = 1.0; + } else if (const Schema_2x3::IfcColourRgb *const rgb = in.ResolveSelectPtr(conv.db)) { + ConvertColor(out, *rgb); + } else { IFCImporter::LogWarn("skipping unknown IfcColourOrFactor entity"); } } // ------------------------------------------------------------------------------------------------ -void ConvertCartesianPoint(IfcVector3& out, const Schema_2x3::IfcCartesianPoint& in) -{ +void ConvertCartesianPoint(IfcVector3 &out, const Schema_2x3::IfcCartesianPoint &in) { out = IfcVector3(); - for(size_t i = 0; i < in.Coordinates.size(); ++i) { + for (size_t i = 0; i < in.Coordinates.size(); ++i) { out[static_cast(i)] = in.Coordinates[i]; } } // ------------------------------------------------------------------------------------------------ -void ConvertVector(IfcVector3& out, const Schema_2x3::IfcVector& in) -{ - ConvertDirection(out,in.Orientation); +void ConvertVector(IfcVector3 &out, const Schema_2x3::IfcVector &in) { + ConvertDirection(out, in.Orientation); out *= in.Magnitude; } // ------------------------------------------------------------------------------------------------ -void ConvertDirection(IfcVector3& out, const Schema_2x3::IfcDirection& in) -{ +void ConvertDirection(IfcVector3 &out, const Schema_2x3::IfcDirection &in) { out = IfcVector3(); - for(size_t i = 0; i < in.DirectionRatios.size(); ++i) { + for (size_t i = 0; i < in.DirectionRatios.size(); ++i) { out[static_cast(i)] = in.DirectionRatios[i]; } const IfcFloat len = out.Length(); - if (len<1e-6) { + if (len < 1e-6) { IFCImporter::LogWarn("direction vector magnitude too small, normalization would result in a division by zero"); return; } @@ -573,8 +527,7 @@ void ConvertDirection(IfcVector3& out, const Schema_2x3::IfcDirection& in) } // ------------------------------------------------------------------------------------------------ -void AssignMatrixAxes(IfcMatrix4& out, const IfcVector3& x, const IfcVector3& y, const IfcVector3& z) -{ +void AssignMatrixAxes(IfcMatrix4 &out, const IfcVector3 &x, const IfcVector3 &y, const IfcVector3 &z) { out.a1 = x.x; out.b1 = x.y; out.c1 = x.z; @@ -589,116 +542,105 @@ void AssignMatrixAxes(IfcMatrix4& out, const IfcVector3& x, const IfcVector3& y, } // ------------------------------------------------------------------------------------------------ -void ConvertAxisPlacement(IfcMatrix4& out, const Schema_2x3::IfcAxis2Placement3D& in) -{ +void ConvertAxisPlacement(IfcMatrix4 &out, const Schema_2x3::IfcAxis2Placement3D &in) { IfcVector3 loc; - ConvertCartesianPoint(loc,in.Location); + ConvertCartesianPoint(loc, in.Location); - IfcVector3 z(0.f,0.f,1.f),r(1.f,0.f,0.f),x; + IfcVector3 z(0.f, 0.f, 1.f), r(1.f, 0.f, 0.f), x; if (in.Axis) { - ConvertDirection(z,*in.Axis.Get()); + ConvertDirection(z, *in.Axis.Get()); } if (in.RefDirection) { - ConvertDirection(r,*in.RefDirection.Get()); + ConvertDirection(r, *in.RefDirection.Get()); } IfcVector3 v = r.Normalize(); - IfcVector3 tmpx = z * (v*z); + IfcVector3 tmpx = z * (v * z); - x = (v-tmpx).Normalize(); - IfcVector3 y = (z^x); + x = (v - tmpx).Normalize(); + IfcVector3 y = (z ^ x); - IfcMatrix4::Translation(loc,out); - AssignMatrixAxes(out,x,y,z); + IfcMatrix4::Translation(loc, out); + AssignMatrixAxes(out, x, y, z); } // ------------------------------------------------------------------------------------------------ -void ConvertAxisPlacement(IfcMatrix4& out, const Schema_2x3::IfcAxis2Placement2D& in) -{ +void ConvertAxisPlacement(IfcMatrix4 &out, const Schema_2x3::IfcAxis2Placement2D &in) { IfcVector3 loc; - ConvertCartesianPoint(loc,in.Location); + ConvertCartesianPoint(loc, in.Location); - IfcVector3 x(1.f,0.f,0.f); + IfcVector3 x(1.f, 0.f, 0.f); if (in.RefDirection) { - ConvertDirection(x,*in.RefDirection.Get()); + ConvertDirection(x, *in.RefDirection.Get()); } - const IfcVector3 y = IfcVector3(x.y,-x.x,0.f); + const IfcVector3 y = IfcVector3(x.y, -x.x, 0.f); - IfcMatrix4::Translation(loc,out); - AssignMatrixAxes(out,x,y,IfcVector3(0.f,0.f,1.f)); + IfcMatrix4::Translation(loc, out); + AssignMatrixAxes(out, x, y, IfcVector3(0.f, 0.f, 1.f)); } // ------------------------------------------------------------------------------------------------ -void ConvertAxisPlacement(IfcVector3& axis, IfcVector3& pos, const Schema_2x3::IfcAxis1Placement& in) -{ - ConvertCartesianPoint(pos,in.Location); +void ConvertAxisPlacement(IfcVector3 &axis, IfcVector3 &pos, const Schema_2x3::IfcAxis1Placement &in) { + ConvertCartesianPoint(pos, in.Location); if (in.Axis) { - ConvertDirection(axis,in.Axis.Get()); - } - else { - axis = IfcVector3(0.f,0.f,1.f); + ConvertDirection(axis, in.Axis.Get()); + } else { + axis = IfcVector3(0.f, 0.f, 1.f); } } // ------------------------------------------------------------------------------------------------ -void ConvertAxisPlacement(IfcMatrix4& out, const Schema_2x3::IfcAxis2Placement& in, ConversionData& conv) -{ - if(const Schema_2x3::IfcAxis2Placement3D* pl3 = in.ResolveSelectPtr(conv.db)) { - ConvertAxisPlacement(out,*pl3); - } - else if(const Schema_2x3::IfcAxis2Placement2D* pl2 = in.ResolveSelectPtr(conv.db)) { - ConvertAxisPlacement(out,*pl2); - } - else { +void ConvertAxisPlacement(IfcMatrix4 &out, const Schema_2x3::IfcAxis2Placement &in, ConversionData &conv) { + if (const Schema_2x3::IfcAxis2Placement3D *pl3 = in.ResolveSelectPtr(conv.db)) { + ConvertAxisPlacement(out, *pl3); + } else if (const Schema_2x3::IfcAxis2Placement2D *pl2 = in.ResolveSelectPtr(conv.db)) { + ConvertAxisPlacement(out, *pl2); + } else { IFCImporter::LogWarn("skipping unknown IfcAxis2Placement entity"); } } // ------------------------------------------------------------------------------------------------ -void ConvertTransformOperator(IfcMatrix4& out, const Schema_2x3::IfcCartesianTransformationOperator& op) -{ +void ConvertTransformOperator(IfcMatrix4 &out, const Schema_2x3::IfcCartesianTransformationOperator &op) { IfcVector3 loc; - ConvertCartesianPoint(loc,op.LocalOrigin); + ConvertCartesianPoint(loc, op.LocalOrigin); - IfcVector3 x(1.f,0.f,0.f),y(0.f,1.f,0.f),z(0.f,0.f,1.f); + IfcVector3 x(1.f, 0.f, 0.f), y(0.f, 1.f, 0.f), z(0.f, 0.f, 1.f); if (op.Axis1) { - ConvertDirection(x,*op.Axis1.Get()); + ConvertDirection(x, *op.Axis1.Get()); } if (op.Axis2) { - ConvertDirection(y,*op.Axis2.Get()); + ConvertDirection(y, *op.Axis2.Get()); } - if (const Schema_2x3::IfcCartesianTransformationOperator3D* op2 = op.ToPtr()) { - if(op2->Axis3) { - ConvertDirection(z,*op2->Axis3.Get()); + if (const Schema_2x3::IfcCartesianTransformationOperator3D *op2 = op.ToPtr()) { + if (op2->Axis3) { + ConvertDirection(z, *op2->Axis3.Get()); } } IfcMatrix4 locm; - IfcMatrix4::Translation(loc,locm); - AssignMatrixAxes(out,x,y,z); - + IfcMatrix4::Translation(loc, locm); + AssignMatrixAxes(out, x, y, z); IfcVector3 vscale; - if (const Schema_2x3::IfcCartesianTransformationOperator3DnonUniform* nuni = op.ToPtr()) { - vscale.x = nuni->Scale?op.Scale.Get():1.f; - vscale.y = nuni->Scale2?nuni->Scale2.Get():1.f; - vscale.z = nuni->Scale3?nuni->Scale3.Get():1.f; - } - else { - const IfcFloat sc = op.Scale?op.Scale.Get():1.f; - vscale = IfcVector3(sc,sc,sc); + if (const Schema_2x3::IfcCartesianTransformationOperator3DnonUniform *nuni = op.ToPtr()) { + vscale.x = nuni->Scale ? op.Scale.Get() : 1.f; + vscale.y = nuni->Scale2 ? nuni->Scale2.Get() : 1.f; + vscale.z = nuni->Scale3 ? nuni->Scale3.Get() : 1.f; + } else { + const IfcFloat sc = op.Scale ? op.Scale.Get() : 1.f; + vscale = IfcVector3(sc, sc, sc); } IfcMatrix4 s; - IfcMatrix4::Scaling(vscale,s); + IfcMatrix4::Scaling(vscale, s); out = locm * out * s; } - -} // ! IFC -} // ! Assimp +} // namespace IFC +} // namespace Assimp #endif diff --git a/code/Common/Importer.cpp b/code/Common/Importer.cpp index 38eb63f40..737d0df9d 100644 --- a/code/Common/Importer.cpp +++ b/code/Common/Importer.cpp @@ -43,9 +43,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * @brief Implementation of the CPP-API class #Importer */ -#include #include #include +#include // ------------------------------------------------------------------------------------------------ /* Uncomment this line to prevent Assimp from catching unknown exceptions. @@ -56,35 +56,36 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // ------------------------------------------------------------------------------------------------ #ifndef ASSIMP_BUILD_DEBUG -# define ASSIMP_CATCH_GLOBAL_EXCEPTIONS +#define ASSIMP_CATCH_GLOBAL_EXCEPTIONS #endif // ------------------------------------------------------------------------------------------------ // Internal headers // ------------------------------------------------------------------------------------------------ -#include "Common/Importer.h" #include "Common/BaseProcess.h" #include "Common/DefaultProgressHandler.h" -#include "PostProcessing/ProcessHelper.h" +#include "Common/Importer.h" #include "Common/ScenePreprocessor.h" #include "Common/ScenePrivate.h" +#include "PostProcessing/ProcessHelper.h" #include +#include #include #include #include #include -#include -#include #include -#include -#include #include +#include +#include #include #include +// clang-format off + #ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS # include "PostProcessing/ValidateDataStructure.h" #endif @@ -94,13 +95,14 @@ using namespace Assimp::Formatter; namespace Assimp { // ImporterRegistry.cpp - void GetImporterInstanceList(std::vector< BaseImporter* >& out); - void DeleteImporterInstanceList(std::vector< BaseImporter* >& out); + void GetImporterInstanceList(std::vector &out); + void DeleteImporterInstanceList(std::vector &out); // PostStepRegistry.cpp - void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out); -} + void GetPostProcessingStepInstanceList(std::vector &out); +} // namespace Assimp +// clang-format on using namespace Assimp; using namespace Assimp::Intern; @@ -110,50 +112,49 @@ using namespace Assimp::Intern; // utilize our DLL heap. // See http://www.gotw.ca/publications/mill15.htm // ------------------------------------------------------------------------------------------------ -void* AllocateFromAssimpHeap::operator new ( size_t num_bytes) { +void *AllocateFromAssimpHeap::operator new(size_t num_bytes) { return ::operator new(num_bytes); } -void* AllocateFromAssimpHeap::operator new ( size_t num_bytes, const std::nothrow_t& ) throw() { +void *AllocateFromAssimpHeap::operator new(size_t num_bytes, const std::nothrow_t &) throw() { try { - return AllocateFromAssimpHeap::operator new( num_bytes ); - } - catch( ... ) { + return AllocateFromAssimpHeap::operator new(num_bytes); + } catch (...) { return nullptr; } } -void AllocateFromAssimpHeap::operator delete ( void* data) { +void AllocateFromAssimpHeap::operator delete(void *data) { return ::operator delete(data); } -void* AllocateFromAssimpHeap::operator new[] ( size_t num_bytes) { +void *AllocateFromAssimpHeap::operator new[](size_t num_bytes) { return ::operator new[](num_bytes); } -void* AllocateFromAssimpHeap::operator new[] ( size_t num_bytes, const std::nothrow_t& ) throw() { +void *AllocateFromAssimpHeap::operator new[](size_t num_bytes, const std::nothrow_t &) throw() { try { - return AllocateFromAssimpHeap::operator new[]( num_bytes ); - } catch( ... ) { + return AllocateFromAssimpHeap::operator new[](num_bytes); + } catch (...) { return nullptr; } } -void AllocateFromAssimpHeap::operator delete[] ( void* data) { +void AllocateFromAssimpHeap::operator delete[](void *data) { return ::operator delete[](data); } // ------------------------------------------------------------------------------------------------ // Importer constructor. -Importer::Importer() - : pimpl( new ImporterPimpl ) { +Importer::Importer() : + pimpl(new ImporterPimpl) { pimpl->mScene = nullptr; pimpl->mErrorString = ""; // Allocate a default IO handler pimpl->mIOHandler = new DefaultIOSystem; pimpl->mIsDefaultHandler = true; - pimpl->bExtraVerbose = false; // disable extra verbose mode by default + pimpl->bExtraVerbose = false; // disable extra verbose mode by default pimpl->mProgressHandler = new DefaultProgressHandler(); pimpl->mIsDefaultProgressHandler = true; @@ -163,9 +164,9 @@ Importer::Importer() // Allocate a SharedPostProcessInfo object and store pointers to it in all post-process steps in the list. pimpl->mPPShared = new SharedPostProcessInfo(); - for (std::vector::iterator it = pimpl->mPostProcessingSteps.begin(); - it != pimpl->mPostProcessingSteps.end(); - ++it) { + for (std::vector::iterator it = pimpl->mPostProcessingSteps.begin(); + it != pimpl->mPostProcessingSteps.end(); + ++it) { (*it)->SetSharedData(pimpl->mPPShared); } @@ -175,10 +176,10 @@ Importer::Importer() // Destructor of Importer Importer::~Importer() { // Delete all import plugins - DeleteImporterInstanceList(pimpl->mImporter); + DeleteImporterInstanceList(pimpl->mImporter); // Delete all post-processing plug-ins - for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); ++a ) { + for (unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); ++a) { delete pimpl->mPostProcessingSteps[a]; } @@ -198,13 +199,13 @@ Importer::~Importer() { // ------------------------------------------------------------------------------------------------ // Register a custom post-processing step -aiReturn Importer::RegisterPPStep(BaseProcess* pImp) { - ai_assert( nullptr != pImp ); - +aiReturn Importer::RegisterPPStep(BaseProcess *pImp) { + ai_assert(nullptr != pImp); + ASSIMP_BEGIN_EXCEPTION_REGION(); - pimpl->mPostProcessingSteps.push_back(pImp); - ASSIMP_LOG_INFO("Registering custom post-processing step"); + pimpl->mPostProcessingSteps.push_back(pImp); + ASSIMP_LOG_INFO("Registering custom post-processing step"); ASSIMP_END_EXCEPTION_REGION(aiReturn); return AI_SUCCESS; @@ -212,9 +213,9 @@ aiReturn Importer::RegisterPPStep(BaseProcess* pImp) { // ------------------------------------------------------------------------------------------------ // Register a custom loader plugin -aiReturn Importer::RegisterLoader(BaseImporter* pImp) { +aiReturn Importer::RegisterLoader(BaseImporter *pImp) { ai_assert(nullptr != pImp); - + ASSIMP_BEGIN_EXCEPTION_REGION(); // -------------------------------------------------------------------- @@ -227,7 +228,7 @@ aiReturn Importer::RegisterLoader(BaseImporter* pImp) { std::string baked; pImp->GetExtensionList(st); - for(std::set::const_iterator it = st.begin(); it != st.end(); ++it) { + for (std::set::const_iterator it = st.begin(); it != st.end(); ++it) { #ifdef ASSIMP_BUILD_DEBUG if (IsExtensionSupported(*it)) { @@ -241,23 +242,23 @@ aiReturn Importer::RegisterLoader(BaseImporter* pImp) { pimpl->mImporter.push_back(pImp); ASSIMP_LOG_INFO_F("Registering custom importer for these file extensions: ", baked); ASSIMP_END_EXCEPTION_REGION(aiReturn); - + return AI_SUCCESS; } // ------------------------------------------------------------------------------------------------ // Unregister a custom loader plugin -aiReturn Importer::UnregisterLoader(BaseImporter* pImp) { - if(!pImp) { +aiReturn Importer::UnregisterLoader(BaseImporter *pImp) { + if (!pImp) { // unregistering a nullptr importer is no problem for us ... really! return AI_SUCCESS; } ASSIMP_BEGIN_EXCEPTION_REGION(); - std::vector::iterator it = std::find(pimpl->mImporter.begin(), - pimpl->mImporter.end(),pImp); + std::vector::iterator it = std::find(pimpl->mImporter.begin(), + pimpl->mImporter.end(), pImp); - if (it != pimpl->mImporter.end()) { + if (it != pimpl->mImporter.end()) { pimpl->mImporter.erase(it); ASSIMP_LOG_INFO("Unregistering custom importer: "); return AI_SUCCESS; @@ -270,17 +271,17 @@ aiReturn Importer::UnregisterLoader(BaseImporter* pImp) { // ------------------------------------------------------------------------------------------------ // Unregister a custom loader plugin -aiReturn Importer::UnregisterPPStep(BaseProcess* pImp) { - if(!pImp) { +aiReturn Importer::UnregisterPPStep(BaseProcess *pImp) { + if (!pImp) { // unregistering a nullptr ppstep is no problem for us ... really! return AI_SUCCESS; } ASSIMP_BEGIN_EXCEPTION_REGION(); - std::vector::iterator it = std::find(pimpl->mPostProcessingSteps.begin(), - pimpl->mPostProcessingSteps.end(),pImp); + std::vector::iterator it = std::find(pimpl->mPostProcessingSteps.begin(), + pimpl->mPostProcessingSteps.end(), pImp); - if (it != pimpl->mPostProcessingSteps.end()) { + if (it != pimpl->mPostProcessingSteps.end()) { pimpl->mPostProcessingSteps.erase(it); ASSIMP_LOG_INFO("Unregistering custom post-processing step"); return AI_SUCCESS; @@ -293,9 +294,9 @@ aiReturn Importer::UnregisterPPStep(BaseProcess* pImp) { // ------------------------------------------------------------------------------------------------ // Supplies a custom IO handler to the importer to open and access files. -void Importer::SetIOHandler( IOSystem* pIOHandler) { +void Importer::SetIOHandler(IOSystem *pIOHandler) { ai_assert(nullptr != pimpl); - + ASSIMP_BEGIN_EXCEPTION_REGION(); // If the new handler is zero, allocate a default IO implementation. if (!pIOHandler) { @@ -312,9 +313,9 @@ void Importer::SetIOHandler( IOSystem* pIOHandler) { // ------------------------------------------------------------------------------------------------ // Get the currently set IO handler -IOSystem* Importer::GetIOHandler() const { +IOSystem *Importer::GetIOHandler() const { ai_assert(nullptr != pimpl); - + return pimpl->mIOHandler; } @@ -322,17 +323,17 @@ IOSystem* Importer::GetIOHandler() const { // Check whether a custom IO handler is currently set bool Importer::IsDefaultIOHandler() const { ai_assert(nullptr != pimpl); - + return pimpl->mIsDefaultHandler; } // ------------------------------------------------------------------------------------------------ // Supplies a custom progress handler to get regular callbacks during importing -void Importer::SetProgressHandler ( ProgressHandler* pHandler ) { +void Importer::SetProgressHandler(ProgressHandler *pHandler) { ai_assert(nullptr != pimpl); - + ASSIMP_BEGIN_EXCEPTION_REGION(); - + // If the new handler is zero, allocate a default implementation. if (!pHandler) { // Release pointer in the possession of the caller @@ -348,9 +349,9 @@ void Importer::SetProgressHandler ( ProgressHandler* pHandler ) { // ------------------------------------------------------------------------------------------------ // Get the currently set progress handler -ProgressHandler* Importer::GetProgressHandler() const { +ProgressHandler *Importer::GetProgressHandler() const { ai_assert(nullptr != pimpl); - + return pimpl->mProgressHandler; } @@ -358,18 +359,18 @@ ProgressHandler* Importer::GetProgressHandler() const { // Check whether a custom progress handler is currently set bool Importer::IsDefaultProgressHandler() const { ai_assert(nullptr != pimpl); - + return pimpl->mIsDefaultProgressHandler; } // ------------------------------------------------------------------------------------------------ // Validate post process step flags bool _ValidateFlags(unsigned int pFlags) { - if (pFlags & aiProcess_GenSmoothNormals && pFlags & aiProcess_GenNormals) { + if (pFlags & aiProcess_GenSmoothNormals && pFlags & aiProcess_GenNormals) { ASSIMP_LOG_ERROR("#aiProcess_GenSmoothNormals and #aiProcess_GenNormals are incompatible"); return false; } - if (pFlags & aiProcess_OptimizeGraph && pFlags & aiProcess_PreTransformVertices) { + if (pFlags & aiProcess_OptimizeGraph && pFlags & aiProcess_PreTransformVertices) { ASSIMP_LOG_ERROR("#aiProcess_OptimizeGraph and #aiProcess_PreTransformVertices are incompatible"); return false; } @@ -378,9 +379,9 @@ bool _ValidateFlags(unsigned int pFlags) { // ------------------------------------------------------------------------------------------------ // Free the current scene -void Importer::FreeScene( ) { +void Importer::FreeScene() { ai_assert(nullptr != pimpl); - + ASSIMP_BEGIN_EXCEPTION_REGION(); delete pimpl->mScene; @@ -393,16 +394,16 @@ void Importer::FreeScene( ) { // ------------------------------------------------------------------------------------------------ // Get the current error string, if any -const char* Importer::GetErrorString() const { +const char *Importer::GetErrorString() const { ai_assert(nullptr != pimpl); - + // Must remain valid as long as ReadFile() or FreeFile() are not called return pimpl->mErrorString.c_str(); } -const std::exception_ptr& Importer::GetException() const { +const std::exception_ptr &Importer::GetException() const { ai_assert(nullptr != pimpl); - + // Must remain valid as long as ReadFile() or FreeFile() are not called return pimpl->mException; } @@ -411,32 +412,32 @@ const std::exception_ptr& Importer::GetException() const { // Enable extra-verbose mode void Importer::SetExtraVerbose(bool bDo) { ai_assert(nullptr != pimpl); - + pimpl->bExtraVerbose = bDo; } // ------------------------------------------------------------------------------------------------ // Get the current scene -const aiScene* Importer::GetScene() const { +const aiScene *Importer::GetScene() const { ai_assert(nullptr != pimpl); - + return pimpl->mScene; } // ------------------------------------------------------------------------------------------------ // Orphan the current scene and return it. -aiScene* Importer::GetOrphanedScene() { +aiScene *Importer::GetOrphanedScene() { ai_assert(nullptr != pimpl); - - aiScene* s = pimpl->mScene; + + aiScene *s = pimpl->mScene; ASSIMP_BEGIN_EXCEPTION_REGION(); pimpl->mScene = nullptr; pimpl->mErrorString = ""; // reset error string pimpl->mException = std::exception_ptr(); - ASSIMP_END_EXCEPTION_REGION(aiScene*); - + ASSIMP_END_EXCEPTION_REGION(aiScene *); + return s; } @@ -445,7 +446,7 @@ aiScene* Importer::GetOrphanedScene() { bool Importer::ValidateFlags(unsigned int pFlags) const { ASSIMP_BEGIN_EXCEPTION_REGION(); // run basic checks for mutually exclusive flags - if(!_ValidateFlags(pFlags)) { + if (!_ValidateFlags(pFlags)) { return false; } @@ -459,13 +460,13 @@ bool Importer::ValidateFlags(unsigned int pFlags) const { // Now iterate through all bits which are set in the flags and check whether we find at least // one pp plugin which handles it. - for (unsigned int mask = 1; mask < (1u << (sizeof(unsigned int)*8-1));mask <<= 1) { + for (unsigned int mask = 1; mask < (1u << (sizeof(unsigned int) * 8 - 1)); mask <<= 1) { if (pFlags & mask) { bool have = false; - for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) { - if (pimpl->mPostProcessingSteps[a]-> IsActive(mask) ) { + for (unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) { + if (pimpl->mPostProcessingSteps[a]->IsActive(mask)) { have = true; break; @@ -481,43 +482,43 @@ bool Importer::ValidateFlags(unsigned int pFlags) const { } // ------------------------------------------------------------------------------------------------ -const aiScene* Importer::ReadFileFromMemory( const void* pBuffer, - size_t pLength, - unsigned int pFlags, - const char* pHint /*= ""*/) { +const aiScene *Importer::ReadFileFromMemory(const void *pBuffer, + size_t pLength, + unsigned int pFlags, + const char *pHint /*= ""*/) { ai_assert(nullptr != pimpl); - + ASSIMP_BEGIN_EXCEPTION_REGION(); if (!pHint) { pHint = ""; } - if (!pBuffer || !pLength || strlen(pHint) > MaxLenHint ) { + if (!pBuffer || !pLength || strlen(pHint) > MaxLenHint) { pimpl->mErrorString = "Invalid parameters passed to ReadFileFromMemory()"; return nullptr; } // prevent deletion of the previous IOHandler - IOSystem* io = pimpl->mIOHandler; + IOSystem *io = pimpl->mIOHandler; pimpl->mIOHandler = nullptr; - SetIOHandler(new MemoryIOSystem((const uint8_t*)pBuffer,pLength,io)); + SetIOHandler(new MemoryIOSystem((const uint8_t *)pBuffer, pLength, io)); // read the file and recover the previous IOSystem static const size_t BufSize(Importer::MaxLenHint + 28); char fbuff[BufSize]; - ai_snprintf(fbuff, BufSize, "%s.%s",AI_MEMORYIO_MAGIC_FILENAME,pHint); + ai_snprintf(fbuff, BufSize, "%s.%s", AI_MEMORYIO_MAGIC_FILENAME, pHint); - ReadFile(fbuff,pFlags); + ReadFile(fbuff, pFlags); SetIOHandler(io); - ASSIMP_END_EXCEPTION_REGION_WITH_ERROR_STRING(const aiScene*, pimpl->mErrorString, pimpl->mException); + ASSIMP_END_EXCEPTION_REGION_WITH_ERROR_STRING(const aiScene *, pimpl->mErrorString, pimpl->mException); return pimpl->mScene; } // ------------------------------------------------------------------------------------------------ -void WriteLogOpening(const std::string& file) { - +void WriteLogOpening(const std::string &file) { + ASSIMP_LOG_INFO_F("Load ", file); // print a full version dump. This is nice because we don't @@ -577,9 +578,9 @@ void WriteLogOpening(const std::string& file) { // ------------------------------------------------------------------------------------------------ // Reads the given file and returns its contents if successful. -const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) { +const aiScene *Importer::ReadFile(const char *_pFile, unsigned int pFlags) { ai_assert(nullptr != pimpl); - + ASSIMP_BEGIN_EXCEPTION_REGION(); const std::string pFile(_pFile); @@ -597,14 +598,14 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) { { // Check whether this Importer instance has already loaded // a scene. In this case we need to delete the old one - if (pimpl->mScene) { + if (pimpl->mScene) { ASSIMP_LOG_DEBUG("(Deleting previous scene)"); FreeScene(); } // First check if the file is accessible at all - if( !pimpl->mIOHandler->Exists( pFile)) { + if (!pimpl->mIOHandler->Exists(pFile)) { pimpl->mErrorString = "Unable to open file \"" + pFile + "\"."; ASSIMP_LOG_ERROR(pimpl->mErrorString); @@ -617,24 +618,24 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) { } // Find an worker class which can handle the file - BaseImporter* imp = nullptr; + BaseImporter *imp = nullptr; SetPropertyInteger("importerIndex", -1); - for( unsigned int a = 0; a < pimpl->mImporter.size(); a++) { + for (unsigned int a = 0; a < pimpl->mImporter.size(); a++) { - if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, false)) { + if (pimpl->mImporter[a]->CanRead(pFile, pimpl->mIOHandler, false)) { imp = pimpl->mImporter[a]; SetPropertyInteger("importerIndex", a); break; } } - if (!imp) { + if (!imp) { // not so bad yet ... try format auto detection. const std::string::size_type s = pFile.find_last_of('.'); if (s != std::string::npos) { ASSIMP_LOG_INFO("File extension not known, trying signature-based detection"); - for( unsigned int a = 0; a < pimpl->mImporter.size(); a++) { - if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, true)) { + for (unsigned int a = 0; a < pimpl->mImporter.size(); a++) { + if (pimpl->mImporter[a]->CanRead(pFile, pimpl->mIOHandler, true)) { imp = pimpl->mImporter[a]; SetPropertyInteger("importerIndex", a); break; @@ -642,7 +643,7 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) { } } // Put a proper error message if no suitable importer was found - if( !imp) { + if (!imp) { pimpl->mErrorString = "No suitable reader found for the file format of file \"" + pFile + "\"."; ASSIMP_LOG_ERROR(pimpl->mErrorString); return nullptr; @@ -650,29 +651,28 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) { } // Get file size for progress handler - IOStream * fileIO = pimpl->mIOHandler->Open( pFile ); + IOStream *fileIO = pimpl->mIOHandler->Open(pFile); uint32_t fileSize = 0; - if (fileIO) - { + if (fileIO) { fileSize = static_cast(fileIO->FileSize()); - pimpl->mIOHandler->Close( fileIO ); + pimpl->mIOHandler->Close(fileIO); } // Dispatch the reading to the worker class for this format - const aiImporterDesc *desc( imp->GetInfo() ); - std::string ext( "unknown" ); - if ( nullptr != desc ) { + const aiImporterDesc *desc(imp->GetInfo()); + std::string ext("unknown"); + if (nullptr != desc) { ext = desc->mName; } - ASSIMP_LOG_INFO("Found a matching importer for this file format: " + ext + "." ); - pimpl->mProgressHandler->UpdateFileRead( 0, fileSize ); + ASSIMP_LOG_INFO("Found a matching importer for this file format: " + ext + "."); + pimpl->mProgressHandler->UpdateFileRead(0, fileSize); if (profiler) { profiler->BeginRegion("import"); } - pimpl->mScene = imp->ReadFile( this, pFile, pimpl->mIOHandler); - pimpl->mProgressHandler->UpdateFileRead( fileSize, fileSize ); + pimpl->mScene = imp->ReadFile(this, pFile, pimpl->mIOHandler); + pimpl->mProgressHandler->UpdateFileRead(fileSize, fileSize); if (profiler) { profiler->EndRegion("import"); @@ -681,7 +681,7 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) { SetPropertyString("sourceFilePath", pFile); // If successful, apply all active post processing steps to the imported data - if( pimpl->mScene) { + if (pimpl->mScene) { if (!pimpl->mScene->mMetaData || !pimpl->mScene->mMetaData->HasKey(AI_METADATA_SOURCE_FORMAT)) { if (!pimpl->mScene->mMetaData) { pimpl->mScene->mMetaData = new aiMetadata; @@ -693,7 +693,7 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) { // The ValidateDS process is an exception. It is executed first, even before ScenePreprocessor is called. if (pFlags & aiProcess_ValidateDataStructure) { ValidateDSProcess ds; - ds.ExecuteOnScene (this); + ds.ExecuteOnScene(this); if (!pimpl->mScene) { return nullptr; } @@ -716,7 +716,7 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) { ApplyPostProcessing(pFlags & (~aiProcess_ValidateDataStructure)); } // if failed, extract the error string - else if( !pimpl->mScene) { + else if (!pimpl->mScene) { pimpl->mErrorString = imp->GetErrorText(); pimpl->mException = imp->GetException(); } @@ -730,30 +730,30 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) { } #ifdef ASSIMP_CATCH_GLOBAL_EXCEPTIONS catch (std::exception &e) { -#if (defined _MSC_VER) && (defined _CPPRTTI) +#if (defined _MSC_VER) && (defined _CPPRTTI) // if we have RTTI get the full name of the exception that occurred - pimpl->mErrorString = std::string(typeid( e ).name()) + ": " + e.what(); + pimpl->mErrorString = std::string(typeid(e).name()) + ": " + e.what(); #else pimpl->mErrorString = std::string("std::exception: ") + e.what(); #endif ASSIMP_LOG_ERROR(pimpl->mErrorString); - delete pimpl->mScene; pimpl->mScene = nullptr; + delete pimpl->mScene; + pimpl->mScene = nullptr; } #endif // ! ASSIMP_CATCH_GLOBAL_EXCEPTIONS // either successful or failure - the pointer expresses it anyways - ASSIMP_END_EXCEPTION_REGION_WITH_ERROR_STRING(const aiScene*, pimpl->mErrorString, pimpl->mException); - + ASSIMP_END_EXCEPTION_REGION_WITH_ERROR_STRING(const aiScene *, pimpl->mErrorString, pimpl->mException); + return pimpl->mScene; } - // ------------------------------------------------------------------------------------------------ // Apply post-processing to the currently bound scene -const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags) { +const aiScene *Importer::ApplyPostProcessing(unsigned int pFlags) { ai_assert(nullptr != pimpl); - + ASSIMP_BEGIN_EXCEPTION_REGION(); // Return immediately if no scene is active if (!pimpl->mScene) { @@ -774,18 +774,17 @@ const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags) { // list of post-processing steps, so we need to call it manually. if (pFlags & aiProcess_ValidateDataStructure) { ValidateDSProcess ds; - ds.ExecuteOnScene (this); + ds.ExecuteOnScene(this); if (!pimpl->mScene) { return nullptr; } } #endif // no validation #ifdef ASSIMP_BUILD_DEBUG - if (pimpl->bExtraVerbose) - { + if (pimpl->bExtraVerbose) { #ifdef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS ASSIMP_LOG_ERROR("Verbose Import is not available due to build settings"); -#endif // no validation +#endif // no validation pFlags |= aiProcess_ValidateDataStructure; } #else @@ -795,67 +794,67 @@ const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags) { #endif // ! DEBUG std::unique_ptr profiler(GetPropertyInteger(AI_CONFIG_GLOB_MEASURE_TIME, 0) ? new Profiler() : nullptr); - for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) { - BaseProcess* process = pimpl->mPostProcessingSteps[a]; - pimpl->mProgressHandler->UpdatePostProcess(static_cast(a), static_cast(pimpl->mPostProcessingSteps.size()) ); - if( process->IsActive( pFlags)) { + for (unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) { + BaseProcess *process = pimpl->mPostProcessingSteps[a]; + pimpl->mProgressHandler->UpdatePostProcess(static_cast(a), static_cast(pimpl->mPostProcessingSteps.size())); + if (process->IsActive(pFlags)) { if (profiler) { profiler->BeginRegion("postprocess"); } - process->ExecuteOnScene ( this ); + process->ExecuteOnScene(this); if (profiler) { profiler->EndRegion("postprocess"); } } - if( !pimpl->mScene) { + if (!pimpl->mScene) { break; } #ifdef ASSIMP_BUILD_DEBUG #ifdef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS continue; -#endif // no validation +#endif // no validation // If the extra verbose mode is active, execute the ValidateDataStructureStep again - after each step - if (pimpl->bExtraVerbose) { + if (pimpl->bExtraVerbose) { ASSIMP_LOG_DEBUG("Verbose Import: re-validating data structures"); ValidateDSProcess ds; - ds.ExecuteOnScene (this); - if( !pimpl->mScene) { + ds.ExecuteOnScene(this); + if (!pimpl->mScene) { ASSIMP_LOG_ERROR("Verbose Import: failed to re-validate data structures"); break; } } #endif // ! DEBUG } - pimpl->mProgressHandler->UpdatePostProcess( static_cast(pimpl->mPostProcessingSteps.size()), - static_cast(pimpl->mPostProcessingSteps.size()) ); + pimpl->mProgressHandler->UpdatePostProcess(static_cast(pimpl->mPostProcessingSteps.size()), + static_cast(pimpl->mPostProcessingSteps.size())); // update private scene flags - if( pimpl->mScene ) { - ScenePriv(pimpl->mScene)->mPPStepsApplied |= pFlags; + if (pimpl->mScene) { + ScenePriv(pimpl->mScene)->mPPStepsApplied |= pFlags; } // clear any data allocated by post-process steps pimpl->mPPShared->Clean(); ASSIMP_LOG_INFO("Leaving post processing pipeline"); - ASSIMP_END_EXCEPTION_REGION(const aiScene*); - + ASSIMP_END_EXCEPTION_REGION(const aiScene *); + return pimpl->mScene; } // ------------------------------------------------------------------------------------------------ -const aiScene* Importer::ApplyCustomizedPostProcessing( BaseProcess *rootProcess, bool requestValidation ) { +const aiScene *Importer::ApplyCustomizedPostProcessing(BaseProcess *rootProcess, bool requestValidation) { ai_assert(nullptr != pimpl); - + ASSIMP_BEGIN_EXCEPTION_REGION(); // Return immediately if no scene is active - if ( nullptr == pimpl->mScene ) { + if (nullptr == pimpl->mScene) { return nullptr; } @@ -865,93 +864,90 @@ const aiScene* Importer::ApplyCustomizedPostProcessing( BaseProcess *rootProcess } // In debug builds: run basic flag validation - ASSIMP_LOG_INFO( "Entering customized post processing pipeline" ); + ASSIMP_LOG_INFO("Entering customized post processing pipeline"); #ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS // The ValidateDS process plays an exceptional role. It isn't contained in the global // list of post-processing steps, so we need to call it manually. - if ( requestValidation ) - { + if (requestValidation) { ValidateDSProcess ds; - ds.ExecuteOnScene( this ); - if ( !pimpl->mScene ) { + ds.ExecuteOnScene(this); + if (!pimpl->mScene) { return nullptr; } } #endif // no validation #ifdef ASSIMP_BUILD_DEBUG - if ( pimpl->bExtraVerbose ) - { + if (pimpl->bExtraVerbose) { #ifdef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS - ASSIMP_LOG_ERROR( "Verbose Import is not available due to build settings" ); -#endif // no validation + ASSIMP_LOG_ERROR("Verbose Import is not available due to build settings"); +#endif // no validation } #else - if ( pimpl->bExtraVerbose ) { - ASSIMP_LOG_WARN( "Not a debug build, ignoring extra verbose setting" ); + if (pimpl->bExtraVerbose) { + ASSIMP_LOG_WARN("Not a debug build, ignoring extra verbose setting"); } #endif // ! DEBUG std::unique_ptr profiler(GetPropertyInteger(AI_CONFIG_GLOB_MEASURE_TIME, 0) ? new Profiler() : nullptr); - if ( profiler ) { - profiler->BeginRegion( "postprocess" ); + if (profiler) { + profiler->BeginRegion("postprocess"); } - rootProcess->ExecuteOnScene( this ); + rootProcess->ExecuteOnScene(this); - if ( profiler ) { - profiler->EndRegion( "postprocess" ); + if (profiler) { + profiler->EndRegion("postprocess"); } // If the extra verbose mode is active, execute the ValidateDataStructureStep again - after each step - if ( pimpl->bExtraVerbose || requestValidation ) { - ASSIMP_LOG_DEBUG( "Verbose Import: revalidating data structures" ); + if (pimpl->bExtraVerbose || requestValidation) { + ASSIMP_LOG_DEBUG("Verbose Import: revalidating data structures"); ValidateDSProcess ds; - ds.ExecuteOnScene( this ); - if ( !pimpl->mScene ) { - ASSIMP_LOG_ERROR( "Verbose Import: failed to revalidate data structures" ); + ds.ExecuteOnScene(this); + if (!pimpl->mScene) { + ASSIMP_LOG_ERROR("Verbose Import: failed to revalidate data structures"); } } // clear any data allocated by post-process steps pimpl->mPPShared->Clean(); - ASSIMP_LOG_INFO( "Leaving customized post processing pipeline" ); + ASSIMP_LOG_INFO("Leaving customized post processing pipeline"); - ASSIMP_END_EXCEPTION_REGION( const aiScene* ); + ASSIMP_END_EXCEPTION_REGION(const aiScene *); return pimpl->mScene; } // ------------------------------------------------------------------------------------------------ // Helper function to check whether an extension is supported by ASSIMP -bool Importer::IsExtensionSupported(const char* szExtension) const { +bool Importer::IsExtensionSupported(const char *szExtension) const { return nullptr != GetImporter(szExtension); } // ------------------------------------------------------------------------------------------------ size_t Importer::GetImporterCount() const { ai_assert(nullptr != pimpl); - + return pimpl->mImporter.size(); } // ------------------------------------------------------------------------------------------------ -const aiImporterDesc* Importer::GetImporterInfo(size_t index) const { +const aiImporterDesc *Importer::GetImporterInfo(size_t index) const { ai_assert(nullptr != pimpl); - + if (index >= pimpl->mImporter.size()) { return nullptr; } return pimpl->mImporter[index]->GetInfo(); } - // ------------------------------------------------------------------------------------------------ -BaseImporter* Importer::GetImporter (size_t index) const { +BaseImporter *Importer::GetImporter(size_t index) const { ai_assert(nullptr != pimpl); - + if (index >= pimpl->mImporter.size()) { return nullptr; } @@ -960,37 +956,38 @@ BaseImporter* Importer::GetImporter (size_t index) const { // ------------------------------------------------------------------------------------------------ // Find a loader plugin for a given file extension -BaseImporter* Importer::GetImporter (const char* szExtension) const { +BaseImporter *Importer::GetImporter(const char *szExtension) const { ai_assert(nullptr != pimpl); - + return GetImporter(GetImporterIndex(szExtension)); } // ------------------------------------------------------------------------------------------------ // Find a loader plugin for a given file extension -size_t Importer::GetImporterIndex (const char* szExtension) const { +size_t Importer::GetImporterIndex(const char *szExtension) const { ai_assert(nullptr != pimpl); ai_assert(nullptr != szExtension); ASSIMP_BEGIN_EXCEPTION_REGION(); // skip over wildcard and dot characters at string head -- - for ( ; *szExtension == '*' || *szExtension == '.'; ++szExtension ); + for (; *szExtension == '*' || *szExtension == '.'; ++szExtension) + ; std::string ext(szExtension); if (ext.empty()) { return static_cast(-1); } - std::transform( ext.begin(), ext.end(), ext.begin(), ToLower ); + std::transform(ext.begin(), ext.end(), ext.begin(), ToLower); std::set str; - for (std::vector::const_iterator i = pimpl->mImporter.begin();i != pimpl->mImporter.end();++i) { + for (std::vector::const_iterator i = pimpl->mImporter.begin(); i != pimpl->mImporter.end(); ++i) { str.clear(); (*i)->GetExtensionList(str); for (std::set::const_iterator it = str.begin(); it != str.end(); ++it) { if (ext == *it) { - return std::distance(static_cast< std::vector::const_iterator >(pimpl->mImporter.begin()), i); + return std::distance(static_cast::const_iterator>(pimpl->mImporter.begin()), i); } } } @@ -1000,133 +997,132 @@ size_t Importer::GetImporterIndex (const char* szExtension) const { // ------------------------------------------------------------------------------------------------ // Helper function to build a list of all file extensions supported by ASSIMP -void Importer::GetExtensionList(aiString& szOut) const { +void Importer::GetExtensionList(aiString &szOut) const { ai_assert(nullptr != pimpl); - + ASSIMP_BEGIN_EXCEPTION_REGION(); std::set str; - for (std::vector::const_iterator i = pimpl->mImporter.begin();i != pimpl->mImporter.end();++i) { + for (std::vector::const_iterator i = pimpl->mImporter.begin(); i != pimpl->mImporter.end(); ++i) { (*i)->GetExtensionList(str); } - // List can be empty - if( !str.empty() ) { - for (std::set::const_iterator it = str.begin();; ) { - szOut.Append("*."); - szOut.Append((*it).c_str()); + // List can be empty + if (!str.empty()) { + for (std::set::const_iterator it = str.begin();;) { + szOut.Append("*."); + szOut.Append((*it).c_str()); - if (++it == str.end()) { - break; - } - szOut.Append(";"); - } - } + if (++it == str.end()) { + break; + } + szOut.Append(";"); + } + } ASSIMP_END_EXCEPTION_REGION(void); } // ------------------------------------------------------------------------------------------------ // Set a configuration property -bool Importer::SetPropertyInteger(const char* szName, int iValue) { +bool Importer::SetPropertyInteger(const char *szName, int iValue) { ai_assert(nullptr != pimpl); - + bool existing; ASSIMP_BEGIN_EXCEPTION_REGION(); - existing = SetGenericProperty(pimpl->mIntProperties, szName,iValue); + existing = SetGenericProperty(pimpl->mIntProperties, szName, iValue); ASSIMP_END_EXCEPTION_REGION(bool); return existing; } // ------------------------------------------------------------------------------------------------ // Set a configuration property -bool Importer::SetPropertyFloat(const char* szName, ai_real iValue) { +bool Importer::SetPropertyFloat(const char *szName, ai_real iValue) { ai_assert(nullptr != pimpl); - + bool existing; ASSIMP_BEGIN_EXCEPTION_REGION(); - existing = SetGenericProperty(pimpl->mFloatProperties, szName,iValue); + existing = SetGenericProperty(pimpl->mFloatProperties, szName, iValue); ASSIMP_END_EXCEPTION_REGION(bool); return existing; } // ------------------------------------------------------------------------------------------------ // Set a configuration property -bool Importer::SetPropertyString(const char* szName, const std::string& value) { +bool Importer::SetPropertyString(const char *szName, const std::string &value) { ai_assert(nullptr != pimpl); - + bool existing; ASSIMP_BEGIN_EXCEPTION_REGION(); - existing = SetGenericProperty(pimpl->mStringProperties, szName,value); + existing = SetGenericProperty(pimpl->mStringProperties, szName, value); ASSIMP_END_EXCEPTION_REGION(bool); return existing; } // ------------------------------------------------------------------------------------------------ // Set a configuration property -bool Importer::SetPropertyMatrix(const char* szName, const aiMatrix4x4& value) { +bool Importer::SetPropertyMatrix(const char *szName, const aiMatrix4x4 &value) { ai_assert(nullptr != pimpl); - + bool existing; ASSIMP_BEGIN_EXCEPTION_REGION(); - existing = SetGenericProperty(pimpl->mMatrixProperties, szName,value); + existing = SetGenericProperty(pimpl->mMatrixProperties, szName, value); ASSIMP_END_EXCEPTION_REGION(bool); return existing; } // ------------------------------------------------------------------------------------------------ // Get a configuration property -int Importer::GetPropertyInteger(const char* szName, int iErrorReturn /*= 0xffffffff*/) const { +int Importer::GetPropertyInteger(const char *szName, int iErrorReturn /*= 0xffffffff*/) const { ai_assert(nullptr != pimpl); - - return GetGenericProperty(pimpl->mIntProperties,szName,iErrorReturn); + + return GetGenericProperty(pimpl->mIntProperties, szName, iErrorReturn); } // ------------------------------------------------------------------------------------------------ // Get a configuration property -ai_real Importer::GetPropertyFloat(const char* szName, ai_real iErrorReturn /*= 10e10*/) const { +ai_real Importer::GetPropertyFloat(const char *szName, ai_real iErrorReturn /*= 10e10*/) const { ai_assert(nullptr != pimpl); - - return GetGenericProperty(pimpl->mFloatProperties,szName,iErrorReturn); + + return GetGenericProperty(pimpl->mFloatProperties, szName, iErrorReturn); } // ------------------------------------------------------------------------------------------------ // Get a configuration property -std::string Importer::GetPropertyString(const char* szName, const std::string& iErrorReturn /*= ""*/) const { +std::string Importer::GetPropertyString(const char *szName, const std::string &iErrorReturn /*= ""*/) const { ai_assert(nullptr != pimpl); - - return GetGenericProperty(pimpl->mStringProperties,szName,iErrorReturn); + + return GetGenericProperty(pimpl->mStringProperties, szName, iErrorReturn); } // ------------------------------------------------------------------------------------------------ // Get a configuration property -aiMatrix4x4 Importer::GetPropertyMatrix(const char* szName, const aiMatrix4x4& iErrorReturn /*= aiMatrix4x4()*/) const { +aiMatrix4x4 Importer::GetPropertyMatrix(const char *szName, const aiMatrix4x4 &iErrorReturn /*= aiMatrix4x4()*/) const { ai_assert(nullptr != pimpl); - - return GetGenericProperty(pimpl->mMatrixProperties,szName,iErrorReturn); + + return GetGenericProperty(pimpl->mMatrixProperties, szName, iErrorReturn); } // ------------------------------------------------------------------------------------------------ // Get the memory requirements of a single node -inline -void AddNodeWeight(unsigned int& iScene,const aiNode* pcNode) { - if ( nullptr == pcNode ) { +inline void AddNodeWeight(unsigned int &iScene, const aiNode *pcNode) { + if (nullptr == pcNode) { return; } iScene += sizeof(aiNode); iScene += sizeof(unsigned int) * pcNode->mNumMeshes; - iScene += sizeof(void*) * pcNode->mNumChildren; + iScene += sizeof(void *) * pcNode->mNumChildren; - for (unsigned int i = 0; i < pcNode->mNumChildren;++i) { - AddNodeWeight(iScene,pcNode->mChildren[i]); + for (unsigned int i = 0; i < pcNode->mNumChildren; ++i) { + AddNodeWeight(iScene, pcNode->mChildren[i]); } } // ------------------------------------------------------------------------------------------------ // Get the memory requirements of the scene -void Importer::GetMemoryRequirements(aiMemoryInfo& in) const { +void Importer::GetMemoryRequirements(aiMemoryInfo &in) const { ai_assert(nullptr != pimpl); - + in = aiMemoryInfo(); - aiScene* mScene = pimpl->mScene; + aiScene *mScene = pimpl->mScene; // return if we have no scene loaded if (!mScene) @@ -1135,7 +1131,7 @@ void Importer::GetMemoryRequirements(aiMemoryInfo& in) const { in.total = sizeof(aiScene); // add all meshes - for (unsigned int i = 0; i < mScene->mNumMeshes;++i) { + for (unsigned int i = 0; i < mScene->mNumMeshes; ++i) { in.meshes += sizeof(aiMesh); if (mScene->mMeshes[i]->HasPositions()) { in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices; @@ -1149,14 +1145,14 @@ void Importer::GetMemoryRequirements(aiMemoryInfo& in) const { in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices * 2; } - for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS;++a) { + for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a) { if (mScene->mMeshes[i]->HasVertexColors(a)) { in.meshes += sizeof(aiColor4D) * mScene->mMeshes[i]->mNumVertices; } else { break; } } - for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS;++a) { + for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) { if (mScene->mMeshes[i]->HasTextureCoords(a)) { in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices; } else { @@ -1164,19 +1160,19 @@ void Importer::GetMemoryRequirements(aiMemoryInfo& in) const { } } if (mScene->mMeshes[i]->HasBones()) { - in.meshes += sizeof(void*) * mScene->mMeshes[i]->mNumBones; - for (unsigned int p = 0; p < mScene->mMeshes[i]->mNumBones;++p) { + in.meshes += sizeof(void *) * mScene->mMeshes[i]->mNumBones; + for (unsigned int p = 0; p < mScene->mMeshes[i]->mNumBones; ++p) { in.meshes += sizeof(aiBone); in.meshes += mScene->mMeshes[i]->mBones[p]->mNumWeights * sizeof(aiVertexWeight); } } - in.meshes += (sizeof(aiFace) + 3 * sizeof(unsigned int))*mScene->mMeshes[i]->mNumFaces; + in.meshes += (sizeof(aiFace) + 3 * sizeof(unsigned int)) * mScene->mMeshes[i]->mNumFaces; } in.total += in.meshes; // add all embedded textures - for (unsigned int i = 0; i < mScene->mNumTextures;++i) { - const aiTexture* pc = mScene->mTextures[i]; + for (unsigned int i = 0; i < mScene->mNumTextures; ++i) { + const aiTexture *pc = mScene->mTextures[i]; in.textures += sizeof(aiTexture); if (pc->mHeight) { in.textures += 4 * pc->mHeight * pc->mWidth; @@ -1187,13 +1183,13 @@ void Importer::GetMemoryRequirements(aiMemoryInfo& in) const { in.total += in.textures; // add all animations - for (unsigned int i = 0; i < mScene->mNumAnimations;++i) { - const aiAnimation* pc = mScene->mAnimations[i]; + for (unsigned int i = 0; i < mScene->mNumAnimations; ++i) { + const aiAnimation *pc = mScene->mAnimations[i]; in.animations += sizeof(aiAnimation); // add all bone anims for (unsigned int a = 0; a < pc->mNumChannels; ++a) { - const aiNodeAnim* pc2 = pc->mChannels[a]; + const aiNodeAnim *pc2 = pc->mChannels[a]; in.animations += sizeof(aiNodeAnim); in.animations += pc2->mNumPositionKeys * sizeof(aiVectorKey); in.animations += pc2->mNumScalingKeys * sizeof(aiVectorKey); @@ -1203,20 +1199,20 @@ void Importer::GetMemoryRequirements(aiMemoryInfo& in) const { in.total += in.animations; // add all cameras and all lights - in.total += in.cameras = sizeof(aiCamera) * mScene->mNumCameras; - in.total += in.lights = sizeof(aiLight) * mScene->mNumLights; + in.total += in.cameras = sizeof(aiCamera) * mScene->mNumCameras; + in.total += in.lights = sizeof(aiLight) * mScene->mNumLights; // add all nodes - AddNodeWeight(in.nodes,mScene->mRootNode); + AddNodeWeight(in.nodes, mScene->mRootNode); in.total += in.nodes; // add all materials - for (unsigned int i = 0; i < mScene->mNumMaterials;++i) { - const aiMaterial* pc = mScene->mMaterials[i]; + for (unsigned int i = 0; i < mScene->mNumMaterials; ++i) { + const aiMaterial *pc = mScene->mMaterials[i]; in.materials += sizeof(aiMaterial); - in.materials += pc->mNumAllocated * sizeof(void*); + in.materials += pc->mNumAllocated * sizeof(void *); - for (unsigned int a = 0; a < pc->mNumProperties;++a) { + for (unsigned int a = 0; a < pc->mNumProperties; ++a) { in.materials += pc->mProperties[a]->mDataLength; } } diff --git a/code/Common/Importer.h b/code/Common/Importer.h index eb70bc38f..0116d14c5 100644 --- a/code/Common/Importer.h +++ b/code/Common/Importer.h @@ -44,20 +44,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef INCLUDED_AI_IMPORTER_H #define INCLUDED_AI_IMPORTER_H -#include -#include -#include #include +#include +#include +#include struct aiScene; -namespace Assimp { - class ProgressHandler; - class IOSystem; - class BaseImporter; - class BaseProcess; - class SharedPostProcessInfo; - +namespace Assimp { +class ProgressHandler; +class IOSystem; +class BaseImporter; +class BaseProcess; +class SharedPostProcessInfo; //! @cond never // --------------------------------------------------------------------------- @@ -70,7 +69,7 @@ namespace Assimp { class ImporterPimpl { public: // Data type to store the key hash - typedef unsigned int KeyType; + using KeyType = unsigned int; // typedefs for our four configuration maps. // We don't need more, so there is no need for a generic solution @@ -80,21 +79,21 @@ public: typedef std::map MatrixPropertyMap; /** IO handler to use for all file accesses. */ - IOSystem* mIOHandler; + IOSystem *mIOHandler; bool mIsDefaultHandler; /** Progress handler for feedback. */ - ProgressHandler* mProgressHandler; + ProgressHandler *mProgressHandler; bool mIsDefaultProgressHandler; /** Format-specific importer worker objects - one for each format we can read.*/ - std::vector< BaseImporter* > mImporter; + std::vector mImporter; /** Post processing steps we can apply at the imported data. */ - std::vector< BaseProcess* > mPostProcessingSteps; + std::vector mPostProcessingSteps; /** The imported data, if ReadFile() was successful, nullptr otherwise. */ - aiScene* mScene; + aiScene *mScene; /** The error description, if there was one. In the case of an exception, * mException will carry the full details. */ @@ -120,29 +119,27 @@ public: bool bExtraVerbose; /** Used by post-process steps to share data */ - SharedPostProcessInfo* mPPShared; + SharedPostProcessInfo *mPPShared; /// The default class constructor. ImporterPimpl() AI_NO_EXCEPT; }; -inline -ImporterPimpl::ImporterPimpl() AI_NO_EXCEPT : - mIOHandler( nullptr ), - mIsDefaultHandler( false ), - mProgressHandler( nullptr ), - mIsDefaultProgressHandler( false ), - mImporter(), - mPostProcessingSteps(), - mScene( nullptr ), - mErrorString(), - mException(), - mIntProperties(), - mFloatProperties(), - mStringProperties(), - mMatrixProperties(), - bExtraVerbose( false ), - mPPShared( nullptr ) { +inline ImporterPimpl::ImporterPimpl() AI_NO_EXCEPT : mIOHandler(nullptr), + mIsDefaultHandler(false), + mProgressHandler(nullptr), + mIsDefaultProgressHandler(false), + mImporter(), + mPostProcessingSteps(), + mScene(nullptr), + mErrorString(), + mException(), + mIntProperties(), + mFloatProperties(), + mStringProperties(), + mMatrixProperties(), + bExtraVerbose(false), + mPPShared(nullptr) { // empty } //! @endcond @@ -164,17 +161,17 @@ public: /** Wraps a full list of configuration properties for an importer. * Properties can be set using SetGenericProperty */ struct PropertyMap { - ImporterPimpl::IntPropertyMap ints; - ImporterPimpl::FloatPropertyMap floats; - ImporterPimpl::StringPropertyMap strings; - ImporterPimpl::MatrixPropertyMap matrices; + ImporterPimpl::IntPropertyMap ints; + ImporterPimpl::FloatPropertyMap floats; + ImporterPimpl::StringPropertyMap strings; + ImporterPimpl::MatrixPropertyMap matrices; - bool operator == (const PropertyMap& prop) const { + bool operator==(const PropertyMap &prop) const { // fixme: really isocpp? gcc complains return ints == prop.ints && floats == prop.floats && strings == prop.strings && matrices == prop.matrices; } - bool empty () const { + bool empty() const { return ints.empty() && floats.empty() && strings.empty() && matrices.empty(); } }; @@ -184,7 +181,7 @@ public: /** Construct a batch loader from a given IO system to be used * to access external files */ - explicit BatchLoader(IOSystem* pIO, bool validate = false ); + explicit BatchLoader(IOSystem *pIO, bool validate = false); // ------------------------------------------------------------------- /** The class destructor. @@ -195,14 +192,14 @@ public: /** Sets the validation step. True for enable validation during postprocess. * @param enable True for validation. */ - void setValidation( bool enabled ); - + void setValidation(bool enabled); + // ------------------------------------------------------------------- /** Returns the current validation step. * @return The current validation step. */ bool getValidation() const; - + // ------------------------------------------------------------------- /** Add a new file to the list of files to be loaded. * @param file File to be loaded @@ -211,11 +208,10 @@ public: * @return 'Load request channel' - an unique ID that can later * be used to access the imported file data. * @see GetImport */ - unsigned int AddLoadRequest ( - const std::string& file, - unsigned int steps = 0, - const PropertyMap *map = nullptr - ); + unsigned int AddLoadRequest( + const std::string &file, + unsigned int steps = 0, + const PropertyMap *map = nullptr); // ------------------------------------------------------------------- /** Get an imported scene. @@ -226,9 +222,8 @@ public: * @param which LRWC returned by AddLoadRequest(). * @return nullptr if there is no scene with this file name * in the queue of the scene hasn't been loaded yet. */ - aiScene* GetImport( - unsigned int which - ); + aiScene *GetImport( + unsigned int which); // ------------------------------------------------------------------- /** Waits until all scenes have been loaded. This returns diff --git a/code/Common/PolyTools.h b/code/Common/PolyTools.h index 1b8972877..35e88ef9a 100644 --- a/code/Common/PolyTools.h +++ b/code/Common/PolyTools.h @@ -45,8 +45,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AI_POLYTOOLS_H_INCLUDED #define AI_POLYTOOLS_H_INCLUDED -#include #include +#include +#include namespace Assimp { @@ -55,8 +56,7 @@ namespace Assimp { * The function accepts an unconstrained template parameter for use with * both aiVector3D and aiVector2D, but generally ignores the third coordinate.*/ template -inline double GetArea2D(const T& v1, const T& v2, const T& v3) -{ +inline double GetArea2D(const T &v1, const T &v2, const T &v3) { return 0.5 * (v1.x * ((double)v3.y - v2.y) + v2.x * ((double)v1.y - v3.y) + v3.x * ((double)v2.y - v1.y)); } @@ -65,9 +65,8 @@ inline double GetArea2D(const T& v1, const T& v2, const T& v3) * The function accepts an unconstrained template parameter for use with * both aiVector3D and aiVector2D, but generally ignores the third coordinate.*/ template -inline bool OnLeftSideOfLine2D(const T& p0, const T& p1,const T& p2) -{ - return GetArea2D(p0,p2,p1) > 0; +inline bool OnLeftSideOfLine2D(const T &p0, const T &p1, const T &p2) { + return GetArea2D(p0, p2, p1) > 0; } // ------------------------------------------------------------------------------- @@ -75,8 +74,7 @@ inline bool OnLeftSideOfLine2D(const T& p0, const T& p1,const T& p2) * The function accepts an unconstrained template parameter for use with * both aiVector3D and aiVector2D, but generally ignores the third coordinate.*/ template -inline bool PointInTriangle2D(const T& p0, const T& p1,const T& p2, const T& pp) -{ +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; @@ -95,7 +93,6 @@ inline bool PointInTriangle2D(const T& p0, const T& p1,const T& p2, const T& pp) return (dot11 > 0) && (dot00 > 0) && (dot11 + dot00 < 1); } - // ------------------------------------------------------------------------------- /** Check whether the winding order of a given polygon is counter-clockwise. * The function accepts an unconstrained template parameter, but is intended @@ -104,7 +101,7 @@ inline bool PointInTriangle2D(const T& p0, const T& p1,const T& p2, const T& pp) * @note Code taken from http://cgm.cs.mcgill.ca/~godfried/teaching/cg-projects/97/Ian/applet1.html and translated to C++ */ template -inline bool IsCCW(T* in, size_t npoints) { +inline bool IsCCW(T *in, size_t npoints) { double aa, bb, cc, b, c, theta; double convex_turn; double convex_sum = 0; @@ -112,44 +109,43 @@ inline bool IsCCW(T* in, size_t npoints) { ai_assert(npoints >= 3); for (size_t i = 0; i < npoints - 2; i++) { - aa = ((in[i+2].x - in[i].x) * (in[i+2].x - in[i].x)) + - ((-in[i+2].y + in[i].y) * (-in[i+2].y + in[i].y)); + aa = ((in[i + 2].x - in[i].x) * (in[i + 2].x - in[i].x)) + + ((-in[i + 2].y + in[i].y) * (-in[i + 2].y + in[i].y)); - bb = ((in[i+1].x - in[i].x) * (in[i+1].x - in[i].x)) + - ((-in[i+1].y + in[i].y) * (-in[i+1].y + in[i].y)); + bb = ((in[i + 1].x - in[i].x) * (in[i + 1].x - in[i].x)) + + ((-in[i + 1].y + in[i].y) * (-in[i + 1].y + in[i].y)); - cc = ((in[i+2].x - in[i+1].x) * - (in[i+2].x - in[i+1].x)) + - ((-in[i+2].y + in[i+1].y) * - (-in[i+2].y + in[i+1].y)); + cc = ((in[i + 2].x - in[i + 1].x) * + (in[i + 2].x - in[i + 1].x)) + + ((-in[i + 2].y + in[i + 1].y) * + (-in[i + 2].y + in[i + 1].y)); b = std::sqrt(bb); c = std::sqrt(cc); theta = std::acos((bb + cc - aa) / (2 * b * c)); - if (OnLeftSideOfLine2D(in[i],in[i+2],in[i+1])) { + if (OnLeftSideOfLine2D(in[i], in[i + 2], in[i + 1])) { // if (convex(in[i].x, in[i].y, // in[i+1].x, in[i+1].y, // in[i+2].x, in[i+2].y)) { convex_turn = AI_MATH_PI_F - theta; convex_sum += convex_turn; - } - else { + } else { convex_sum -= AI_MATH_PI_F - theta; } } - aa = ((in[1].x - in[npoints-2].x) * - (in[1].x - in[npoints-2].x)) + - ((-in[1].y + in[npoints-2].y) * - (-in[1].y + in[npoints-2].y)); + aa = ((in[1].x - in[npoints - 2].x) * + (in[1].x - in[npoints - 2].x)) + + ((-in[1].y + in[npoints - 2].y) * + (-in[1].y + in[npoints - 2].y)); - bb = ((in[0].x - in[npoints-2].x) * - (in[0].x - in[npoints-2].x)) + - ((-in[0].y + in[npoints-2].y) * - (-in[0].y + in[npoints-2].y)); + bb = ((in[0].x - in[npoints - 2].x) * + (in[0].x - in[npoints - 2].x)) + + ((-in[0].y + in[npoints - 2].y) * + (-in[0].y + in[npoints - 2].y)); cc = ((in[1].x - in[0].x) * (in[1].x - in[0].x)) + - ((-in[1].y + in[0].y) * (-in[1].y + in[0].y)); + ((-in[1].y + in[0].y) * (-in[1].y + in[0].y)); b = std::sqrt(bb); c = std::sqrt(cc); @@ -158,18 +154,16 @@ inline bool IsCCW(T* in, size_t npoints) { //if (convex(in[npoints-2].x, in[npoints-2].y, // in[0].x, in[0].y, // in[1].x, in[1].y)) { - if (OnLeftSideOfLine2D(in[npoints-2],in[1],in[0])) { + if (OnLeftSideOfLine2D(in[npoints - 2], in[1], in[0])) { convex_turn = AI_MATH_PI_F - theta; convex_sum += convex_turn; - } - else { + } else { convex_sum -= AI_MATH_PI_F - theta; } return convex_sum >= (2 * AI_MATH_PI_F); } - // ------------------------------------------------------------------------------- /** Compute the normal of an arbitrary polygon in R3. * @@ -185,45 +179,50 @@ inline bool IsCCW(T* in, size_t npoints) { * @note The data arrays must have storage for at least num+2 elements. Using * this method is much faster than the 'other' NewellNormal() */ -template -inline void NewellNormal (aiVector3t& out, int num, TReal* x, TReal* y, TReal* z) -{ +template +inline void NewellNormal(aiVector3t &out, size_t num, TReal *x, TReal *y, TReal *z, size_t bufferSize) { + ai_assert(bufferSize > num); + + if (nullptr == x || nullptr == y || nullptr == z || 0 == bufferSize || 0 == num) { + return; + } + // Duplicate the first two vertices at the end - x[(num+0)*ofs_x] = x[0]; - x[(num+1)*ofs_x] = x[ofs_x]; + x[(num + 0) * ofs_x] = x[0]; + x[(num + 1) * ofs_x] = x[ofs_x]; - y[(num+0)*ofs_y] = y[0]; - y[(num+1)*ofs_y] = y[ofs_y]; + y[(num + 0) * ofs_y] = y[0]; + y[(num + 1) * ofs_y] = y[ofs_y]; - z[(num+0)*ofs_z] = z[0]; - z[(num+1)*ofs_z] = z[ofs_z]; + z[(num + 0) * ofs_z] = z[0]; + z[(num + 1) * ofs_z] = z[ofs_z]; TReal sum_xy = 0.0, sum_yz = 0.0, sum_zx = 0.0; - TReal *xptr = x +ofs_x, *xlow = x, *xhigh = x + ofs_x*2; - TReal *yptr = y +ofs_y, *ylow = y, *yhigh = y + ofs_y*2; - TReal *zptr = z +ofs_z, *zlow = z, *zhigh = z + ofs_z*2; + TReal *xptr = x + ofs_x, *xlow = x, *xhigh = x + ofs_x * 2; + TReal *yptr = y + ofs_y, *ylow = y, *yhigh = y + ofs_y * 2; + TReal *zptr = z + ofs_z, *zlow = z, *zhigh = z + ofs_z * 2; - for (int tmp=0; tmp < num; tmp++) { - sum_xy += (*xptr) * ( (*yhigh) - (*ylow) ); - sum_yz += (*yptr) * ( (*zhigh) - (*zlow) ); - sum_zx += (*zptr) * ( (*xhigh) - (*xlow) ); + for (size_t tmp = 0; tmp < num; ++tmp ) { + sum_xy += (*xptr) * ((*yhigh) - (*ylow)); + sum_yz += (*yptr) * ((*zhigh) - (*zlow)); + sum_zx += (*zptr) * ((*xhigh) - (*xlow)); - xptr += ofs_x; - xlow += ofs_x; + xptr += ofs_x; + xlow += ofs_x; xhigh += ofs_x; - yptr += ofs_y; - ylow += ofs_y; + yptr += ofs_y; + ylow += ofs_y; yhigh += ofs_y; - zptr += ofs_z; - zlow += ofs_z; + zptr += ofs_z; + zlow += ofs_z; zhigh += ofs_z; } - out = aiVector3t(sum_yz,sum_zx,sum_xy); + out = aiVector3t(sum_yz, sum_zx, sum_xy); } -} // ! Assimp +} // namespace Assimp #endif diff --git a/code/PostProcessing/TriangulateProcess.cpp b/code/PostProcessing/TriangulateProcess.cpp index ebd35c997..fc55d975a 100644 --- a/code/PostProcessing/TriangulateProcess.cpp +++ b/code/PostProcessing/TriangulateProcess.cpp @@ -60,14 +60,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef ASSIMP_BUILD_NO_TRIANGULATE_PROCESS #include "PostProcessing/TriangulateProcess.h" -#include "PostProcessing/ProcessHelper.h" #include "Common/PolyTools.h" +#include "PostProcessing/ProcessHelper.h" -#include #include +#include //#define AI_BUILD_TRIANGULATE_COLOR_FACE_WINDING -//#define AI_BUILD_TRIANGULATE_DEBUG_POLYS +#define AI_BUILD_TRIANGULATE_DEBUG_POLYS #define POLY_GRID_Y 40 #define POLY_GRID_X 70 @@ -78,86 +78,91 @@ using namespace Assimp; // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer -TriangulateProcess::TriangulateProcess() -{ +TriangulateProcess::TriangulateProcess() { // nothing to do here } // ------------------------------------------------------------------------------------------------ // Destructor, private as well -TriangulateProcess::~TriangulateProcess() -{ +TriangulateProcess::~TriangulateProcess() { // nothing to do here } // ------------------------------------------------------------------------------------------------ // Returns whether the processing step is present in the given flag field. -bool TriangulateProcess::IsActive( unsigned int pFlags) const -{ +bool TriangulateProcess::IsActive(unsigned int pFlags) const { return (pFlags & aiProcess_Triangulate) != 0; } // ------------------------------------------------------------------------------------------------ // Executes the post processing step on the given imported data. -void TriangulateProcess::Execute( aiScene* pScene) -{ +void TriangulateProcess::Execute(aiScene *pScene) { ASSIMP_LOG_DEBUG("TriangulateProcess begin"); bool bHas = false; - for( unsigned int a = 0; a < pScene->mNumMeshes; a++) - { - if (pScene->mMeshes[ a ]) { - if ( TriangulateMesh( pScene->mMeshes[ a ] ) ) { + for (unsigned int a = 0; a < pScene->mNumMeshes; a++) { + if (pScene->mMeshes[a]) { + if (TriangulateMesh(pScene->mMeshes[a])) { bHas = true; } } } - if ( bHas ) { - ASSIMP_LOG_INFO( "TriangulateProcess finished. All polygons have been triangulated." ); + if (bHas) { + ASSIMP_LOG_INFO("TriangulateProcess finished. All polygons have been triangulated."); } else { - ASSIMP_LOG_DEBUG( "TriangulateProcess finished. There was nothing to be done." ); + ASSIMP_LOG_DEBUG("TriangulateProcess finished. There was nothing to be done."); + } +} + +// ------------------------------------------------------------------------------------------------ +static bool validateNumIndices(aiMesh *mesh) { + bool bNeed = false; + for (unsigned int a = 0; a < mesh->mNumFaces; a++) { + const aiFace &face = mesh->mFaces[a]; + if (face.mNumIndices != 3) { + bNeed = true; + break; + } + } + + return bNeed; +} + +static void calulateNumOutputFaces(aiMesh *mesh, size_t &numOut, size_t &maxOut, bool &getNormals) { + numOut = maxOut = 0; + getNormals = true; + for (unsigned int a = 0; a < mesh->mNumFaces; a++) { + aiFace &face = mesh->mFaces[a]; + if (face.mNumIndices <= 4) { + getNormals = false; + } + if (face.mNumIndices <= 3) { + numOut++; + + } else { + numOut += face.mNumIndices - 2; + maxOut = std::max(maxOut, static_cast(face.mNumIndices)); + } } } // ------------------------------------------------------------------------------------------------ // Triangulates the given mesh. -bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh) -{ +bool TriangulateProcess::TriangulateMesh(aiMesh *pMesh) { // Now we have aiMesh::mPrimitiveTypes, so this is only here for test cases - if (!pMesh->mPrimitiveTypes) { - bool bNeed = false; - for( unsigned int a = 0; a < pMesh->mNumFaces; a++) { - const aiFace& face = pMesh->mFaces[a]; - - if( face.mNumIndices != 3) { - bNeed = true; - } - } - if (!bNeed) + if (!pMesh->mPrimitiveTypes) { + if (!validateNumIndices(pMesh)) { return false; - } - else if (!(pMesh->mPrimitiveTypes & aiPrimitiveType_POLYGON)) { + } + } else if (!(pMesh->mPrimitiveTypes & aiPrimitiveType_POLYGON)) { return false; } // Find out how many output faces we'll get - uint32_t numOut = 0, max_out = 0; - bool get_normals = true; - for( unsigned int a = 0; a < pMesh->mNumFaces; a++) { - aiFace& face = pMesh->mFaces[a]; - if (face.mNumIndices <= 4) { - get_normals = false; - } - if( face.mNumIndices <= 3) { - numOut++; - - } - else { - numOut += face.mNumIndices-2; - max_out = std::max(max_out,face.mNumIndices); - } - } + size_t numOut = 0, max_out = 0; + bool getNormals = true; + calulateNumOutputFaces(pMesh, numOut, max_out, getNormals); // Just another check whether aiMesh::mPrimitiveTypes is correct ai_assert(numOut != pMesh->mNumFaces); @@ -166,87 +171,87 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh) // if we don't have normals yet, but expect them to be a cheap side // product of triangulation anyway, allocate storage for them. - if (!pMesh->mNormals && get_normals) { + if (!pMesh->mNormals && getNormals) { // XXX need a mechanism to inform the GenVertexNormals process to treat these normals as preprocessed per-face normals - // nor_out = pMesh->mNormals = new aiVector3D[pMesh->mNumVertices]; + // nor_out = pMesh->mNormals = new aiVector3D[pMesh->mNumVertices]; } // the output mesh will contain triangles, but no polys anymore pMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE; pMesh->mPrimitiveTypes &= ~aiPrimitiveType_POLYGON; - aiFace* out = new aiFace[numOut](), *curOut = out; - std::vector temp_verts3d(max_out+2); /* temporary storage for vertices */ - std::vector temp_verts(max_out+2); + aiFace *out = new aiFace[numOut](), *curOut = out; + const size_t Capa = max_out + 2; + std::vector temp_verts3d(max_out + 2); /* temporary storage for vertices */ + std::vector temp_verts(max_out + 2); // Apply vertex colors to represent the face winding? #ifdef AI_BUILD_TRIANGULATE_COLOR_FACE_WINDING if (!pMesh->mColors[0]) pMesh->mColors[0] = new aiColor4D[pMesh->mNumVertices]; else - new(pMesh->mColors[0]) aiColor4D[pMesh->mNumVertices]; + new (pMesh->mColors[0]) aiColor4D[pMesh->mNumVertices]; - aiColor4D* clr = pMesh->mColors[0]; + aiColor4D *clr = pMesh->mColors[0]; #endif #ifdef AI_BUILD_TRIANGULATE_DEBUG_POLYS - FILE* fout = fopen(POLY_OUTPUT_FILE,"a"); + FILE *fout = fopen(POLY_OUTPUT_FILE, "a"); #endif - const aiVector3D* verts = pMesh->mVertices; + const aiVector3D *verts = pMesh->mVertices; // use std::unique_ptr to avoid slow std::vector specialiations std::unique_ptr done(new bool[max_out]); - for( unsigned int a = 0; a < pMesh->mNumFaces; a++) { - aiFace& face = pMesh->mFaces[a]; + for (unsigned int a = 0; a < pMesh->mNumFaces; a++) { + aiFace &face = pMesh->mFaces[a]; - unsigned int* idx = face.mIndices; - int num = (int)face.mNumIndices, ear = 0, tmp, prev = num-1, next = 0, max = num; + unsigned int *idx = face.mIndices; + int num = (int)face.mNumIndices, ear = 0, tmp, prev = num - 1, next = 0, max = num; // Apply vertex colors to represent the face winding? #ifdef AI_BUILD_TRIANGULATE_COLOR_FACE_WINDING for (unsigned int i = 0; i < face.mNumIndices; ++i) { - aiColor4D& c = clr[idx[i]]; - c.r = (i+1) / (float)max; + aiColor4D &c = clr[idx[i]]; + c.r = (i + 1) / (float)max; c.b = 1.f - c.r; } #endif - aiFace* const last_face = curOut; + aiFace *const last_face = curOut; // if it's a simple point,line or triangle: just copy it - if( face.mNumIndices <= 3) - { - aiFace& nface = *curOut++; + if (face.mNumIndices <= 3) { + aiFace &nface = *curOut++; nface.mNumIndices = face.mNumIndices; - nface.mIndices = face.mIndices; + nface.mIndices = face.mIndices; face.mIndices = nullptr; continue; } // optimized code for quadrilaterals - else if ( face.mNumIndices == 4) { + else if (face.mNumIndices == 4) { // quads can have at maximum one concave vertex. Determine // this vertex (if it exists) and start tri-fanning from // it. unsigned int start_vertex = 0; for (unsigned int i = 0; i < 4; ++i) { - const aiVector3D& v0 = verts[face.mIndices[(i+3) % 4]]; - const aiVector3D& v1 = verts[face.mIndices[(i+2) % 4]]; - const aiVector3D& v2 = verts[face.mIndices[(i+1) % 4]]; + const aiVector3D &v0 = verts[face.mIndices[(i + 3) % 4]]; + const aiVector3D &v1 = verts[face.mIndices[(i + 2) % 4]]; + const aiVector3D &v2 = verts[face.mIndices[(i + 1) % 4]]; - const aiVector3D& v = verts[face.mIndices[i]]; + const aiVector3D &v = verts[face.mIndices[i]]; - aiVector3D left = (v0-v); - aiVector3D diag = (v1-v); - aiVector3D right = (v2-v); + aiVector3D left = (v0 - v); + aiVector3D diag = (v1 - v); + aiVector3D right = (v2 - v); left.Normalize(); diag.Normalize(); right.Normalize(); - const float angle = std::acos(left*diag) + std::acos(right*diag); + const float angle = std::acos(left * diag) + std::acos(right * diag); if (angle > AI_MATH_PI_F) { // this is the concave point start_vertex = i; @@ -254,9 +259,9 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh) } } - const unsigned int temp[] = {face.mIndices[0], face.mIndices[1], face.mIndices[2], face.mIndices[3]}; + const unsigned int temp[] = { face.mIndices[0], face.mIndices[1], face.mIndices[2], face.mIndices[3] }; - aiFace& nface = *curOut++; + aiFace &nface = *curOut++; nface.mNumIndices = 3; nface.mIndices = face.mIndices; @@ -264,7 +269,7 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh) nface.mIndices[1] = temp[(start_vertex + 1) % 4]; nface.mIndices[2] = temp[(start_vertex + 2) % 4]; - aiFace& sface = *curOut++; + aiFace &sface = *curOut++; sface.mNumIndices = 3; sface.mIndices = new unsigned int[3]; @@ -275,9 +280,7 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh) // prevent double deletion of the indices field face.mIndices = nullptr; continue; - } - else - { + } else { // A polygon with more than 3 vertices can be either concave or convex. // Usually everything we're getting is convex and we could easily // triangulate by tri-fanning. However, LightWave is probably the only @@ -288,42 +291,43 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh) // We project it onto a plane to get a 2d triangle. // Collect all vertices of of the polygon. - for (tmp = 0; tmp < max; ++tmp) { + for (tmp = 0; tmp < max; ++tmp) { temp_verts3d[tmp] = verts[idx[tmp]]; } - // Get newell normal of the polygon. Store it for future use if it's a polygon-only mesh + // Get Newell-Normal of the polygon. Store it for future use if it's a polygon-only mesh aiVector3D n; - NewellNormal<3,3,3>(n,max,&temp_verts3d.front().x,&temp_verts3d.front().y,&temp_verts3d.front().z); + NewellNormal<3, 3, 3>(n, max, &temp_verts3d.front().x, &temp_verts3d.front().y, &temp_verts3d.front().z, Capa); if (nor_out) { - for (tmp = 0; tmp < max; ++tmp) - nor_out[idx[tmp]] = n; + for (tmp = 0; tmp < max; ++tmp) + nor_out[idx[tmp]] = n; } // Select largest normal coordinate to ignore for projection - const float ax = (n.x>0 ? n.x : -n.x); - const float ay = (n.y>0 ? n.y : -n.y); - const float az = (n.z>0 ? n.z : -n.z); + const float ax = (n.x > 0 ? n.x : -n.x); + const float ay = (n.y > 0 ? n.y : -n.y); + const float az = (n.z > 0 ? n.z : -n.z); - unsigned int ac = 0, bc = 1; /* no z coord. projection to xy */ + unsigned int ac = 0, bc = 1; // no z coord. projection to xy float inv = n.z; if (ax > ay) { - if (ax > az) { /* no x coord. projection to yz */ - ac = 1; bc = 2; + if (ax > az) { // no x coord. projection to yz + ac = 1; + bc = 2; inv = n.x; } - } - else if (ay > az) { /* no y coord. projection to zy */ - ac = 2; bc = 0; + } else if (ay > az) { // no y coord. projection to zy + ac = 2; + bc = 0; inv = n.y; } // Swap projection axes to take the negated projection vector into account if (inv < 0.f) { - std::swap(ac,bc); + std::swap(ac, bc); } - for (tmp =0; tmp < max; ++tmp) { + for (tmp = 0; tmp < max; ++tmp) { temp_verts[tmp].x = verts[idx[tmp]][ac]; temp_verts[tmp].y = verts[idx[tmp]][bc]; done[tmp] = false; @@ -331,30 +335,30 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh) #ifdef AI_BUILD_TRIANGULATE_DEBUG_POLYS // plot the plane onto which we mapped the polygon to a 2D ASCII pic - aiVector2D bmin,bmax; - ArrayBounds(&temp_verts[0],max,bmin,bmax); + aiVector2D bmin, bmax; + ArrayBounds(&temp_verts[0], max, bmin, bmax); - char grid[POLY_GRID_Y][POLY_GRID_X+POLY_GRID_XPAD]; - std::fill_n((char*)grid,POLY_GRID_Y*(POLY_GRID_X+POLY_GRID_XPAD),' '); + char grid[POLY_GRID_Y][POLY_GRID_X + POLY_GRID_XPAD]; + std::fill_n((char *)grid, POLY_GRID_Y * (POLY_GRID_X + POLY_GRID_XPAD), ' '); - for (int i =0; i < max; ++i) { - const aiVector2D& v = (temp_verts[i] - bmin) / (bmax-bmin); - const size_t x = static_cast(v.x*(POLY_GRID_X-1)), y = static_cast(v.y*(POLY_GRID_Y-1)); - char* loc = grid[y]+x; + for (int i = 0; i < max; ++i) { + const aiVector2D &v = (temp_verts[i] - bmin) / (bmax - bmin); + const size_t x = static_cast(v.x * (POLY_GRID_X - 1)), y = static_cast(v.y * (POLY_GRID_Y - 1)); + char *loc = grid[y] + x; if (grid[y][x] != ' ') { - for(;*loc != ' '; ++loc); + for (; *loc != ' '; ++loc) + ; *loc++ = '_'; } - *(loc+::ai_snprintf(loc, POLY_GRID_XPAD,"%i",i)) = ' '; + *(loc + ::ai_snprintf(loc, POLY_GRID_XPAD, "%i", i)) = ' '; } - - for(size_t y = 0; y < POLY_GRID_Y; ++y) { - grid[y][POLY_GRID_X+POLY_GRID_XPAD-1] = '\0'; - fprintf(fout,"%s\n",grid[y]); + for (size_t y = 0; y < POLY_GRID_Y; ++y) { + grid[y][POLY_GRID_X + POLY_GRID_XPAD - 1] = '\0'; + fprintf(fout, "%s\n", grid[y]); } - fprintf(fout,"\ntriangulation sequence: "); + fprintf(fout, "\ntriangulation sequence: "); #endif // @@ -364,26 +368,27 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh) // Find the next ear of the polygon int num_found = 0; - for (ear = next;;prev = ear,ear = next) { + for (ear = next;; prev = ear, ear = next) { // break after we looped two times without a positive match - for (next=ear+1;done[(next>=max?next=0:next)];++next); + for (next = ear + 1; done[(next >= max ? next = 0 : next)]; ++next) + ; if (next < ear) { if (++num_found == 2) { break; } } - const aiVector2D* pnt1 = &temp_verts[ear], - *pnt0 = &temp_verts[prev], - *pnt2 = &temp_verts[next]; + const aiVector2D *pnt1 = &temp_verts[ear], + *pnt0 = &temp_verts[prev], + *pnt2 = &temp_verts[next]; // Must be a convex point. Assuming ccw winding, it must be on the right of the line between p-1 and p+1. - if (OnLeftSideOfLine2D(*pnt0,*pnt2,*pnt1)) { + if (OnLeftSideOfLine2D(*pnt0, *pnt2, *pnt1)) { continue; } // and no other point may be contained in this triangle - for ( tmp = 0; tmp < max; ++tmp) { + for (tmp = 0; tmp < max; ++tmp) { // We need to compare the actual values because it's possible that multiple indexes in // the polygon are referring to the same position. concave_polygon.obj is a sample @@ -392,8 +397,8 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh) // PointInTriangle() I'm guessing that it's actually possible to construct // input data that would cause us to end up with no ears. The problem is, // which epsilon? If we chose a too large value, we'd get wrong results - const aiVector2D& vtmp = temp_verts[tmp]; - if ( vtmp != *pnt1 && vtmp != *pnt2 && vtmp != *pnt0 && PointInTriangle2D(*pnt0,*pnt1,*pnt2,vtmp)) { + const aiVector2D &vtmp = temp_verts[tmp]; + if (vtmp != *pnt1 && vtmp != *pnt2 && vtmp != *pnt0 && PointInTriangle2D(*pnt0, *pnt1, *pnt2, vtmp)) { break; } } @@ -415,29 +420,13 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh) ASSIMP_LOG_ERROR("Failed to triangulate polygon (no ear found). Probably not a simple polygon?"); #ifdef AI_BUILD_TRIANGULATE_DEBUG_POLYS - fprintf(fout,"critical error here, no ear found! "); + fprintf(fout, "critical error here, no ear found! "); #endif num = 0; break; - - /*curOut -= (max-num); // undo all previous work - for (tmp = 0; tmp < max-2; ++tmp) { - aiFace& nface = *curOut++; - - nface.mNumIndices = 3; - if (!nface.mIndices) - nface.mIndices = new unsigned int[3]; - - nface.mIndices[0] = 0; - nface.mIndices[1] = tmp+1; - nface.mIndices[2] = tmp+2; - - } - num = 0; - break;*/ } - aiFace& nface = *curOut++; + aiFace &nface = *curOut++; nface.mNumIndices = 3; if (!nface.mIndices) { @@ -455,56 +444,40 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh) } if (num > 0) { // We have three indices forming the last 'ear' remaining. Collect them. - aiFace& nface = *curOut++; + aiFace &nface = *curOut++; nface.mNumIndices = 3; if (!nface.mIndices) { nface.mIndices = new unsigned int[3]; } - for (tmp = 0; done[tmp]; ++tmp); + for (tmp = 0; done[tmp]; ++tmp) + ; nface.mIndices[0] = tmp; - for (++tmp; done[tmp]; ++tmp); + for (++tmp; done[tmp]; ++tmp) + ; nface.mIndices[1] = tmp; - for (++tmp; done[tmp]; ++tmp); + for (++tmp; done[tmp]; ++tmp) + ; nface.mIndices[2] = tmp; - } } #ifdef AI_BUILD_TRIANGULATE_DEBUG_POLYS - for(aiFace* f = last_face; f != curOut; ++f) { - unsigned int* i = f->mIndices; - fprintf(fout," (%i %i %i)",i[0],i[1],i[2]); + for (aiFace *f = last_face; f != curOut; ++f) { + unsigned int *i = f->mIndices; + fprintf(fout, " (%i %i %i)", i[0], i[1], i[2]); } - fprintf(fout,"\n*********************************************************************\n"); + fprintf(fout, "\n*********************************************************************\n"); fflush(fout); #endif - for(aiFace* f = last_face; f != curOut; ) { - unsigned int* i = f->mIndices; - - // drop dumb 0-area triangles - deactivated for now: - //FindDegenerates post processing step can do the same thing - //if (std::fabs(GetArea2D(temp_verts[i[0]],temp_verts[i[1]],temp_verts[i[2]])) < 1e-5f) { - // ASSIMP_LOG_VERBOSE_DEBUG("Dropping triangle with area 0"); - // --curOut; - - // delete[] f->mIndices; - // f->mIndices = nullptr; - - // for(aiFace* ff = f; ff != curOut; ++ff) { - // ff->mNumIndices = (ff+1)->mNumIndices; - // ff->mIndices = (ff+1)->mIndices; - // (ff+1)->mIndices = nullptr; - // } - // continue; - //} - + for (aiFace *f = last_face; f != curOut;) { + unsigned int *i = f->mIndices; i[0] = idx[i[0]]; i[1] = idx[i[1]]; i[2] = idx[i[2]]; @@ -520,11 +493,11 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh) #endif // kill the old faces - delete [] pMesh->mFaces; + delete[] pMesh->mFaces; // ... and store the new ones - pMesh->mFaces = out; - pMesh->mNumFaces = (unsigned int)(curOut-out); /* not necessarily equal to numOut */ + pMesh->mFaces = out; + pMesh->mNumFaces = (unsigned int)(curOut - out); /* not necessarily equal to numOut */ return true; } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 7f6d2ac86..027cc5ef4 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -96,6 +96,7 @@ SET( COMMON unit/Common/utSpatialSort.cpp unit/Common/utAssertHandler.cpp unit/Common/utXmlParser.cpp + unit/Common/utPolyTools.cpp ) SET( IMPORTERS diff --git a/test/unit/utProfiler.cpp b/test/unit/utProfiler.cpp index 5b5871135..ae4c1be75 100644 --- a/test/unit/utProfiler.cpp +++ b/test/unit/utProfiler.cpp @@ -5,8 +5,6 @@ Open Asset Import Library (assimp) Copyright (c) 2006-2020, assimp team - - All rights reserved. Redistribution and use of this software in source and binary forms, diff --git a/tools/assimp_view/AnimEvaluator.h b/tools/assimp_view/AnimEvaluator.h index 12bb91c30..49a0f5a4a 100644 --- a/tools/assimp_view/AnimEvaluator.h +++ b/tools/assimp_view/AnimEvaluator.h @@ -43,9 +43,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AV_ANIMEVALUATOR_H_INCLUDED #define AV_ANIMEVALUATOR_H_INCLUDED +#include + #include #include +struct aiAnimation; + namespace AssimpView { /** @@ -74,7 +78,7 @@ public: * the aiAnimation. */ const std::vector &GetTransformations() const { return mTransforms; } -protected: +private: const aiAnimation *mAnim; double mLastTime; std::vector> mLastPositions; diff --git a/tools/assimp_view/Display.cpp b/tools/assimp_view/Display.cpp index 1f6bb89eb..4dc5ed0db 100644 --- a/tools/assimp_view/Display.cpp +++ b/tools/assimp_view/Display.cpp @@ -38,9 +38,9 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------------------------- */ -#include "assimp_view.h" #include "AnimEvaluator.h" #include "SceneAnimator.h" +#include "assimp_view.h" #include #include @@ -51,9 +51,8 @@ using namespace Assimp; extern std::string g_szCheckerBackgroundShader; -struct SVertex -{ - float x,y,z,w,u,v; +struct SVertex { + float x, y, z, w, u, v; }; CDisplay CDisplay::s_cInstance; @@ -65,37 +64,34 @@ extern float g_fLoadTime; //------------------------------------------------------------------------------- // Table of colors used for normal vectors. //------------------------------------------------------------------------------- -D3DXVECTOR4 g_aclNormalColors[14] = -{ - D3DXVECTOR4(0xFF / 255.0f,0xFF / 255.0f,0xFF / 255.0f, 1.0f), // white +D3DXVECTOR4 g_aclNormalColors[14] = { + D3DXVECTOR4(0xFF / 255.0f, 0xFF / 255.0f, 0xFF / 255.0f, 1.0f), // white - D3DXVECTOR4(0xFF / 255.0f,0x00 / 255.0f,0x00 / 255.0f,1.0f), // red - D3DXVECTOR4(0x00 / 255.0f,0xFF / 255.0f,0x00 / 255.0f,1.0f), // green - D3DXVECTOR4(0x00 / 255.0f,0x00 / 255.0f,0xFF / 255.0f,1.0f), // blue + D3DXVECTOR4(0xFF / 255.0f, 0x00 / 255.0f, 0x00 / 255.0f, 1.0f), // red + D3DXVECTOR4(0x00 / 255.0f, 0xFF / 255.0f, 0x00 / 255.0f, 1.0f), // green + D3DXVECTOR4(0x00 / 255.0f, 0x00 / 255.0f, 0xFF / 255.0f, 1.0f), // blue - D3DXVECTOR4(0xFF / 255.0f,0xFF / 255.0f,0x00 / 255.0f,1.0f), // yellow - D3DXVECTOR4(0xFF / 255.0f,0x00 / 255.0f,0xFF / 255.0f,1.0f), // magenta - D3DXVECTOR4(0x00 / 255.0f,0xFF / 255.0f,0xFF / 255.0f,1.0f), // wtf + D3DXVECTOR4(0xFF / 255.0f, 0xFF / 255.0f, 0x00 / 255.0f, 1.0f), // yellow + D3DXVECTOR4(0xFF / 255.0f, 0x00 / 255.0f, 0xFF / 255.0f, 1.0f), // magenta + D3DXVECTOR4(0x00 / 255.0f, 0xFF / 255.0f, 0xFF / 255.0f, 1.0f), // wtf - D3DXVECTOR4(0xFF / 255.0f,0x60 / 255.0f,0x60 / 255.0f,1.0f), // light red - D3DXVECTOR4(0x60 / 255.0f,0xFF / 255.0f,0x60 / 255.0f,1.0f), // light green - D3DXVECTOR4(0x60 / 255.0f,0x60 / 255.0f,0xFF / 255.0f,1.0f), // light blue + D3DXVECTOR4(0xFF / 255.0f, 0x60 / 255.0f, 0x60 / 255.0f, 1.0f), // light red + D3DXVECTOR4(0x60 / 255.0f, 0xFF / 255.0f, 0x60 / 255.0f, 1.0f), // light green + D3DXVECTOR4(0x60 / 255.0f, 0x60 / 255.0f, 0xFF / 255.0f, 1.0f), // light blue - D3DXVECTOR4(0xA0 / 255.0f,0x00 / 255.0f,0x00 / 255.0f,1.0f), // dark red - D3DXVECTOR4(0x00 / 255.0f,0xA0 / 255.0f,0x00 / 255.0f,1.0f), // dark green - D3DXVECTOR4(0x00 / 255.0f,0x00 / 255.0f,0xA0 / 255.0f,1.0f), // dark blue + D3DXVECTOR4(0xA0 / 255.0f, 0x00 / 255.0f, 0x00 / 255.0f, 1.0f), // dark red + D3DXVECTOR4(0x00 / 255.0f, 0xA0 / 255.0f, 0x00 / 255.0f, 1.0f), // dark green + D3DXVECTOR4(0x00 / 255.0f, 0x00 / 255.0f, 0xA0 / 255.0f, 1.0f), // dark blue - D3DXVECTOR4(0x88 / 255.0f,0x88 / 255.0f,0x88 / 255.0f, 1.0f) // gray + D3DXVECTOR4(0x88 / 255.0f, 0x88 / 255.0f, 0x88 / 255.0f, 1.0f) // gray }; - //------------------------------------------------------------------------------- -// Recursivly count the number of nodes in an asset's node graph +// Recursively count the number of nodes in an asset's node graph // Used by LoadAsset() //------------------------------------------------------------------------------- -void GetNodeCount(aiNode* pcNode, unsigned int* piCnt) -{ - *piCnt = *piCnt+1; +void GetNodeCount(aiNode *pcNode, unsigned int *piCnt) { + *piCnt = *piCnt + 1; for (unsigned int i = 0; i < pcNode->mNumChildren; ++i) { GetNodeCount(pcNode->mChildren[i], piCnt); } @@ -103,88 +99,81 @@ void GetNodeCount(aiNode* pcNode, unsigned int* piCnt) //------------------------------------------------------------------------------- int CDisplay::EnableAnimTools(BOOL hm) { - EnableWindow(GetDlgItem(g_hDlg,IDC_PLAY),hm); - EnableWindow(GetDlgItem(g_hDlg,IDC_SLIDERANIM),hm); - + EnableWindow(GetDlgItem(g_hDlg, IDC_PLAY), hm); + EnableWindow(GetDlgItem(g_hDlg, IDC_SLIDERANIM), hm); + return 1; } //------------------------------------------------------------------------------- // Fill animation combo box int CDisplay::FillAnimList(void) { - if (0 != g_pcAsset->pcScene->mNumAnimations) - { + if (0 != g_pcAsset->pcScene->mNumAnimations) { // now fill in all animation names - for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumAnimations;++i) { - SendDlgItemMessage(g_hDlg,IDC_COMBO1,CB_ADDSTRING,0, - ( LPARAM ) g_pcAsset->pcScene->mAnimations[i]->mName.data); + for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumAnimations; ++i) { + SendDlgItemMessage(g_hDlg, IDC_COMBO1, CB_ADDSTRING, 0, + (LPARAM)g_pcAsset->pcScene->mAnimations[i]->mName.data); } // also add a dummy - 'none' - SendDlgItemMessage(g_hDlg,IDC_COMBO1,CB_ADDSTRING,0,(LPARAM)"none"); + SendDlgItemMessage(g_hDlg, IDC_COMBO1, CB_ADDSTRING, 0, (LPARAM) "none"); // select first - SendDlgItemMessage(g_hDlg,IDC_COMBO1,CB_SETCURSEL,0,0); + SendDlgItemMessage(g_hDlg, IDC_COMBO1, CB_SETCURSEL, 0, 0); EnableAnimTools(TRUE); - } - else // tools remain disabled + } else { + // tools remain disabled EnableAnimTools(FALSE); + } return 1; } //------------------------------------------------------------------------------- // Clear the list of animations -int CDisplay::ClearAnimList(void) -{ +int CDisplay::ClearAnimList(void) { // clear the combo box - SendDlgItemMessage(g_hDlg,IDC_COMBO1,CB_RESETCONTENT,0,0); + SendDlgItemMessage(g_hDlg, IDC_COMBO1, CB_RESETCONTENT, 0, 0); return 1; } //------------------------------------------------------------------------------- // Clear the tree view -int CDisplay::ClearDisplayList(void) -{ +int CDisplay::ClearDisplayList(void) { // clear the combo box - TreeView_DeleteAllItems(GetDlgItem(g_hDlg,IDC_TREE1)); + TreeView_DeleteAllItems(GetDlgItem(g_hDlg, IDC_TREE1)); this->Reset(); return 1; } //------------------------------------------------------------------------------- // Add a specific node to the display list int CDisplay::AddNodeToDisplayList( - unsigned int iIndex, - unsigned int iDepth, - aiNode* pcNode, - HTREEITEM hRoot) -{ + unsigned int iIndex, + unsigned int iDepth, + aiNode *pcNode, + HTREEITEM hRoot) { ai_assert(nullptr != pcNode); ai_assert(nullptr != hRoot); char chTemp[MAXLEN]; - if(0 == pcNode->mName.length) { - if (iIndex >= 100) { - iIndex += iDepth * 1000; - } - else if (iIndex >= 10) - { - iIndex += iDepth * 100; - } - else - iIndex += iDepth * 10; - ai_snprintf(chTemp, MAXLEN,"Node %u",iIndex); + if (0 == pcNode->mName.length) { + if (iIndex >= 100) { + iIndex += iDepth * 1000; + } else if (iIndex >= 10) { + iIndex += iDepth * 100; + } else + iIndex += iDepth * 10; + ai_snprintf(chTemp, MAXLEN, "Node %u", iIndex); + } else { + ai_snprintf(chTemp, MAXLEN, "%s", pcNode->mName.data); } - else { - ai_snprintf(chTemp, MAXLEN,"%s",pcNode->mName.data); - } - ai_snprintf(chTemp+strlen(chTemp), MAXLEN- strlen(chTemp), iIndex ? " (%i)" : " (%i meshes)",pcNode->mNumMeshes); + ai_snprintf(chTemp + strlen(chTemp), MAXLEN - strlen(chTemp), iIndex ? " (%i)" : " (%i meshes)", pcNode->mNumMeshes); TVITEMEXW tvi; TVINSERTSTRUCTW sNew; wchar_t tmp[512]; - int t = MultiByteToWideChar(CP_UTF8,0,chTemp,-1,tmp,512); + int t = MultiByteToWideChar(CP_UTF8, 0, chTemp, -1, tmp, 512); tvi.pszText = tmp; tvi.cchTextMax = (int)t; @@ -199,15 +188,15 @@ int CDisplay::AddNodeToDisplayList( sNew.hParent = hRoot; // add the item to the list - HTREEITEM hTexture = (HTREEITEM)SendMessage(GetDlgItem(g_hDlg,IDC_TREE1), - TVM_INSERTITEMW, - 0, - (LPARAM)(LPTVINSERTSTRUCT)&sNew); + HTREEITEM hTexture = (HTREEITEM)SendMessage(GetDlgItem(g_hDlg, IDC_TREE1), + TVM_INSERTITEMW, + 0, + (LPARAM)(LPTVINSERTSTRUCT)&sNew); // recursively add all child nodes ++iDepth; - for (unsigned int i = 0; i< pcNode->mNumChildren;++i){ - AddNodeToDisplayList(i,iDepth,pcNode->mChildren[i],hTexture); + for (unsigned int i = 0; i < pcNode->mNumChildren; ++i) { + AddNodeToDisplayList(i, iDepth, pcNode->mChildren[i], hTexture); } // add the node to the list @@ -219,25 +208,23 @@ int CDisplay::AddNodeToDisplayList( } //------------------------------------------------------------------------------- -int CDisplay::AddMeshToDisplayList(unsigned int iIndex, HTREEITEM hRoot) -{ - aiMesh* pcMesh = g_pcAsset->pcScene->mMeshes[iIndex]; +int CDisplay::AddMeshToDisplayList(unsigned int iIndex, HTREEITEM hRoot) { + aiMesh *pcMesh = g_pcAsset->pcScene->mMeshes[iIndex]; char chTemp[MAXLEN]; - if(0 == pcMesh->mName.length) { - ai_snprintf(chTemp,MAXLEN,"Mesh %u",iIndex); + if (0 == pcMesh->mName.length) { + ai_snprintf(chTemp, MAXLEN, "Mesh %u", iIndex); + } else { + ai_snprintf(chTemp, MAXLEN, "%s", pcMesh->mName.data); } - else { - ai_snprintf(chTemp,MAXLEN,"%s",pcMesh->mName.data); - } - ai_snprintf(chTemp+strlen(chTemp),MAXLEN-strlen(chTemp), iIndex ? " (%i)" : " (%i faces)",pcMesh->mNumFaces); + ai_snprintf(chTemp + strlen(chTemp), MAXLEN - strlen(chTemp), iIndex ? " (%i)" : " (%i faces)", pcMesh->mNumFaces); TVITEMEXW tvi; TVINSERTSTRUCTW sNew; wchar_t tmp[512]; - int t = MultiByteToWideChar(CP_UTF8,0,chTemp,-1,tmp,512); + int t = MultiByteToWideChar(CP_UTF8, 0, chTemp, -1, tmp, 512); tvi.pszText = tmp; tvi.cchTextMax = (int)t; @@ -252,10 +239,10 @@ int CDisplay::AddMeshToDisplayList(unsigned int iIndex, HTREEITEM hRoot) sNew.hParent = hRoot; // add the item to the list - HTREEITEM hTexture = (HTREEITEM)SendMessage(GetDlgItem(g_hDlg,IDC_TREE1), - TVM_INSERTITEMW, - 0, - (LPARAM)(LPTVINSERTSTRUCT)&sNew); + HTREEITEM hTexture = (HTREEITEM)SendMessage(GetDlgItem(g_hDlg, IDC_TREE1), + TVM_INSERTITEMW, + 0, + (LPARAM)(LPTVINSERTSTRUCT)&sNew); // add the mesh to the list of all mesh entries in the scene browser MeshInfo info; @@ -267,20 +254,19 @@ int CDisplay::AddMeshToDisplayList(unsigned int iIndex, HTREEITEM hRoot) //------------------------------------------------------------------------------- // Replace the currently selected texture by another one -int CDisplay::ReplaceCurrentTexture(const char* szPath) -{ +int CDisplay::ReplaceCurrentTexture(const char *szPath) { ai_assert(nullptr != szPath); // well ... try to load it - IDirect3DTexture9* piTexture = nullptr; + IDirect3DTexture9 *piTexture = nullptr; aiString szString; - strcpy(szString.data,szPath); + strcpy(szString.data, szPath); szString.length = static_cast(strlen(szPath)); - CMaterialManager::Instance().LoadTexture(&piTexture,&szString); + CMaterialManager::Instance().LoadTexture(&piTexture, &szString); if (!piTexture) { CLogDisplay::Instance().AddEntry("[ERROR] Unable to load this texture", - D3DCOLOR_ARGB(0xFF,0xFF,0x0,0x0)); + D3DCOLOR_ARGB(0xFF, 0xFF, 0x0, 0x0)); return 0; } @@ -291,21 +277,19 @@ int CDisplay::ReplaceCurrentTexture(const char* szPath) tvi.iImage = m_aiImageList[AI_VIEW_IMGLIST_MATERIAL]; tvi.iSelectedImage = m_aiImageList[AI_VIEW_IMGLIST_MATERIAL]; - TreeView_SetItem(GetDlgItem(g_hDlg,IDC_TREE1), - m_pcCurrentTexture->hTreeItem); + TreeView_SetItem(GetDlgItem(g_hDlg, IDC_TREE1), + m_pcCurrentTexture->hTreeItem); // update all meshes referencing this material - for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i) - { + for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes; ++i) { if (this->m_pcCurrentTexture->iMatIndex != g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex) continue; - AssetHelper::MeshHelper* pcMesh = g_pcAsset->apcMeshes[i]; - IDirect3DTexture9** tex = nullptr; - const char* tex_string = nullptr; + AssetHelper::MeshHelper *pcMesh = g_pcAsset->apcMeshes[i]; + IDirect3DTexture9 **tex = nullptr; + const char *tex_string = nullptr; - switch (this->m_pcCurrentTexture->iType) - { + switch (this->m_pcCurrentTexture->iType) { case aiTextureType_DIFFUSE: tex = &pcMesh->piDiffuseTexture; tex_string = "DIFFUSE_TEXTURE"; @@ -338,15 +322,15 @@ int CDisplay::ReplaceCurrentTexture(const char* szPath) case aiTextureType_HEIGHT: // special handling here - if (pcMesh->piNormalTexture && pcMesh->piNormalTexture != piTexture) { + if (pcMesh->piNormalTexture && pcMesh->piNormalTexture != piTexture) { piTexture->AddRef(); pcMesh->piNormalTexture->Release(); pcMesh->piNormalTexture = piTexture; - CMaterialManager::Instance().HMtoNMIfNecessary(pcMesh->piNormalTexture,&pcMesh->piNormalTexture,true); + CMaterialManager::Instance().HMtoNMIfNecessary(pcMesh->piNormalTexture, &pcMesh->piNormalTexture, true); m_pcCurrentTexture->piTexture = &pcMesh->piNormalTexture; if (!pcMesh->bSharedFX) { - pcMesh->piEffect->SetTexture("NORMAL_TEXTURE",piTexture); + pcMesh->piEffect->SetTexture("NORMAL_TEXTURE", piTexture); } } break; @@ -356,13 +340,12 @@ int CDisplay::ReplaceCurrentTexture(const char* szPath) tex_string = "OPACITY_TEXTURE"; break; }; - if (tex && *tex && *tex != piTexture) - { + if (tex && *tex && *tex != piTexture) { (**tex).Release(); *tex = piTexture; m_pcCurrentTexture->piTexture = tex; - pcMesh->piEffect->SetTexture(tex_string,piTexture); + pcMesh->piEffect->SetTexture(tex_string, piTexture); } } @@ -370,39 +353,33 @@ int CDisplay::ReplaceCurrentTexture(const char* szPath) } //------------------------------------------------------------------------------- int CDisplay::AddTextureToDisplayList(unsigned int iType, - unsigned int iIndex, - const aiString* szPath, - HTREEITEM hFX, - unsigned int iUVIndex /*= 0*/, - const float fBlendFactor /*= 0.0f*/, - aiTextureOp eTextureOp /*= aiTextureOp_Multiply*/, - unsigned int iMesh /*= 0*/) -{ + unsigned int iIndex, + const aiString *szPath, + HTREEITEM hFX, + unsigned int iUVIndex /*= 0*/, + const float fBlendFactor /*= 0.0f*/, + aiTextureOp eTextureOp /*= aiTextureOp_Multiply*/, + unsigned int iMesh /*= 0*/) { ai_assert(nullptr != szPath); char chTemp[512]; char chTempEmb[256]; - const char* sz = strrchr(szPath->data,'\\'); - if (!sz)sz = strrchr(szPath->data,'/'); - if (!sz) - { - if ('*' == *szPath->data) - { - int iIndex2 = atoi(szPath->data+1); - ai_snprintf(chTempEmb,256,"Embedded #%i",iIndex2); + const char *sz = strrchr(szPath->data, '\\'); + if (!sz) sz = strrchr(szPath->data, '/'); + if (!sz) { + if ('*' == *szPath->data) { + int iIndex2 = atoi(szPath->data + 1); + ai_snprintf(chTempEmb, 256, "Embedded #%i", iIndex2); sz = chTempEmb; - } - else - { + } else { sz = szPath->data; } } bool bIsExtraOpacity = 0 != (iType & 0x40000000); - const char* szType; - IDirect3DTexture9** piTexture; - switch (iType) - { + const char *szType; + IDirect3DTexture9 **piTexture; + switch (iType) { case aiTextureType_DIFFUSE: piTexture = &g_pcAsset->apcMeshes[iMesh]->piDiffuseTexture; szType = "Diffuse"; @@ -452,11 +429,10 @@ int CDisplay::AddTextureToDisplayList(unsigned int iType, szType = "Opacity"; break; }; - if (bIsExtraOpacity) { - ai_snprintf(chTemp,512,"%s %i ()",szType,iIndex+1); - } - else - ai_snprintf(chTemp,512,"%s %i (%s)",szType,iIndex+1,sz); + if (bIsExtraOpacity) { + ai_snprintf(chTemp, 512, "%s %i ()", szType, iIndex + 1); + } else + ai_snprintf(chTemp, 512, "%s %i (%s)", szType, iIndex + 1, sz); TVITEMEX tvi; TVINSERTSTRUCT sNew; @@ -467,29 +443,23 @@ int CDisplay::AddTextureToDisplayList(unsigned int iType, // find out whether this is the default texture or not - if (piTexture && *piTexture) { + if (piTexture && *piTexture) { // {9785DA94-1D96-426b-B3CB-BADC36347F5E} - static const GUID guidPrivateData = - { 0x9785da94, 0x1d96, 0x426b, + static const GUID guidPrivateData = { 0x9785da94, 0x1d96, 0x426b, { 0xb3, 0xcb, 0xba, 0xdc, 0x36, 0x34, 0x7f, 0x5e } }; uint32_t iData = 0; DWORD dwSize = 4; - (*piTexture)->GetPrivateData(guidPrivateData,&iData,&dwSize); + (*piTexture)->GetPrivateData(guidPrivateData, &iData, &dwSize); - if (0xFFFFFFFF == iData) - { + if (0xFFFFFFFF == iData) { tvi.iImage = m_aiImageList[AI_VIEW_IMGLIST_TEXTURE_INVALID]; tvi.iSelectedImage = m_aiImageList[AI_VIEW_IMGLIST_TEXTURE_INVALID]; - } - else - { + } else { tvi.iImage = m_aiImageList[AI_VIEW_IMGLIST_TEXTURE]; tvi.iSelectedImage = m_aiImageList[AI_VIEW_IMGLIST_TEXTURE]; } - } - else - { + } else { tvi.iImage = m_aiImageList[AI_VIEW_IMGLIST_TEXTURE_INVALID]; tvi.iSelectedImage = m_aiImageList[AI_VIEW_IMGLIST_TEXTURE_INVALID]; } @@ -499,10 +469,10 @@ int CDisplay::AddTextureToDisplayList(unsigned int iType, sNew.hParent = hFX; // add the item to the list - HTREEITEM hTexture = (HTREEITEM)SendMessage(GetDlgItem(g_hDlg,IDC_TREE1), - TVM_INSERTITEM, - 0, - (LPARAM)(LPTVINSERTSTRUCT)&sNew); + HTREEITEM hTexture = (HTREEITEM)SendMessage(GetDlgItem(g_hDlg, IDC_TREE1), + TVM_INSERTITEM, + 0, + (LPARAM)(LPTVINSERTSTRUCT)&sNew); // add it to the list CDisplay::TextureInfo sInfo; @@ -519,19 +489,15 @@ int CDisplay::AddTextureToDisplayList(unsigned int iType, } //------------------------------------------------------------------------------- int CDisplay::AddMaterialToDisplayList(HTREEITEM hRoot, - unsigned int iIndex) -{ + unsigned int iIndex) { ai_assert(nullptr != hRoot); - aiMaterial* pcMat = g_pcAsset->pcScene->mMaterials[iIndex]; - + aiMaterial *pcMat = g_pcAsset->pcScene->mMaterials[iIndex]; // find the first mesh using this material index unsigned int iMesh = 0; - for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i) - { - if (iIndex == g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex) - { + for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes; ++i) { + if (iIndex == g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex) { iMesh = i; break; } @@ -540,23 +506,20 @@ int CDisplay::AddMaterialToDisplayList(HTREEITEM hRoot, // use the name of the material, if possible char chTemp[512]; aiString szOut; - if (AI_SUCCESS != aiGetMaterialString(pcMat,AI_MATKEY_NAME,&szOut)) - { - ai_snprintf(chTemp,512,"Material %i",iIndex+1); - } - else - { - ai_snprintf(chTemp,512,"%s (%i)",szOut.data,iIndex+1); + if (AI_SUCCESS != aiGetMaterialString(pcMat, AI_MATKEY_NAME, &szOut)) { + ai_snprintf(chTemp, 512, "Material %i", iIndex + 1); + } else { + ai_snprintf(chTemp, 512, "%s (%i)", szOut.data, iIndex + 1); } TVITEMEXW tvi; TVINSERTSTRUCTW sNew; wchar_t tmp[512]; - int t = MultiByteToWideChar(CP_UTF8,0,chTemp,-1,tmp,512); + int t = MultiByteToWideChar(CP_UTF8, 0, chTemp, -1, tmp, 512); tvi.pszText = tmp; tvi.cchTextMax = (int)t; - tvi.mask = TVIF_TEXT | TVIF_SELECTEDIMAGE | TVIF_IMAGE | TVIF_HANDLE | TVIF_PARAM ; + tvi.mask = TVIF_TEXT | TVIF_SELECTEDIMAGE | TVIF_IMAGE | TVIF_HANDLE | TVIF_PARAM; tvi.iImage = m_aiImageList[AI_VIEW_IMGLIST_MATERIAL]; tvi.iSelectedImage = m_aiImageList[AI_VIEW_IMGLIST_MATERIAL]; tvi.lParam = (LPARAM)10; @@ -566,10 +529,10 @@ int CDisplay::AddMaterialToDisplayList(HTREEITEM hRoot, sNew.hParent = hRoot; // add the item to the list - HTREEITEM hTexture = (HTREEITEM)SendMessage(GetDlgItem(g_hDlg,IDC_TREE1), - TVM_INSERTITEMW, - 0, - (LPARAM)(LPTVINSERTSTRUCT)&sNew); + HTREEITEM hTexture = (HTREEITEM)SendMessage(GetDlgItem(g_hDlg, IDC_TREE1), + TVM_INSERTITEMW, + 0, + (LPARAM)(LPTVINSERTSTRUCT)&sNew); // for each texture in the list ... add it unsigned int iUV; @@ -577,42 +540,36 @@ int CDisplay::AddMaterialToDisplayList(HTREEITEM hRoot, aiTextureOp eOp; aiString szPath; bool bNoOpacity = true; - for (unsigned int i = 0; i <= AI_TEXTURE_TYPE_MAX;++i) - { + for (unsigned int i = 0; i <= AI_TEXTURE_TYPE_MAX; ++i) { unsigned int iNum = 0; - while (true) - { - if (AI_SUCCESS != aiGetMaterialTexture(pcMat,(aiTextureType)i,iNum, - &szPath,nullptr, &iUV,&fBlend,&eOp)) - { + while (true) { + if (AI_SUCCESS != aiGetMaterialTexture(pcMat, (aiTextureType)i, iNum, + &szPath, nullptr, &iUV, &fBlend, &eOp)) { break; } - if (aiTextureType_OPACITY == i)bNoOpacity = false; - AddTextureToDisplayList(i,iNum,&szPath,hTexture,iUV,fBlend,eOp,iMesh); + if (aiTextureType_OPACITY == i) bNoOpacity = false; + AddTextureToDisplayList(i, iNum, &szPath, hTexture, iUV, fBlend, eOp, iMesh); ++iNum; } } - AssetHelper::MeshHelper* pcMesh = g_pcAsset->apcMeshes[iMesh]; + AssetHelper::MeshHelper *pcMesh = g_pcAsset->apcMeshes[iMesh]; - if (pcMesh->piDiffuseTexture && pcMesh->piDiffuseTexture == pcMesh->piOpacityTexture && bNoOpacity) - { + if (pcMesh->piDiffuseTexture && pcMesh->piDiffuseTexture == pcMesh->piOpacityTexture && bNoOpacity) { // check whether the diffuse texture is not a default texture // {9785DA94-1D96-426b-B3CB-BADC36347F5E} - static const GUID guidPrivateData = - { 0x9785da94, 0x1d96, 0x426b, + static const GUID guidPrivateData = { 0x9785da94, 0x1d96, 0x426b, { 0xb3, 0xcb, 0xba, 0xdc, 0x36, 0x34, 0x7f, 0x5e } }; uint32_t iData = 0; DWORD dwSize = 4; - if(FAILED( pcMesh->piDiffuseTexture->GetPrivateData(guidPrivateData,&iData,&dwSize) || - 0xffffffff == iData)) - { + if (FAILED(pcMesh->piDiffuseTexture->GetPrivateData(guidPrivateData, &iData, &dwSize) || + 0xffffffff == iData)) { // seems the diffuse texture contains alpha, therefore it has been // added to the opacity channel, too. Add a special value ... AddTextureToDisplayList(aiTextureType_OPACITY | 0x40000000, - 0,&szPath,hTexture,iUV,fBlend,eOp,iMesh); + 0, &szPath, hTexture, iUV, fBlend, eOp, iMesh); } } @@ -627,34 +584,29 @@ int CDisplay::AddMaterialToDisplayList(HTREEITEM hRoot, } //------------------------------------------------------------------------------- // Expand all elements in the tree-view -int CDisplay::ExpandTree() -{ +int CDisplay::ExpandTree() { // expand all materials - for (std::vector< MaterialInfo >::iterator - i = m_asMaterials.begin(); - i != m_asMaterials.end();++i) - { - TreeView_Expand(GetDlgItem(g_hDlg,IDC_TREE1),(*i).hTreeItem,TVE_EXPAND); + for (std::vector::iterator + i = m_asMaterials.begin(); + i != m_asMaterials.end(); ++i) { + TreeView_Expand(GetDlgItem(g_hDlg, IDC_TREE1), (*i).hTreeItem, TVE_EXPAND); } // expand all nodes - for (std::vector< NodeInfo >::iterator - i = m_asNodes.begin(); - i != m_asNodes.end();++i) - { - TreeView_Expand(GetDlgItem(g_hDlg,IDC_TREE1),(*i).hTreeItem,TVE_EXPAND); + for (std::vector::iterator + i = m_asNodes.begin(); + i != m_asNodes.end(); ++i) { + TreeView_Expand(GetDlgItem(g_hDlg, IDC_TREE1), (*i).hTreeItem, TVE_EXPAND); } - TreeView_Expand(GetDlgItem(g_hDlg,IDC_TREE1),m_hRoot,TVE_EXPAND); + TreeView_Expand(GetDlgItem(g_hDlg, IDC_TREE1), m_hRoot, TVE_EXPAND); return 1; } //------------------------------------------------------------------------------- // Get image list for tree view -int CDisplay::LoadImageList(void) -{ - if (!m_hImageList) - { +int CDisplay::LoadImageList(void) { + if (!m_hImageList) { // First, create the image list we will need. // FIX: Need RGB888 color space to display all colors correctly - HIMAGELIST hIml = ImageList_Create( 16,16,ILC_COLOR24, 5, 0 ); + HIMAGELIST hIml = ImageList_Create(16, 16, ILC_COLOR24, 5, 0); // Load the bitmaps and add them to the image lists. HBITMAP hBmp = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_BFX)); @@ -678,7 +630,7 @@ int CDisplay::LoadImageList(void) DeleteObject(hBmp); // Associate the image list with the tree. - TreeView_SetImageList(GetDlgItem(g_hDlg,IDC_TREE1), hIml, TVSIL_NORMAL); + TreeView_SetImageList(GetDlgItem(g_hDlg, IDC_TREE1), hIml, TVSIL_NORMAL); m_hImageList = hIml; } @@ -686,15 +638,14 @@ int CDisplay::LoadImageList(void) } //------------------------------------------------------------------------------- // Fill tree view -int CDisplay::FillDisplayList(void) -{ +int CDisplay::FillDisplayList(void) { LoadImageList(); // Initialize the tree view window. // fill in the first entry TVITEMEX tvi; TVINSERTSTRUCT sNew; - tvi.pszText = (char*) "Model"; + tvi.pszText = (char *)"Model"; tvi.cchTextMax = (int)strlen(tvi.pszText); tvi.mask = TVIF_TEXT | TVIF_SELECTEDIMAGE | TVIF_IMAGE | TVIF_HANDLE | TVIF_STATE; tvi.state = TVIS_EXPANDED; @@ -707,21 +658,21 @@ int CDisplay::FillDisplayList(void) sNew.hParent = 0; // add the root item to the tree - m_hRoot = (HTREEITEM)SendMessage(GetDlgItem(g_hDlg,IDC_TREE1), - TVM_INSERTITEM, - 0, - (LPARAM)(LPTVINSERTSTRUCT)&sNew); + m_hRoot = (HTREEITEM)SendMessage(GetDlgItem(g_hDlg, IDC_TREE1), + TVM_INSERTITEM, + 0, + (LPARAM)(LPTVINSERTSTRUCT)&sNew); // add each loaded material to the tree - for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMaterials;++i) - AddMaterialToDisplayList(m_hRoot,i); + for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMaterials; ++i) + AddMaterialToDisplayList(m_hRoot, i); // add each mesh to the tree - for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i) - AddMeshToDisplayList(i,m_hRoot); + for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes; ++i) + AddMeshToDisplayList(i, m_hRoot); // now add all loaded nodes recursively - AddNodeToDisplayList(0,0,g_pcAsset->pcScene->mRootNode,m_hRoot); + AddNodeToDisplayList(0, 0, g_pcAsset->pcScene->mRootNode, m_hRoot); // now expand all parent nodes in the tree ExpandTree(); @@ -733,34 +684,31 @@ int CDisplay::FillDisplayList(void) } //------------------------------------------------------------------------------- // Main render loop -int CDisplay::OnRender() -{ +int CDisplay::OnRender() { // update possible animation - if( g_pcAsset) - { + if (g_pcAsset) { static double lastPlaying = 0.; - ai_assert( g_pcAsset->mAnimator); + ai_assert(g_pcAsset->mAnimator); if (g_bPlay) { - g_dCurrent += clock()/ double( CLOCKS_PER_SEC) -lastPlaying; + g_dCurrent += clock() / double(CLOCKS_PER_SEC) - lastPlaying; double time = g_dCurrent; - aiAnimation* mAnim = g_pcAsset->mAnimator->CurrentAnim(); - if( mAnim && mAnim->mDuration > 0.0) { + aiAnimation *mAnim = g_pcAsset->mAnimator->CurrentAnim(); + if (mAnim && mAnim->mDuration > 0.0) { double tps = mAnim->mTicksPerSecond ? mAnim->mTicksPerSecond : 25.f; - time = fmod( time, mAnim->mDuration/tps); - SendDlgItemMessage(g_hDlg,IDC_SLIDERANIM,TBM_SETPOS,TRUE,LPARAM(10000 * (time/(mAnim->mDuration/tps)))); + time = fmod(time, mAnim->mDuration / tps); + SendDlgItemMessage(g_hDlg, IDC_SLIDERANIM, TBM_SETPOS, TRUE, LPARAM(10000 * (time / (mAnim->mDuration / tps)))); } - g_pcAsset->mAnimator->Calculate( time ); + g_pcAsset->mAnimator->Calculate(time); lastPlaying = g_dCurrent; } } // begin the frame g_piDevice->BeginScene(); - switch (m_iViewMode) - { + switch (m_iViewMode) { case VIEWMODE_FULL: case VIEWMODE_NODE: RenderFullScene(); @@ -778,7 +726,7 @@ int CDisplay::OnRender() // present the back-buffer g_piDevice->EndScene(); - g_piDevice->Present(nullptr,nullptr,nullptr,nullptr); + g_piDevice->Present(nullptr, nullptr, nullptr, nullptr); // don't remove this, problems on some older machines (AMD timing bug) Sleep(10); @@ -786,64 +734,60 @@ int CDisplay::OnRender() } //------------------------------------------------------------------------------- // Update UI -void UpdateColorFieldsInUI() -{ - InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR1),nullptr,TRUE); - InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR2),nullptr,TRUE); - InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR3),nullptr,TRUE); +void UpdateColorFieldsInUI() { + InvalidateRect(GetDlgItem(g_hDlg, IDC_LCOLOR1), nullptr, TRUE); + InvalidateRect(GetDlgItem(g_hDlg, IDC_LCOLOR2), nullptr, TRUE); + InvalidateRect(GetDlgItem(g_hDlg, IDC_LCOLOR3), nullptr, TRUE); - UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR1)); - UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR2)); - UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR3)); + UpdateWindow(GetDlgItem(g_hDlg, IDC_LCOLOR1)); + UpdateWindow(GetDlgItem(g_hDlg, IDC_LCOLOR2)); + UpdateWindow(GetDlgItem(g_hDlg, IDC_LCOLOR3)); } //------------------------------------------------------------------------------- // FIll statistics UI -int CDisplay::FillDefaultStatistics(void) -{ - if (!g_pcAsset) - { +int CDisplay::FillDefaultStatistics(void) { + if (!g_pcAsset) { // clear all stats edit controls - SetDlgItemText(g_hDlg,IDC_EVERT,"0"); - SetDlgItemText(g_hDlg,IDC_EFACE,"0"); - SetDlgItemText(g_hDlg,IDC_EMAT,"0"); - SetDlgItemText(g_hDlg,IDC_ENODE,"0"); - SetDlgItemText(g_hDlg,IDC_ESHADER,"0"); - SetDlgItemText(g_hDlg,IDC_ETEX,"0"); + SetDlgItemText(g_hDlg, IDC_EVERT, "0"); + SetDlgItemText(g_hDlg, IDC_EFACE, "0"); + SetDlgItemText(g_hDlg, IDC_EMAT, "0"); + SetDlgItemText(g_hDlg, IDC_ENODE, "0"); + SetDlgItemText(g_hDlg, IDC_ESHADER, "0"); + SetDlgItemText(g_hDlg, IDC_ETEX, "0"); return 1; } // get the number of vertices/faces in the model unsigned int iNumVert = 0; unsigned int iNumFaces = 0; - for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i) - { + for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes; ++i) { iNumVert += g_pcAsset->pcScene->mMeshes[i]->mNumVertices; iNumFaces += g_pcAsset->pcScene->mMeshes[i]->mNumFaces; } // and fill the statistic edit controls char szOut[1024]; - ai_snprintf(szOut,1024,"%i",(int)iNumVert); - SetDlgItemText(g_hDlg,IDC_EVERT,szOut); - ai_snprintf(szOut, 1024,"%i",(int)iNumFaces); - SetDlgItemText(g_hDlg,IDC_EFACE,szOut); - ai_snprintf(szOut, 1024,"%i",(int)g_pcAsset->pcScene->mNumMaterials); - SetDlgItemText(g_hDlg,IDC_EMAT,szOut); - ai_snprintf(szOut, 1024,"%i",(int)g_pcAsset->pcScene->mNumMeshes); - SetDlgItemText(g_hDlg,IDC_EMESH,szOut); + ai_snprintf(szOut, 1024, "%i", (int)iNumVert); + SetDlgItemText(g_hDlg, IDC_EVERT, szOut); + ai_snprintf(szOut, 1024, "%i", (int)iNumFaces); + SetDlgItemText(g_hDlg, IDC_EFACE, szOut); + ai_snprintf(szOut, 1024, "%i", (int)g_pcAsset->pcScene->mNumMaterials); + SetDlgItemText(g_hDlg, IDC_EMAT, szOut); + ai_snprintf(szOut, 1024, "%i", (int)g_pcAsset->pcScene->mNumMeshes); + SetDlgItemText(g_hDlg, IDC_EMESH, szOut); // need to get the number of nodes iNumVert = 0; - GetNodeCount(g_pcAsset->pcScene->mRootNode,&iNumVert); - ai_snprintf(szOut, 1024,"%i",(int)iNumVert); - SetDlgItemText(g_hDlg,IDC_ENODEWND,szOut); + GetNodeCount(g_pcAsset->pcScene->mRootNode, &iNumVert); + ai_snprintf(szOut, 1024, "%i", (int)iNumVert); + SetDlgItemText(g_hDlg, IDC_ENODEWND, szOut); // now get the number of unique shaders generated for the asset // (even if the environment changes this number won't change) - ai_snprintf(szOut, 1024,"%i", CMaterialManager::Instance().GetShaderCount()); - SetDlgItemText(g_hDlg,IDC_ESHADER,szOut); + ai_snprintf(szOut, 1024, "%i", CMaterialManager::Instance().GetShaderCount()); + SetDlgItemText(g_hDlg, IDC_ESHADER, szOut); - sprintf(szOut,"%.5f",(float)g_fLoadTime); - SetDlgItemText(g_hDlg,IDC_ELOAD,szOut); + sprintf(szOut, "%.5f", (float)g_fLoadTime); + SetDlgItemText(g_hDlg, IDC_ELOAD, szOut); UpdateColorFieldsInUI(); UpdateWindow(g_hDlg); @@ -851,8 +795,7 @@ int CDisplay::FillDefaultStatistics(void) } //------------------------------------------------------------------------------- // Reset UI -int CDisplay::Reset(void) -{ +int CDisplay::Reset(void) { // clear all lists m_asMaterials.clear(); m_asTextures.clear(); @@ -865,32 +808,29 @@ int CDisplay::Reset(void) } //------------------------------------------------------------------------------- // reset to standard statistics view -void ShowNormalUIComponents() -{ - ShowWindow(GetDlgItem(g_hDlg,IDC_NUMNODES),SW_SHOW); - ShowWindow(GetDlgItem(g_hDlg,IDC_ENODEWND),SW_SHOW); - ShowWindow(GetDlgItem(g_hDlg,IDC_NUMSHADERS),SW_SHOW); - ShowWindow(GetDlgItem(g_hDlg,IDC_LOADTIME),SW_SHOW); - ShowWindow(GetDlgItem(g_hDlg,IDC_ESHADER),SW_SHOW); - ShowWindow(GetDlgItem(g_hDlg,IDC_ELOAD),SW_SHOW); - ShowWindow(GetDlgItem(g_hDlg,IDC_VIEWMATRIX),SW_HIDE); +void ShowNormalUIComponents() { + ShowWindow(GetDlgItem(g_hDlg, IDC_NUMNODES), SW_SHOW); + ShowWindow(GetDlgItem(g_hDlg, IDC_ENODEWND), SW_SHOW); + ShowWindow(GetDlgItem(g_hDlg, IDC_NUMSHADERS), SW_SHOW); + ShowWindow(GetDlgItem(g_hDlg, IDC_LOADTIME), SW_SHOW); + ShowWindow(GetDlgItem(g_hDlg, IDC_ESHADER), SW_SHOW); + ShowWindow(GetDlgItem(g_hDlg, IDC_ELOAD), SW_SHOW); + ShowWindow(GetDlgItem(g_hDlg, IDC_VIEWMATRIX), SW_HIDE); } //------------------------------------------------------------------------------- -int CDisplay::OnSetupNormalView() -{ - if (VIEWMODE_NODE == m_iViewMode) - { +int CDisplay::OnSetupNormalView() { + if (VIEWMODE_NODE == m_iViewMode) { ShowNormalUIComponents(); } // now ... change the meaning of the statistics fields back - SetWindowText(GetDlgItem(g_hDlg,IDC_NUMVERTS),"Vertices:"); - SetWindowText(GetDlgItem(g_hDlg,IDC_NUMNODES),"Nodes:"); - SetWindowText(GetDlgItem(g_hDlg,IDC_NUMFACES),"Faces:"); - SetWindowText(GetDlgItem(g_hDlg,IDC_NUMSHADERS),"Shaders:"); - SetWindowText(GetDlgItem(g_hDlg,IDC_NUMMATS),"Materials:"); - SetWindowText(GetDlgItem(g_hDlg,IDC_NUMMESHES),"Meshes:"); - SetWindowText(GetDlgItem(g_hDlg,IDC_LOADTIME),"Time:"); + SetWindowText(GetDlgItem(g_hDlg, IDC_NUMVERTS), "Vertices:"); + SetWindowText(GetDlgItem(g_hDlg, IDC_NUMNODES), "Nodes:"); + SetWindowText(GetDlgItem(g_hDlg, IDC_NUMFACES), "Faces:"); + SetWindowText(GetDlgItem(g_hDlg, IDC_NUMSHADERS), "Shaders:"); + SetWindowText(GetDlgItem(g_hDlg, IDC_NUMMATS), "Materials:"); + SetWindowText(GetDlgItem(g_hDlg, IDC_NUMMESHES), "Meshes:"); + SetWindowText(GetDlgItem(g_hDlg, IDC_LOADTIME), "Time:"); FillDefaultStatistics(); SetViewMode(VIEWMODE_FULL); @@ -906,46 +846,44 @@ int CDisplay::OnSetupNormalView() return 1; } //------------------------------------------------------------------------------- -int CDisplay::OnSetupNodeView(NodeInfo* pcNew) -{ +int CDisplay::OnSetupNodeView(NodeInfo *pcNew) { ai_assert(nullptr != pcNew); - if (m_pcCurrentNode == pcNew)return 2; + if (m_pcCurrentNode == pcNew) return 2; // now ... change the meaning of the statistics fields back - SetWindowText(GetDlgItem(g_hDlg,IDC_NUMVERTS),"Vertices:"); - SetWindowText(GetDlgItem(g_hDlg,IDC_NUMFACES),"Faces:"); - SetWindowText(GetDlgItem(g_hDlg,IDC_NUMMATS),"Materials:"); - SetWindowText(GetDlgItem(g_hDlg,IDC_NUMMESHES),"Meshes:"); + SetWindowText(GetDlgItem(g_hDlg, IDC_NUMVERTS), "Vertices:"); + SetWindowText(GetDlgItem(g_hDlg, IDC_NUMFACES), "Faces:"); + SetWindowText(GetDlgItem(g_hDlg, IDC_NUMMATS), "Materials:"); + SetWindowText(GetDlgItem(g_hDlg, IDC_NUMMESHES), "Meshes:"); - ShowWindow(GetDlgItem(g_hDlg,IDC_NUMNODES),SW_HIDE); - ShowWindow(GetDlgItem(g_hDlg,IDC_ENODEWND),SW_HIDE); - ShowWindow(GetDlgItem(g_hDlg,IDC_NUMSHADERS),SW_HIDE); - ShowWindow(GetDlgItem(g_hDlg,IDC_LOADTIME),SW_HIDE); - ShowWindow(GetDlgItem(g_hDlg,IDC_ESHADER),SW_HIDE); - ShowWindow(GetDlgItem(g_hDlg,IDC_ELOAD),SW_HIDE); - ShowWindow(GetDlgItem(g_hDlg,IDC_VIEWMATRIX),SW_SHOW); + ShowWindow(GetDlgItem(g_hDlg, IDC_NUMNODES), SW_HIDE); + ShowWindow(GetDlgItem(g_hDlg, IDC_ENODEWND), SW_HIDE); + ShowWindow(GetDlgItem(g_hDlg, IDC_NUMSHADERS), SW_HIDE); + ShowWindow(GetDlgItem(g_hDlg, IDC_LOADTIME), SW_HIDE); + ShowWindow(GetDlgItem(g_hDlg, IDC_ESHADER), SW_HIDE); + ShowWindow(GetDlgItem(g_hDlg, IDC_ELOAD), SW_HIDE); + ShowWindow(GetDlgItem(g_hDlg, IDC_VIEWMATRIX), SW_SHOW); char szTemp[1024]; sprintf(szTemp, - "%.2f %.2f %.2f\r\n" - "%.2f %.2f %.2f\r\n" - "%.2f %.2f %.2f\r\n" - "%.2f %.2f %.2f\r\n", - pcNew->psNode->mTransformation.a1, - pcNew->psNode->mTransformation.b1, - pcNew->psNode->mTransformation.c1, - pcNew->psNode->mTransformation.a2, - pcNew->psNode->mTransformation.b2, - pcNew->psNode->mTransformation.c2, - pcNew->psNode->mTransformation.a3, - pcNew->psNode->mTransformation.b3, - pcNew->psNode->mTransformation.c3, - pcNew->psNode->mTransformation.a4, - pcNew->psNode->mTransformation.b4, - pcNew->psNode->mTransformation.c4); - SetWindowText(GetDlgItem(g_hDlg,IDC_VIEWMATRIX),szTemp); - + "%.2f %.2f %.2f\r\n" + "%.2f %.2f %.2f\r\n" + "%.2f %.2f %.2f\r\n" + "%.2f %.2f %.2f\r\n", + pcNew->psNode->mTransformation.a1, + pcNew->psNode->mTransformation.b1, + pcNew->psNode->mTransformation.c1, + pcNew->psNode->mTransformation.a2, + pcNew->psNode->mTransformation.b2, + pcNew->psNode->mTransformation.c2, + pcNew->psNode->mTransformation.a3, + pcNew->psNode->mTransformation.b3, + pcNew->psNode->mTransformation.c3, + pcNew->psNode->mTransformation.a4, + pcNew->psNode->mTransformation.b4, + pcNew->psNode->mTransformation.c4); + SetWindowText(GetDlgItem(g_hDlg, IDC_VIEWMATRIX), szTemp); m_pcCurrentNode = pcNew; SetViewMode(VIEWMODE_NODE); @@ -953,11 +891,10 @@ int CDisplay::OnSetupNodeView(NodeInfo* pcNew) return 1; } //------------------------------------------------------------------------------- -int CDisplay::OnSetupMaterialView(MaterialInfo* pcNew) -{ +int CDisplay::OnSetupMaterialView(MaterialInfo *pcNew) { ai_assert(nullptr != pcNew); - if (m_pcCurrentMaterial == pcNew)return 2; + if (m_pcCurrentMaterial == pcNew) return 2; if (VIEWMODE_NODE == m_iViewMode) ShowNormalUIComponents(); @@ -971,32 +908,30 @@ int CDisplay::OnSetupMaterialView(MaterialInfo* pcNew) return 1; } //------------------------------------------------------------------------------- -int CDisplay::OnSetupTextureView(TextureInfo* pcNew) -{ +int CDisplay::OnSetupTextureView(TextureInfo *pcNew) { ai_assert(nullptr != pcNew); - if (this->m_pcCurrentTexture == pcNew)return 2; + if (this->m_pcCurrentTexture == pcNew) return 2; - if (VIEWMODE_NODE == this->m_iViewMode) - { + if (VIEWMODE_NODE == this->m_iViewMode) { ShowNormalUIComponents(); } - if ((aiTextureType_OPACITY | 0x40000000) == pcNew->iType) - { + if ((aiTextureType_OPACITY | 0x40000000) == pcNew->iType) { // for opacity textures display a warn message CLogDisplay::Instance().AddEntry("[INFO] This texture is not existing in the " - "original mesh",D3DCOLOR_ARGB(0xFF,0xFF,0xFF,0)); + "original mesh", + D3DCOLOR_ARGB(0xFF, 0xFF, 0xFF, 0)); CLogDisplay::Instance().AddEntry("It is a copy of the alpha channel of the first " - "diffuse texture",D3DCOLOR_ARGB(0xFF,0xFF,0xFF,0)); + "diffuse texture", + D3DCOLOR_ARGB(0xFF, 0xFF, 0xFF, 0)); } // check whether the pattern background effect is supported - if (g_sCaps.PixelShaderVersion < D3DPS_VERSION(3,0)) - { + if (g_sCaps.PixelShaderVersion < D3DPS_VERSION(3, 0)) { CLogDisplay::Instance().AddEntry("[WARN] The background shader won't work " - "on your system, it required PS 3.0 hardware. A default color is used ...", - D3DCOLOR_ARGB(0xFF,0xFF,0x00,0)); + "on your system, it required PS 3.0 hardware. A default color is used ...", + D3DCOLOR_ARGB(0xFF, 0xFF, 0x00, 0)); } this->m_fTextureZoom = 1000.0f; @@ -1006,38 +941,37 @@ int CDisplay::OnSetupTextureView(TextureInfo* pcNew) this->SetViewMode(VIEWMODE_TEXTURE); // now ... change the meaning of the statistics fields - SetWindowText(GetDlgItem(g_hDlg,IDC_NUMVERTS),"Width:"); - SetWindowText(GetDlgItem(g_hDlg,IDC_NUMNODES),"Height:"); - SetWindowText(GetDlgItem(g_hDlg,IDC_NUMFACES),"Format:"); - SetWindowText(GetDlgItem(g_hDlg,IDC_NUMSHADERS),"MIPs:"); - SetWindowText(GetDlgItem(g_hDlg,IDC_NUMMATS),"UV:"); - SetWindowText(GetDlgItem(g_hDlg,IDC_NUMMESHES),"Blend:"); - SetWindowText(GetDlgItem(g_hDlg,IDC_LOADTIME),"Op:"); + SetWindowText(GetDlgItem(g_hDlg, IDC_NUMVERTS), "Width:"); + SetWindowText(GetDlgItem(g_hDlg, IDC_NUMNODES), "Height:"); + SetWindowText(GetDlgItem(g_hDlg, IDC_NUMFACES), "Format:"); + SetWindowText(GetDlgItem(g_hDlg, IDC_NUMSHADERS), "MIPs:"); + SetWindowText(GetDlgItem(g_hDlg, IDC_NUMMATS), "UV:"); + SetWindowText(GetDlgItem(g_hDlg, IDC_NUMMESHES), "Blend:"); + SetWindowText(GetDlgItem(g_hDlg, IDC_LOADTIME), "Op:"); // and fill them with data D3DSURFACE_DESC sDesc; if (pcNew->piTexture && *pcNew->piTexture) { - (*pcNew->piTexture)->GetLevelDesc(0,&sDesc); + (*pcNew->piTexture)->GetLevelDesc(0, &sDesc); char szTemp[128]; - sprintf(szTemp,"%i",sDesc.Width); - SetWindowText(GetDlgItem(g_hDlg,IDC_EVERT),szTemp); + sprintf(szTemp, "%i", sDesc.Width); + SetWindowText(GetDlgItem(g_hDlg, IDC_EVERT), szTemp); - sprintf(szTemp,"%i",sDesc.Height); - SetWindowText(GetDlgItem(g_hDlg,IDC_ENODEWND),szTemp); + sprintf(szTemp, "%i", sDesc.Height); + SetWindowText(GetDlgItem(g_hDlg, IDC_ENODEWND), szTemp); - sprintf(szTemp,"%i",(*pcNew->piTexture)->GetLevelCount()); - SetWindowText(GetDlgItem(g_hDlg,IDC_ESHADER),szTemp); + sprintf(szTemp, "%i", (*pcNew->piTexture)->GetLevelCount()); + SetWindowText(GetDlgItem(g_hDlg, IDC_ESHADER), szTemp); - sprintf(szTemp,"%u",pcNew->iUV); - SetWindowText(GetDlgItem(g_hDlg,IDC_EMAT),szTemp); + sprintf(szTemp, "%u", pcNew->iUV); + SetWindowText(GetDlgItem(g_hDlg, IDC_EMAT), szTemp); - sprintf(szTemp,"%f",pcNew->fBlend); - SetWindowText(GetDlgItem(g_hDlg,IDC_EMESH),szTemp); + sprintf(szTemp, "%f", pcNew->fBlend); + SetWindowText(GetDlgItem(g_hDlg, IDC_EMESH), szTemp); - const char* szOp; - switch (pcNew->eOp) - { + const char *szOp; + switch (pcNew->eOp) { case aiTextureOp_Add: szOp = "add"; break; @@ -1053,33 +987,30 @@ int CDisplay::OnSetupTextureView(TextureInfo* pcNew) case aiTextureOp_SmoothAdd: szOp = "addsmooth"; break; - default: + default: szOp = "mul"; break; }; - SetWindowText(GetDlgItem(g_hDlg,IDC_ELOAD),szOp); + SetWindowText(GetDlgItem(g_hDlg, IDC_ELOAD), szOp); // NOTE: Format is always ARGB8888 since other formats are // converted to this format ... - SetWindowText(GetDlgItem(g_hDlg,IDC_EFACE),"ARGB8"); + SetWindowText(GetDlgItem(g_hDlg, IDC_EFACE), "ARGB8"); // check whether this is the default texture - if (pcNew->piTexture) - { + if (pcNew->piTexture) { // {9785DA94-1D96-426b-B3CB-BADC36347F5E} - static const GUID guidPrivateData = - { 0x9785da94, 0x1d96, 0x426b, - { 0xb3, 0xcb, 0xba, 0xdc, 0x36, 0x34, 0x7f, 0x5e } }; + static const GUID guidPrivateData = { 0x9785da94, 0x1d96, 0x426b, + { 0xb3, 0xcb, 0xba, 0xdc, 0x36, 0x34, 0x7f, 0x5e } }; uint32_t iData = 0; DWORD dwSize = 4; - (*pcNew->piTexture)->GetPrivateData(guidPrivateData,&iData,&dwSize); + (*pcNew->piTexture)->GetPrivateData(guidPrivateData, &iData, &dwSize); - if (0xFFFFFFFF == iData) - { + if (0xFFFFFFFF == iData) { CLogDisplay::Instance().AddEntry("[ERROR] Texture could not be loaded. " - "The displayed texture is a default texture", - D3DCOLOR_ARGB(0xFF,0xFF,0,0)); + "The displayed texture is a default texture", + D3DCOLOR_ARGB(0xFF, 0xFF, 0, 0)); return 0; } } @@ -1090,29 +1021,28 @@ int CDisplay::OnSetupTextureView(TextureInfo* pcNew) return 1; } //------------------------------------------------------------------------------- -int CDisplay::OnSetup(HTREEITEM p_hTreeItem) -{ +int CDisplay::OnSetup(HTREEITEM p_hTreeItem) { // search in our list for the item - union { - TextureInfo* pcNew; - NodeInfo* pcNew2; - MaterialInfo* pcNew3; + union { + TextureInfo *pcNew; + NodeInfo *pcNew2; + MaterialInfo *pcNew3; }; pcNew = nullptr; - for (std::vector::iterator i = m_asTextures.begin();i != m_asTextures.end();++i){ - if (p_hTreeItem == (*i).hTreeItem) { + for (std::vector::iterator i = m_asTextures.begin(); i != m_asTextures.end(); ++i) { + if (p_hTreeItem == (*i).hTreeItem) { pcNew = &(*i); break; } } - if (pcNew) { + if (pcNew) { return OnSetupTextureView(pcNew); } // search the node list - for (std::vector::iterator i = m_asNodes.begin(); i != m_asNodes.end();++i){ - if (p_hTreeItem == (*i).hTreeItem) { + for (std::vector::iterator i = m_asNodes.begin(); i != m_asNodes.end(); ++i) { + if (p_hTreeItem == (*i).hTreeItem) { pcNew2 = &(*i); break; } @@ -1122,8 +1052,8 @@ int CDisplay::OnSetup(HTREEITEM p_hTreeItem) } // search the material list - for (std::vector::iterator i = m_asMaterials.begin();i != m_asMaterials.end();++i){ - if (p_hTreeItem == (*i).hTreeItem){ + for (std::vector::iterator i = m_asMaterials.begin(); i != m_asMaterials.end(); ++i) { + if (p_hTreeItem == (*i).hTreeItem) { pcNew3 = &(*i); break; } @@ -1134,49 +1064,43 @@ int CDisplay::OnSetup(HTREEITEM p_hTreeItem) return OnSetupNormalView(); } //------------------------------------------------------------------------------- -int CDisplay::ShowTreeViewContextMenu(HTREEITEM hItem) -{ +int CDisplay::ShowTreeViewContextMenu(HTREEITEM hItem) { ai_assert(nullptr != hItem); HMENU hDisplay = nullptr; // search in our list for the item - TextureInfo* pcNew = nullptr; + TextureInfo *pcNew = nullptr; for (std::vector::iterator - i = m_asTextures.begin(); - i != m_asTextures.end();++i) - { - if (hItem == (*i).hTreeItem) { + i = m_asTextures.begin(); + i != m_asTextures.end(); ++i) { + if (hItem == (*i).hTreeItem) { pcNew = &(*i); break; } } - if (pcNew) - { - HMENU hMenu = LoadMenu(g_hInstance,MAKEINTRESOURCE(IDR_TXPOPUP)); - hDisplay = GetSubMenu(hMenu,0); + if (pcNew) { + HMENU hMenu = LoadMenu(g_hInstance, MAKEINTRESOURCE(IDR_TXPOPUP)); + hDisplay = GetSubMenu(hMenu, 0); } // search in the material list for the item - MaterialInfo* pcNew2 = nullptr; + MaterialInfo *pcNew2 = nullptr; for (std::vector::iterator - i = m_asMaterials.begin(); - i != m_asMaterials.end();++i) - { - if (hItem == (*i).hTreeItem) { + i = m_asMaterials.begin(); + i != m_asMaterials.end(); ++i) { + if (hItem == (*i).hTreeItem) { pcNew2 = &(*i); break; } } - if (pcNew2) - { - HMENU hMenu = LoadMenu(g_hInstance,MAKEINTRESOURCE(IDR_MATPOPUP)); - hDisplay = GetSubMenu(hMenu,0); + if (pcNew2) { + HMENU hMenu = LoadMenu(g_hInstance, MAKEINTRESOURCE(IDR_MATPOPUP)); + hDisplay = GetSubMenu(hMenu, 0); } - if (nullptr != hDisplay) - { + if (nullptr != hDisplay) { // select this entry (this should all OnSetup()) - TreeView_Select(GetDlgItem(g_hDlg,IDC_TREE1),hItem,TVGN_CARET); + TreeView_Select(GetDlgItem(g_hDlg, IDC_TREE1), hItem, TVGN_CARET); // FIX: Render the scene once that the correct texture/material // is displayed while the context menu is active @@ -1185,59 +1109,49 @@ int CDisplay::ShowTreeViewContextMenu(HTREEITEM hItem) POINT sPoint; GetCursorPos(&sPoint); TrackPopupMenu(hDisplay, TPM_LEFTALIGN, sPoint.x, sPoint.y, 0, - g_hDlg,nullptr); + g_hDlg, nullptr); } return 1; } //------------------------------------------------------------------------------- -int CDisplay::HandleTreeViewPopup(WPARAM wParam,LPARAM lParam) -{ +int CDisplay::HandleTreeViewPopup(WPARAM wParam, LPARAM lParam) { // get the current selected material std::vector apclrOut; - const char* szMatKey = ""; + const char *szMatKey = ""; - switch (LOWORD(wParam)) - { + switch (LOWORD(wParam)) { case ID_SOLONG_CLEARDIFFUSECOLOR: - for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i) - { - if (this->m_pcCurrentMaterial->iIndex == g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex) - { - apclrOut.push_back( Info( &g_pcAsset->apcMeshes[i]->vDiffuseColor, - g_pcAsset->apcMeshes[i],"DIFFUSE_COLOR")); + for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes; ++i) { + if (this->m_pcCurrentMaterial->iIndex == g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex) { + apclrOut.push_back(Info(&g_pcAsset->apcMeshes[i]->vDiffuseColor, + g_pcAsset->apcMeshes[i], "DIFFUSE_COLOR")); } } szMatKey = "$clr.diffuse"; break; case ID_SOLONG_CLEARSPECULARCOLOR: - for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i) - { - if (this->m_pcCurrentMaterial->iIndex == g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex) - { - apclrOut.push_back( Info( &g_pcAsset->apcMeshes[i]->vSpecularColor, - g_pcAsset->apcMeshes[i],"SPECULAR_COLOR")); + for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes; ++i) { + if (this->m_pcCurrentMaterial->iIndex == g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex) { + apclrOut.push_back(Info(&g_pcAsset->apcMeshes[i]->vSpecularColor, + g_pcAsset->apcMeshes[i], "SPECULAR_COLOR")); } } szMatKey = "$clr.specular"; break; case ID_SOLONG_CLEARAMBIENTCOLOR: - for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i) - { - if (this->m_pcCurrentMaterial->iIndex == g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex) - { - apclrOut.push_back( Info( &g_pcAsset->apcMeshes[i]->vAmbientColor, - g_pcAsset->apcMeshes[i],"AMBIENT_COLOR")); + for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes; ++i) { + if (this->m_pcCurrentMaterial->iIndex == g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex) { + apclrOut.push_back(Info(&g_pcAsset->apcMeshes[i]->vAmbientColor, + g_pcAsset->apcMeshes[i], "AMBIENT_COLOR")); } } szMatKey = "$clr.ambient"; break; case ID_SOLONG_CLEAREMISSIVECOLOR: - for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i) - { - if (this->m_pcCurrentMaterial->iIndex == g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex) - { - apclrOut.push_back( Info( &g_pcAsset->apcMeshes[i]->vEmissiveColor, - g_pcAsset->apcMeshes[i],"EMISSIVE_COLOR")); + for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes; ++i) { + if (this->m_pcCurrentMaterial->iIndex == g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex) { + apclrOut.push_back(Info(&g_pcAsset->apcMeshes[i]->vEmissiveColor, + g_pcAsset->apcMeshes[i], "EMISSIVE_COLOR")); } } szMatKey = "$clr.emissive"; @@ -1245,20 +1159,19 @@ int CDisplay::HandleTreeViewPopup(WPARAM wParam,LPARAM lParam) default: // let the next function do this ... no spaghetti code ;-) - HandleTreeViewPopup2(wParam,lParam); + HandleTreeViewPopup2(wParam, lParam); }; - if (!apclrOut.empty()) - { - aiColor4D clrOld = *((aiColor4D*)(apclrOut.front().pclrColor)); + if (!apclrOut.empty()) { + aiColor4D clrOld = *((aiColor4D *)(apclrOut.front().pclrColor)); CHOOSECOLOR clr; clr.lStructSize = sizeof(CHOOSECOLOR); clr.hwndOwner = g_hDlg; clr.Flags = CC_RGBINIT | CC_FULLOPEN; clr.rgbResult = RGB( - clamp(clrOld.r * 255.0f), - clamp(clrOld.g * 255.0f), - clamp(clrOld.b * 255.0f)); + clamp(clrOld.r * 255.0f), + clamp(clrOld.g * 255.0f), + clamp(clrOld.b * 255.0f)); clr.lpCustColors = g_aclCustomColors; clr.lpfnHook = nullptr; clr.lpTemplateName = nullptr; @@ -1266,76 +1179,66 @@ int CDisplay::HandleTreeViewPopup(WPARAM wParam,LPARAM lParam) ChooseColor(&clr); - clrOld.r = (float)(((unsigned int)clr.rgbResult) & 0xFF) / 255.0f; - clrOld.g = (float)(((unsigned int)clr.rgbResult >> 8) & 0xFF) / 255.0f; + clrOld.r = (float)(((unsigned int)clr.rgbResult) & 0xFF) / 255.0f; + clrOld.g = (float)(((unsigned int)clr.rgbResult >> 8) & 0xFF) / 255.0f; clrOld.b = (float)(((unsigned int)clr.rgbResult >> 16) & 0xFF) / 255.0f; // update the color values in the mesh instances and // update all shaders ... for (std::vector::iterator - i = apclrOut.begin(); - i != apclrOut.end();++i) - { - *((*i).pclrColor) = *((D3DXVECTOR4*)&clrOld); - if (!(*i).pMesh->bSharedFX) - { - (*i).pMesh->piEffect->SetVector((*i).szShaderParam,(*i).pclrColor); + i = apclrOut.begin(); + i != apclrOut.end(); ++i) { + *((*i).pclrColor) = *((D3DXVECTOR4 *)&clrOld); + if (!(*i).pMesh->bSharedFX) { + (*i).pMesh->piEffect->SetVector((*i).szShaderParam, (*i).pclrColor); } } // change the material key ... - aiMaterial* pcMat = (aiMaterial*)g_pcAsset->pcScene->mMaterials[ - this->m_pcCurrentMaterial->iIndex]; - pcMat->AddProperty(&clrOld,1,szMatKey,0,0); + aiMaterial *pcMat = (aiMaterial *)g_pcAsset->pcScene->mMaterials[this->m_pcCurrentMaterial->iIndex]; + pcMat->AddProperty(&clrOld, 1, szMatKey, 0, 0); if (ID_SOLONG_CLEARSPECULARCOLOR == LOWORD(wParam) && - aiShadingMode_Gouraud == apclrOut.front().pMesh->eShadingMode) - { + aiShadingMode_Gouraud == apclrOut.front().pMesh->eShadingMode) { CLogDisplay::Instance().AddEntry("[INFO] You have just changed the specular " - "material color",D3DCOLOR_ARGB(0xFF,0xFF,0xFF,0)); + "material color", + D3DCOLOR_ARGB(0xFF, 0xFF, 0xFF, 0)); CLogDisplay::Instance().AddEntry( - "This is great, especially since there is currently no specular shading", - D3DCOLOR_ARGB(0xFF,0xFF,0xFF,0)); + "This is great, especially since there is currently no specular shading", + D3DCOLOR_ARGB(0xFF, 0xFF, 0xFF, 0)); } } return 1; } //------------------------------------------------------------------------------- -int CALLBACK TreeViewCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) -{ - if (lParamSort == lParam1)return -1; - if (lParamSort == lParam2)return 1; +int CALLBACK TreeViewCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { + if (lParamSort == lParam1) return -1; + if (lParamSort == lParam2) return 1; return 0; } //------------------------------------------------------------------------------- -int CDisplay::HandleTreeViewPopup2(WPARAM wParam,LPARAM /*lParam*/) -{ +int CDisplay::HandleTreeViewPopup2(WPARAM wParam, LPARAM /*lParam*/) { char szFileName[MAX_PATH]; DWORD dwTemp = MAX_PATH; - switch (LOWORD(wParam)) - { - case ID_HEY_REPLACE: - { + switch (LOWORD(wParam)) { + case ID_HEY_REPLACE: { // get a path to a new texture - if(ERROR_SUCCESS != RegQueryValueEx(g_hRegistry,"ReplaceTextureSrc",nullptr,nullptr, - (BYTE*)szFileName,&dwTemp)) - { + if (ERROR_SUCCESS != RegQueryValueEx(g_hRegistry, "ReplaceTextureSrc", nullptr, nullptr, + (BYTE *)szFileName, &dwTemp)) { // Key was not found. Use C: - strcpy(szFileName,""); - } - else - { + strcpy(szFileName, ""); + } else { // need to remove the file name - char* sz = strrchr(szFileName,'\\'); + char *sz = strrchr(szFileName, '\\'); if (!sz) - sz = strrchr(szFileName,'/'); + sz = strrchr(szFileName, '/'); if (sz) *sz = 0; } OPENFILENAME sFilename1 = { sizeof(OPENFILENAME), - g_hDlg,GetModuleHandle(nullptr), + g_hDlg, GetModuleHandle(nullptr), "Textures\0*.png;*.dds;*.tga;*.bmp;*.tif;*.ppm;*.ppx;*.jpg;*.jpeg;*.exr\0*.*\0", nullptr, 0, 1, szFileName, MAX_PATH, nullptr, 0, nullptr, @@ -1343,165 +1246,152 @@ int CDisplay::HandleTreeViewPopup2(WPARAM wParam,LPARAM /*lParam*/) OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_NOCHANGEDIR, 0, 1, ".jpg", 0, nullptr, nullptr }; - if(GetOpenFileName(&sFilename1) == 0) return 0; + if (GetOpenFileName(&sFilename1) == 0) return 0; // Now store the file in the registry - RegSetValueExA(g_hRegistry,"ReplaceTextureSrc",0,REG_SZ,(const BYTE*)szFileName,MAX_PATH); + RegSetValueExA(g_hRegistry, "ReplaceTextureSrc", 0, REG_SZ, (const BYTE *)szFileName, MAX_PATH); this->ReplaceCurrentTexture(szFileName); - } + } return 1; - case ID_HEY_EXPORT: - { - if(ERROR_SUCCESS != RegQueryValueEx(g_hRegistry,"TextureExportDest",nullptr,nullptr, - (BYTE*)szFileName,&dwTemp)) - { + case ID_HEY_EXPORT: { + if (ERROR_SUCCESS != RegQueryValueEx(g_hRegistry, "TextureExportDest", nullptr, nullptr, + (BYTE *)szFileName, &dwTemp)) { // Key was not found. Use C: - strcpy(szFileName,""); - } - else - { + strcpy(szFileName, ""); + } else { // need to remove the file name - char* sz = strrchr(szFileName,'\\'); + char *sz = strrchr(szFileName, '\\'); if (!sz) - sz = strrchr(szFileName,'/'); + sz = strrchr(szFileName, '/'); if (sz) *sz = 0; } OPENFILENAME sFilename1 = { sizeof(OPENFILENAME), - g_hDlg,GetModuleHandle(nullptr), + g_hDlg, GetModuleHandle(nullptr), "Textures\0*.png;*.dds;*.bmp;*.tif;*.pfm;*.jpg;*.jpeg;*.hdr\0*.*\0", nullptr, 0, 1, szFileName, MAX_PATH, nullptr, 0, nullptr, "Export texture to file", OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_NOCHANGEDIR, 0, 1, ".png", 0, nullptr, nullptr }; - if(GetSaveFileName(&sFilename1) == 0) return 0; + if (GetSaveFileName(&sFilename1) == 0) return 0; // Now store the file in the registry - RegSetValueExA(g_hRegistry,"TextureExportDest",0,REG_SZ,(const BYTE*)szFileName,MAX_PATH); + RegSetValueExA(g_hRegistry, "TextureExportDest", 0, REG_SZ, (const BYTE *)szFileName, MAX_PATH); // determine the file format ... D3DXIMAGE_FILEFORMAT eFormat = D3DXIFF_PNG; - const char* sz = strrchr(szFileName,'.'); - if (sz) - { + const char *sz = strrchr(szFileName, '.'); + if (sz) { ++sz; - if (0 == Assimp::ASSIMP_stricmp(sz,"pfm"))eFormat = D3DXIFF_PFM; - else if (0 == Assimp::ASSIMP_stricmp(sz,"dds"))eFormat = D3DXIFF_DDS; - else if (0 == Assimp::ASSIMP_stricmp(sz,"jpg"))eFormat = D3DXIFF_JPG; - else if (0 == Assimp::ASSIMP_stricmp(sz,"jpeg"))eFormat = D3DXIFF_JPG; - else if (0 == Assimp::ASSIMP_stricmp(sz,"hdr"))eFormat = D3DXIFF_HDR; - else if (0 == Assimp::ASSIMP_stricmp(sz,"bmp"))eFormat = D3DXIFF_BMP; + if (0 == Assimp::ASSIMP_stricmp(sz, "pfm")) + eFormat = D3DXIFF_PFM; + else if (0 == Assimp::ASSIMP_stricmp(sz, "dds")) + eFormat = D3DXIFF_DDS; + else if (0 == Assimp::ASSIMP_stricmp(sz, "jpg")) + eFormat = D3DXIFF_JPG; + else if (0 == Assimp::ASSIMP_stricmp(sz, "jpeg")) + eFormat = D3DXIFF_JPG; + else if (0 == Assimp::ASSIMP_stricmp(sz, "hdr")) + eFormat = D3DXIFF_HDR; + else if (0 == Assimp::ASSIMP_stricmp(sz, "bmp")) + eFormat = D3DXIFF_BMP; } // get a pointer to the first surface of the current texture - IDirect3DSurface9* pi = nullptr; - (*this->m_pcCurrentTexture->piTexture)->GetSurfaceLevel(0,&pi); - if(!pi || FAILED(D3DXSaveSurfaceToFile(szFileName,eFormat,pi,nullptr,nullptr))) - { + IDirect3DSurface9 *pi = nullptr; + (*this->m_pcCurrentTexture->piTexture)->GetSurfaceLevel(0, &pi); + if (!pi || FAILED(D3DXSaveSurfaceToFile(szFileName, eFormat, pi, nullptr, nullptr))) { CLogDisplay::Instance().AddEntry("[ERROR] Unable to export texture", - D3DCOLOR_ARGB(0xFF,0xFF,0,0)); - } - else - { + D3DCOLOR_ARGB(0xFF, 0xFF, 0, 0)); + } else { CLogDisplay::Instance().AddEntry("[INFO] The texture has been exported", - D3DCOLOR_ARGB(0xFF,0xFF,0xFF,0)); - } - if(pi)pi->Release(); + D3DCOLOR_ARGB(0xFF, 0xFF, 0xFF, 0)); } + if (pi) pi->Release(); + } return 1; - case ID_HEY_REMOVE: - { + case ID_HEY_REMOVE: { - if(IDYES != MessageBox(g_hDlg,"To recover the texture you need to reload the model. Do you wish to continue?", - "Remove texture",MB_YESNO)) { + if (IDYES != MessageBox(g_hDlg, "To recover the texture you need to reload the model. Do you wish to continue?", + "Remove texture", MB_YESNO)) { return 1; } - aiMaterial* pcMat = (aiMaterial*)g_pcAsset->pcScene->mMaterials[ - m_pcCurrentTexture->iMatIndex]; + aiMaterial *pcMat = (aiMaterial *)g_pcAsset->pcScene->mMaterials[m_pcCurrentTexture->iMatIndex]; unsigned int s; - if (m_pcCurrentTexture->iType == (aiTextureType_OPACITY | 0x40000000)) - { + if (m_pcCurrentTexture->iType == (aiTextureType_OPACITY | 0x40000000)) { // set a special property to indicate that no alpha channel is required int iVal = 1; - pcMat->AddProperty(&iVal,1,"no_a_from_d",0,0); + pcMat->AddProperty(&iVal, 1, "no_a_from_d", 0, 0); s = aiTextureType_OPACITY; - } - else s = m_pcCurrentTexture->iType; - pcMat->RemoveProperty(AI_MATKEY_TEXTURE(m_pcCurrentTexture->iType,0)); + } else + s = m_pcCurrentTexture->iType; + pcMat->RemoveProperty(AI_MATKEY_TEXTURE(m_pcCurrentTexture->iType, 0)); // need to update all meshes associated with this material - for (unsigned int i = 0;i < g_pcAsset->pcScene->mNumMeshes;++i) - { - if (m_pcCurrentTexture->iMatIndex == g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex) - { + for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes; ++i) { + if (m_pcCurrentTexture->iMatIndex == g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex) { CMaterialManager::Instance().DeleteMaterial(g_pcAsset->apcMeshes[i]); - CMaterialManager::Instance().CreateMaterial(g_pcAsset->apcMeshes[i],g_pcAsset->pcScene->mMeshes[i]); + CMaterialManager::Instance().CreateMaterial(g_pcAsset->apcMeshes[i], g_pcAsset->pcScene->mMeshes[i]); } } // find the corresponding MaterialInfo structure const unsigned int iMatIndex = m_pcCurrentTexture->iMatIndex; for (std::vector::iterator - a = m_asMaterials.begin(); - a != m_asMaterials.end();++a) - { - if (iMatIndex == (*a).iIndex) - { + a = m_asMaterials.begin(); + a != m_asMaterials.end(); ++a) { + if (iMatIndex == (*a).iIndex) { // good news. we will also need to find all other textures // associated with this item ... for (std::vector::iterator - n = m_asTextures.begin(); - n != m_asTextures.end();++n) - { - if ((*n).iMatIndex == iMatIndex) - { - n = m_asTextures.erase(n); - if (m_asTextures.end() == n)break; + n = m_asTextures.begin(); + n != m_asTextures.end(); ++n) { + if ((*n).iMatIndex == iMatIndex) { + n = m_asTextures.erase(n); + if (m_asTextures.end() == n) break; } } // delete this material from all lists ... - TreeView_DeleteItem(GetDlgItem(g_hDlg,IDC_TREE1),(*a).hTreeItem); + TreeView_DeleteItem(GetDlgItem(g_hDlg, IDC_TREE1), (*a).hTreeItem); this->m_asMaterials.erase(a); break; } } // add the new material to the list and make sure it will be fully expanded - AddMaterialToDisplayList(m_hRoot,iMatIndex); + AddMaterialToDisplayList(m_hRoot, iMatIndex); HTREEITEM hNewItem = m_asMaterials.back().hTreeItem; - TreeView_Expand(GetDlgItem(g_hDlg,IDC_TREE1),hNewItem,TVE_EXPAND); + TreeView_Expand(GetDlgItem(g_hDlg, IDC_TREE1), hNewItem, TVE_EXPAND); // we need to sort the list, materials come first, then nodes TVSORTCB sSort; sSort.hParent = m_hRoot; sSort.lParam = 10; sSort.lpfnCompare = &TreeViewCompareFunc; - TreeView_SortChildrenCB(GetDlgItem(g_hDlg,IDC_TREE1),&sSort,0); + TreeView_SortChildrenCB(GetDlgItem(g_hDlg, IDC_TREE1), &sSort, 0); // the texture was selected, but the silly user has just deleted it // ... go back to normal viewing mode - TreeView_Select(GetDlgItem(g_hDlg,IDC_TREE1),m_hRoot,TVGN_CARET); + TreeView_Select(GetDlgItem(g_hDlg, IDC_TREE1), m_hRoot, TVGN_CARET); return 1; - } + } } return 0; } //------------------------------------------------------------------------------- // Setup stereo view -int CDisplay::SetupStereoView() -{ - if (nullptr != g_pcAsset && nullptr != g_pcAsset->pcScene->mRootNode) - { +int CDisplay::SetupStereoView() { + if (nullptr != g_pcAsset && nullptr != g_pcAsset->pcScene->mRootNode) { // enable the RED, GREEN and ALPHA channels g_piDevice->SetRenderState(D3DRS_COLORWRITEENABLE, - D3DCOLORWRITEENABLE_RED | - D3DCOLORWRITEENABLE_ALPHA | - D3DCOLORWRITEENABLE_GREEN); + D3DCOLORWRITEENABLE_RED | + D3DCOLORWRITEENABLE_ALPHA | + D3DCOLORWRITEENABLE_GREEN); // move the camera a little bit to the left g_sCamera.vPos -= g_sCamera.vRight * 0.03f; @@ -1510,87 +1400,80 @@ int CDisplay::SetupStereoView() } //------------------------------------------------------------------------------- // Do the actual rendering pass for the stereo view -int CDisplay::RenderStereoView(const aiMatrix4x4& m) -{ +int CDisplay::RenderStereoView(const aiMatrix4x4 &m) { // and rerender the scene - if (nullptr != g_pcAsset && nullptr != g_pcAsset->pcScene->mRootNode) - { + if (nullptr != g_pcAsset && nullptr != g_pcAsset->pcScene->mRootNode) { // enable the BLUE, GREEN and ALPHA channels g_piDevice->SetRenderState(D3DRS_COLORWRITEENABLE, - D3DCOLORWRITEENABLE_GREEN | - D3DCOLORWRITEENABLE_ALPHA | - D3DCOLORWRITEENABLE_BLUE); + D3DCOLORWRITEENABLE_GREEN | + D3DCOLORWRITEENABLE_ALPHA | + D3DCOLORWRITEENABLE_BLUE); // clear the z-buffer - g_piDevice->Clear(0,nullptr,D3DCLEAR_ZBUFFER,0,1.0f,0); + g_piDevice->Clear(0, nullptr, D3DCLEAR_ZBUFFER, 0, 1.0f, 0); // move the camera a little bit to the right g_sCamera.vPos += g_sCamera.vRight * 0.06f; - RenderNode(g_pcAsset->pcScene->mRootNode,m,false); - g_piDevice->SetRenderState(D3DRS_ZWRITEENABLE,FALSE); - RenderNode(g_pcAsset->pcScene->mRootNode,m,true); - g_piDevice->SetRenderState(D3DRS_ZWRITEENABLE,TRUE); + RenderNode(g_pcAsset->pcScene->mRootNode, m, false); + g_piDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + RenderNode(g_pcAsset->pcScene->mRootNode, m, true); + g_piDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); // (move back to the original position) g_sCamera.vPos -= g_sCamera.vRight * 0.03f; // reenable all channels g_piDevice->SetRenderState(D3DRS_COLORWRITEENABLE, - D3DCOLORWRITEENABLE_RED | - D3DCOLORWRITEENABLE_GREEN | - D3DCOLORWRITEENABLE_ALPHA | - D3DCOLORWRITEENABLE_BLUE); + D3DCOLORWRITEENABLE_RED | + D3DCOLORWRITEENABLE_GREEN | + D3DCOLORWRITEENABLE_ALPHA | + D3DCOLORWRITEENABLE_BLUE); } return 1; } //------------------------------------------------------------------------------- // Process input for the texture view -int CDisplay::HandleInputTextureView() -{ +int CDisplay::HandleInputTextureView() { HandleMouseInputTextureView(); HandleKeyboardInputTextureView(); return 1; } //------------------------------------------------------------------------------- // Get input for the current state -int CDisplay::HandleInput() -{ - if(CBackgroundPainter::TEXTURE_CUBE == CBackgroundPainter::Instance().GetMode()) +int CDisplay::HandleInput() { + if (CBackgroundPainter::TEXTURE_CUBE == CBackgroundPainter::Instance().GetMode()) HandleMouseInputSkyBox(); // handle input commands HandleMouseInputLightRotate(); HandleMouseInputLightIntensityAndColor(); - if(g_bFPSView) - { + if (g_bFPSView) { HandleMouseInputFPS(); HandleKeyboardInputFPS(); - } - else HandleMouseInputLocal(); + } else + HandleMouseInputLocal(); // compute auto rotation depending on the time which has passed - if (g_sOptions.bRotate) - { + if (g_sOptions.bRotate) { aiMatrix4x4 mMat; - D3DXMatrixRotationYawPitchRoll((D3DXMATRIX*)&mMat, - g_vRotateSpeed.x * g_fElpasedTime, - g_vRotateSpeed.y * g_fElpasedTime, - g_vRotateSpeed.z * g_fElpasedTime); + D3DXMatrixRotationYawPitchRoll((D3DXMATRIX *)&mMat, + g_vRotateSpeed.x * g_fElpasedTime, + g_vRotateSpeed.y * g_fElpasedTime, + g_vRotateSpeed.z * g_fElpasedTime); g_mWorldRotate = g_mWorldRotate * mMat; } // Handle rotations of light source(s) - if (g_sOptions.bLightRotate) - { + if (g_sOptions.bLightRotate) { aiMatrix4x4 mMat; - D3DXMatrixRotationYawPitchRoll((D3DXMATRIX*)&mMat, - g_vRotateSpeed.x * g_fElpasedTime * 0.5f, - g_vRotateSpeed.y * g_fElpasedTime * 0.5f, - g_vRotateSpeed.z * g_fElpasedTime * 0.5f); + D3DXMatrixRotationYawPitchRoll((D3DXMATRIX *)&mMat, + g_vRotateSpeed.x * g_fElpasedTime * 0.5f, + g_vRotateSpeed.y * g_fElpasedTime * 0.5f, + g_vRotateSpeed.z * g_fElpasedTime * 0.5f); - D3DXVec3TransformNormal((D3DXVECTOR3*)&g_avLightDirs[0], - (D3DXVECTOR3*)&g_avLightDirs[0],(D3DXMATRIX*)&mMat); + D3DXVec3TransformNormal((D3DXVECTOR3 *)&g_avLightDirs[0], + (D3DXVECTOR3 *)&g_avLightDirs[0], (D3DXMATRIX *)&mMat); g_avLightDirs[0].Normalize(); } @@ -1598,12 +1481,9 @@ int CDisplay::HandleInput() } //------------------------------------------------------------------------------- // Process input for an empty scene view to allow for sky-box rotations -int CDisplay::HandleInputEmptyScene() -{ - if(CBackgroundPainter::TEXTURE_CUBE == CBackgroundPainter::Instance().GetMode()) - { - if (g_bFPSView) - { +int CDisplay::HandleInputEmptyScene() { + if (CBackgroundPainter::TEXTURE_CUBE == CBackgroundPainter::Instance().GetMode()) { + if (g_bFPSView) { HandleMouseInputFPS(); HandleKeyboardInputFPS(); } @@ -1611,8 +1491,7 @@ int CDisplay::HandleInputEmptyScene() // need to store the last mouse position in the global variable // HandleMouseInputFPS() is doing this internally - if (!g_bFPSView) - { + if (!g_bFPSView) { g_LastmousePos.x = g_mousePos.x; g_LastmousePos.y = g_mousePos.y; } @@ -1621,39 +1500,38 @@ int CDisplay::HandleInputEmptyScene() } //------------------------------------------------------------------------------- // Draw the HUD on top of the scene -int CDisplay::DrawHUD() -{ - // HACK: (thom) can't get the effect to work on non-shader cards, therefore deactivated for the moment - if( g_sCaps.PixelShaderVersion < D3DPS_VERSION(2,0)) - return 1; +int CDisplay::DrawHUD() { + // HACK: (thom) can't get the effect to work on non-shader cards, therefore deactivated for the moment + if (g_sCaps.PixelShaderVersion < D3DPS_VERSION(2, 0)) + return 1; // get the dimension of the back buffer RECT sRect; - GetWindowRect(GetDlgItem(g_hDlg,IDC_RT),&sRect); + GetWindowRect(GetDlgItem(g_hDlg, IDC_RT), &sRect); sRect.right -= sRect.left; sRect.bottom -= sRect.top; // commit the texture to the shader // FIX: Necessary because the texture view is also using this shader - g_piPassThroughEffect->SetTexture("TEXTURE_2D",g_pcTexture); + g_piPassThroughEffect->SetTexture("TEXTURE_2D", g_pcTexture); // NOTE: The shader might be used for other purposes, too. // So ensure the right technique is there - if( g_sCaps.PixelShaderVersion < D3DPS_VERSION(2,0)) - g_piPassThroughEffect->SetTechnique( "PassThrough_FF"); + if (g_sCaps.PixelShaderVersion < D3DPS_VERSION(2, 0)) + g_piPassThroughEffect->SetTechnique("PassThrough_FF"); else g_piPassThroughEffect->SetTechnique("PassThrough"); // build vertices for drawing from system memory UINT dw; - g_piPassThroughEffect->Begin(&dw,0); + g_piPassThroughEffect->Begin(&dw, 0); g_piPassThroughEffect->BeginPass(0); D3DSURFACE_DESC sDesc; - g_pcTexture->GetLevelDesc(0,&sDesc); + g_pcTexture->GetLevelDesc(0, &sDesc); SVertex as[4]; - float fHalfX = ((float)sRect.right-(float)sDesc.Width) / 2.0f; - float fHalfY = ((float)sRect.bottom-(float)sDesc.Height) / 2.0f; + float fHalfX = ((float)sRect.right - (float)sDesc.Width) / 2.0f; + float fHalfY = ((float)sRect.bottom - (float)sDesc.Height) / 2.0f; as[1].x = fHalfX; as[1].y = fHalfY; as[1].z = 0.2f; @@ -1661,7 +1539,7 @@ int CDisplay::DrawHUD() as[1].u = 0.0f; as[1].v = 0.0f; - as[3].x = (float)sRect.right-fHalfX; + as[3].x = (float)sRect.right - fHalfX; as[3].y = fHalfY; as[3].z = 0.2f; as[3].w = 1.0f; @@ -1669,30 +1547,37 @@ int CDisplay::DrawHUD() as[3].v = 0.0f; as[0].x = fHalfX; - as[0].y = (float)sRect.bottom-fHalfY; + as[0].y = (float)sRect.bottom - fHalfY; as[0].z = 0.2f; as[0].w = 1.0f; as[0].u = 0.0f; as[0].v = 1.0f; - as[2].x = (float)sRect.right-fHalfX; - as[2].y = (float)sRect.bottom-fHalfY; + as[2].x = (float)sRect.right - fHalfX; + as[2].y = (float)sRect.bottom - fHalfY; as[2].z = 0.2f; as[2].w = 1.0f; as[2].u = 1.0f; as[2].v = 1.0f; - as[0].x -= 0.5f;as[1].x -= 0.5f;as[2].x -= 0.5f;as[3].x -= 0.5f; - as[0].y -= 0.5f;as[1].y -= 0.5f;as[2].y -= 0.5f;as[3].y -= 0.5f; + as[0].x -= 0.5f; + as[1].x -= 0.5f; + as[2].x -= 0.5f; + as[3].x -= 0.5f; + as[0].y -= 0.5f; + as[1].y -= 0.5f; + as[2].y -= 0.5f; + as[3].y -= 0.5f; - g_piDevice->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR); - g_piDevice->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_LINEAR); + g_piDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + g_piDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); // draw the screen-filling squad - DWORD dw2;g_piDevice->GetFVF(&dw2); + DWORD dw2; + g_piDevice->GetFVF(&dw2); g_piDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1); - g_piDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2, - &as,sizeof(SVertex)); + g_piDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, + &as, sizeof(SVertex)); // end the effect and recover the old vertex format g_piPassThroughEffect->EndPass(); @@ -1703,8 +1588,7 @@ int CDisplay::DrawHUD() } //------------------------------------------------------------------------------- // Render the full scene, all nodes -int CDisplay::RenderFullScene() -{ +int CDisplay::RenderFullScene() { // reset the color index used for drawing normals g_iCurrentColor = 0; @@ -1716,28 +1600,29 @@ int CDisplay::RenderFullScene() // setup wireframe/solid rendering mode if (g_sOptions.eDrawMode == RenderOptions::WIREFRAME) - g_piDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME); - else g_piDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_SOLID); + g_piDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); + else + g_piDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); if (g_sOptions.bCulling) - g_piDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_CCW); - else g_piDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE); + g_piDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); + else + g_piDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); // for high-quality mode, enable anisotropic texture filtering if (g_sOptions.bLowQuality) { - for (DWORD d = 0; d < 8;++d) { - g_piDevice->SetSamplerState(d,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR); - g_piDevice->SetSamplerState(d,D3DSAMP_MINFILTER,D3DTEXF_LINEAR); - g_piDevice->SetSamplerState(d,D3DSAMP_MIPFILTER,D3DTEXF_LINEAR); + for (DWORD d = 0; d < 8; ++d) { + g_piDevice->SetSamplerState(d, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + g_piDevice->SetSamplerState(d, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + g_piDevice->SetSamplerState(d, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); } - } - else { - for (DWORD d = 0; d < 8;++d) { - g_piDevice->SetSamplerState(d,D3DSAMP_MAGFILTER,D3DTEXF_ANISOTROPIC); - g_piDevice->SetSamplerState(d,D3DSAMP_MINFILTER,D3DTEXF_ANISOTROPIC); - g_piDevice->SetSamplerState(d,D3DSAMP_MIPFILTER,D3DTEXF_LINEAR); + } else { + for (DWORD d = 0; d < 8; ++d) { + g_piDevice->SetSamplerState(d, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC); + g_piDevice->SetSamplerState(d, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC); + g_piDevice->SetSamplerState(d, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); - g_piDevice->SetSamplerState(d,D3DSAMP_MAXANISOTROPY,g_sCaps.MaxAnisotropy); + g_piDevice->SetSamplerState(d, D3DSAMP_MAXANISOTROPY, g_sCaps.MaxAnisotropy); } } @@ -1748,14 +1633,12 @@ int CDisplay::RenderFullScene() if (g_sOptions.bStereoView) SetupStereoView(); - // draw all opaque objects in the scene aiMatrix4x4 m; - if (nullptr != g_pcAsset && nullptr != g_pcAsset->pcScene->mRootNode) - { + if (nullptr != g_pcAsset && nullptr != g_pcAsset->pcScene->mRootNode) { HandleInput(); - m = g_mWorld * g_mWorldRotate; - RenderNode(g_pcAsset->pcScene->mRootNode,m,false); + m = g_mWorld * g_mWorldRotate; + RenderNode(g_pcAsset->pcScene->mRootNode, m, false); } // if a cube texture is loaded as background image, the user @@ -1766,16 +1649,15 @@ int CDisplay::RenderFullScene() CBackgroundPainter::Instance().OnPostRender(); // draw all non-opaque objects in the scene - if (nullptr != g_pcAsset && nullptr != g_pcAsset->pcScene->mRootNode) - { + if (nullptr != g_pcAsset && nullptr != g_pcAsset->pcScene->mRootNode) { // disable the z-buffer if (!g_sOptions.bNoAlphaBlending) { - g_piDevice->SetRenderState(D3DRS_ZWRITEENABLE,FALSE); + g_piDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); } - RenderNode(g_pcAsset->pcScene->mRootNode,m,true); + RenderNode(g_pcAsset->pcScene->mRootNode, m, true); if (!g_sOptions.bNoAlphaBlending) { - g_piDevice->SetRenderState(D3DRS_ZWRITEENABLE,TRUE); + g_piDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); } } @@ -1786,30 +1668,31 @@ int CDisplay::RenderFullScene() // render the skeleton if necessary if (g_sOptions.bSkeleton && nullptr != g_pcAsset && nullptr != g_pcAsset->pcScene->mRootNode) { // disable the z-buffer - g_piDevice->SetRenderState(D3DRS_ZWRITEENABLE,FALSE); + g_piDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); if (g_sOptions.eDrawMode != RenderOptions::WIREFRAME) { - g_piDevice->SetRenderState(D3DRS_ZENABLE,FALSE); + g_piDevice->SetRenderState(D3DRS_ZENABLE, FALSE); } - g_piDevice->SetVertexDeclaration( gDefaultVertexDecl); + g_piDevice->SetVertexDeclaration(gDefaultVertexDecl); // this is very similar to the code in SetupMaterial() - ID3DXEffect* piEnd = g_piNormalsEffect; + ID3DXEffect *piEnd = g_piNormalsEffect; aiMatrix4x4 pcProj2 = m * mViewProjection; - D3DXVECTOR4 vVector(1.f,0.f,0.f,1.f); - piEnd->SetVector("OUTPUT_COLOR",&vVector); - piEnd->SetMatrix("WorldViewProjection", (const D3DXMATRIX*)&pcProj2); + D3DXVECTOR4 vVector(1.f, 0.f, 0.f, 1.f); + piEnd->SetVector("OUTPUT_COLOR", &vVector); + piEnd->SetMatrix("WorldViewProjection", (const D3DXMATRIX *)&pcProj2); UINT dwPasses = 0; - piEnd->Begin(&dwPasses,0); + piEnd->Begin(&dwPasses, 0); piEnd->BeginPass(0); - RenderSkeleton(g_pcAsset->pcScene->mRootNode,m,m); + RenderSkeleton(g_pcAsset->pcScene->mRootNode, m, m); - piEnd->EndPass();piEnd->End(); - g_piDevice->SetRenderState(D3DRS_ZWRITEENABLE,TRUE); - g_piDevice->SetRenderState(D3DRS_ZENABLE,TRUE); + piEnd->EndPass(); + piEnd->End(); + g_piDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); + g_piDevice->SetRenderState(D3DRS_ZENABLE, TRUE); } // draw the HUD texture on top of the rendered scene using @@ -1820,22 +1703,20 @@ int CDisplay::RenderFullScene() return 1; } //------------------------------------------------------------------------------- -int CDisplay::RenderMaterialView() -{ +int CDisplay::RenderMaterialView() { return 1; } //------------------------------------------------------------------------------- // Render animation skeleton -int CDisplay::RenderSkeleton (aiNode* piNode,const aiMatrix4x4& piMatrix, const aiMatrix4x4& parent) -{ - aiMatrix4x4 me = g_pcAsset->mAnimator->GetGlobalTransform( piNode); +int CDisplay::RenderSkeleton(aiNode *piNode, const aiMatrix4x4 &piMatrix, const aiMatrix4x4 &parent) { + aiMatrix4x4 me = g_pcAsset->mAnimator->GetGlobalTransform(piNode); me.Transpose(); //me *= piMatrix; if (piNode->mParent) { AssetHelper::LineVertex data[2]; - data[0].dColorDiffuse = data[1].dColorDiffuse = D3DCOLOR_ARGB(0xff,0xff,0,0); + data[0].dColorDiffuse = data[1].dColorDiffuse = D3DCOLOR_ARGB(0xff, 0xff, 0, 0); data[0].vPosition.x = parent.d1; data[0].vPosition.y = parent.d2; @@ -1845,33 +1726,30 @@ int CDisplay::RenderSkeleton (aiNode* piNode,const aiMatrix4x4& piMatrix, const data[1].vPosition.y = me.d2; data[1].vPosition.z = me.d3; - g_piDevice->DrawPrimitiveUP(D3DPT_LINELIST,1,&data,sizeof(AssetHelper::LineVertex)); + g_piDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, &data, sizeof(AssetHelper::LineVertex)); } // render all child nodes - for (unsigned int i = 0; i < piNode->mNumChildren;++i) - RenderSkeleton(piNode->mChildren[i],piMatrix, me ); + for (unsigned int i = 0; i < piNode->mNumChildren; ++i) + RenderSkeleton(piNode->mChildren[i], piMatrix, me); return 1; } //------------------------------------------------------------------------------- // Render a single node -int CDisplay::RenderNode (aiNode* piNode,const aiMatrix4x4& piMatrix, - bool bAlpha /*= false*/) -{ - aiMatrix4x4 aiMe = g_pcAsset->mAnimator->GetGlobalTransform( piNode); +int CDisplay::RenderNode(aiNode *piNode, const aiMatrix4x4 &piMatrix, + bool bAlpha /*= false*/) { + aiMatrix4x4 aiMe = g_pcAsset->mAnimator->GetGlobalTransform(piNode); aiMe.Transpose(); aiMe *= piMatrix; bool bChangedVM = false; - if (VIEWMODE_NODE == m_iViewMode && m_pcCurrentNode) - { - if (piNode != m_pcCurrentNode->psNode) - { + if (VIEWMODE_NODE == m_iViewMode && m_pcCurrentNode) { + if (piNode != m_pcCurrentNode->psNode) { // directly call our children - for (unsigned int i = 0; i < piNode->mNumChildren;++i) - RenderNode(piNode->mChildren[i],piMatrix,bAlpha ); + for (unsigned int i = 0; i < piNode->mNumChildren; ++i) + RenderNode(piNode->mChildren[i], piMatrix, bAlpha); return 1; } @@ -1885,25 +1763,23 @@ int CDisplay::RenderNode (aiNode* piNode,const aiMatrix4x4& piMatrix, pcCam.Inverse().Transpose(); // VERY UNOPTIMIZED, much stuff is redundant. Who cares? - if (!g_sOptions.bRenderMats && !bAlpha) - { + if (!g_sOptions.bRenderMats && !bAlpha) { // this is very similar to the code in SetupMaterial() - ID3DXEffect* piEnd = g_piDefaultEffect; + ID3DXEffect *piEnd = g_piDefaultEffect; // commit transformation matrices to the shader piEnd->SetMatrix("WorldViewProjection", - (const D3DXMATRIX*)&pcProj); + (const D3DXMATRIX *)&pcProj); - piEnd->SetMatrix("World",(const D3DXMATRIX*)&aiMe); + piEnd->SetMatrix("World", (const D3DXMATRIX *)&aiMe); piEnd->SetMatrix("WorldInverseTranspose", - (const D3DXMATRIX*)&pcCam); + (const D3DXMATRIX *)&pcCam); - if ( CBackgroundPainter::TEXTURE_CUBE == CBackgroundPainter::Instance().GetMode()) - { + if (CBackgroundPainter::TEXTURE_CUBE == CBackgroundPainter::Instance().GetMode()) { pcCam = pcCam * pcProj; - piEnd->SetMatrix("ViewProj",(const D3DXMATRIX*)&pcCam); + piEnd->SetMatrix("ViewProj", (const D3DXMATRIX *)&pcCam); pcCam.Inverse(); - piEnd->SetMatrix("InvViewProj",(const D3DXMATRIX*)&pcCam); + piEnd->SetMatrix("InvViewProj", (const D3DXMATRIX *)&pcCam); } // commit light colors and direction to the shader @@ -1917,23 +1793,21 @@ int CDisplay::RenderNode (aiNode* piNode,const aiMatrix4x4& piMatrix, apcVec[1].z = g_avLightDirs[0].z * -1.0f; apcVec[1].w = 0.0f; - D3DXVec4Normalize(&apcVec[0],&apcVec[0]); - D3DXVec4Normalize(&apcVec[1],&apcVec[1]); - piEnd->SetVectorArray("afLightDir",apcVec,5); + D3DXVec4Normalize(&apcVec[0], &apcVec[0]); + D3DXVec4Normalize(&apcVec[1], &apcVec[1]); + piEnd->SetVectorArray("afLightDir", apcVec, 5); apcVec[0].x = ((g_avLightColors[0] >> 16) & 0xFF) / 255.0f; apcVec[0].y = ((g_avLightColors[0] >> 8) & 0xFF) / 255.0f; apcVec[0].z = ((g_avLightColors[0]) & 0xFF) / 255.0f; apcVec[0].w = 1.0f; - if( g_sOptions.b3Lights) - { + if (g_sOptions.b3Lights) { apcVec[1].x = ((g_avLightColors[1] >> 16) & 0xFF) / 255.0f; apcVec[1].y = ((g_avLightColors[1] >> 8) & 0xFF) / 255.0f; apcVec[1].z = ((g_avLightColors[1]) & 0xFF) / 255.0f; apcVec[1].w = 0.0f; - } else - { + } else { apcVec[1].x = 0.0f; apcVec[1].y = 0.0f; apcVec[1].z = 0.0f; @@ -1942,146 +1816,145 @@ int CDisplay::RenderNode (aiNode* piNode,const aiMatrix4x4& piMatrix, apcVec[0] *= g_fLightIntensity; apcVec[1] *= g_fLightIntensity; - piEnd->SetVectorArray("afLightColor",apcVec,5); + piEnd->SetVectorArray("afLightColor", apcVec, 5); apcVec[0].x = vPos.x; apcVec[0].y = vPos.y; apcVec[0].z = vPos.z; - piEnd->SetVector( "vCameraPos",&apcVec[0]); + piEnd->SetVector("vCameraPos", &apcVec[0]); // setup the best technique - if( g_sCaps.PixelShaderVersion < D3DPS_VERSION(2,0)) - { - g_piDefaultEffect->SetTechnique( "DefaultFXSpecular_FF"); - } else - if (g_sCaps.PixelShaderVersion < D3DPS_VERSION(3,0) || g_sOptions.bLowQuality) - { + if (g_sCaps.PixelShaderVersion < D3DPS_VERSION(2, 0)) { + g_piDefaultEffect->SetTechnique("DefaultFXSpecular_FF"); + } else if (g_sCaps.PixelShaderVersion < D3DPS_VERSION(3, 0) || g_sOptions.bLowQuality) { if (g_sOptions.b3Lights) piEnd->SetTechnique("DefaultFXSpecular_PS20_D2"); - else piEnd->SetTechnique("DefaultFXSpecular_PS20_D1"); - } - else - { + else + piEnd->SetTechnique("DefaultFXSpecular_PS20_D1"); + } else { if (g_sOptions.b3Lights) piEnd->SetTechnique("DefaultFXSpecular_D2"); - else piEnd->SetTechnique("DefaultFXSpecular_D1"); + else + piEnd->SetTechnique("DefaultFXSpecular_D1"); } // setup the default material UINT dwPasses = 0; - piEnd->Begin(&dwPasses,0); + piEnd->Begin(&dwPasses, 0); piEnd->BeginPass(0); } D3DXVECTOR4 vVector = g_aclNormalColors[g_iCurrentColor]; - if (++g_iCurrentColor == 14) - { + if (++g_iCurrentColor == 14) { g_iCurrentColor = 0; } - if (! (!g_sOptions.bRenderMats && bAlpha )) - { - for (unsigned int i = 0; i < piNode->mNumMeshes;++i) - { - const aiMesh* mesh = g_pcAsset->pcScene->mMeshes[piNode->mMeshes[i]]; - AssetHelper::MeshHelper* helper = g_pcAsset->apcMeshes[piNode->mMeshes[i]]; + if (!(!g_sOptions.bRenderMats && bAlpha)) { + for (unsigned int i = 0; i < piNode->mNumMeshes; ++i) { + const aiMesh *mesh = g_pcAsset->pcScene->mMeshes[piNode->mMeshes[i]]; + AssetHelper::MeshHelper *helper = g_pcAsset->apcMeshes[piNode->mMeshes[i]]; // don't render the mesh if the render pass is incorrect - if (g_sOptions.bRenderMats && (helper->piOpacityTexture || helper->fOpacity != 1.0f) && !mesh->HasBones()) - { - if (!bAlpha)continue; + if (g_sOptions.bRenderMats && (helper->piOpacityTexture || helper->fOpacity != 1.0f) && !mesh->HasBones()) { + if (!bAlpha) { + continue; + } + } else if (bAlpha) { + continue; } - else if (bAlpha)continue; // Upload bone matrices. This maybe is the wrong place to do it, but for the heck of it I don't understand this code flow - if( mesh->HasBones()) - { - if( helper->piEffect) - { - static float matrices[4*4*60]; - float* tempmat = matrices; - const std::vector& boneMats = g_pcAsset->mAnimator->GetBoneMatrices( piNode, i); - ai_assert( boneMats.size() == mesh->mNumBones); + if (mesh->HasBones()) { + if (helper->piEffect) { + static float matrices[4 * 4 * 60]; + float *tempmat = matrices; + const std::vector &boneMats = g_pcAsset->mAnimator->GetBoneMatrices(piNode, i); + ai_assert(boneMats.size() == mesh->mNumBones); - for( unsigned int a = 0; a < mesh->mNumBones; a++) - { - const aiMatrix4x4& mat = boneMats[a]; - *tempmat++ = mat.a1; *tempmat++ = mat.a2; *tempmat++ = mat.a3; *tempmat++ = mat.a4; - *tempmat++ = mat.b1; *tempmat++ = mat.b2; *tempmat++ = mat.b3; *tempmat++ = mat.b4; - *tempmat++ = mat.c1; *tempmat++ = mat.c2; *tempmat++ = mat.c3; *tempmat++ = mat.c4; - *tempmat++ = mat.d1; *tempmat++ = mat.d2; *tempmat++ = mat.d3; *tempmat++ = mat.d4; + for (unsigned int a = 0; a < mesh->mNumBones; a++) { + const aiMatrix4x4 &mat = boneMats[a]; + *tempmat++ = mat.a1; + *tempmat++ = mat.a2; + *tempmat++ = mat.a3; + *tempmat++ = mat.a4; + *tempmat++ = mat.b1; + *tempmat++ = mat.b2; + *tempmat++ = mat.b3; + *tempmat++ = mat.b4; + *tempmat++ = mat.c1; + *tempmat++ = mat.c2; + *tempmat++ = mat.c3; + *tempmat++ = mat.c4; + *tempmat++ = mat.d1; + *tempmat++ = mat.d2; + *tempmat++ = mat.d3; + *tempmat++ = mat.d4; //tempmat += 4; } - if( g_sOptions.bRenderMats) - { - helper->piEffect->SetMatrixTransposeArray( "gBoneMatrix", (D3DXMATRIX*)matrices, 60); - } else - { - g_piDefaultEffect->SetMatrixTransposeArray( "gBoneMatrix", (D3DXMATRIX*)matrices, 60); + if (g_sOptions.bRenderMats) { + helper->piEffect->SetMatrixTransposeArray("gBoneMatrix", (D3DXMATRIX *)matrices, 60); + } else { + g_piDefaultEffect->SetMatrixTransposeArray("gBoneMatrix", (D3DXMATRIX *)matrices, 60); g_piDefaultEffect->CommitChanges(); } } - } else - { + } else { // upload identity matrices instead. Only the first is ever going to be used in meshes without bones - if( !g_sOptions.bRenderMats) - { - D3DXMATRIX identity( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - g_piDefaultEffect->SetMatrixTransposeArray( "gBoneMatrix", &identity, 1); + if (!g_sOptions.bRenderMats) { + D3DXMATRIX identity(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + g_piDefaultEffect->SetMatrixTransposeArray("gBoneMatrix", &identity, 1); g_piDefaultEffect->CommitChanges(); } } // now setup the material - if (g_sOptions.bRenderMats) - { - CMaterialManager::Instance().SetupMaterial( helper, pcProj, aiMe, pcCam, vPos); + if (g_sOptions.bRenderMats) { + CMaterialManager::Instance().SetupMaterial(helper, pcProj, aiMe, pcCam, vPos); } - g_piDevice->SetVertexDeclaration( gDefaultVertexDecl); + g_piDevice->SetVertexDeclaration(gDefaultVertexDecl); if (g_sOptions.bNoAlphaBlending) { // manually disable alpha-blending - g_piDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,FALSE); + g_piDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); } - if (bAlpha)CMeshRenderer::Instance().DrawSorted(piNode->mMeshes[i],aiMe); - else CMeshRenderer::Instance().DrawUnsorted(piNode->mMeshes[i]); + if (bAlpha) + CMeshRenderer::Instance().DrawSorted(piNode->mMeshes[i], aiMe); + else + CMeshRenderer::Instance().DrawUnsorted(piNode->mMeshes[i]); // now end the material - if (g_sOptions.bRenderMats) - { - CMaterialManager::Instance().EndMaterial( helper); + if (g_sOptions.bRenderMats) { + CMaterialManager::Instance().EndMaterial(helper); } // render normal vectors? - if (g_sOptions.bRenderNormals && helper->piVBNormals) - { + if (g_sOptions.bRenderNormals && helper->piVBNormals) { // this is very similar to the code in SetupMaterial() - ID3DXEffect* piEnd = g_piNormalsEffect; + ID3DXEffect *piEnd = g_piNormalsEffect; - piEnd->SetVector("OUTPUT_COLOR",&vVector); - piEnd->SetMatrix("WorldViewProjection", (const D3DXMATRIX*)&pcProj); + piEnd->SetVector("OUTPUT_COLOR", &vVector); + piEnd->SetMatrix("WorldViewProjection", (const D3DXMATRIX *)&pcProj); UINT dwPasses = 0; - piEnd->Begin(&dwPasses,0); + piEnd->Begin(&dwPasses, 0); piEnd->BeginPass(0); g_piDevice->SetStreamSource(0, helper->piVBNormals, 0, sizeof(AssetHelper::LineVertex)); - g_piDevice->DrawPrimitive(D3DPT_LINELIST,0, g_pcAsset->pcScene->mMeshes[piNode->mMeshes[i]]->mNumVertices); + g_piDevice->DrawPrimitive(D3DPT_LINELIST, 0, g_pcAsset->pcScene->mMeshes[piNode->mMeshes[i]]->mNumVertices); piEnd->EndPass(); piEnd->End(); } } // end the default material - if (!g_sOptions.bRenderMats) - { + if (!g_sOptions.bRenderMats) { g_piDefaultEffect->EndPass(); g_piDefaultEffect->End(); } } // render all child nodes - for (unsigned int i = 0; i < piNode->mNumChildren;++i) - RenderNode(piNode->mChildren[i],piMatrix,bAlpha ); + for (unsigned int i = 0; i < piNode->mNumChildren; ++i) + RenderNode(piNode->mChildren[i], piMatrix, bAlpha); // need to reset the viewmode? if (bChangedVM) @@ -2089,70 +1962,61 @@ int CDisplay::RenderNode (aiNode* piNode,const aiMatrix4x4& piMatrix, return 1; } //------------------------------------------------------------------------------- -int CDisplay::RenderPatternBG() -{ - if (!g_piPatternEffect) - { +int CDisplay::RenderPatternBG() { + if (!g_piPatternEffect) { // the pattern effect won't work on ps_2_0 cards - if (g_sCaps.PixelShaderVersion >= D3DPS_VERSION(3,0)) - { + if (g_sCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) { // seems we have not yet compiled this shader. // and NOW is the best time to do that ... - ID3DXBuffer* piBuffer = nullptr; - if(FAILED( D3DXCreateEffect(g_piDevice, - g_szCheckerBackgroundShader.c_str(), - (UINT)g_szCheckerBackgroundShader.length(), - nullptr, - nullptr, - D3DXSHADER_USE_LEGACY_D3DX9_31_DLL, - nullptr, - &g_piPatternEffect,&piBuffer))) - { - if( piBuffer) - { - MessageBox(g_hDlg,(LPCSTR)piBuffer->GetBufferPointer(),"HLSL",MB_OK); + ID3DXBuffer *piBuffer = nullptr; + if (FAILED(D3DXCreateEffect(g_piDevice, + g_szCheckerBackgroundShader.c_str(), + (UINT)g_szCheckerBackgroundShader.length(), + nullptr, + nullptr, + D3DXSHADER_USE_LEGACY_D3DX9_31_DLL, + nullptr, + &g_piPatternEffect, &piBuffer))) { + if (piBuffer) { + MessageBox(g_hDlg, (LPCSTR)piBuffer->GetBufferPointer(), "HLSL", MB_OK); piBuffer->Release(); } return 0; } - if( piBuffer) - { + if (piBuffer) { piBuffer->Release(); piBuffer = nullptr; } - } - else - { + } else { // clear the color buffer in magenta // (hopefully this is ugly enough that every ps_2_0 cards owner // runs to the next shop to buy himself a new card ...) - g_piDevice->Clear(0,nullptr,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, - D3DCOLOR_ARGB(0xFF,0xFF,0,0xFF), 1.0f,0 ); + g_piDevice->Clear(0, nullptr, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, + D3DCOLOR_ARGB(0xFF, 0xFF, 0, 0xFF), 1.0f, 0); return 1; } } // clear the depth buffer only - g_piDevice->Clear(0,nullptr,D3DCLEAR_ZBUFFER, - D3DCOLOR_ARGB(0xFF,0xFF,0,0xFF), 1.0f,0 ); + g_piDevice->Clear(0, nullptr, D3DCLEAR_ZBUFFER, + D3DCOLOR_ARGB(0xFF, 0xFF, 0, 0xFF), 1.0f, 0); // setup the colors to be used ... - g_piPatternEffect->SetVector("COLOR_ONE",&m_avCheckerColors[0]); - g_piPatternEffect->SetVector("COLOR_TWO",&m_avCheckerColors[1]); + g_piPatternEffect->SetVector("COLOR_ONE", &m_avCheckerColors[0]); + g_piPatternEffect->SetVector("COLOR_TWO", &m_avCheckerColors[1]); // setup the shader UINT dw; - g_piPatternEffect->Begin(&dw,0); + g_piPatternEffect->Begin(&dw, 0); g_piPatternEffect->BeginPass(0); RECT sRect; - GetWindowRect(GetDlgItem(g_hDlg,IDC_RT),&sRect); + GetWindowRect(GetDlgItem(g_hDlg, IDC_RT), &sRect); sRect.right -= sRect.left; sRect.bottom -= sRect.top; - struct SVertex - { - float x,y,z,w; + struct SVertex { + float x, y, z, w; }; // build the screen-filling rectangle SVertex as[4]; @@ -2174,14 +2038,21 @@ int CDisplay::RenderPatternBG() as[2].w = 1.0f; as[3].w = 1.0f; - as[0].x -= 0.5f;as[1].x -= 0.5f;as[2].x -= 0.5f;as[3].x -= 0.5f; - as[0].y -= 0.5f;as[1].y -= 0.5f;as[2].y -= 0.5f;as[3].y -= 0.5f; + as[0].x -= 0.5f; + as[1].x -= 0.5f; + as[2].x -= 0.5f; + as[3].x -= 0.5f; + as[0].y -= 0.5f; + as[1].y -= 0.5f; + as[2].y -= 0.5f; + as[3].y -= 0.5f; // draw the rectangle - DWORD dw2;g_piDevice->GetFVF(&dw2); + DWORD dw2; + g_piDevice->GetFVF(&dw2); g_piDevice->SetFVF(D3DFVF_XYZRHW); - g_piDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2, - &as,sizeof(SVertex)); + g_piDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, + &as, sizeof(SVertex)); g_piDevice->SetFVF(dw2); // cleanup @@ -2190,9 +2061,8 @@ int CDisplay::RenderPatternBG() return 1; } //------------------------------------------------------------------------------- -int CDisplay::RenderTextureView() -{ - if (!g_pcAsset || !g_pcAsset->pcScene)return 0; +int CDisplay::RenderTextureView() { + if (!g_pcAsset || !g_pcAsset->pcScene) return 0; // handle input this->HandleInputTextureView(); @@ -2201,58 +2071,53 @@ int CDisplay::RenderTextureView() RenderPatternBG(); // it might be that there is no texture ... - if (!m_pcCurrentTexture->piTexture) - { + if (!m_pcCurrentTexture->piTexture) { return 0; } - RECT sRect; - GetWindowRect(GetDlgItem(g_hDlg,IDC_RT),&sRect); + GetWindowRect(GetDlgItem(g_hDlg, IDC_RT), &sRect); sRect.right -= sRect.left; sRect.bottom -= sRect.top; // commit the texture to the shader - g_piPassThroughEffect->SetTexture("TEXTURE_2D",*m_pcCurrentTexture->piTexture); + g_piPassThroughEffect->SetTexture("TEXTURE_2D", *m_pcCurrentTexture->piTexture); - if (aiTextureType_OPACITY == m_pcCurrentTexture->iType) - { + if (aiTextureType_OPACITY == m_pcCurrentTexture->iType) { g_piPassThroughEffect->SetTechnique("PassThroughAlphaFromR"); - } - else if ((aiTextureType_OPACITY | 0x40000000) == m_pcCurrentTexture->iType) - { + } else if ((aiTextureType_OPACITY | 0x40000000) == m_pcCurrentTexture->iType) { g_piPassThroughEffect->SetTechnique("PassThroughAlphaFromA"); - } - else if( g_sCaps.PixelShaderVersion < D3DPS_VERSION(2,0)) - g_piPassThroughEffect->SetTechnique( "PassThrough_FF"); + } else if (g_sCaps.PixelShaderVersion < D3DPS_VERSION(2, 0)) + g_piPassThroughEffect->SetTechnique("PassThrough_FF"); else g_piPassThroughEffect->SetTechnique("PassThrough"); UINT dw; - g_piPassThroughEffect->Begin(&dw,0); + g_piPassThroughEffect->Begin(&dw, 0); g_piPassThroughEffect->BeginPass(0); if (aiTextureType_HEIGHT == m_pcCurrentTexture->iType || - aiTextureType_NORMALS == m_pcCurrentTexture->iType || g_sOptions.bNoAlphaBlending) - { + aiTextureType_NORMALS == m_pcCurrentTexture->iType || g_sOptions.bNoAlphaBlending) { // manually disable alpha blending - g_piDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,FALSE); + g_piDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); } // build a rectangle which centers the texture // scaling is OK, but no stretching D3DSURFACE_DESC sDesc; - if ( m_pcCurrentTexture->piTexture && *m_pcCurrentTexture->piTexture) { /* just a dirty fix */ - (*m_pcCurrentTexture->piTexture)->GetLevelDesc(0,&sDesc); + if (m_pcCurrentTexture->piTexture && *m_pcCurrentTexture->piTexture) { /* just a dirty fix */ + (*m_pcCurrentTexture->piTexture)->GetLevelDesc(0, &sDesc); - struct SVertex{float x,y,z,w,u,v;}; + struct SVertex { + float x, y, z, w, u, v; + }; SVertex as[4]; const float nx = (float)sRect.right; const float ny = (float)sRect.bottom; - const float x = (float)sDesc.Width; - const float y = (float)sDesc.Height; - float f = std::min((nx-30) / x,(ny-30) / y) * (m_fTextureZoom/1000.0f); + const float x = (float)sDesc.Width; + const float y = (float)sDesc.Height; + float f = std::min((nx - 30) / x, (ny - 30) / y) * (m_fTextureZoom / 1000.0f); float fHalfX = (nx - (f * x)) / 2.0f; float fHalfY = (ny - (f * y)) / 2.0f; @@ -2262,32 +2127,39 @@ int CDisplay::RenderTextureView() as[1].w = 1.0f; as[1].u = 0.0f; as[1].v = 0.0f; - as[3].x = nx-fHalfX + m_vTextureOffset.x; + as[3].x = nx - fHalfX + m_vTextureOffset.x; as[3].y = fHalfY + m_vTextureOffset.y; as[3].z = 0.2f; as[3].w = 1.0f; as[3].u = 1.0f; as[3].v = 0.0f; as[0].x = fHalfX + m_vTextureOffset.x; - as[0].y = ny-fHalfY + m_vTextureOffset.y; + as[0].y = ny - fHalfY + m_vTextureOffset.y; as[0].z = 0.2f; as[0].w = 1.0f; as[0].u = 0.0f; as[0].v = 1.0f; - as[2].x = nx-fHalfX + m_vTextureOffset.x; - as[2].y = ny-fHalfY + m_vTextureOffset.y; + as[2].x = nx - fHalfX + m_vTextureOffset.x; + as[2].y = ny - fHalfY + m_vTextureOffset.y; as[2].z = 0.2f; as[2].w = 1.0f; as[2].u = 1.0f; as[2].v = 1.0f; - as[0].x -= 0.5f;as[1].x -= 0.5f;as[2].x -= 0.5f;as[3].x -= 0.5f; - as[0].y -= 0.5f;as[1].y -= 0.5f;as[2].y -= 0.5f;as[3].y -= 0.5f; + as[0].x -= 0.5f; + as[1].x -= 0.5f; + as[2].x -= 0.5f; + as[3].x -= 0.5f; + as[0].y -= 0.5f; + as[1].y -= 0.5f; + as[2].y -= 0.5f; + as[3].y -= 0.5f; // draw the rectangle - DWORD dw2;g_piDevice->GetFVF(&dw2); + DWORD dw2; + g_piDevice->GetFVF(&dw2); g_piDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1); - g_piDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2, - &as,sizeof(SVertex)); + g_piDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, + &as, sizeof(SVertex)); g_piDevice->SetFVF(dw2); } @@ -2298,5 +2170,4 @@ int CDisplay::RenderTextureView() return 1; } -} - +} // namespace AssimpView diff --git a/tools/assimp_view/SceneAnimator.h b/tools/assimp_view/SceneAnimator.h index 33b8568a4..b630dc81c 100644 --- a/tools/assimp_view/SceneAnimator.h +++ b/tools/assimp_view/SceneAnimator.h @@ -47,7 +47,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AV_SCENEANIMATOR_H_INCLUDED #define AV_SCENEANIMATOR_H_INCLUDED +#include + #include +#include namespace AssimpView { @@ -59,7 +62,7 @@ namespace AssimpView { struct SceneAnimNode { std::string mName; SceneAnimNode *mParent; - std::vector mChildren; + std::vector mChildren; //! most recently calculated local transform aiMatrix4x4 mLocalTransform; @@ -72,13 +75,23 @@ struct SceneAnimNode { //! Default construction SceneAnimNode() : - mName(), mParent(nullptr), mChildren(), mLocalTransform(), mGlobalTransform(), mChannelIndex(-1) { + mName(), + mParent(nullptr), + mChildren(), + mLocalTransform(), + mGlobalTransform(), + mChannelIndex(-1) { // empty } //! Construction from a given name SceneAnimNode(const std::string &pName) : - mName(pName), mParent(nullptr), mChildren(), mLocalTransform(), mGlobalTransform(), mChannelIndex(-1) { + mName(pName), + mParent(nullptr), + mChildren(), + mLocalTransform(), + mGlobalTransform(), + mChannelIndex(-1) { // empty } @@ -125,7 +138,7 @@ public: // ---------------------------------------------------------------------------- /** Calculates the node transformations for the scene. Call this to get - * uptodate results before calling one of the getters. + * up-to-date results before calling one of the getters. * @param pTime Current time. Can be an arbitrary range. */ void Calculate(double pTime); @@ -136,7 +149,7 @@ public: * The returned matrix is in the node's parent's local space, just like the * original node's transformation matrix. If the node is not animated, the * node's original transformation is returned so that you can safely use or - * assign it to the node itsself. If there is no node with the given name, + * assign it to the node itself. If there is no node with the given name, * the identity matrix is returned. All transformations are updated whenever * Calculate() is called. * @param pNodeName Name of the node @@ -151,7 +164,7 @@ public: * The returned matrix is in world space, which is the same coordinate space * as the transformation of the scene's root node. If the node is not animated, * the node's original transformation is returned so that you can safely use or - * assign it to the node itsself. If there is no node with the given name, the + * assign it to the node itself. If there is no node with the given name, the * identity matrix is returned. All transformations are updated whenever * Calculate() is called. * @param pNodeName Name of the node @@ -190,7 +203,7 @@ public: /** @brief Get the current animation or NULL */ aiAnimation *CurrentAnim() const { - return static_cast(mCurrentAnimIndex) < mScene->mNumAnimations ? mScene->mAnimations[mCurrentAnimIndex] : NULL; + return static_cast(mCurrentAnimIndex) < mScene->mNumAnimations ? mScene->mAnimations[mCurrentAnimIndex] : nullptr; } protected: