Merge pull request #4666 from assimp/kimkulling/waveform_obj_optimizations
Improvements and optimizations for the obj-parsers.kimkulling/parallel-github-action
commit
dabaa7bdae
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2020, assimp team
|
Copyright (c) 2006-2022, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ struct Face {
|
||||||
using IndexArray = std::vector<unsigned int>;
|
using IndexArray = std::vector<unsigned int>;
|
||||||
|
|
||||||
//! Primitive type
|
//! Primitive type
|
||||||
aiPrimitiveType m_PrimitiveType;
|
aiPrimitiveType mPrimitiveType;
|
||||||
//! Vertex indices
|
//! Vertex indices
|
||||||
IndexArray m_vertices;
|
IndexArray m_vertices;
|
||||||
//! Normal indices
|
//! Normal indices
|
||||||
|
@ -76,14 +76,12 @@ struct Face {
|
||||||
|
|
||||||
//! \brief Default constructor
|
//! \brief Default constructor
|
||||||
Face(aiPrimitiveType pt = aiPrimitiveType_POLYGON) :
|
Face(aiPrimitiveType pt = aiPrimitiveType_POLYGON) :
|
||||||
m_PrimitiveType(pt), m_vertices(), m_normals(), m_texturCoords(), m_pMaterial(0L) {
|
mPrimitiveType(pt), m_vertices(), m_normals(), m_texturCoords(), m_pMaterial(nullptr) {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \brief Destructor
|
//! \brief Destructor
|
||||||
~Face() {
|
~Face() = default;
|
||||||
// empty
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -230,7 +228,7 @@ struct Mesh {
|
||||||
/// The name for the mesh
|
/// The name for the mesh
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
/// Array with pointer to all stored faces
|
/// Array with pointer to all stored faces
|
||||||
std::vector<Face *> m_Faces;
|
std::vector<Face*> m_Faces;
|
||||||
/// Assigned material
|
/// Assigned material
|
||||||
Material *m_pMaterial;
|
Material *m_pMaterial;
|
||||||
/// Number of stored indices.
|
/// Number of stored indices.
|
||||||
|
@ -273,65 +271,65 @@ struct Model {
|
||||||
using ConstGroupMapIt = std::map<std::string, std::vector<unsigned int> *>::const_iterator;
|
using ConstGroupMapIt = std::map<std::string, std::vector<unsigned int> *>::const_iterator;
|
||||||
|
|
||||||
//! Model name
|
//! Model name
|
||||||
std::string m_ModelName;
|
std::string mModelName;
|
||||||
//! List ob assigned objects
|
//! List ob assigned objects
|
||||||
std::vector<Object *> m_Objects;
|
std::vector<Object *> mObjects;
|
||||||
//! Pointer to current object
|
//! Pointer to current object
|
||||||
ObjFile::Object *m_pCurrent;
|
ObjFile::Object *mCurrentObject;
|
||||||
//! Pointer to current material
|
//! Pointer to current material
|
||||||
ObjFile::Material *m_pCurrentMaterial;
|
ObjFile::Material *mCurrentMaterial;
|
||||||
//! Pointer to default material
|
//! Pointer to default material
|
||||||
ObjFile::Material *m_pDefaultMaterial;
|
ObjFile::Material *mDefaultMaterial;
|
||||||
//! Vector with all generated materials
|
//! Vector with all generated materials
|
||||||
std::vector<std::string> m_MaterialLib;
|
std::vector<std::string> mMaterialLib;
|
||||||
//! Vector with all generated vertices
|
//! Vector with all generated vertices
|
||||||
std::vector<aiVector3D> m_Vertices;
|
std::vector<aiVector3D> mVertices;
|
||||||
//! vector with all generated normals
|
//! vector with all generated normals
|
||||||
std::vector<aiVector3D> m_Normals;
|
std::vector<aiVector3D> mNormals;
|
||||||
//! vector with all vertex colors
|
//! vector with all vertex colors
|
||||||
std::vector<aiVector3D> m_VertexColors;
|
std::vector<aiVector3D> mVertexColors;
|
||||||
//! Group map
|
//! Group map
|
||||||
GroupMap m_Groups;
|
GroupMap mGroups;
|
||||||
//! Group to face id assignment
|
//! Group to face id assignment
|
||||||
std::vector<unsigned int> *m_pGroupFaceIDs;
|
std::vector<unsigned int> *mGroupFaceIDs;
|
||||||
//! Active group
|
//! Active group
|
||||||
std::string m_strActiveGroup;
|
std::string mActiveGroup;
|
||||||
//! Vector with generated texture coordinates
|
//! Vector with generated texture coordinates
|
||||||
std::vector<aiVector3D> m_TextureCoord;
|
std::vector<aiVector3D> mTextureCoord;
|
||||||
//! Maximum dimension of texture coordinates
|
//! Maximum dimension of texture coordinates
|
||||||
unsigned int m_TextureCoordDim;
|
unsigned int mTextureCoordDim;
|
||||||
//! Current mesh instance
|
//! Current mesh instance
|
||||||
Mesh *m_pCurrentMesh;
|
Mesh *mCurrentMesh;
|
||||||
//! Vector with stored meshes
|
//! Vector with stored meshes
|
||||||
std::vector<Mesh *> m_Meshes;
|
std::vector<Mesh *> mMeshes;
|
||||||
//! Material map
|
//! Material map
|
||||||
std::map<std::string, Material *> m_MaterialMap;
|
std::map<std::string, Material*> mMaterialMap;
|
||||||
|
|
||||||
//! \brief The default class constructor
|
//! \brief The default class constructor
|
||||||
Model() :
|
Model() :
|
||||||
m_ModelName(),
|
mModelName(),
|
||||||
m_pCurrent(nullptr),
|
mCurrentObject(nullptr),
|
||||||
m_pCurrentMaterial(nullptr),
|
mCurrentMaterial(nullptr),
|
||||||
m_pDefaultMaterial(nullptr),
|
mDefaultMaterial(nullptr),
|
||||||
m_pGroupFaceIDs(nullptr),
|
mGroupFaceIDs(nullptr),
|
||||||
m_strActiveGroup(),
|
mActiveGroup(),
|
||||||
m_TextureCoordDim(0),
|
mTextureCoordDim(0),
|
||||||
m_pCurrentMesh(nullptr) {
|
mCurrentMesh(nullptr) {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \brief The class destructor
|
//! \brief The class destructor
|
||||||
~Model() {
|
~Model() {
|
||||||
for (auto & it : m_Objects) {
|
for (auto & it : mObjects) {
|
||||||
delete it;
|
delete it;
|
||||||
}
|
}
|
||||||
for (auto & Meshe : m_Meshes) {
|
for (auto & Meshe : mMeshes) {
|
||||||
delete Meshe;
|
delete Meshe;
|
||||||
}
|
}
|
||||||
for (auto & Group : m_Groups) {
|
for (auto & Group : mGroups) {
|
||||||
delete Group.second;
|
delete Group.second;
|
||||||
}
|
}
|
||||||
for (auto & it : m_MaterialMap) {
|
for (auto & it : mMaterialMap) {
|
||||||
delete it.second;
|
delete it.second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,20 +163,20 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model *pModel, aiScene
|
||||||
|
|
||||||
// Create the root node of the scene
|
// Create the root node of the scene
|
||||||
pScene->mRootNode = new aiNode;
|
pScene->mRootNode = new aiNode;
|
||||||
if (!pModel->m_ModelName.empty()) {
|
if (!pModel->mModelName.empty()) {
|
||||||
// Set the name of the scene
|
// Set the name of the scene
|
||||||
pScene->mRootNode->mName.Set(pModel->m_ModelName);
|
pScene->mRootNode->mName.Set(pModel->mModelName);
|
||||||
} else {
|
} else {
|
||||||
// This is a fatal error, so break down the application
|
// This is a fatal error, so break down the application
|
||||||
ai_assert(false);
|
ai_assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pModel->m_Objects.empty()) {
|
if (!pModel->mObjects.empty()) {
|
||||||
|
|
||||||
unsigned int meshCount = 0;
|
unsigned int meshCount = 0;
|
||||||
unsigned int childCount = 0;
|
unsigned int childCount = 0;
|
||||||
|
|
||||||
for (auto object : pModel->m_Objects) {
|
for (auto object : pModel->mObjects) {
|
||||||
if (object) {
|
if (object) {
|
||||||
++childCount;
|
++childCount;
|
||||||
meshCount += (unsigned int)object->m_Meshes.size();
|
meshCount += (unsigned int)object->m_Meshes.size();
|
||||||
|
@ -189,8 +189,8 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model *pModel, aiScene
|
||||||
// Create nodes for the whole scene
|
// Create nodes for the whole scene
|
||||||
std::vector<aiMesh *> MeshArray;
|
std::vector<aiMesh *> MeshArray;
|
||||||
MeshArray.reserve(meshCount);
|
MeshArray.reserve(meshCount);
|
||||||
for (size_t index = 0; index < pModel->m_Objects.size(); ++index) {
|
for (size_t index = 0; index < pModel->mObjects.size(); ++index) {
|
||||||
createNodes(pModel, pModel->m_Objects[index], pScene->mRootNode, pScene, MeshArray);
|
createNodes(pModel, pModel->mObjects[index], pScene->mRootNode, pScene, MeshArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
ai_assert(pScene->mRootNode->mNumChildren == childCount);
|
ai_assert(pScene->mRootNode->mNumChildren == childCount);
|
||||||
|
@ -206,31 +206,31 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model *pModel, aiScene
|
||||||
// Create all materials
|
// Create all materials
|
||||||
createMaterials(pModel, pScene);
|
createMaterials(pModel, pScene);
|
||||||
} else {
|
} else {
|
||||||
if (pModel->m_Vertices.empty()) {
|
if (pModel->mVertices.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<aiMesh> mesh(new aiMesh);
|
std::unique_ptr<aiMesh> mesh(new aiMesh);
|
||||||
mesh->mPrimitiveTypes = aiPrimitiveType_POINT;
|
mesh->mPrimitiveTypes = aiPrimitiveType_POINT;
|
||||||
unsigned int n = (unsigned int)pModel->m_Vertices.size();
|
unsigned int n = (unsigned int)pModel->mVertices.size();
|
||||||
mesh->mNumVertices = n;
|
mesh->mNumVertices = n;
|
||||||
|
|
||||||
mesh->mVertices = new aiVector3D[n];
|
mesh->mVertices = new aiVector3D[n];
|
||||||
memcpy(mesh->mVertices, pModel->m_Vertices.data(), n * sizeof(aiVector3D));
|
memcpy(mesh->mVertices, pModel->mVertices.data(), n * sizeof(aiVector3D));
|
||||||
|
|
||||||
if (!pModel->m_Normals.empty()) {
|
if (!pModel->mNormals.empty()) {
|
||||||
mesh->mNormals = new aiVector3D[n];
|
mesh->mNormals = new aiVector3D[n];
|
||||||
if (pModel->m_Normals.size() < n) {
|
if (pModel->mNormals.size() < n) {
|
||||||
throw DeadlyImportError("OBJ: vertex normal index out of range");
|
throw DeadlyImportError("OBJ: vertex normal index out of range");
|
||||||
}
|
}
|
||||||
memcpy(mesh->mNormals, pModel->m_Normals.data(), n * sizeof(aiVector3D));
|
memcpy(mesh->mNormals, pModel->mNormals.data(), n * sizeof(aiVector3D));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pModel->m_VertexColors.empty()) {
|
if (!pModel->mVertexColors.empty()) {
|
||||||
mesh->mColors[0] = new aiColor4D[mesh->mNumVertices];
|
mesh->mColors[0] = new aiColor4D[mesh->mNumVertices];
|
||||||
for (unsigned int i = 0; i < n; ++i) {
|
for (unsigned int i = 0; i < n; ++i) {
|
||||||
if (i < pModel->m_VertexColors.size()) {
|
if (i < pModel->mVertexColors.size()) {
|
||||||
const aiVector3D &color = pModel->m_VertexColors[i];
|
const aiVector3D &color = pModel->mVertexColors[i];
|
||||||
mesh->mColors[0][i] = aiColor4D(color.x, color.y, color.z, 1.0);
|
mesh->mColors[0][i] = aiColor4D(color.x, color.y, color.z, 1.0);
|
||||||
} else {
|
} else {
|
||||||
throw DeadlyImportError("OBJ: vertex color index out of range");
|
throw DeadlyImportError("OBJ: vertex color index out of range");
|
||||||
|
@ -315,7 +315,7 @@ aiMesh *ObjFileImporter::createTopology(const ObjFile::Model *pModel, const ObjF
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create faces
|
// Create faces
|
||||||
ObjFile::Mesh *pObjMesh = pModel->m_Meshes[meshIndex];
|
ObjFile::Mesh *pObjMesh = pModel->mMeshes[meshIndex];
|
||||||
if (!pObjMesh) {
|
if (!pObjMesh) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -330,13 +330,13 @@ aiMesh *ObjFileImporter::createTopology(const ObjFile::Model *pModel, const ObjF
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) {
|
for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) {
|
||||||
ObjFile::Face *const inp = pObjMesh->m_Faces[index];
|
const ObjFile::Face *inp = pObjMesh->m_Faces[index];
|
||||||
ai_assert(nullptr != inp);
|
//ai_assert(nullptr != inp);
|
||||||
|
|
||||||
if (inp->m_PrimitiveType == aiPrimitiveType_LINE) {
|
if (inp->mPrimitiveType == aiPrimitiveType_LINE) {
|
||||||
pMesh->mNumFaces += static_cast<unsigned int>(inp->m_vertices.size() - 1);
|
pMesh->mNumFaces += static_cast<unsigned int>(inp->m_vertices.size() - 1);
|
||||||
pMesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
|
pMesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
|
||||||
} else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) {
|
} else if (inp->mPrimitiveType == aiPrimitiveType_POINT) {
|
||||||
pMesh->mNumFaces += static_cast<unsigned int>(inp->m_vertices.size());
|
pMesh->mNumFaces += static_cast<unsigned int>(inp->m_vertices.size());
|
||||||
pMesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
|
pMesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
|
||||||
} else {
|
} else {
|
||||||
|
@ -360,15 +360,15 @@ aiMesh *ObjFileImporter::createTopology(const ObjFile::Model *pModel, const ObjF
|
||||||
|
|
||||||
// Copy all data from all stored meshes
|
// Copy all data from all stored meshes
|
||||||
for (auto &face : pObjMesh->m_Faces) {
|
for (auto &face : pObjMesh->m_Faces) {
|
||||||
ObjFile::Face *const inp = face;
|
const ObjFile::Face *inp = face;
|
||||||
if (inp->m_PrimitiveType == aiPrimitiveType_LINE) {
|
if (inp->mPrimitiveType == aiPrimitiveType_LINE) {
|
||||||
for (size_t i = 0; i < inp->m_vertices.size() - 1; ++i) {
|
for (size_t i = 0; i < inp->m_vertices.size() - 1; ++i) {
|
||||||
aiFace &f = pMesh->mFaces[outIndex++];
|
aiFace &f = pMesh->mFaces[outIndex++];
|
||||||
uiIdxCount += f.mNumIndices = 2;
|
uiIdxCount += f.mNumIndices = 2;
|
||||||
f.mIndices = new unsigned int[2];
|
f.mIndices = new unsigned int[2];
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
} else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) {
|
} else if (inp->mPrimitiveType == aiPrimitiveType_POINT) {
|
||||||
for (size_t i = 0; i < inp->m_vertices.size(); ++i) {
|
for (size_t i = 0; i < inp->m_vertices.size(); ++i) {
|
||||||
aiFace &f = pMesh->mFaces[outIndex++];
|
aiFace &f = pMesh->mFaces[outIndex++];
|
||||||
uiIdxCount += f.mNumIndices = 1;
|
uiIdxCount += f.mNumIndices = 1;
|
||||||
|
@ -407,7 +407,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model *pModel,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Get current mesh
|
// Get current mesh
|
||||||
ObjFile::Mesh *pObjMesh = pModel->m_Meshes[uiMeshIndex];
|
ObjFile::Mesh *pObjMesh = pModel->mMeshes[uiMeshIndex];
|
||||||
if (nullptr == pObjMesh || pObjMesh->m_uiNumIndices < 1) {
|
if (nullptr == pObjMesh || pObjMesh->m_uiNumIndices < 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -422,16 +422,16 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model *pModel,
|
||||||
pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
|
pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
|
||||||
|
|
||||||
// Allocate buffer for normal vectors
|
// Allocate buffer for normal vectors
|
||||||
if (!pModel->m_Normals.empty() && pObjMesh->m_hasNormals)
|
if (!pModel->mNormals.empty() && pObjMesh->m_hasNormals)
|
||||||
pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
|
pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
|
||||||
|
|
||||||
// Allocate buffer for vertex-color vectors
|
// Allocate buffer for vertex-color vectors
|
||||||
if (!pModel->m_VertexColors.empty())
|
if (!pModel->mVertexColors.empty())
|
||||||
pMesh->mColors[0] = new aiColor4D[pMesh->mNumVertices];
|
pMesh->mColors[0] = new aiColor4D[pMesh->mNumVertices];
|
||||||
|
|
||||||
// Allocate buffer for texture coordinates
|
// Allocate buffer for texture coordinates
|
||||||
if (!pModel->m_TextureCoord.empty() && pObjMesh->m_uiUVCoordinates[0]) {
|
if (!pModel->mTextureCoord.empty() && pObjMesh->m_uiUVCoordinates[0]) {
|
||||||
pMesh->mNumUVComponents[0] = pModel->m_TextureCoordDim;
|
pMesh->mNumUVComponents[0] = pModel->mTextureCoordDim;
|
||||||
pMesh->mTextureCoords[0] = new aiVector3D[pMesh->mNumVertices];
|
pMesh->mTextureCoords[0] = new aiVector3D[pMesh->mNumVertices];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,7 +442,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model *pModel,
|
||||||
// Copy all index arrays
|
// Copy all index arrays
|
||||||
for (size_t vertexIndex = 0, outVertexIndex = 0; vertexIndex < sourceFace->m_vertices.size(); vertexIndex++) {
|
for (size_t vertexIndex = 0, outVertexIndex = 0; vertexIndex < sourceFace->m_vertices.size(); vertexIndex++) {
|
||||||
const unsigned int vertex = sourceFace->m_vertices.at(vertexIndex);
|
const unsigned int vertex = sourceFace->m_vertices.at(vertexIndex);
|
||||||
if (vertex >= pModel->m_Vertices.size()) {
|
if (vertex >= pModel->mVertices.size()) {
|
||||||
throw DeadlyImportError("OBJ: vertex index out of range");
|
throw DeadlyImportError("OBJ: vertex index out of range");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,32 +450,32 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model *pModel,
|
||||||
throw DeadlyImportError("OBJ: bad vertex index");
|
throw DeadlyImportError("OBJ: bad vertex index");
|
||||||
}
|
}
|
||||||
|
|
||||||
pMesh->mVertices[newIndex] = pModel->m_Vertices[vertex];
|
pMesh->mVertices[newIndex] = pModel->mVertices[vertex];
|
||||||
|
|
||||||
// Copy all normals
|
// Copy all normals
|
||||||
if (normalsok && !pModel->m_Normals.empty() && vertexIndex < sourceFace->m_normals.size()) {
|
if (normalsok && !pModel->mNormals.empty() && vertexIndex < sourceFace->m_normals.size()) {
|
||||||
const unsigned int normal = sourceFace->m_normals.at(vertexIndex);
|
const unsigned int normal = sourceFace->m_normals.at(vertexIndex);
|
||||||
if (normal >= pModel->m_Normals.size()) {
|
if (normal >= pModel->mNormals.size()) {
|
||||||
normalsok = false;
|
normalsok = false;
|
||||||
} else {
|
} else {
|
||||||
pMesh->mNormals[newIndex] = pModel->m_Normals[normal];
|
pMesh->mNormals[newIndex] = pModel->mNormals[normal];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy all vertex colors
|
// Copy all vertex colors
|
||||||
if (vertex < pModel->m_VertexColors.size()) {
|
if (vertex < pModel->mVertexColors.size()) {
|
||||||
const aiVector3D &color = pModel->m_VertexColors[vertex];
|
const aiVector3D &color = pModel->mVertexColors[vertex];
|
||||||
pMesh->mColors[0][newIndex] = aiColor4D(color.x, color.y, color.z, 1.0);
|
pMesh->mColors[0][newIndex] = aiColor4D(color.x, color.y, color.z, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy all texture coordinates
|
// Copy all texture coordinates
|
||||||
if (uvok && !pModel->m_TextureCoord.empty() && vertexIndex < sourceFace->m_texturCoords.size()) {
|
if (uvok && !pModel->mTextureCoord.empty() && vertexIndex < sourceFace->m_texturCoords.size()) {
|
||||||
const unsigned int tex = sourceFace->m_texturCoords.at(vertexIndex);
|
const unsigned int tex = sourceFace->m_texturCoords.at(vertexIndex);
|
||||||
|
|
||||||
if (tex >= pModel->m_TextureCoord.size()) {
|
if (tex >= pModel->mTextureCoord.size()) {
|
||||||
uvok = false;
|
uvok = false;
|
||||||
} else {
|
} else {
|
||||||
const aiVector3D &coord3d = pModel->m_TextureCoord[tex];
|
const aiVector3D &coord3d = pModel->mTextureCoord[tex];
|
||||||
pMesh->mTextureCoords[0][newIndex] = aiVector3D(coord3d.x, coord3d.y, coord3d.z);
|
pMesh->mTextureCoords[0][newIndex] = aiVector3D(coord3d.x, coord3d.y, coord3d.z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -484,15 +484,15 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model *pModel,
|
||||||
aiFace *pDestFace = &pMesh->mFaces[outIndex];
|
aiFace *pDestFace = &pMesh->mFaces[outIndex];
|
||||||
|
|
||||||
const bool last = (vertexIndex == sourceFace->m_vertices.size() - 1);
|
const bool last = (vertexIndex == sourceFace->m_vertices.size() - 1);
|
||||||
if (sourceFace->m_PrimitiveType != aiPrimitiveType_LINE || !last) {
|
if (sourceFace->mPrimitiveType != aiPrimitiveType_LINE || !last) {
|
||||||
pDestFace->mIndices[outVertexIndex] = newIndex;
|
pDestFace->mIndices[outVertexIndex] = newIndex;
|
||||||
outVertexIndex++;
|
outVertexIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sourceFace->m_PrimitiveType == aiPrimitiveType_POINT) {
|
if (sourceFace->mPrimitiveType == aiPrimitiveType_POINT) {
|
||||||
outIndex++;
|
outIndex++;
|
||||||
outVertexIndex = 0;
|
outVertexIndex = 0;
|
||||||
} else if (sourceFace->m_PrimitiveType == aiPrimitiveType_LINE) {
|
} else if (sourceFace->mPrimitiveType == aiPrimitiveType_LINE) {
|
||||||
outVertexIndex = 0;
|
outVertexIndex = 0;
|
||||||
|
|
||||||
if (!last)
|
if (!last)
|
||||||
|
@ -501,10 +501,10 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model *pModel,
|
||||||
if (vertexIndex) {
|
if (vertexIndex) {
|
||||||
if (!last) {
|
if (!last) {
|
||||||
pMesh->mVertices[newIndex + 1] = pMesh->mVertices[newIndex];
|
pMesh->mVertices[newIndex + 1] = pMesh->mVertices[newIndex];
|
||||||
if (!sourceFace->m_normals.empty() && !pModel->m_Normals.empty()) {
|
if (!sourceFace->m_normals.empty() && !pModel->mNormals.empty()) {
|
||||||
pMesh->mNormals[newIndex + 1] = pMesh->mNormals[newIndex];
|
pMesh->mNormals[newIndex + 1] = pMesh->mNormals[newIndex];
|
||||||
}
|
}
|
||||||
if (!pModel->m_TextureCoord.empty()) {
|
if (!pModel->mTextureCoord.empty()) {
|
||||||
for (size_t i = 0; i < pMesh->GetNumUVChannels(); i++) {
|
for (size_t i = 0; i < pMesh->GetNumUVChannels(); i++) {
|
||||||
pMesh->mTextureCoords[i][newIndex + 1] = pMesh->mTextureCoords[i][newIndex];
|
pMesh->mTextureCoords[i][newIndex + 1] = pMesh->mTextureCoords[i][newIndex];
|
||||||
}
|
}
|
||||||
|
@ -565,9 +565,9 @@ void ObjFileImporter::createMaterials(const ObjFile::Model *pModel, aiScene *pSc
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned int numMaterials = (unsigned int)pModel->m_MaterialLib.size();
|
const unsigned int numMaterials = (unsigned int)pModel->mMaterialLib.size();
|
||||||
pScene->mNumMaterials = 0;
|
pScene->mNumMaterials = 0;
|
||||||
if (pModel->m_MaterialLib.empty()) {
|
if (pModel->mMaterialLib.empty()) {
|
||||||
ASSIMP_LOG_DEBUG("OBJ: no materials specified");
|
ASSIMP_LOG_DEBUG("OBJ: no materials specified");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -576,10 +576,10 @@ void ObjFileImporter::createMaterials(const ObjFile::Model *pModel, aiScene *pSc
|
||||||
for (unsigned int matIndex = 0; matIndex < numMaterials; matIndex++) {
|
for (unsigned int matIndex = 0; matIndex < numMaterials; matIndex++) {
|
||||||
// Store material name
|
// Store material name
|
||||||
std::map<std::string, ObjFile::Material *>::const_iterator it;
|
std::map<std::string, ObjFile::Material *>::const_iterator it;
|
||||||
it = pModel->m_MaterialMap.find(pModel->m_MaterialLib[matIndex]);
|
it = pModel->mMaterialMap.find(pModel->mMaterialLib[matIndex]);
|
||||||
|
|
||||||
// No material found, use the default material
|
// No material found, use the default material
|
||||||
if (pModel->m_MaterialMap.end() == it)
|
if (pModel->mMaterialMap.end() == it)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
aiMaterial *mat = new aiMaterial;
|
aiMaterial *mat = new aiMaterial;
|
||||||
|
|
|
@ -99,9 +99,9 @@ ObjFileMtlImporter::ObjFileMtlImporter(std::vector<char> &buffer,
|
||||||
ai_assert(nullptr != m_pModel);
|
ai_assert(nullptr != m_pModel);
|
||||||
m_buffer.resize(BUFFERSIZE);
|
m_buffer.resize(BUFFERSIZE);
|
||||||
std::fill(m_buffer.begin(), m_buffer.end(), '\0');
|
std::fill(m_buffer.begin(), m_buffer.end(), '\0');
|
||||||
if (nullptr == m_pModel->m_pDefaultMaterial) {
|
if (nullptr == m_pModel->mDefaultMaterial) {
|
||||||
m_pModel->m_pDefaultMaterial = new ObjFile::Material;
|
m_pModel->mDefaultMaterial = new ObjFile::Material;
|
||||||
m_pModel->m_pDefaultMaterial->MaterialName.Set("default");
|
m_pModel->mDefaultMaterial->MaterialName.Set("default");
|
||||||
}
|
}
|
||||||
load();
|
load();
|
||||||
}
|
}
|
||||||
|
@ -126,21 +126,21 @@ void ObjFileMtlImporter::load() {
|
||||||
if (*m_DataIt == 'a') // Ambient color
|
if (*m_DataIt == 'a') // Ambient color
|
||||||
{
|
{
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
if (m_pModel->m_pCurrentMaterial != nullptr)
|
if (m_pModel->mCurrentMaterial != nullptr)
|
||||||
getColorRGBA(&m_pModel->m_pCurrentMaterial->ambient);
|
getColorRGBA(&m_pModel->mCurrentMaterial->ambient);
|
||||||
} else if (*m_DataIt == 'd') {
|
} else if (*m_DataIt == 'd') {
|
||||||
// Diffuse color
|
// Diffuse color
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
if (m_pModel->m_pCurrentMaterial != nullptr)
|
if (m_pModel->mCurrentMaterial != nullptr)
|
||||||
getColorRGBA(&m_pModel->m_pCurrentMaterial->diffuse);
|
getColorRGBA(&m_pModel->mCurrentMaterial->diffuse);
|
||||||
} else if (*m_DataIt == 's') {
|
} else if (*m_DataIt == 's') {
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
if (m_pModel->m_pCurrentMaterial != nullptr)
|
if (m_pModel->mCurrentMaterial != nullptr)
|
||||||
getColorRGBA(&m_pModel->m_pCurrentMaterial->specular);
|
getColorRGBA(&m_pModel->mCurrentMaterial->specular);
|
||||||
} else if (*m_DataIt == 'e') {
|
} else if (*m_DataIt == 'e') {
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
if (m_pModel->m_pCurrentMaterial != nullptr)
|
if (m_pModel->mCurrentMaterial != nullptr)
|
||||||
getColorRGBA(&m_pModel->m_pCurrentMaterial->emissive);
|
getColorRGBA(&m_pModel->mCurrentMaterial->emissive);
|
||||||
}
|
}
|
||||||
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
||||||
} break;
|
} break;
|
||||||
|
@ -149,15 +149,15 @@ void ObjFileMtlImporter::load() {
|
||||||
// Material transmission color
|
// Material transmission color
|
||||||
if (*m_DataIt == 'f') {
|
if (*m_DataIt == 'f') {
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
if (m_pModel->m_pCurrentMaterial != nullptr)
|
if (m_pModel->mCurrentMaterial != nullptr)
|
||||||
getColorRGBA(&m_pModel->m_pCurrentMaterial->transparent);
|
getColorRGBA(&m_pModel->mCurrentMaterial->transparent);
|
||||||
} else if (*m_DataIt == 'r') {
|
} else if (*m_DataIt == 'r') {
|
||||||
// Material transmission alpha value
|
// Material transmission alpha value
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
ai_real d;
|
ai_real d;
|
||||||
getFloatValue(d);
|
getFloatValue(d);
|
||||||
if (m_pModel->m_pCurrentMaterial != nullptr)
|
if (m_pModel->mCurrentMaterial != nullptr)
|
||||||
m_pModel->m_pCurrentMaterial->alpha = static_cast<ai_real>(1.0) - d;
|
m_pModel->mCurrentMaterial->alpha = static_cast<ai_real>(1.0) - d;
|
||||||
}
|
}
|
||||||
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
||||||
} break;
|
} break;
|
||||||
|
@ -168,8 +168,8 @@ void ObjFileMtlImporter::load() {
|
||||||
} else {
|
} else {
|
||||||
// Alpha value
|
// Alpha value
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
if (m_pModel->m_pCurrentMaterial != nullptr)
|
if (m_pModel->mCurrentMaterial != nullptr)
|
||||||
getFloatValue(m_pModel->m_pCurrentMaterial->alpha);
|
getFloatValue(m_pModel->mCurrentMaterial->alpha);
|
||||||
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
@ -180,13 +180,13 @@ void ObjFileMtlImporter::load() {
|
||||||
switch (*m_DataIt) {
|
switch (*m_DataIt) {
|
||||||
case 's': // Specular exponent
|
case 's': // Specular exponent
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
if (m_pModel->m_pCurrentMaterial != nullptr)
|
if (m_pModel->mCurrentMaterial != nullptr)
|
||||||
getFloatValue(m_pModel->m_pCurrentMaterial->shineness);
|
getFloatValue(m_pModel->mCurrentMaterial->shineness);
|
||||||
break;
|
break;
|
||||||
case 'i': // Index Of refraction
|
case 'i': // Index Of refraction
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
if (m_pModel->m_pCurrentMaterial != nullptr)
|
if (m_pModel->mCurrentMaterial != nullptr)
|
||||||
getFloatValue(m_pModel->m_pCurrentMaterial->ior);
|
getFloatValue(m_pModel->mCurrentMaterial->ior);
|
||||||
break;
|
break;
|
||||||
case 'e': // New material
|
case 'e': // New material
|
||||||
createMaterial();
|
createMaterial();
|
||||||
|
@ -206,28 +206,28 @@ void ObjFileMtlImporter::load() {
|
||||||
{
|
{
|
||||||
case 'r':
|
case 'r':
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
if (m_pModel->m_pCurrentMaterial != nullptr)
|
if (m_pModel->mCurrentMaterial != nullptr)
|
||||||
getFloatValue(m_pModel->m_pCurrentMaterial->roughness);
|
getFloatValue(m_pModel->mCurrentMaterial->roughness);
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
if (m_pModel->m_pCurrentMaterial != nullptr)
|
if (m_pModel->mCurrentMaterial != nullptr)
|
||||||
getFloatValue(m_pModel->m_pCurrentMaterial->metallic);
|
getFloatValue(m_pModel->mCurrentMaterial->metallic);
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
if (m_pModel->m_pCurrentMaterial != nullptr)
|
if (m_pModel->mCurrentMaterial != nullptr)
|
||||||
getColorRGBA(m_pModel->m_pCurrentMaterial->sheen);
|
getColorRGBA(m_pModel->mCurrentMaterial->sheen);
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
if (*m_DataIt == 'r') {
|
if (*m_DataIt == 'r') {
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
if (m_pModel->m_pCurrentMaterial != nullptr)
|
if (m_pModel->mCurrentMaterial != nullptr)
|
||||||
getFloatValue(m_pModel->m_pCurrentMaterial->clearcoat_roughness);
|
getFloatValue(m_pModel->mCurrentMaterial->clearcoat_roughness);
|
||||||
} else {
|
} else {
|
||||||
if (m_pModel->m_pCurrentMaterial != nullptr)
|
if (m_pModel->mCurrentMaterial != nullptr)
|
||||||
getFloatValue(m_pModel->m_pCurrentMaterial->clearcoat_thickness);
|
getFloatValue(m_pModel->mCurrentMaterial->clearcoat_thickness);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -246,16 +246,16 @@ void ObjFileMtlImporter::load() {
|
||||||
case 'i': // Illumination model
|
case 'i': // Illumination model
|
||||||
{
|
{
|
||||||
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
||||||
if (m_pModel->m_pCurrentMaterial != nullptr)
|
if (m_pModel->mCurrentMaterial != nullptr)
|
||||||
getIlluminationModel(m_pModel->m_pCurrentMaterial->illumination_model);
|
getIlluminationModel(m_pModel->mCurrentMaterial->illumination_model);
|
||||||
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case 'a': // Anisotropy
|
case 'a': // Anisotropy
|
||||||
{
|
{
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
getFloatValue(m_pModel->m_pCurrentMaterial->anisotropy);
|
getFloatValue(m_pModel->mCurrentMaterial->anisotropy);
|
||||||
if (m_pModel->m_pCurrentMaterial != nullptr)
|
if (m_pModel->mCurrentMaterial != nullptr)
|
||||||
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -345,20 +345,20 @@ void ObjFileMtlImporter::createMaterial() {
|
||||||
|
|
||||||
name = trim_whitespaces(name);
|
name = trim_whitespaces(name);
|
||||||
|
|
||||||
std::map<std::string, ObjFile::Material *>::iterator it = m_pModel->m_MaterialMap.find(name);
|
std::map<std::string, ObjFile::Material *>::iterator it = m_pModel->mMaterialMap.find(name);
|
||||||
if (m_pModel->m_MaterialMap.end() == it) {
|
if (m_pModel->mMaterialMap.end() == it) {
|
||||||
// New Material created
|
// New Material created
|
||||||
m_pModel->m_pCurrentMaterial = new ObjFile::Material();
|
m_pModel->mCurrentMaterial = new ObjFile::Material();
|
||||||
m_pModel->m_pCurrentMaterial->MaterialName.Set(name);
|
m_pModel->mCurrentMaterial->MaterialName.Set(name);
|
||||||
m_pModel->m_MaterialLib.push_back(name);
|
m_pModel->mMaterialLib.push_back(name);
|
||||||
m_pModel->m_MaterialMap[name] = m_pModel->m_pCurrentMaterial;
|
m_pModel->mMaterialMap[name] = m_pModel->mCurrentMaterial;
|
||||||
|
|
||||||
if (m_pModel->m_pCurrentMesh) {
|
if (m_pModel->mCurrentMesh) {
|
||||||
m_pModel->m_pCurrentMesh->m_uiMaterialIndex = static_cast<unsigned int>(m_pModel->m_MaterialLib.size() - 1);
|
m_pModel->mCurrentMesh->m_uiMaterialIndex = static_cast<unsigned int>(m_pModel->mMaterialLib.size() - 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Use older material
|
// Use older material
|
||||||
m_pModel->m_pCurrentMaterial = (*it).second;
|
m_pModel->mCurrentMaterial = (*it).second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,38 +371,38 @@ void ObjFileMtlImporter::getTexture() {
|
||||||
const char *pPtr(&(*m_DataIt));
|
const char *pPtr(&(*m_DataIt));
|
||||||
if (!ASSIMP_strincmp(pPtr, DiffuseTexture.c_str(), static_cast<unsigned int>(DiffuseTexture.size()))) {
|
if (!ASSIMP_strincmp(pPtr, DiffuseTexture.c_str(), static_cast<unsigned int>(DiffuseTexture.size()))) {
|
||||||
// Diffuse texture
|
// Diffuse texture
|
||||||
out = &m_pModel->m_pCurrentMaterial->texture;
|
out = &m_pModel->mCurrentMaterial->texture;
|
||||||
clampIndex = ObjFile::Material::TextureDiffuseType;
|
clampIndex = ObjFile::Material::TextureDiffuseType;
|
||||||
} else if (!ASSIMP_strincmp(pPtr, AmbientTexture.c_str(), static_cast<unsigned int>(AmbientTexture.size()))) {
|
} else if (!ASSIMP_strincmp(pPtr, AmbientTexture.c_str(), static_cast<unsigned int>(AmbientTexture.size()))) {
|
||||||
// Ambient texture
|
// Ambient texture
|
||||||
out = &m_pModel->m_pCurrentMaterial->textureAmbient;
|
out = &m_pModel->mCurrentMaterial->textureAmbient;
|
||||||
clampIndex = ObjFile::Material::TextureAmbientType;
|
clampIndex = ObjFile::Material::TextureAmbientType;
|
||||||
} else if (!ASSIMP_strincmp(pPtr, SpecularTexture.c_str(), static_cast<unsigned int>(SpecularTexture.size()))) {
|
} else if (!ASSIMP_strincmp(pPtr, SpecularTexture.c_str(), static_cast<unsigned int>(SpecularTexture.size()))) {
|
||||||
// Specular texture
|
// Specular texture
|
||||||
out = &m_pModel->m_pCurrentMaterial->textureSpecular;
|
out = &m_pModel->mCurrentMaterial->textureSpecular;
|
||||||
clampIndex = ObjFile::Material::TextureSpecularType;
|
clampIndex = ObjFile::Material::TextureSpecularType;
|
||||||
} else if (!ASSIMP_strincmp(pPtr, DisplacementTexture1.c_str(), static_cast<unsigned int>(DisplacementTexture1.size())) ||
|
} else if (!ASSIMP_strincmp(pPtr, DisplacementTexture1.c_str(), static_cast<unsigned int>(DisplacementTexture1.size())) ||
|
||||||
!ASSIMP_strincmp(pPtr, DisplacementTexture2.c_str(), static_cast<unsigned int>(DisplacementTexture2.size()))) {
|
!ASSIMP_strincmp(pPtr, DisplacementTexture2.c_str(), static_cast<unsigned int>(DisplacementTexture2.size()))) {
|
||||||
// Displacement texture
|
// Displacement texture
|
||||||
out = &m_pModel->m_pCurrentMaterial->textureDisp;
|
out = &m_pModel->mCurrentMaterial->textureDisp;
|
||||||
clampIndex = ObjFile::Material::TextureDispType;
|
clampIndex = ObjFile::Material::TextureDispType;
|
||||||
} else if (!ASSIMP_strincmp(pPtr, OpacityTexture.c_str(), static_cast<unsigned int>(OpacityTexture.size()))) {
|
} else if (!ASSIMP_strincmp(pPtr, OpacityTexture.c_str(), static_cast<unsigned int>(OpacityTexture.size()))) {
|
||||||
// Opacity texture
|
// Opacity texture
|
||||||
out = &m_pModel->m_pCurrentMaterial->textureOpacity;
|
out = &m_pModel->mCurrentMaterial->textureOpacity;
|
||||||
clampIndex = ObjFile::Material::TextureOpacityType;
|
clampIndex = ObjFile::Material::TextureOpacityType;
|
||||||
} else if (!ASSIMP_strincmp(pPtr, EmissiveTexture1.c_str(), static_cast<unsigned int>(EmissiveTexture1.size())) ||
|
} else if (!ASSIMP_strincmp(pPtr, EmissiveTexture1.c_str(), static_cast<unsigned int>(EmissiveTexture1.size())) ||
|
||||||
!ASSIMP_strincmp(pPtr, EmissiveTexture2.c_str(), static_cast<unsigned int>(EmissiveTexture2.size()))) {
|
!ASSIMP_strincmp(pPtr, EmissiveTexture2.c_str(), static_cast<unsigned int>(EmissiveTexture2.size()))) {
|
||||||
// Emissive texture
|
// Emissive texture
|
||||||
out = &m_pModel->m_pCurrentMaterial->textureEmissive;
|
out = &m_pModel->mCurrentMaterial->textureEmissive;
|
||||||
clampIndex = ObjFile::Material::TextureEmissiveType;
|
clampIndex = ObjFile::Material::TextureEmissiveType;
|
||||||
} else if (!ASSIMP_strincmp(pPtr, BumpTexture1.c_str(), static_cast<unsigned int>(BumpTexture1.size())) ||
|
} else if (!ASSIMP_strincmp(pPtr, BumpTexture1.c_str(), static_cast<unsigned int>(BumpTexture1.size())) ||
|
||||||
!ASSIMP_strincmp(pPtr, BumpTexture2.c_str(), static_cast<unsigned int>(BumpTexture2.size()))) {
|
!ASSIMP_strincmp(pPtr, BumpTexture2.c_str(), static_cast<unsigned int>(BumpTexture2.size()))) {
|
||||||
// Bump texture
|
// Bump texture
|
||||||
out = &m_pModel->m_pCurrentMaterial->textureBump;
|
out = &m_pModel->mCurrentMaterial->textureBump;
|
||||||
clampIndex = ObjFile::Material::TextureBumpType;
|
clampIndex = ObjFile::Material::TextureBumpType;
|
||||||
} else if (!ASSIMP_strincmp(pPtr, NormalTextureV1.c_str(), static_cast<unsigned int>(NormalTextureV1.size())) || !ASSIMP_strincmp(pPtr, NormalTextureV2.c_str(), static_cast<unsigned int>(NormalTextureV2.size()))) {
|
} else if (!ASSIMP_strincmp(pPtr, NormalTextureV1.c_str(), static_cast<unsigned int>(NormalTextureV1.size())) || !ASSIMP_strincmp(pPtr, NormalTextureV2.c_str(), static_cast<unsigned int>(NormalTextureV2.size()))) {
|
||||||
// Normal map
|
// Normal map
|
||||||
out = &m_pModel->m_pCurrentMaterial->textureNormal;
|
out = &m_pModel->mCurrentMaterial->textureNormal;
|
||||||
clampIndex = ObjFile::Material::TextureNormalType;
|
clampIndex = ObjFile::Material::TextureNormalType;
|
||||||
} else if (!ASSIMP_strincmp(pPtr, ReflectionTexture.c_str(), static_cast<unsigned int>(ReflectionTexture.size()))) {
|
} else if (!ASSIMP_strincmp(pPtr, ReflectionTexture.c_str(), static_cast<unsigned int>(ReflectionTexture.size()))) {
|
||||||
// Reflection texture(s)
|
// Reflection texture(s)
|
||||||
|
@ -410,23 +410,23 @@ void ObjFileMtlImporter::getTexture() {
|
||||||
return;
|
return;
|
||||||
} else if (!ASSIMP_strincmp(pPtr, SpecularityTexture.c_str(), static_cast<unsigned int>(SpecularityTexture.size()))) {
|
} else if (!ASSIMP_strincmp(pPtr, SpecularityTexture.c_str(), static_cast<unsigned int>(SpecularityTexture.size()))) {
|
||||||
// Specularity scaling (glossiness)
|
// Specularity scaling (glossiness)
|
||||||
out = &m_pModel->m_pCurrentMaterial->textureSpecularity;
|
out = &m_pModel->mCurrentMaterial->textureSpecularity;
|
||||||
clampIndex = ObjFile::Material::TextureSpecularityType;
|
clampIndex = ObjFile::Material::TextureSpecularityType;
|
||||||
} else if ( !ASSIMP_strincmp( pPtr, RoughnessTexture.c_str(), static_cast<unsigned int>(RoughnessTexture.size()))) {
|
} else if ( !ASSIMP_strincmp( pPtr, RoughnessTexture.c_str(), static_cast<unsigned int>(RoughnessTexture.size()))) {
|
||||||
// PBR Roughness texture
|
// PBR Roughness texture
|
||||||
out = & m_pModel->m_pCurrentMaterial->textureRoughness;
|
out = & m_pModel->mCurrentMaterial->textureRoughness;
|
||||||
clampIndex = ObjFile::Material::TextureRoughnessType;
|
clampIndex = ObjFile::Material::TextureRoughnessType;
|
||||||
} else if ( !ASSIMP_strincmp( pPtr, MetallicTexture.c_str(), static_cast<unsigned int>(MetallicTexture.size()))) {
|
} else if ( !ASSIMP_strincmp( pPtr, MetallicTexture.c_str(), static_cast<unsigned int>(MetallicTexture.size()))) {
|
||||||
// PBR Metallic texture
|
// PBR Metallic texture
|
||||||
out = & m_pModel->m_pCurrentMaterial->textureMetallic;
|
out = & m_pModel->mCurrentMaterial->textureMetallic;
|
||||||
clampIndex = ObjFile::Material::TextureMetallicType;
|
clampIndex = ObjFile::Material::TextureMetallicType;
|
||||||
} else if (!ASSIMP_strincmp( pPtr, SheenTexture.c_str(), static_cast<unsigned int>(SheenTexture.size()))) {
|
} else if (!ASSIMP_strincmp( pPtr, SheenTexture.c_str(), static_cast<unsigned int>(SheenTexture.size()))) {
|
||||||
// PBR Sheen (reflectance) texture
|
// PBR Sheen (reflectance) texture
|
||||||
out = & m_pModel->m_pCurrentMaterial->textureSheen;
|
out = & m_pModel->mCurrentMaterial->textureSheen;
|
||||||
clampIndex = ObjFile::Material::TextureSheenType;
|
clampIndex = ObjFile::Material::TextureSheenType;
|
||||||
} else if (!ASSIMP_strincmp( pPtr, RMATexture.c_str(), static_cast<unsigned int>(RMATexture.size()))) {
|
} else if (!ASSIMP_strincmp( pPtr, RMATexture.c_str(), static_cast<unsigned int>(RMATexture.size()))) {
|
||||||
// PBR Rough/Metal/AO texture
|
// PBR Rough/Metal/AO texture
|
||||||
out = & m_pModel->m_pCurrentMaterial->textureRMA;
|
out = & m_pModel->mCurrentMaterial->textureRMA;
|
||||||
clampIndex = ObjFile::Material::TextureRMAType;
|
clampIndex = ObjFile::Material::TextureRMAType;
|
||||||
} else {
|
} else {
|
||||||
ASSIMP_LOG_ERROR("OBJ/MTL: Encountered unknown texture type");
|
ASSIMP_LOG_ERROR("OBJ/MTL: Encountered unknown texture type");
|
||||||
|
@ -435,7 +435,7 @@ void ObjFileMtlImporter::getTexture() {
|
||||||
|
|
||||||
bool clamp = false;
|
bool clamp = false;
|
||||||
getTextureOption(clamp, clampIndex, out);
|
getTextureOption(clamp, clampIndex, out);
|
||||||
m_pModel->m_pCurrentMaterial->clamp[clampIndex] = clamp;
|
m_pModel->mCurrentMaterial->clamp[clampIndex] = clamp;
|
||||||
|
|
||||||
std::string texture;
|
std::string texture;
|
||||||
m_DataIt = getName<DataArrayIt>(m_DataIt, m_DataItEnd, texture);
|
m_DataIt = getName<DataArrayIt>(m_DataIt, m_DataItEnd, texture);
|
||||||
|
@ -483,31 +483,31 @@ void ObjFileMtlImporter::getTextureOption(bool &clamp, int &clampIndex, aiString
|
||||||
CopyNextWord(it, m_DataItEnd, value, sizeof(value) / sizeof(*value));
|
CopyNextWord(it, m_DataItEnd, value, sizeof(value) / sizeof(*value));
|
||||||
if (!ASSIMP_strincmp(value, "cube_top", 8)) {
|
if (!ASSIMP_strincmp(value, "cube_top", 8)) {
|
||||||
clampIndex = ObjFile::Material::TextureReflectionCubeTopType;
|
clampIndex = ObjFile::Material::TextureReflectionCubeTopType;
|
||||||
out = &m_pModel->m_pCurrentMaterial->textureReflection[0];
|
out = &m_pModel->mCurrentMaterial->textureReflection[0];
|
||||||
} else if (!ASSIMP_strincmp(value, "cube_bottom", 11)) {
|
} else if (!ASSIMP_strincmp(value, "cube_bottom", 11)) {
|
||||||
clampIndex = ObjFile::Material::TextureReflectionCubeBottomType;
|
clampIndex = ObjFile::Material::TextureReflectionCubeBottomType;
|
||||||
out = &m_pModel->m_pCurrentMaterial->textureReflection[1];
|
out = &m_pModel->mCurrentMaterial->textureReflection[1];
|
||||||
} else if (!ASSIMP_strincmp(value, "cube_front", 10)) {
|
} else if (!ASSIMP_strincmp(value, "cube_front", 10)) {
|
||||||
clampIndex = ObjFile::Material::TextureReflectionCubeFrontType;
|
clampIndex = ObjFile::Material::TextureReflectionCubeFrontType;
|
||||||
out = &m_pModel->m_pCurrentMaterial->textureReflection[2];
|
out = &m_pModel->mCurrentMaterial->textureReflection[2];
|
||||||
} else if (!ASSIMP_strincmp(value, "cube_back", 9)) {
|
} else if (!ASSIMP_strincmp(value, "cube_back", 9)) {
|
||||||
clampIndex = ObjFile::Material::TextureReflectionCubeBackType;
|
clampIndex = ObjFile::Material::TextureReflectionCubeBackType;
|
||||||
out = &m_pModel->m_pCurrentMaterial->textureReflection[3];
|
out = &m_pModel->mCurrentMaterial->textureReflection[3];
|
||||||
} else if (!ASSIMP_strincmp(value, "cube_left", 9)) {
|
} else if (!ASSIMP_strincmp(value, "cube_left", 9)) {
|
||||||
clampIndex = ObjFile::Material::TextureReflectionCubeLeftType;
|
clampIndex = ObjFile::Material::TextureReflectionCubeLeftType;
|
||||||
out = &m_pModel->m_pCurrentMaterial->textureReflection[4];
|
out = &m_pModel->mCurrentMaterial->textureReflection[4];
|
||||||
} else if (!ASSIMP_strincmp(value, "cube_right", 10)) {
|
} else if (!ASSIMP_strincmp(value, "cube_right", 10)) {
|
||||||
clampIndex = ObjFile::Material::TextureReflectionCubeRightType;
|
clampIndex = ObjFile::Material::TextureReflectionCubeRightType;
|
||||||
out = &m_pModel->m_pCurrentMaterial->textureReflection[5];
|
out = &m_pModel->mCurrentMaterial->textureReflection[5];
|
||||||
} else if (!ASSIMP_strincmp(value, "sphere", 6)) {
|
} else if (!ASSIMP_strincmp(value, "sphere", 6)) {
|
||||||
clampIndex = ObjFile::Material::TextureReflectionSphereType;
|
clampIndex = ObjFile::Material::TextureReflectionSphereType;
|
||||||
out = &m_pModel->m_pCurrentMaterial->textureReflection[0];
|
out = &m_pModel->mCurrentMaterial->textureReflection[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
skipToken = 2;
|
skipToken = 2;
|
||||||
} else if (!ASSIMP_strincmp(pPtr, BumpOption.c_str(), static_cast<unsigned int>(BumpOption.size()))) {
|
} else if (!ASSIMP_strincmp(pPtr, BumpOption.c_str(), static_cast<unsigned int>(BumpOption.size()))) {
|
||||||
DataArrayIt it = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
DataArrayIt it = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
||||||
getFloat(it, m_DataItEnd, m_pModel->m_pCurrentMaterial->bump_multiplier);
|
getFloat(it, m_DataItEnd, m_pModel->mCurrentMaterial->bump_multiplier);
|
||||||
skipToken = 2;
|
skipToken = 2;
|
||||||
} else if (!ASSIMP_strincmp(pPtr, BlendUOption.c_str(), static_cast<unsigned int>(BlendUOption.size())) || !ASSIMP_strincmp(pPtr, BlendVOption.c_str(), static_cast<unsigned int>(BlendVOption.size())) || !ASSIMP_strincmp(pPtr, BoostOption.c_str(), static_cast<unsigned int>(BoostOption.size())) || !ASSIMP_strincmp(pPtr, ResolutionOption.c_str(), static_cast<unsigned int>(ResolutionOption.size())) || !ASSIMP_strincmp(pPtr, ChannelOption.c_str(), static_cast<unsigned int>(ChannelOption.size()))) {
|
} else if (!ASSIMP_strincmp(pPtr, BlendUOption.c_str(), static_cast<unsigned int>(BlendUOption.size())) || !ASSIMP_strincmp(pPtr, BlendVOption.c_str(), static_cast<unsigned int>(BlendVOption.size())) || !ASSIMP_strincmp(pPtr, BoostOption.c_str(), static_cast<unsigned int>(BoostOption.size())) || !ASSIMP_strincmp(pPtr, ResolutionOption.c_str(), static_cast<unsigned int>(ResolutionOption.size())) || !ASSIMP_strincmp(pPtr, ChannelOption.c_str(), static_cast<unsigned int>(ChannelOption.size()))) {
|
||||||
skipToken = 2;
|
skipToken = 2;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2020, assimp team
|
Copyright (c) 2006-2022, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -52,6 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
|
@ -84,13 +85,13 @@ ObjFileParser::ObjFileParser(IOStreamBuffer<char> &streamBuffer, const std::stri
|
||||||
|
|
||||||
// Create the model instance to store all the data
|
// Create the model instance to store all the data
|
||||||
m_pModel.reset(new ObjFile::Model());
|
m_pModel.reset(new ObjFile::Model());
|
||||||
m_pModel->m_ModelName = modelName;
|
m_pModel->mModelName = modelName;
|
||||||
|
|
||||||
// create default material and store it
|
// create default material and store it
|
||||||
m_pModel->m_pDefaultMaterial = new ObjFile::Material;
|
m_pModel->mDefaultMaterial = new ObjFile::Material;
|
||||||
m_pModel->m_pDefaultMaterial->MaterialName.Set(DEFAULT_MATERIAL);
|
m_pModel->mDefaultMaterial->MaterialName.Set(DEFAULT_MATERIAL);
|
||||||
m_pModel->m_MaterialLib.push_back(DEFAULT_MATERIAL);
|
m_pModel->mMaterialLib.push_back(DEFAULT_MATERIAL);
|
||||||
m_pModel->m_MaterialMap[DEFAULT_MATERIAL] = m_pModel->m_pDefaultMaterial;
|
m_pModel->mMaterialMap[DEFAULT_MATERIAL] = m_pModel->mDefaultMaterial;
|
||||||
|
|
||||||
// Start parsing the file
|
// Start parsing the file
|
||||||
parseFile(streamBuffer);
|
parseFile(streamBuffer);
|
||||||
|
@ -153,23 +154,23 @@ void ObjFileParser::parseFile(IOStreamBuffer<char> &streamBuffer) {
|
||||||
size_t numComponents = getNumComponentsInDataDefinition();
|
size_t numComponents = getNumComponentsInDataDefinition();
|
||||||
if (numComponents == 3) {
|
if (numComponents == 3) {
|
||||||
// read in vertex definition
|
// read in vertex definition
|
||||||
getVector3(m_pModel->m_Vertices);
|
getVector3(m_pModel->mVertices);
|
||||||
} else if (numComponents == 4) {
|
} else if (numComponents == 4) {
|
||||||
// read in vertex definition (homogeneous coords)
|
// read in vertex definition (homogeneous coords)
|
||||||
getHomogeneousVector3(m_pModel->m_Vertices);
|
getHomogeneousVector3(m_pModel->mVertices);
|
||||||
} else if (numComponents == 6) {
|
} else if (numComponents == 6) {
|
||||||
// read vertex and vertex-color
|
// read vertex and vertex-color
|
||||||
getTwoVectors3(m_pModel->m_Vertices, m_pModel->m_VertexColors);
|
getTwoVectors3(m_pModel->mVertices, m_pModel->mVertexColors);
|
||||||
}
|
}
|
||||||
} else if (*m_DataIt == 't') {
|
} else if (*m_DataIt == 't') {
|
||||||
// read in texture coordinate ( 2D or 3D )
|
// read in texture coordinate ( 2D or 3D )
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
size_t dim = getTexCoordVector(m_pModel->m_TextureCoord);
|
size_t dim = getTexCoordVector(m_pModel->mTextureCoord);
|
||||||
m_pModel->m_TextureCoordDim = std::max(m_pModel->m_TextureCoordDim, (unsigned int)dim);
|
m_pModel->mTextureCoordDim = std::max(m_pModel->mTextureCoordDim, (unsigned int)dim);
|
||||||
} else if (*m_DataIt == 'n') {
|
} else if (*m_DataIt == 'n') {
|
||||||
// Read in normal vector definition
|
// Read in normal vector definition
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
getVector3(m_pModel->m_Normals);
|
getVector3(m_pModel->mNormals);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -424,7 +425,7 @@ void ObjFileParser::getVector2(std::vector<aiVector2D> &point2d_array) {
|
||||||
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const std::string DefaultObjName = "defaultobject";
|
static constexpr char DefaultObjName[] = "defaultobject";
|
||||||
|
|
||||||
void ObjFileParser::getFace(aiPrimitiveType type) {
|
void ObjFileParser::getFace(aiPrimitiveType type) {
|
||||||
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
||||||
|
@ -435,12 +436,12 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
|
||||||
ObjFile::Face *face = new ObjFile::Face(type);
|
ObjFile::Face *face = new ObjFile::Face(type);
|
||||||
bool hasNormal = false;
|
bool hasNormal = false;
|
||||||
|
|
||||||
const int vSize = static_cast<unsigned int>(m_pModel->m_Vertices.size());
|
const int vSize = static_cast<unsigned int>(m_pModel->mVertices.size());
|
||||||
const int vtSize = static_cast<unsigned int>(m_pModel->m_TextureCoord.size());
|
const int vtSize = static_cast<unsigned int>(m_pModel->mTextureCoord.size());
|
||||||
const int vnSize = static_cast<unsigned int>(m_pModel->m_Normals.size());
|
const int vnSize = static_cast<unsigned int>(m_pModel->mNormals.size());
|
||||||
|
|
||||||
const bool vt = (!m_pModel->m_TextureCoord.empty());
|
const bool vt = (!m_pModel->mTextureCoord.empty());
|
||||||
const bool vn = (!m_pModel->m_Normals.empty());
|
const bool vn = (!m_pModel->mNormals.empty());
|
||||||
int iPos = 0;
|
int iPos = 0;
|
||||||
while (m_DataIt != m_DataItEnd) {
|
while (m_DataIt != m_DataItEnd) {
|
||||||
int iStep = 1;
|
int iStep = 1;
|
||||||
|
@ -458,8 +459,8 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
|
||||||
iPos = 0;
|
iPos = 0;
|
||||||
} else {
|
} else {
|
||||||
//OBJ USES 1 Base ARRAYS!!!!
|
//OBJ USES 1 Base ARRAYS!!!!
|
||||||
std::string number(&(*m_DataIt), m_DataItEnd - m_DataIt);
|
const char *token = &(*m_DataIt);
|
||||||
const int iVal(::atoi(number.c_str()));
|
const int iVal = ::atoi(token);
|
||||||
|
|
||||||
// increment iStep position based off of the sign and # of digits
|
// increment iStep position based off of the sign and # of digits
|
||||||
int tmp = iVal;
|
int tmp = iVal;
|
||||||
|
@ -500,7 +501,7 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
|
||||||
} else {
|
} else {
|
||||||
//On error, std::atoi will return 0 which is not a valid value
|
//On error, std::atoi will return 0 which is not a valid value
|
||||||
delete face;
|
delete face;
|
||||||
throw DeadlyImportError("OBJ: Invalid face indice");
|
throw DeadlyImportError("OBJ: Invalid face index.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_DataIt += iStep;
|
m_DataIt += iStep;
|
||||||
|
@ -515,28 +516,28 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set active material, if one set
|
// Set active material, if one set
|
||||||
if (nullptr != m_pModel->m_pCurrentMaterial) {
|
if (nullptr != m_pModel->mCurrentMaterial) {
|
||||||
face->m_pMaterial = m_pModel->m_pCurrentMaterial;
|
face->m_pMaterial = m_pModel->mCurrentMaterial;
|
||||||
} else {
|
} else {
|
||||||
face->m_pMaterial = m_pModel->m_pDefaultMaterial;
|
face->m_pMaterial = m_pModel->mDefaultMaterial;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a default object, if nothing is there
|
// Create a default object, if nothing is there
|
||||||
if (nullptr == m_pModel->m_pCurrent) {
|
if (nullptr == m_pModel->mCurrentObject) {
|
||||||
createObject(DefaultObjName);
|
createObject(DefaultObjName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign face to mesh
|
// Assign face to mesh
|
||||||
if (nullptr == m_pModel->m_pCurrentMesh) {
|
if (nullptr == m_pModel->mCurrentMesh) {
|
||||||
createMesh(DefaultObjName);
|
createMesh(DefaultObjName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the face
|
// Store the face
|
||||||
m_pModel->m_pCurrentMesh->m_Faces.push_back(face);
|
m_pModel->mCurrentMesh->m_Faces.emplace_back(face);
|
||||||
m_pModel->m_pCurrentMesh->m_uiNumIndices += (unsigned int)face->m_vertices.size();
|
m_pModel->mCurrentMesh->m_uiNumIndices += static_cast<unsigned int>(face->m_vertices.size());
|
||||||
m_pModel->m_pCurrentMesh->m_uiUVCoordinates[0] += (unsigned int)face->m_texturCoords.size();
|
m_pModel->mCurrentMesh->m_uiUVCoordinates[0] += static_cast<unsigned int>(face->m_texturCoords.size());
|
||||||
if (!m_pModel->m_pCurrentMesh->m_hasNormals && hasNormal) {
|
if (!m_pModel->mCurrentMesh->m_hasNormals && hasNormal) {
|
||||||
m_pModel->m_pCurrentMesh->m_hasNormals = true;
|
m_pModel->mCurrentMesh->m_hasNormals = true;
|
||||||
}
|
}
|
||||||
// Skip the rest of the line
|
// Skip the rest of the line
|
||||||
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
||||||
|
@ -565,33 +566,33 @@ void ObjFileParser::getMaterialDesc() {
|
||||||
|
|
||||||
// If the current mesh has the same material, we simply ignore that 'usemtl' command
|
// If the current mesh has the same material, we simply ignore that 'usemtl' command
|
||||||
// There is no need to create another object or even mesh here
|
// There is no need to create another object or even mesh here
|
||||||
if (m_pModel->m_pCurrentMaterial && m_pModel->m_pCurrentMaterial->MaterialName == aiString(strName)) {
|
if (m_pModel->mCurrentMaterial && m_pModel->mCurrentMaterial->MaterialName == aiString(strName)) {
|
||||||
skip = true;
|
skip = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!skip) {
|
if (!skip) {
|
||||||
// Search for material
|
// Search for material
|
||||||
std::map<std::string, ObjFile::Material *>::iterator it = m_pModel->m_MaterialMap.find(strName);
|
std::map<std::string, ObjFile::Material *>::iterator it = m_pModel->mMaterialMap.find(strName);
|
||||||
if (it == m_pModel->m_MaterialMap.end()) {
|
if (it == m_pModel->mMaterialMap.end()) {
|
||||||
// Not found, so we don't know anything about the material except for its name.
|
// Not found, so we don't know anything about the material except for its name.
|
||||||
// This may be the case if the material library is missing. We don't want to lose all
|
// This may be the case if the material library is missing. We don't want to lose all
|
||||||
// materials if that happens, so create a new named material instead of discarding it
|
// materials if that happens, so create a new named material instead of discarding it
|
||||||
// completely.
|
// completely.
|
||||||
ASSIMP_LOG_ERROR("OBJ: failed to locate material ", strName, ", creating new material");
|
ASSIMP_LOG_ERROR("OBJ: failed to locate material ", strName, ", creating new material");
|
||||||
m_pModel->m_pCurrentMaterial = new ObjFile::Material();
|
m_pModel->mCurrentMaterial = new ObjFile::Material();
|
||||||
m_pModel->m_pCurrentMaterial->MaterialName.Set(strName);
|
m_pModel->mCurrentMaterial->MaterialName.Set(strName);
|
||||||
m_pModel->m_MaterialLib.push_back(strName);
|
m_pModel->mMaterialLib.push_back(strName);
|
||||||
m_pModel->m_MaterialMap[strName] = m_pModel->m_pCurrentMaterial;
|
m_pModel->mMaterialMap[strName] = m_pModel->mCurrentMaterial;
|
||||||
} else {
|
} else {
|
||||||
// Found, using detected material
|
// Found, using detected material
|
||||||
m_pModel->m_pCurrentMaterial = (*it).second;
|
m_pModel->mCurrentMaterial = (*it).second;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needsNewMesh(strName)) {
|
if (needsNewMesh(strName)) {
|
||||||
createMesh(strName);
|
createMesh(strName);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex(strName);
|
m_pModel->mCurrentMesh->m_uiMaterialIndex = getMaterialIndex(strName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip rest of line
|
// Skip rest of line
|
||||||
|
@ -678,17 +679,17 @@ void ObjFileParser::getNewMaterial() {
|
||||||
while (m_DataIt != m_DataItEnd && IsSpaceOrNewLine(*m_DataIt)) {
|
while (m_DataIt != m_DataItEnd && IsSpaceOrNewLine(*m_DataIt)) {
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
}
|
}
|
||||||
std::map<std::string, ObjFile::Material *>::iterator it = m_pModel->m_MaterialMap.find(strMat);
|
std::map<std::string, ObjFile::Material *>::iterator it = m_pModel->mMaterialMap.find(strMat);
|
||||||
if (it == m_pModel->m_MaterialMap.end()) {
|
if (it == m_pModel->mMaterialMap.end()) {
|
||||||
// Show a warning, if material was not found
|
// Show a warning, if material was not found
|
||||||
ASSIMP_LOG_WARN("OBJ: Unsupported material requested: ", strMat);
|
ASSIMP_LOG_WARN("OBJ: Unsupported material requested: ", strMat);
|
||||||
m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial;
|
m_pModel->mCurrentMaterial = m_pModel->mDefaultMaterial;
|
||||||
} else {
|
} else {
|
||||||
// Set new material
|
// Set new material
|
||||||
if (needsNewMesh(strMat)) {
|
if (needsNewMesh(strMat)) {
|
||||||
createMesh(strMat);
|
createMesh(strMat);
|
||||||
}
|
}
|
||||||
m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex(strMat);
|
m_pModel->mCurrentMesh->m_uiMaterialIndex = getMaterialIndex(strMat);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
||||||
|
@ -700,8 +701,8 @@ int ObjFileParser::getMaterialIndex(const std::string &strMaterialName) {
|
||||||
if (strMaterialName.empty()) {
|
if (strMaterialName.empty()) {
|
||||||
return mat_index;
|
return mat_index;
|
||||||
}
|
}
|
||||||
for (size_t index = 0; index < m_pModel->m_MaterialLib.size(); ++index) {
|
for (size_t index = 0; index < m_pModel->mMaterialLib.size(); ++index) {
|
||||||
if (strMaterialName == m_pModel->m_MaterialLib[index]) {
|
if (strMaterialName == m_pModel->mMaterialLib[index]) {
|
||||||
mat_index = (int)index;
|
mat_index = (int)index;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -722,22 +723,22 @@ void ObjFileParser::getGroupName() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change active group, if necessary
|
// Change active group, if necessary
|
||||||
if (m_pModel->m_strActiveGroup != groupName) {
|
if (m_pModel->mActiveGroup != groupName) {
|
||||||
// Search for already existing entry
|
// Search for already existing entry
|
||||||
ObjFile::Model::ConstGroupMapIt it = m_pModel->m_Groups.find(groupName);
|
ObjFile::Model::ConstGroupMapIt it = m_pModel->mGroups.find(groupName);
|
||||||
|
|
||||||
// We are mapping groups into the object structure
|
// We are mapping groups into the object structure
|
||||||
createObject(groupName);
|
createObject(groupName);
|
||||||
|
|
||||||
// New group name, creating a new entry
|
// New group name, creating a new entry
|
||||||
if (it == m_pModel->m_Groups.end()) {
|
if (it == m_pModel->mGroups.end()) {
|
||||||
std::vector<unsigned int> *pFaceIDArray = new std::vector<unsigned int>;
|
std::vector<unsigned int> *pFaceIDArray = new std::vector<unsigned int>;
|
||||||
m_pModel->m_Groups[groupName] = pFaceIDArray;
|
m_pModel->mGroups[groupName] = pFaceIDArray;
|
||||||
m_pModel->m_pGroupFaceIDs = (pFaceIDArray);
|
m_pModel->mGroupFaceIDs = (pFaceIDArray);
|
||||||
} else {
|
} else {
|
||||||
m_pModel->m_pGroupFaceIDs = (*it).second;
|
m_pModel->mGroupFaceIDs = (*it).second;
|
||||||
}
|
}
|
||||||
m_pModel->m_strActiveGroup = groupName;
|
m_pModel->mActiveGroup = groupName;
|
||||||
}
|
}
|
||||||
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
||||||
}
|
}
|
||||||
|
@ -774,20 +775,20 @@ void ObjFileParser::getObjectName() {
|
||||||
std::string strObjectName(pStart, &(*m_DataIt));
|
std::string strObjectName(pStart, &(*m_DataIt));
|
||||||
if (!strObjectName.empty()) {
|
if (!strObjectName.empty()) {
|
||||||
// Reset current object
|
// Reset current object
|
||||||
m_pModel->m_pCurrent = nullptr;
|
m_pModel->mCurrentObject = nullptr;
|
||||||
|
|
||||||
// Search for actual object
|
// Search for actual object
|
||||||
for (std::vector<ObjFile::Object *>::const_iterator it = m_pModel->m_Objects.begin();
|
for (std::vector<ObjFile::Object *>::const_iterator it = m_pModel->mObjects.begin();
|
||||||
it != m_pModel->m_Objects.end();
|
it != m_pModel->mObjects.end();
|
||||||
++it) {
|
++it) {
|
||||||
if ((*it)->m_strObjName == strObjectName) {
|
if ((*it)->m_strObjName == strObjectName) {
|
||||||
m_pModel->m_pCurrent = *it;
|
m_pModel->mCurrentObject = *it;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate a new object, if current one was not found before
|
// Allocate a new object, if current one was not found before
|
||||||
if (nullptr == m_pModel->m_pCurrent) {
|
if (nullptr == m_pModel->mCurrentObject) {
|
||||||
createObject(strObjectName);
|
createObject(strObjectName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -798,16 +799,16 @@ void ObjFileParser::getObjectName() {
|
||||||
void ObjFileParser::createObject(const std::string &objName) {
|
void ObjFileParser::createObject(const std::string &objName) {
|
||||||
ai_assert(nullptr != m_pModel);
|
ai_assert(nullptr != m_pModel);
|
||||||
|
|
||||||
m_pModel->m_pCurrent = new ObjFile::Object;
|
m_pModel->mCurrentObject = new ObjFile::Object;
|
||||||
m_pModel->m_pCurrent->m_strObjName = objName;
|
m_pModel->mCurrentObject->m_strObjName = objName;
|
||||||
m_pModel->m_Objects.push_back(m_pModel->m_pCurrent);
|
m_pModel->mObjects.push_back(m_pModel->mCurrentObject);
|
||||||
|
|
||||||
createMesh(objName);
|
createMesh(objName);
|
||||||
|
|
||||||
if (m_pModel->m_pCurrentMaterial) {
|
if (m_pModel->mCurrentMaterial) {
|
||||||
m_pModel->m_pCurrentMesh->m_uiMaterialIndex =
|
m_pModel->mCurrentMesh->m_uiMaterialIndex =
|
||||||
getMaterialIndex(m_pModel->m_pCurrentMaterial->MaterialName.data);
|
getMaterialIndex(m_pModel->mCurrentMaterial->MaterialName.data);
|
||||||
m_pModel->m_pCurrentMesh->m_pMaterial = m_pModel->m_pCurrentMaterial;
|
m_pModel->mCurrentMesh->m_pMaterial = m_pModel->mCurrentMaterial;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
@ -815,11 +816,11 @@ void ObjFileParser::createObject(const std::string &objName) {
|
||||||
void ObjFileParser::createMesh(const std::string &meshName) {
|
void ObjFileParser::createMesh(const std::string &meshName) {
|
||||||
ai_assert(nullptr != m_pModel);
|
ai_assert(nullptr != m_pModel);
|
||||||
|
|
||||||
m_pModel->m_pCurrentMesh = new ObjFile::Mesh(meshName);
|
m_pModel->mCurrentMesh = new ObjFile::Mesh(meshName);
|
||||||
m_pModel->m_Meshes.push_back(m_pModel->m_pCurrentMesh);
|
m_pModel->mMeshes.push_back(m_pModel->mCurrentMesh);
|
||||||
unsigned int meshId = static_cast<unsigned int>(m_pModel->m_Meshes.size() - 1);
|
unsigned int meshId = static_cast<unsigned int>(m_pModel->mMeshes.size() - 1);
|
||||||
if (nullptr != m_pModel->m_pCurrent) {
|
if (nullptr != m_pModel->mCurrentObject) {
|
||||||
m_pModel->m_pCurrent->m_Meshes.push_back(meshId);
|
m_pModel->mCurrentObject->m_Meshes.push_back(meshId);
|
||||||
} else {
|
} else {
|
||||||
ASSIMP_LOG_ERROR("OBJ: No object detected to attach a new mesh instance.");
|
ASSIMP_LOG_ERROR("OBJ: No object detected to attach a new mesh instance.");
|
||||||
}
|
}
|
||||||
|
@ -829,16 +830,16 @@ void ObjFileParser::createMesh(const std::string &meshName) {
|
||||||
// Returns true, if a new mesh must be created.
|
// Returns true, if a new mesh must be created.
|
||||||
bool ObjFileParser::needsNewMesh(const std::string &materialName) {
|
bool ObjFileParser::needsNewMesh(const std::string &materialName) {
|
||||||
// If no mesh data yet
|
// If no mesh data yet
|
||||||
if (m_pModel->m_pCurrentMesh == nullptr) {
|
if (m_pModel->mCurrentMesh == nullptr) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool newMat = false;
|
bool newMat = false;
|
||||||
int matIdx = getMaterialIndex(materialName);
|
int matIdx = getMaterialIndex(materialName);
|
||||||
int curMatIdx = m_pModel->m_pCurrentMesh->m_uiMaterialIndex;
|
int curMatIdx = m_pModel->mCurrentMesh->m_uiMaterialIndex;
|
||||||
if (curMatIdx != int(ObjFile::Mesh::NoMaterial) && curMatIdx != matIdx
|
if (curMatIdx != int(ObjFile::Mesh::NoMaterial) && curMatIdx != matIdx
|
||||||
// no need create a new mesh if no faces in current
|
// no need create a new mesh if no faces in current
|
||||||
// lets say 'usemtl' goes straight after 'g'
|
// lets say 'usemtl' goes straight after 'g'
|
||||||
&& !m_pModel->m_pCurrentMesh->m_Faces.empty()) {
|
&& !m_pModel->mCurrentMesh->m_Faces.empty()) {
|
||||||
// New material -> only one material per mesh, so we need to create a new
|
// New material -> only one material per mesh, so we need to create a new
|
||||||
// material
|
// material
|
||||||
newMat = true;
|
newMat = true;
|
||||||
|
|
|
@ -137,9 +137,6 @@ protected:
|
||||||
void reportErrorTokenInFace();
|
void reportErrorTokenInFace();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Copy and assignment constructor should be private
|
|
||||||
// because the class contains pointer to allocated memory
|
|
||||||
|
|
||||||
/// Default material name
|
/// Default material name
|
||||||
static constexpr const char DEFAULT_MATERIAL[] = AI_DEFAULT_MATERIAL_NAME;
|
static constexpr const char DEFAULT_MATERIAL[] = AI_DEFAULT_MATERIAL_NAME;
|
||||||
//! Iterator to current position in buffer
|
//! Iterator to current position in buffer
|
||||||
|
|
|
@ -236,7 +236,7 @@ inline char_t CopyNextWord(char_t it, char_t end, char *pBuffer, size_t length)
|
||||||
template <class char_t>
|
template <class char_t>
|
||||||
inline char_t getFloat(char_t it, char_t end, ai_real &value) {
|
inline char_t getFloat(char_t it, char_t end, ai_real &value) {
|
||||||
static const size_t BUFFERSIZE = 1024;
|
static const size_t BUFFERSIZE = 1024;
|
||||||
char buffer[BUFFERSIZE];
|
char buffer[BUFFERSIZE] = {};
|
||||||
it = CopyNextWord<char_t>(it, end, buffer, BUFFERSIZE);
|
it = CopyNextWord<char_t>(it, end, buffer, BUFFERSIZE);
|
||||||
value = (ai_real)fast_atof(buffer);
|
value = (ai_real)fast_atof(buffer);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue