add FBX Line Element support

add FBX Line Element support
pull/2301/head
SchroerDev 2019-01-17 12:26:22 +01:00 committed by GitHub
parent 3db78e1aa2
commit 3a3340b926
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 114 additions and 3 deletions

View File

@ -870,10 +870,15 @@ namespace Assimp {
for (const Geometry* geo : geos) { for (const Geometry* geo : geos) {
const MeshGeometry* const mesh = dynamic_cast<const MeshGeometry*>(geo); const MeshGeometry* const mesh = dynamic_cast<const MeshGeometry*>(geo);
const LineGeometry* const line = dynamic_cast<const LineGeometry*>(geo);
if (mesh) { if (mesh) {
const std::vector<unsigned int>& indices = ConvertMesh(*mesh, model, node_global_transform, nd); const std::vector<unsigned int>& indices = ConvertMesh(*mesh, model, node_global_transform, nd);
std::copy(indices.begin(), indices.end(), std::back_inserter(meshes)); std::copy(indices.begin(), indices.end(), std::back_inserter(meshes));
} }
else if (line) {
const std::vector<unsigned int>& indices = ConvertLine(*line, model, node_global_transform, nd);
std::copy(indices.begin(), indices.end(), std::back_inserter(meshes));
}
else { else {
FBXImporter::LogWarn("ignoring unrecognized geometry: " + geo->Name()); FBXImporter::LogWarn("ignoring unrecognized geometry: " + geo->Name());
} }
@ -922,7 +927,52 @@ namespace Assimp {
return temp; return temp;
} }
aiMesh* FBXConverter::SetupEmptyMesh(const MeshGeometry& mesh, aiNode& nd) std::vector<unsigned int> FBXConverter::ConvertLine(const LineGeometry& line, const Model& model,
const aiMatrix4x4& node_global_transform, aiNode& nd)
{
std::vector<unsigned int> temp;
const std::vector<aiVector3D>& vertices = line.GetVertices();
const std::vector<int>& 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<unsigned int>(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<unsigned int>(meshes.size() - 1));
return temp;
}
aiMesh* FBXConverter::SetupEmptyMesh(const Geometry& mesh, aiNode& nd)
{ {
aiMesh* const out_mesh = new aiMesh(); aiMesh* const out_mesh = new aiMesh();
meshes.push_back(out_mesh); meshes.push_back(out_mesh);
@ -957,6 +1007,10 @@ namespace Assimp {
// copy vertices // copy vertices
out_mesh->mNumVertices = static_cast<unsigned int>(vertices.size()); out_mesh->mNumVertices = static_cast<unsigned int>(vertices.size());
out_mesh->mVertices = new aiVector3D[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); std::copy(vertices.begin(), vertices.end(), out_mesh->mVertices);
// generate dummy faces // generate dummy faces

View File

@ -174,14 +174,18 @@ private:
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertModel(const Model& model, aiNode& nd, const aiMatrix4x4& node_global_transform); void ConvertModel(const Model& model, aiNode& nd, const aiMatrix4x4& node_global_transform);
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// MeshGeometry -> aiMesh, return mesh index + 1 or 0 if the conversion failed // MeshGeometry -> aiMesh, return mesh index + 1 or 0 if the conversion failed
std::vector<unsigned int> ConvertMesh(const MeshGeometry& mesh, const Model& model, std::vector<unsigned int> ConvertMesh(const MeshGeometry& mesh, const Model& model,
const aiMatrix4x4& node_global_transform, aiNode& nd); const aiMatrix4x4& node_global_transform, aiNode& nd);
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
aiMesh* SetupEmptyMesh(const MeshGeometry& mesh, aiNode& nd); std::vector<unsigned int> 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, unsigned int ConvertMeshSingleMaterial(const MeshGeometry& mesh, const Model& model,
@ -424,6 +428,7 @@ private:
std::vector<aiLight*> lights; std::vector<aiLight*> lights;
std::vector<aiCamera*> cameras; std::vector<aiCamera*> cameras;
std::vector<aiTexture*> textures; std::vector<aiTexture*> textures;
typedef std::map<const Material*, unsigned int> MaterialMap; typedef std::map<const Material*, unsigned int> MaterialMap;
MaterialMap materials_converted; MaterialMap materials_converted;

View File

@ -149,6 +149,9 @@ const Object* LazyObject::Get(bool dieOnError)
if (!strcmp(classtag.c_str(), "Shape")) { if (!strcmp(classtag.c_str(), "Shape")) {
object.reset(new ShapeGeometry(id, element, name, doc)); 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)) { else if (!strncmp(obtype,"NodeAttribute",length)) {
if (!strcmp(classtag.c_str(),"Camera")) { if (!strcmp(classtag.c_str(),"Camera")) {

View File

@ -66,6 +66,7 @@ class PropertyTable;
class Document; class Document;
class Material; class Material;
class ShapeGeometry; class ShapeGeometry;
class LineGeometry;
class Geometry; class Geometry;
class Video; class Video;

View File

@ -679,6 +679,32 @@ const std::vector<aiVector3D>& ShapeGeometry::GetNormals() const {
const std::vector<unsigned int>& ShapeGeometry::GetIndices() const { const std::vector<unsigned int>& ShapeGeometry::GetIndices() const {
return m_indices; 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<aiVector3D>& LineGeometry::GetVertices() const {
return m_vertices;
}
// ------------------------------------------------------------------------------------------------
const std::vector<int>& LineGeometry::GetIndices() const {
return m_indices;
}
} // !FBX } // !FBX
} // !Assimp } // !Assimp
#endif #endif

View File

@ -205,6 +205,28 @@ private:
std::vector<aiVector3D> m_normals; std::vector<aiVector3D> m_normals;
std::vector<unsigned int> m_indices; std::vector<unsigned int> 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<aiVector3D>& GetVertices() const;
/** Return list of vertex indices. */
const std::vector<int>& GetIndices() const;
private:
std::vector<aiVector3D> m_vertices;
std::vector<int> m_indices;
};
} }
} }