From 3a3340b9260a09046d0041b8345eca11c7873c56 Mon Sep 17 00:00:00 2001 From: SchroerDev <46781125+SchroerDev@users.noreply.github.com> Date: Thu, 17 Jan 2019 12:26:22 +0100 Subject: [PATCH] add FBX Line Element support add FBX Line Element support --- code/FBXConverter.cpp | 56 +++++++++++++++++++++++++++++++++++++++- code/FBXConverter.h | 9 +++++-- code/FBXDocument.cpp | 3 +++ code/FBXDocument.h | 1 + code/FBXMeshGeometry.cpp | 26 +++++++++++++++++++ code/FBXMeshGeometry.h | 22 ++++++++++++++++ 6 files changed, 114 insertions(+), 3 deletions(-) diff --git a/code/FBXConverter.cpp b/code/FBXConverter.cpp index b14bbfe98..6070465d5 100644 --- a/code/FBXConverter.cpp +++ b/code/FBXConverter.cpp @@ -870,10 +870,15 @@ namespace Assimp { for (const Geometry* geo : geos) { const MeshGeometry* const mesh = dynamic_cast(geo); + const LineGeometry* const line = dynamic_cast(geo); if (mesh) { const std::vector& indices = ConvertMesh(*mesh, model, node_global_transform, nd); std::copy(indices.begin(), indices.end(), std::back_inserter(meshes)); } + else if (line) { + const std::vector& indices = ConvertLine(*line, model, node_global_transform, nd); + std::copy(indices.begin(), indices.end(), std::back_inserter(meshes)); + } else { FBXImporter::LogWarn("ignoring unrecognized geometry: " + geo->Name()); } @@ -922,7 +927,52 @@ namespace Assimp { return temp; } - aiMesh* FBXConverter::SetupEmptyMesh(const MeshGeometry& mesh, aiNode& nd) + std::vector FBXConverter::ConvertLine(const LineGeometry& line, const Model& model, + const aiMatrix4x4& node_global_transform, aiNode& nd) + { + std::vector temp; + + const std::vector& vertices = line.GetVertices(); + const std::vector& indices = line.GetIndices(); + if (vertices.empty() || indices.empty()) { + FBXImporter::LogWarn("ignoring empty line: " + line.Name()); + return temp; + } + + aiMesh* const out_mesh = SetupEmptyMesh(line, nd); + out_mesh->mPrimitiveTypes |= aiPrimitiveType_LINE; + + // copy vertices + out_mesh->mNumVertices = static_cast(vertices.size()); + out_mesh->mVertices = new aiVector3D[out_mesh->mNumVertices]; + std::copy(vertices.begin(), vertices.end(), out_mesh->mVertices); + + //Number of line segments (faces) is "Number of Points - Number of Endpoints" + //N.B.: Endpoints in FbxLine are denoted by negative indices. + //If such an Index is encountered, add 1 and multiply by -1 to get the real index. + unsigned int epcount = 0; + for (unsigned i = 0; i < indices.size(); i++) + { + if (indices[i] < 0) epcount++; + } + unsigned int pcount = indices.size(); + unsigned int scount = out_mesh->mNumFaces = pcount - epcount; + + aiFace* fac = out_mesh->mFaces = new aiFace[scount](); + for (unsigned int i = 0; i < pcount; ++i) { + if (indices[i] < 0) continue; + aiFace& f = *fac++; + f.mNumIndices = 2; //2 == aiPrimitiveType_LINE + f.mIndices = new unsigned int[2]; + f.mIndices[0] = indices[i]; + int segid = indices[(i + 1 == pcount ? 0 : i + 1)]; //If we have reached he last point, wrap around + f.mIndices[1] = (segid < 0 ? (segid + 1)*-1 : segid); //Convert EndPoint Index to normal Index + } + temp.push_back(static_cast(meshes.size() - 1)); + return temp; + } + + aiMesh* FBXConverter::SetupEmptyMesh(const Geometry& mesh, aiNode& nd) { aiMesh* const out_mesh = new aiMesh(); meshes.push_back(out_mesh); @@ -957,6 +1007,10 @@ namespace Assimp { // copy vertices out_mesh->mNumVertices = static_cast(vertices.size()); out_mesh->mVertices = new aiVector3D[vertices.size()]; + // for (unsigned int i = 0; i < vertices.size(); i++) + // { + // aiMatrix4x4::Translation(vertices[i], nd); + // } std::copy(vertices.begin(), vertices.end(), out_mesh->mVertices); // generate dummy faces diff --git a/code/FBXConverter.h b/code/FBXConverter.h index 039422839..2d1278373 100644 --- a/code/FBXConverter.h +++ b/code/FBXConverter.h @@ -174,14 +174,18 @@ private: // ------------------------------------------------------------------------------------------------ void ConvertModel(const Model& model, aiNode& nd, const aiMatrix4x4& node_global_transform); - + // ------------------------------------------------------------------------------------------------ // MeshGeometry -> aiMesh, return mesh index + 1 or 0 if the conversion failed std::vector ConvertMesh(const MeshGeometry& mesh, const Model& model, const aiMatrix4x4& node_global_transform, aiNode& nd); // ------------------------------------------------------------------------------------------------ - aiMesh* SetupEmptyMesh(const MeshGeometry& mesh, aiNode& nd); + std::vector ConvertLine(const LineGeometry& line, const Model& model, + const aiMatrix4x4& node_global_transform, aiNode& nd); + + // ------------------------------------------------------------------------------------------------ + aiMesh* SetupEmptyMesh(const Geometry& mesh, aiNode& nd); // ------------------------------------------------------------------------------------------------ unsigned int ConvertMeshSingleMaterial(const MeshGeometry& mesh, const Model& model, @@ -424,6 +428,7 @@ private: std::vector lights; std::vector cameras; std::vector textures; + typedef std::map MaterialMap; MaterialMap materials_converted; diff --git a/code/FBXDocument.cpp b/code/FBXDocument.cpp index 29bc052da..deac89ca0 100644 --- a/code/FBXDocument.cpp +++ b/code/FBXDocument.cpp @@ -149,6 +149,9 @@ const Object* LazyObject::Get(bool dieOnError) if (!strcmp(classtag.c_str(), "Shape")) { object.reset(new ShapeGeometry(id, element, name, doc)); } + if (!strcmp(classtag.c_str(), "Line")) { + object.reset(new LineGeometry(id, element, name, doc)); + } } else if (!strncmp(obtype,"NodeAttribute",length)) { if (!strcmp(classtag.c_str(),"Camera")) { diff --git a/code/FBXDocument.h b/code/FBXDocument.h index a7d81cf0a..02accf92e 100644 --- a/code/FBXDocument.h +++ b/code/FBXDocument.h @@ -66,6 +66,7 @@ class PropertyTable; class Document; class Material; class ShapeGeometry; +class LineGeometry; class Geometry; class Video; diff --git a/code/FBXMeshGeometry.cpp b/code/FBXMeshGeometry.cpp index aa60ee184..faa5de75c 100644 --- a/code/FBXMeshGeometry.cpp +++ b/code/FBXMeshGeometry.cpp @@ -679,6 +679,32 @@ const std::vector& ShapeGeometry::GetNormals() 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(); + 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); + ParseVectorDataArray(m_vertices, Points); + ParseVectorDataArray(m_indices, PointsIndex); +} + +// ------------------------------------------------------------------------------------------------ +LineGeometry::~LineGeometry() { + // empty +} +// ------------------------------------------------------------------------------------------------ +const std::vector& LineGeometry::GetVertices() const { + return m_vertices; +} +// ------------------------------------------------------------------------------------------------ +const std::vector& LineGeometry::GetIndices() const { + return m_indices; +} } // !FBX } // !Assimp #endif diff --git a/code/FBXMeshGeometry.h b/code/FBXMeshGeometry.h index 3e10d73d3..641461a69 100644 --- a/code/FBXMeshGeometry.h +++ b/code/FBXMeshGeometry.h @@ -205,6 +205,28 @@ private: std::vector m_normals; std::vector m_indices; }; +/** +* DOM class for FBX geometry of type "Line" +*/ +class LineGeometry : public Geometry +{ +public: + /** The class constructor */ + LineGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc); + + /** The class destructor */ + virtual ~LineGeometry(); + + /** Get a list of all vertex points, non-unique*/ + const std::vector& GetVertices() const; + + /** Return list of vertex indices. */ + const std::vector& GetIndices() const; + +private: + std::vector m_vertices; + std::vector m_indices; +}; } }