mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-12 15:14:35 +00:00
update assimp lib
This commit is contained in:
parent
03a348deb7
commit
d3f8fee74e
1725 changed files with 196314 additions and 62009 deletions
|
|
@ -59,9 +59,9 @@ namespace Assimp {
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Worker function for exporting a scene to Wavefront OBJ. Prototyped and registered in Exporter.cpp
|
||||
void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/) {
|
||||
void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* props) {
|
||||
// invoke the exporter
|
||||
ObjExporter exporter(pFile, pScene);
|
||||
ObjExporter exporter(pFile, pScene, false, props);
|
||||
|
||||
if (exporter.mOutput.fail() || exporter.mOutputMat.fail()) {
|
||||
throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
|
||||
|
|
@ -86,9 +86,9 @@ void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Worker function for exporting a scene to Wavefront OBJ without the material file. Prototyped and registered in Exporter.cpp
|
||||
void ExportSceneObjNoMtl(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* ) {
|
||||
void ExportSceneObjNoMtl(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* props) {
|
||||
// invoke the exporter
|
||||
ObjExporter exporter(pFile, pScene, true);
|
||||
ObjExporter exporter(pFile, pScene, true, props);
|
||||
|
||||
if (exporter.mOutput.fail() || exporter.mOutputMat.fail()) {
|
||||
throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
|
||||
|
|
@ -111,7 +111,7 @@ void ExportSceneObjNoMtl(const char* pFile,IOSystem* pIOSystem, const aiScene* p
|
|||
static const std::string MaterialExt = ".mtl";
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
ObjExporter::ObjExporter(const char* _filename, const aiScene* pScene, bool noMtl)
|
||||
ObjExporter::ObjExporter(const char* _filename, const aiScene* pScene, bool noMtl, const ExportProperties* props)
|
||||
: filename(_filename)
|
||||
, pScene(pScene)
|
||||
, vn()
|
||||
|
|
@ -130,7 +130,10 @@ ObjExporter::ObjExporter(const char* _filename, const aiScene* pScene, bool noMt
|
|||
mOutputMat.imbue(l);
|
||||
mOutputMat.precision(ASSIMP_AI_REAL_TEXT_PRECISION);
|
||||
|
||||
WriteGeometryFile(noMtl);
|
||||
WriteGeometryFile(
|
||||
noMtl,
|
||||
props == nullptr ? true : props->GetPropertyBool("bJoinIdenticalVertices", true)
|
||||
);
|
||||
if ( !noMtl ) {
|
||||
WriteMaterialFile();
|
||||
}
|
||||
|
|
@ -171,9 +174,12 @@ void ObjExporter::WriteHeader(std::ostringstream& out) {
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
std::string ObjExporter::GetMaterialName(unsigned int index) {
|
||||
static const std::string EmptyStr;
|
||||
if ( nullptr == pScene->mMaterials ) {
|
||||
return EmptyStr;
|
||||
}
|
||||
const aiMaterial* const mat = pScene->mMaterials[index];
|
||||
if ( nullptr == mat ) {
|
||||
static const std::string EmptyStr;
|
||||
return EmptyStr;
|
||||
}
|
||||
|
||||
|
|
@ -255,14 +261,14 @@ void ObjExporter::WriteMaterialFile() {
|
|||
}
|
||||
}
|
||||
|
||||
void ObjExporter::WriteGeometryFile(bool noMtl) {
|
||||
void ObjExporter::WriteGeometryFile(bool noMtl, bool merge_identical_vertices) {
|
||||
WriteHeader(mOutput);
|
||||
if (!noMtl)
|
||||
mOutput << "mtllib " << GetMaterialLibName() << endl << endl;
|
||||
|
||||
// collect mesh geometry
|
||||
aiMatrix4x4 mBase;
|
||||
AddNode(pScene->mRootNode, mBase);
|
||||
AddNode(pScene->mRootNode, mBase, merge_identical_vertices);
|
||||
|
||||
// write vertex positions with colors, if any
|
||||
mVpMap.getKeys( vp );
|
||||
|
|
@ -330,7 +336,7 @@ void ObjExporter::WriteGeometryFile(bool noMtl) {
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ObjExporter::AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat) {
|
||||
void ObjExporter::AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat, bool merge_identical_vertices) {
|
||||
mMeshes.emplace_back();
|
||||
MeshInstance& mesh = mMeshes.back();
|
||||
|
||||
|
|
@ -362,13 +368,14 @@ void ObjExporter::AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4
|
|||
for(unsigned int a = 0; a < f.mNumIndices; ++a) {
|
||||
const unsigned int idx = f.mIndices[a];
|
||||
|
||||
const unsigned int fi = merge_identical_vertices ? 0 : idx;
|
||||
aiVector3D vert = mat * m->mVertices[idx];
|
||||
|
||||
if ( nullptr != m->mColors[ 0 ] ) {
|
||||
aiColor4D col4 = m->mColors[ 0 ][ idx ];
|
||||
face.indices[a].vp = mVpMap.getIndex({vert, aiColor3D(col4.r, col4.g, col4.b)});
|
||||
face.indices[a].vp = mVpMap.getIndex({vert, aiColor3D(col4.r, col4.g, col4.b), fi});
|
||||
} else {
|
||||
face.indices[a].vp = mVpMap.getIndex({vert, aiColor3D(0,0,0)});
|
||||
face.indices[a].vp = mVpMap.getIndex({vert, aiColor3D(0,0,0), fi});
|
||||
}
|
||||
|
||||
if (m->mNormals) {
|
||||
|
|
@ -388,21 +395,21 @@ void ObjExporter::AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ObjExporter::AddNode(const aiNode* nd, const aiMatrix4x4& mParent) {
|
||||
void ObjExporter::AddNode(const aiNode* nd, const aiMatrix4x4& mParent, bool merge_identical_vertices) {
|
||||
const aiMatrix4x4& mAbs = mParent * nd->mTransformation;
|
||||
|
||||
aiMesh *cm( nullptr );
|
||||
for(unsigned int i = 0; i < nd->mNumMeshes; ++i) {
|
||||
cm = pScene->mMeshes[nd->mMeshes[i]];
|
||||
if (nullptr != cm) {
|
||||
AddMesh(cm->mName, pScene->mMeshes[nd->mMeshes[i]], mAbs);
|
||||
AddMesh(cm->mName, pScene->mMeshes[nd->mMeshes[i]], mAbs, merge_identical_vertices);
|
||||
} else {
|
||||
AddMesh(nd->mName, pScene->mMeshes[nd->mMeshes[i]], mAbs);
|
||||
AddMesh(nd->mName, pScene->mMeshes[nd->mMeshes[i]], mAbs, merge_identical_vertices);
|
||||
}
|
||||
}
|
||||
|
||||
for(unsigned int i = 0; i < nd->mNumChildren; ++i) {
|
||||
AddNode(nd->mChildren[i], mAbs);
|
||||
AddNode(nd->mChildren[i], mAbs, merge_identical_vertices);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <assimp/Exporter.hpp>
|
||||
|
||||
struct aiScene;
|
||||
struct aiNode;
|
||||
struct aiMesh;
|
||||
|
|
@ -63,7 +65,7 @@ namespace Assimp {
|
|||
class ObjExporter {
|
||||
public:
|
||||
/// Constructor for a specific scene to export
|
||||
ObjExporter(const char* filename, const aiScene* pScene, bool noMtl=false);
|
||||
ObjExporter(const char* filename, const aiScene* pScene, bool noMtl=false, const ExportProperties* props = nullptr);
|
||||
~ObjExporter();
|
||||
std::string GetMaterialLibName();
|
||||
std::string GetMaterialLibFileName();
|
||||
|
|
@ -97,10 +99,10 @@ private:
|
|||
|
||||
void WriteHeader(std::ostringstream& out);
|
||||
void WriteMaterialFile();
|
||||
void WriteGeometryFile(bool noMtl=false);
|
||||
void WriteGeometryFile(bool noMtl=false, bool merge_identical_vertices = false);
|
||||
std::string GetMaterialName(unsigned int index);
|
||||
void AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat);
|
||||
void AddNode(const aiNode* nd, const aiMatrix4x4& mParent);
|
||||
void AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat, bool merge_identical_vertices);
|
||||
void AddNode(const aiNode* nd, const aiMatrix4x4& mParent, bool merge_identical_vertices);
|
||||
|
||||
private:
|
||||
std::string filename;
|
||||
|
|
@ -109,6 +111,7 @@ private:
|
|||
struct vertexData {
|
||||
aiVector3D vp;
|
||||
aiColor3D vc; // OBJ does not support 4D color
|
||||
uint32_t index = 0;
|
||||
};
|
||||
|
||||
std::vector<aiVector3D> vn, vt;
|
||||
|
|
@ -133,7 +136,7 @@ private:
|
|||
if (a.vc.g > b.vc.g) return false;
|
||||
if (a.vc.b < b.vc.b) return true;
|
||||
if (a.vc.b > b.vc.b) return false;
|
||||
return false;
|
||||
return a.index < b.index;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -199,12 +199,12 @@ struct Material {
|
|||
|
||||
//! Constructor
|
||||
Material() :
|
||||
diffuse(ai_real(0.6), ai_real(0.6), ai_real(0.6)),
|
||||
diffuse(0.6f, 0.6f, 0.6f),
|
||||
alpha(ai_real(1.0)),
|
||||
shineness(ai_real(0.0)),
|
||||
illumination_model(1),
|
||||
ior(ai_real(1.0)),
|
||||
transparent(ai_real(1.0), ai_real(1.0), ai_real(1.0)),
|
||||
transparent(1.0f, 1.0, 1.0),
|
||||
roughness(),
|
||||
metallic(),
|
||||
sheen(),
|
||||
|
|
@ -239,8 +239,6 @@ struct Mesh {
|
|||
unsigned int m_uiMaterialIndex;
|
||||
/// True, if normals are stored.
|
||||
bool m_hasNormals;
|
||||
/// True, if vertex colors are stored.
|
||||
bool m_hasVertexColors;
|
||||
|
||||
/// Constructor
|
||||
explicit Mesh(const std::string &name) :
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2020, assimp team
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -54,7 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <assimp/ObjMaterial.h>
|
||||
#include <memory>
|
||||
|
||||
static const aiImporterDesc desc = {
|
||||
static constexpr aiImporterDesc desc = {
|
||||
"Wavefront Object Importer",
|
||||
"",
|
||||
"",
|
||||
|
|
@ -67,7 +67,7 @@ static const aiImporterDesc desc = {
|
|||
"obj"
|
||||
};
|
||||
|
||||
static const unsigned int ObjMinSize = 16;
|
||||
static constexpr unsigned int ObjMinSize = 16u;
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
|
|
@ -78,13 +78,14 @@ using namespace std;
|
|||
ObjFileImporter::ObjFileImporter() :
|
||||
m_Buffer(),
|
||||
m_pRootObject(nullptr),
|
||||
m_strAbsPath(std::string(1, DefaultIOSystem().getOsSeparator())) {}
|
||||
m_strAbsPath(std::string(1, DefaultIOSystem().getOsSeparator())) {
|
||||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Destructor.
|
||||
ObjFileImporter::~ObjFileImporter() {
|
||||
delete m_pRootObject;
|
||||
m_pRootObject = nullptr;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
|
@ -102,13 +103,18 @@ const aiImporterDesc *ObjFileImporter::GetInfo() const {
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Obj-file import implementation
|
||||
void ObjFileImporter::InternReadFile(const std::string &file, aiScene *pScene, IOSystem *pIOHandler) {
|
||||
if (m_pRootObject != nullptr) {
|
||||
delete m_pRootObject;
|
||||
m_pRootObject = nullptr;
|
||||
}
|
||||
|
||||
// Read file into memory
|
||||
static const std::string mode = "rb";
|
||||
static constexpr char mode[] = "rb";
|
||||
auto streamCloser = [&](IOStream *pStream) {
|
||||
pIOHandler->Close(pStream);
|
||||
};
|
||||
std::unique_ptr<IOStream, decltype(streamCloser)> fileStream(pIOHandler->Open(file, mode), streamCloser);
|
||||
if (!fileStream.get()) {
|
||||
if (!fileStream) {
|
||||
throw DeadlyImportError("Failed to open file ", file, ".");
|
||||
}
|
||||
|
||||
|
|
@ -157,7 +163,7 @@ void ObjFileImporter::InternReadFile(const std::string &file, aiScene *pScene, I
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Create the data from parsed obj-file
|
||||
void ObjFileImporter::CreateDataFromImport(const ObjFile::Model *pModel, aiScene *pScene) {
|
||||
if (nullptr == pModel) {
|
||||
if (pModel == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -172,7 +178,6 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model *pModel, aiScene
|
|||
}
|
||||
|
||||
if (!pModel->mObjects.empty()) {
|
||||
|
||||
unsigned int meshCount = 0;
|
||||
unsigned int childCount = 0;
|
||||
|
||||
|
|
@ -187,7 +192,7 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model *pModel, aiScene
|
|||
pScene->mRootNode->mChildren = new aiNode *[childCount];
|
||||
|
||||
// Create nodes for the whole scene
|
||||
std::vector<aiMesh *> MeshArray;
|
||||
std::vector<std::unique_ptr<aiMesh>> MeshArray;
|
||||
MeshArray.reserve(meshCount);
|
||||
for (size_t index = 0; index < pModel->mObjects.size(); ++index) {
|
||||
createNodes(pModel, pModel->mObjects[index], pScene->mRootNode, pScene, MeshArray);
|
||||
|
|
@ -199,7 +204,7 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model *pModel, aiScene
|
|||
if (pScene->mNumMeshes > 0) {
|
||||
pScene->mMeshes = new aiMesh *[MeshArray.size()];
|
||||
for (size_t index = 0; index < MeshArray.size(); ++index) {
|
||||
pScene->mMeshes[index] = MeshArray[index];
|
||||
pScene->mMeshes[index] = MeshArray[index].release();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -251,9 +256,8 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model *pModel, aiScene
|
|||
// Creates all nodes of the model
|
||||
aiNode *ObjFileImporter::createNodes(const ObjFile::Model *pModel, const ObjFile::Object *pObject,
|
||||
aiNode *pParent, aiScene *pScene,
|
||||
std::vector<aiMesh *> &MeshArray) {
|
||||
ai_assert(nullptr != pModel);
|
||||
if (nullptr == pObject) {
|
||||
std::vector<std::unique_ptr<aiMesh>> &MeshArray) {
|
||||
if (nullptr == pObject || pModel == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
@ -269,12 +273,10 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model *pModel, const ObjFile
|
|||
|
||||
for (size_t i = 0; i < pObject->m_Meshes.size(); ++i) {
|
||||
unsigned int meshId = pObject->m_Meshes[i];
|
||||
aiMesh *pMesh = createTopology(pModel, pObject, meshId);
|
||||
if (pMesh) {
|
||||
std::unique_ptr<aiMesh> pMesh = createTopology(pModel, pObject, meshId);
|
||||
if (pMesh != nullptr) {
|
||||
if (pMesh->mNumFaces > 0) {
|
||||
MeshArray.push_back(pMesh);
|
||||
} else {
|
||||
delete pMesh;
|
||||
MeshArray.push_back(std::move(pMesh));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -306,17 +308,14 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model *pModel, const ObjFile
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Create topology data
|
||||
aiMesh *ObjFileImporter::createTopology(const ObjFile::Model *pModel, const ObjFile::Object *pData, unsigned int meshIndex) {
|
||||
// Checking preconditions
|
||||
ai_assert(nullptr != pModel);
|
||||
|
||||
if (nullptr == pData) {
|
||||
std::unique_ptr<aiMesh> ObjFileImporter::createTopology(const ObjFile::Model *pModel, const ObjFile::Object *pData, unsigned int meshIndex) {
|
||||
if (nullptr == pData || pModel == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Create faces
|
||||
ObjFile::Mesh *pObjMesh = pModel->mMeshes[meshIndex];
|
||||
if (!pObjMesh) {
|
||||
if (pObjMesh == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
@ -331,8 +330,10 @@ aiMesh *ObjFileImporter::createTopology(const ObjFile::Model *pModel, const ObjF
|
|||
|
||||
for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) {
|
||||
const ObjFile::Face *inp = pObjMesh->m_Faces[index];
|
||||
//ai_assert(nullptr != inp);
|
||||
|
||||
if (inp == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (inp->mPrimitiveType == aiPrimitiveType_LINE) {
|
||||
pMesh->mNumFaces += static_cast<unsigned int>(inp->m_vertices.size() - 1);
|
||||
pMesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
|
||||
|
|
@ -349,14 +350,14 @@ aiMesh *ObjFileImporter::createTopology(const ObjFile::Model *pModel, const ObjF
|
|||
}
|
||||
}
|
||||
|
||||
unsigned int uiIdxCount(0u);
|
||||
unsigned int uiIdxCount = 0u;
|
||||
if (pMesh->mNumFaces > 0) {
|
||||
pMesh->mFaces = new aiFace[pMesh->mNumFaces];
|
||||
if (pObjMesh->m_uiMaterialIndex != ObjFile::Mesh::NoMaterial) {
|
||||
pMesh->mMaterialIndex = pObjMesh->m_uiMaterialIndex;
|
||||
}
|
||||
|
||||
unsigned int outIndex(0);
|
||||
unsigned int outIndex = 0u;
|
||||
|
||||
// Copy all data from all stored meshes
|
||||
for (auto &face : pObjMesh->m_Faces) {
|
||||
|
|
@ -389,7 +390,7 @@ aiMesh *ObjFileImporter::createTopology(const ObjFile::Model *pModel, const ObjF
|
|||
// Create mesh vertices
|
||||
createVertexArray(pModel, pData, meshIndex, pMesh.get(), uiIdxCount);
|
||||
|
||||
return pMesh.release();
|
||||
return pMesh;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
|
@ -400,11 +401,14 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model *pModel,
|
|||
aiMesh *pMesh,
|
||||
unsigned int numIndices) {
|
||||
// Checking preconditions
|
||||
ai_assert(nullptr != pCurrentObject);
|
||||
if (pCurrentObject == nullptr || pModel == nullptr || pMesh == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Break, if no faces are stored in object
|
||||
if (pCurrentObject->m_Meshes.empty())
|
||||
if (pCurrentObject->m_Meshes.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get current mesh
|
||||
ObjFile::Mesh *pObjMesh = pModel->mMeshes[uiMeshIndex];
|
||||
|
|
@ -500,6 +504,10 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model *pModel,
|
|||
|
||||
if (vertexIndex) {
|
||||
if (!last) {
|
||||
if (pMesh->mNumVertices <= newIndex + 1) {
|
||||
throw DeadlyImportError("OBJ: bad vertex index");
|
||||
}
|
||||
|
||||
pMesh->mVertices[newIndex + 1] = pMesh->mVertices[newIndex];
|
||||
if (!sourceFace->m_normals.empty() && !pModel->mNormals.empty()) {
|
||||
pMesh->mNormals[newIndex + 1] = pMesh->mNormals[newIndex];
|
||||
|
|
@ -579,11 +587,12 @@ void ObjFileImporter::createMaterials(const ObjFile::Model *pModel, aiScene *pSc
|
|||
it = pModel->mMaterialMap.find(pModel->mMaterialLib[matIndex]);
|
||||
|
||||
// No material found, use the default material
|
||||
if (pModel->mMaterialMap.end() == it)
|
||||
if (pModel->mMaterialMap.end() == it) {
|
||||
continue;
|
||||
}
|
||||
|
||||
aiMaterial *mat = new aiMaterial;
|
||||
ObjFile::Material *pCurrentMaterial = (*it).second;
|
||||
ObjFile::Material *pCurrentMaterial = it->second;
|
||||
mat->AddProperty(&pCurrentMaterial->MaterialName, AI_MATKEY_NAME);
|
||||
|
||||
// convert illumination model
|
||||
|
|
@ -770,8 +779,11 @@ void ObjFileImporter::createMaterials(const ObjFile::Model *pModel, aiScene *pSc
|
|||
// Appends this node to the parent node
|
||||
void ObjFileImporter::appendChildToParentNode(aiNode *pParent, aiNode *pChild) {
|
||||
// Checking preconditions
|
||||
ai_assert(nullptr != pParent);
|
||||
ai_assert(nullptr != pChild);
|
||||
if (pParent == nullptr || pChild == nullptr) {
|
||||
ai_assert(nullptr != pParent);
|
||||
ai_assert(nullptr != pChild);
|
||||
return;
|
||||
}
|
||||
|
||||
// Assign parent to child
|
||||
pChild->mParent = pParent;
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include <assimp/BaseImporter.h>
|
||||
#include <assimp/material.h>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
struct aiMesh;
|
||||
|
|
@ -84,10 +85,10 @@ protected:
|
|||
|
||||
//! \brief Creates all nodes stored in imported content.
|
||||
aiNode *createNodes(const ObjFile::Model *pModel, const ObjFile::Object *pData,
|
||||
aiNode *pParent, aiScene *pScene, std::vector<aiMesh *> &MeshArray);
|
||||
aiNode *pParent, aiScene *pScene, std::vector<std::unique_ptr<aiMesh>> &MeshArray);
|
||||
|
||||
//! \brief Creates topology data like faces and meshes for the geometry.
|
||||
aiMesh *createTopology(const ObjFile::Model *pModel, const ObjFile::Object *pData,
|
||||
std::unique_ptr<aiMesh> createTopology(const ObjFile::Model *pModel, const ObjFile::Object *pData,
|
||||
unsigned int uiMeshIndex);
|
||||
|
||||
//! \brief Creates vertices from model.
|
||||
|
|
|
|||
|
|
@ -53,38 +53,38 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
namespace Assimp {
|
||||
|
||||
// Material specific token (case insensitive compare)
|
||||
static const std::string DiffuseTexture = "map_Kd";
|
||||
static const std::string AmbientTexture = "map_Ka";
|
||||
static const std::string SpecularTexture = "map_Ks";
|
||||
static const std::string OpacityTexture = "map_d";
|
||||
static const std::string EmissiveTexture1 = "map_emissive";
|
||||
static const std::string EmissiveTexture2 = "map_Ke";
|
||||
static const std::string BumpTexture1 = "map_bump";
|
||||
static const std::string BumpTexture2 = "bump";
|
||||
static const std::string NormalTextureV1 = "map_Kn";
|
||||
static const std::string NormalTextureV2 = "norm";
|
||||
static const std::string ReflectionTexture = "refl";
|
||||
static const std::string DisplacementTexture1 = "map_disp";
|
||||
static const std::string DisplacementTexture2 = "disp";
|
||||
static const std::string SpecularityTexture = "map_ns";
|
||||
static const std::string RoughnessTexture = "map_Pr";
|
||||
static const std::string MetallicTexture = "map_Pm";
|
||||
static const std::string SheenTexture = "map_Ps";
|
||||
static const std::string RMATexture = "map_Ps";
|
||||
static constexpr char DiffuseTexture[] = "map_Kd";
|
||||
static constexpr char AmbientTexture[] = "map_Ka";
|
||||
static constexpr char SpecularTexture[] = "map_Ks";
|
||||
static constexpr char OpacityTexture[] = "map_d";
|
||||
static constexpr char EmissiveTexture1[] = "map_emissive";
|
||||
static constexpr char EmissiveTexture2[] = "map_Ke";
|
||||
static constexpr char BumpTexture1[] = "map_bump";
|
||||
static constexpr char BumpTexture2[] = "bump";
|
||||
static constexpr char NormalTextureV1[] = "map_Kn";
|
||||
static constexpr char NormalTextureV2[] = "norm";
|
||||
static constexpr char ReflectionTexture[] = "refl";
|
||||
static constexpr char DisplacementTexture1[] = "map_disp";
|
||||
static constexpr char DisplacementTexture2[] = "disp";
|
||||
static constexpr char SpecularityTexture[] = "map_ns";
|
||||
static constexpr char RoughnessTexture[] = "map_Pr";
|
||||
static constexpr char MetallicTexture[] = "map_Pm";
|
||||
static constexpr char SheenTexture[] = "map_Ps";
|
||||
static constexpr char RMATexture[] = "map_Ps";
|
||||
|
||||
// texture option specific token
|
||||
static const std::string BlendUOption = "-blendu";
|
||||
static const std::string BlendVOption = "-blendv";
|
||||
static const std::string BoostOption = "-boost";
|
||||
static const std::string ModifyMapOption = "-mm";
|
||||
static const std::string OffsetOption = "-o";
|
||||
static const std::string ScaleOption = "-s";
|
||||
static const std::string TurbulenceOption = "-t";
|
||||
static const std::string ResolutionOption = "-texres";
|
||||
static const std::string ClampOption = "-clamp";
|
||||
static const std::string BumpOption = "-bm";
|
||||
static const std::string ChannelOption = "-imfchan";
|
||||
static const std::string TypeOption = "-type";
|
||||
static constexpr char BlendUOption[] = "-blendu";
|
||||
static constexpr char BlendVOption[] = "-blendv";
|
||||
static constexpr char BoostOption[] = "-boost";
|
||||
static constexpr char ModifyMapOption[] = "-mm";
|
||||
static constexpr char OffsetOption[] = "-o";
|
||||
static constexpr char ScaleOption[] = "-s";
|
||||
static constexpr char TurbulenceOption[] = "-t";
|
||||
static constexpr char ResolutionOption[] = "-texres";
|
||||
static constexpr char ClampOption[] = "-clamp";
|
||||
static constexpr char BumpOption[] = "-bm";
|
||||
static constexpr char ChannelOption[] = "-imfchan";
|
||||
static constexpr char TypeOption[] = "-type";
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Constructor
|
||||
|
|
@ -252,9 +252,9 @@ void ObjFileMtlImporter::load() {
|
|||
case 'a': // Anisotropy
|
||||
{
|
||||
++m_DataIt;
|
||||
getFloatValue(m_pModel->mCurrentMaterial->anisotropy);
|
||||
if (m_pModel->mCurrentMaterial != nullptr)
|
||||
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
||||
getFloatValue(m_pModel->mCurrentMaterial->anisotropy);
|
||||
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
||||
} break;
|
||||
|
||||
default: {
|
||||
|
|
@ -282,6 +282,7 @@ void ObjFileMtlImporter::getColorRGBA(aiColor3D *pColor) {
|
|||
pColor->b = b;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void ObjFileMtlImporter::getColorRGBA(Maybe<aiColor3D> &value) {
|
||||
aiColor3D v;
|
||||
getColorRGBA(&v);
|
||||
|
|
@ -309,6 +310,7 @@ void ObjFileMtlImporter::getFloatValue(ai_real &value) {
|
|||
value = (ai_real)fast_atof(&m_buffer[0]);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void ObjFileMtlImporter::getFloatValue(Maybe<ai_real> &value) {
|
||||
m_DataIt = CopyNextWord<DataArrayIt>(m_DataIt, m_DataItEnd, &m_buffer[0], BUFFERSIZE);
|
||||
size_t len = std::strlen(&m_buffer[0]);
|
||||
|
|
@ -341,7 +343,7 @@ void ObjFileMtlImporter::createMaterial() {
|
|||
}
|
||||
}
|
||||
|
||||
name = trim_whitespaces(name);
|
||||
name = ai_trim(name);
|
||||
|
||||
std::map<std::string, ObjFile::Material *>::iterator it = m_pModel->mMaterialMap.find(name);
|
||||
if (m_pModel->mMaterialMap.end() == it) {
|
||||
|
|
@ -356,73 +358,79 @@ void ObjFileMtlImporter::createMaterial() {
|
|||
}
|
||||
} else {
|
||||
// Use older material
|
||||
m_pModel->mCurrentMaterial = (*it).second;
|
||||
m_pModel->mCurrentMaterial = it->second;
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Gets a texture name from data.
|
||||
void ObjFileMtlImporter::getTexture() {
|
||||
aiString *out(nullptr);
|
||||
aiString *out = nullptr;
|
||||
int clampIndex = -1;
|
||||
|
||||
if (m_pModel->mCurrentMaterial == nullptr) {
|
||||
m_pModel->mCurrentMaterial = new ObjFile::Material();
|
||||
m_pModel->mCurrentMaterial->MaterialName.Set("Empty_Material");
|
||||
m_pModel->mMaterialMap["Empty_Material"] = m_pModel->mCurrentMaterial;
|
||||
}
|
||||
|
||||
const char *pPtr(&(*m_DataIt));
|
||||
if (!ASSIMP_strincmp(pPtr, DiffuseTexture.c_str(), static_cast<unsigned int>(DiffuseTexture.size()))) {
|
||||
if (!ASSIMP_strincmp(pPtr, DiffuseTexture, static_cast<unsigned int>(strlen(DiffuseTexture)))) {
|
||||
// Diffuse texture
|
||||
out = &m_pModel->mCurrentMaterial->texture;
|
||||
clampIndex = ObjFile::Material::TextureDiffuseType;
|
||||
} else if (!ASSIMP_strincmp(pPtr, AmbientTexture.c_str(), static_cast<unsigned int>(AmbientTexture.size()))) {
|
||||
} else if (!ASSIMP_strincmp(pPtr, AmbientTexture, static_cast<unsigned int>(strlen(AmbientTexture)))) {
|
||||
// Ambient texture
|
||||
out = &m_pModel->mCurrentMaterial->textureAmbient;
|
||||
clampIndex = ObjFile::Material::TextureAmbientType;
|
||||
} else if (!ASSIMP_strincmp(pPtr, SpecularTexture.c_str(), static_cast<unsigned int>(SpecularTexture.size()))) {
|
||||
} else if (!ASSIMP_strincmp(pPtr, SpecularTexture, static_cast<unsigned int>(strlen(SpecularTexture)))) {
|
||||
// Specular texture
|
||||
out = &m_pModel->mCurrentMaterial->textureSpecular;
|
||||
clampIndex = ObjFile::Material::TextureSpecularType;
|
||||
} 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()))) {
|
||||
} else if (!ASSIMP_strincmp(pPtr, DisplacementTexture1, static_cast<unsigned int>(strlen(DisplacementTexture1))) ||
|
||||
!ASSIMP_strincmp(pPtr, DisplacementTexture2, static_cast<unsigned int>(strlen(DisplacementTexture2)))) {
|
||||
// Displacement texture
|
||||
out = &m_pModel->mCurrentMaterial->textureDisp;
|
||||
clampIndex = ObjFile::Material::TextureDispType;
|
||||
} else if (!ASSIMP_strincmp(pPtr, OpacityTexture.c_str(), static_cast<unsigned int>(OpacityTexture.size()))) {
|
||||
} else if (!ASSIMP_strincmp(pPtr, OpacityTexture, static_cast<unsigned int>(strlen(OpacityTexture)))) {
|
||||
// Opacity texture
|
||||
out = &m_pModel->mCurrentMaterial->textureOpacity;
|
||||
clampIndex = ObjFile::Material::TextureOpacityType;
|
||||
} 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()))) {
|
||||
} else if (!ASSIMP_strincmp(pPtr, EmissiveTexture1, static_cast<unsigned int>(strlen(EmissiveTexture1))) ||
|
||||
!ASSIMP_strincmp(pPtr, EmissiveTexture2, static_cast<unsigned int>(strlen(EmissiveTexture2)))) {
|
||||
// Emissive texture
|
||||
out = &m_pModel->mCurrentMaterial->textureEmissive;
|
||||
clampIndex = ObjFile::Material::TextureEmissiveType;
|
||||
} 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()))) {
|
||||
} else if (!ASSIMP_strincmp(pPtr, BumpTexture1, static_cast<unsigned int>(strlen(BumpTexture1))) ||
|
||||
!ASSIMP_strincmp(pPtr, BumpTexture2, static_cast<unsigned int>(strlen(BumpTexture2)))) {
|
||||
// Bump texture
|
||||
out = &m_pModel->mCurrentMaterial->textureBump;
|
||||
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, static_cast<unsigned int>(strlen(NormalTextureV1))) || !ASSIMP_strincmp(pPtr, NormalTextureV2, static_cast<unsigned int>(strlen(NormalTextureV2)))) {
|
||||
// Normal map
|
||||
out = &m_pModel->mCurrentMaterial->textureNormal;
|
||||
clampIndex = ObjFile::Material::TextureNormalType;
|
||||
} else if (!ASSIMP_strincmp(pPtr, ReflectionTexture.c_str(), static_cast<unsigned int>(ReflectionTexture.size()))) {
|
||||
} else if (!ASSIMP_strincmp(pPtr, ReflectionTexture, static_cast<unsigned int>(strlen(ReflectionTexture)))) {
|
||||
// Reflection texture(s)
|
||||
//Do nothing here
|
||||
return;
|
||||
} else if (!ASSIMP_strincmp(pPtr, SpecularityTexture.c_str(), static_cast<unsigned int>(SpecularityTexture.size()))) {
|
||||
} else if (!ASSIMP_strincmp(pPtr, SpecularityTexture, static_cast<unsigned int>(strlen(SpecularityTexture)))) {
|
||||
// Specularity scaling (glossiness)
|
||||
out = &m_pModel->mCurrentMaterial->textureSpecularity;
|
||||
clampIndex = ObjFile::Material::TextureSpecularityType;
|
||||
} else if ( !ASSIMP_strincmp( pPtr, RoughnessTexture.c_str(), static_cast<unsigned int>(RoughnessTexture.size()))) {
|
||||
} else if ( !ASSIMP_strincmp( pPtr, RoughnessTexture, static_cast<unsigned int>(strlen(RoughnessTexture)))) {
|
||||
// PBR Roughness texture
|
||||
out = & m_pModel->mCurrentMaterial->textureRoughness;
|
||||
clampIndex = ObjFile::Material::TextureRoughnessType;
|
||||
} else if ( !ASSIMP_strincmp( pPtr, MetallicTexture.c_str(), static_cast<unsigned int>(MetallicTexture.size()))) {
|
||||
} else if ( !ASSIMP_strincmp( pPtr, MetallicTexture, static_cast<unsigned int>(strlen(MetallicTexture)))) {
|
||||
// PBR Metallic texture
|
||||
out = & m_pModel->mCurrentMaterial->textureMetallic;
|
||||
clampIndex = ObjFile::Material::TextureMetallicType;
|
||||
} else if (!ASSIMP_strincmp( pPtr, SheenTexture.c_str(), static_cast<unsigned int>(SheenTexture.size()))) {
|
||||
} else if (!ASSIMP_strincmp( pPtr, SheenTexture, static_cast<unsigned int>(strlen(SheenTexture)))) {
|
||||
// PBR Sheen (reflectance) texture
|
||||
out = & m_pModel->mCurrentMaterial->textureSheen;
|
||||
clampIndex = ObjFile::Material::TextureSheenType;
|
||||
} else if (!ASSIMP_strincmp( pPtr, RMATexture.c_str(), static_cast<unsigned int>(RMATexture.size()))) {
|
||||
} else if (!ASSIMP_strincmp( pPtr, RMATexture, static_cast<unsigned int>(strlen(RMATexture)))) {
|
||||
// PBR Rough/Metal/AO texture
|
||||
out = & m_pModel->mCurrentMaterial->textureRMA;
|
||||
clampIndex = ObjFile::Material::TextureRMAType;
|
||||
|
|
@ -466,7 +474,7 @@ void ObjFileMtlImporter::getTextureOption(bool &clamp, int &clampIndex, aiString
|
|||
//skip option key and value
|
||||
int skipToken = 1;
|
||||
|
||||
if (!ASSIMP_strincmp(pPtr, ClampOption.c_str(), static_cast<unsigned int>(ClampOption.size()))) {
|
||||
if (!ASSIMP_strincmp(pPtr, ClampOption, static_cast<unsigned int>(strlen(ClampOption)))) {
|
||||
DataArrayIt it = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
||||
char value[3];
|
||||
CopyNextWord(it, m_DataItEnd, value, sizeof(value) / sizeof(*value));
|
||||
|
|
@ -475,7 +483,7 @@ void ObjFileMtlImporter::getTextureOption(bool &clamp, int &clampIndex, aiString
|
|||
}
|
||||
|
||||
skipToken = 2;
|
||||
} else if (!ASSIMP_strincmp(pPtr, TypeOption.c_str(), static_cast<unsigned int>(TypeOption.size()))) {
|
||||
} else if (!ASSIMP_strincmp(pPtr, TypeOption, static_cast<unsigned int>(strlen(TypeOption)))) {
|
||||
DataArrayIt it = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
||||
char value[12];
|
||||
CopyNextWord(it, m_DataItEnd, value, sizeof(value) / sizeof(*value));
|
||||
|
|
@ -503,15 +511,21 @@ void ObjFileMtlImporter::getTextureOption(bool &clamp, int &clampIndex, aiString
|
|||
}
|
||||
|
||||
skipToken = 2;
|
||||
} else if (!ASSIMP_strincmp(pPtr, BumpOption.c_str(), static_cast<unsigned int>(BumpOption.size()))) {
|
||||
} else if (!ASSIMP_strincmp(pPtr, BumpOption, static_cast<unsigned int>(strlen(BumpOption)))) {
|
||||
DataArrayIt it = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
||||
getFloat(it, m_DataItEnd, m_pModel->mCurrentMaterial->bump_multiplier);
|
||||
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, static_cast<unsigned int>(strlen(BlendUOption))) ||
|
||||
!ASSIMP_strincmp(pPtr, BlendVOption, static_cast<unsigned int>(strlen(BlendVOption))) ||
|
||||
!ASSIMP_strincmp(pPtr, BoostOption, static_cast<unsigned int>(strlen(BoostOption))) ||
|
||||
!ASSIMP_strincmp(pPtr, ResolutionOption, static_cast<unsigned int>(strlen(ResolutionOption))) ||
|
||||
!ASSIMP_strincmp(pPtr, ChannelOption, static_cast<unsigned int>(strlen(ChannelOption)))) {
|
||||
skipToken = 2;
|
||||
} else if (!ASSIMP_strincmp(pPtr, ModifyMapOption.c_str(), static_cast<unsigned int>(ModifyMapOption.size()))) {
|
||||
} else if (!ASSIMP_strincmp(pPtr, ModifyMapOption, static_cast<unsigned int>(strlen(ModifyMapOption)))) {
|
||||
skipToken = 3;
|
||||
} else if (!ASSIMP_strincmp(pPtr, OffsetOption.c_str(), static_cast<unsigned int>(OffsetOption.size())) || !ASSIMP_strincmp(pPtr, ScaleOption.c_str(), static_cast<unsigned int>(ScaleOption.size())) || !ASSIMP_strincmp(pPtr, TurbulenceOption.c_str(), static_cast<unsigned int>(TurbulenceOption.size()))) {
|
||||
} else if (!ASSIMP_strincmp(pPtr, OffsetOption, static_cast<unsigned int>(strlen(OffsetOption))) ||
|
||||
!ASSIMP_strincmp(pPtr, ScaleOption, static_cast<unsigned int>(strlen(ScaleOption))) ||
|
||||
!ASSIMP_strincmp(pPtr, TurbulenceOption, static_cast<unsigned int>(strlen(TurbulenceOption)))) {
|
||||
skipToken = 4;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -52,7 +52,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <string_view>
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
|
|
@ -64,6 +63,7 @@ ObjFileParser::ObjFileParser() :
|
|||
m_pModel(nullptr),
|
||||
m_uiLine(0),
|
||||
m_buffer(),
|
||||
mEnd(&m_buffer[Buffersize]),
|
||||
m_pIO(nullptr),
|
||||
m_progress(nullptr),
|
||||
m_originalObjFileName() {
|
||||
|
|
@ -97,8 +97,6 @@ ObjFileParser::ObjFileParser(IOStreamBuffer<char> &streamBuffer, const std::stri
|
|||
parseFile(streamBuffer);
|
||||
}
|
||||
|
||||
ObjFileParser::~ObjFileParser() = default;
|
||||
|
||||
void ObjFileParser::setBuffer(std::vector<char> &buffer) {
|
||||
m_DataIt = buffer.begin();
|
||||
m_DataItEnd = buffer.end();
|
||||
|
|
@ -121,6 +119,7 @@ void ObjFileParser::parseFile(IOStreamBuffer<char> &streamBuffer) {
|
|||
while (streamBuffer.getNextDataLine(buffer, '\\')) {
|
||||
m_DataIt = buffer.begin();
|
||||
m_DataItEnd = buffer.end();
|
||||
mEnd = &buffer[buffer.size() - 1] + 1;
|
||||
|
||||
// Handle progress reporting
|
||||
const size_t filePos(streamBuffer.getFilePos());
|
||||
|
|
@ -130,7 +129,7 @@ void ObjFileParser::parseFile(IOStreamBuffer<char> &streamBuffer) {
|
|||
m_progress->UpdateFileRead(processed, progressTotal);
|
||||
}
|
||||
|
||||
// handle cstype section end (http://paulbourke.net/dataformats/obj/)
|
||||
// handle c-stype section end (http://paulbourke.net/dataformats/obj/)
|
||||
if (insideCstype) {
|
||||
switch (*m_DataIt) {
|
||||
case 'e': {
|
||||
|
|
@ -156,9 +155,17 @@ void ObjFileParser::parseFile(IOStreamBuffer<char> &streamBuffer) {
|
|||
// read in vertex definition (homogeneous coords)
|
||||
getHomogeneousVector3(m_pModel->mVertices);
|
||||
} else if (numComponents == 6) {
|
||||
// fill previous omitted vertex-colors by default
|
||||
if (m_pModel->mVertexColors.size() < m_pModel->mVertices.size()) {
|
||||
m_pModel->mVertexColors.resize(m_pModel->mVertices.size(), aiVector3D(0, 0, 0));
|
||||
}
|
||||
// read vertex and vertex-color
|
||||
getTwoVectors3(m_pModel->mVertices, m_pModel->mVertexColors);
|
||||
}
|
||||
// append omitted vertex-colors as default for the end if any vertex-color exists
|
||||
if (!m_pModel->mVertexColors.empty() && m_pModel->mVertexColors.size() < m_pModel->mVertices.size()) {
|
||||
m_pModel->mVertexColors.resize(m_pModel->mVertices.size(), aiVector3D(0, 0, 0));
|
||||
}
|
||||
} else if (*m_DataIt == 't') {
|
||||
// read in texture coordinate ( 2D or 3D )
|
||||
++m_DataIt;
|
||||
|
|
@ -236,7 +243,7 @@ void ObjFileParser::parseFile(IOStreamBuffer<char> &streamBuffer) {
|
|||
getNameNoSpace(m_DataIt, m_DataItEnd, name);
|
||||
insideCstype = name == "cstype";
|
||||
goto pf_skip_line;
|
||||
} break;
|
||||
}
|
||||
|
||||
default: {
|
||||
pf_skip_line:
|
||||
|
|
@ -293,18 +300,19 @@ size_t ObjFileParser::getNumComponentsInDataDefinition() {
|
|||
} else if (IsLineEnd(*tmp)) {
|
||||
end_of_definition = true;
|
||||
}
|
||||
if (!SkipSpaces(&tmp)) {
|
||||
if (!SkipSpaces(&tmp, mEnd)) {
|
||||
break;
|
||||
}
|
||||
const bool isNum(IsNumeric(*tmp) || isNanOrInf(tmp));
|
||||
SkipToken(tmp);
|
||||
SkipToken(tmp, mEnd);
|
||||
if (isNum) {
|
||||
++numComponents;
|
||||
}
|
||||
if (!SkipSpaces(&tmp)) {
|
||||
if (!SkipSpaces(&tmp, mEnd)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return numComponents;
|
||||
}
|
||||
|
||||
|
|
@ -440,7 +448,7 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
|
|||
const bool vt = (!m_pModel->mTextureCoord.empty());
|
||||
const bool vn = (!m_pModel->mNormals.empty());
|
||||
int iPos = 0;
|
||||
while (m_DataIt != m_DataItEnd) {
|
||||
while (m_DataIt < m_DataItEnd) {
|
||||
int iStep = 1;
|
||||
|
||||
if (IsLineEnd(*m_DataIt)) {
|
||||
|
|
@ -456,9 +464,20 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
|
|||
iPos = 0;
|
||||
} else {
|
||||
//OBJ USES 1 Base ARRAYS!!!!
|
||||
const char *token = &(*m_DataIt);
|
||||
const int iVal = ::atoi(token);
|
||||
|
||||
int iVal;
|
||||
auto end = m_DataIt;
|
||||
// find either the buffer end or the '\0'
|
||||
while (end < m_DataItEnd && *end != '\0')
|
||||
++end;
|
||||
// avoid temporary string allocation if there is a zero
|
||||
if (end != m_DataItEnd) {
|
||||
iVal = ::atoi(&(*m_DataIt));
|
||||
} else {
|
||||
// otherwise make a zero terminated copy, which is safe to pass to atoi
|
||||
std::string number(&(*m_DataIt), m_DataItEnd - m_DataIt);
|
||||
iVal = ::atoi(number.c_str());
|
||||
}
|
||||
|
||||
// increment iStep position based off of the sign and # of digits
|
||||
int tmp = iVal;
|
||||
if (iVal < 0) {
|
||||
|
|
@ -468,8 +487,9 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
|
|||
++iStep;
|
||||
}
|
||||
|
||||
if (iPos == 1 && !vt && vn)
|
||||
if (iPos == 1 && !vt && vn) {
|
||||
iPos = 2; // skip texture coords for normals if there are no tex coords
|
||||
}
|
||||
|
||||
if (iVal > 0) {
|
||||
// Store parsed index
|
||||
|
|
@ -557,14 +577,17 @@ void ObjFileParser::getMaterialDesc() {
|
|||
|
||||
// Get name
|
||||
std::string strName(pStart, &(*m_DataIt));
|
||||
strName = trim_whitespaces(strName);
|
||||
if (strName.empty())
|
||||
strName = ai_trim(strName);
|
||||
if (strName.empty()) {
|
||||
skip = true;
|
||||
}
|
||||
|
||||
// If the current mesh has the same material, we simply ignore that 'usemtl' command
|
||||
// If the current mesh has the same material, we will ignore that 'usemtl' command
|
||||
// There is no need to create another object or even mesh here
|
||||
if (m_pModel->mCurrentMaterial && m_pModel->mCurrentMaterial->MaterialName == aiString(strName)) {
|
||||
skip = true;
|
||||
if (!skip) {
|
||||
if (m_pModel->mCurrentMaterial && m_pModel->mCurrentMaterial->MaterialName == aiString(strName)) {
|
||||
skip = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!skip) {
|
||||
|
|
@ -586,7 +609,8 @@ void ObjFileParser::getMaterialDesc() {
|
|||
}
|
||||
|
||||
if (needsNewMesh(strName)) {
|
||||
createMesh(strName);
|
||||
auto newMeshName = m_pModel->mActiveGroup.empty() ? strName : m_pModel->mActiveGroup;
|
||||
createMesh(newMeshName);
|
||||
}
|
||||
|
||||
m_pModel->mCurrentMesh->m_uiMaterialIndex = getMaterialIndex(strName);
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef OBJ_FILEPARSER_H_INC
|
||||
#define OBJ_FILEPARSER_H_INC
|
||||
|
||||
#include "ObjFileData.h"
|
||||
|
||||
#include <assimp/IOStreamBuffer.h>
|
||||
#include <assimp/material.h>
|
||||
#include <assimp/mesh.h>
|
||||
|
|
@ -53,14 +55,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
namespace Assimp {
|
||||
|
||||
namespace ObjFile {
|
||||
struct Model;
|
||||
struct Object;
|
||||
struct Material;
|
||||
struct Point3;
|
||||
struct Point2;
|
||||
} // namespace ObjFile
|
||||
|
||||
class ObjFileImporter;
|
||||
class IOSystem;
|
||||
class ProgressHandler;
|
||||
|
|
@ -79,7 +73,7 @@ public:
|
|||
/// @brief Constructor with data array.
|
||||
ObjFileParser(IOStreamBuffer<char> &streamBuffer, const std::string &modelName, IOSystem *io, ProgressHandler *progress, const std::string &originalObjFileName);
|
||||
/// @brief Destructor
|
||||
~ObjFileParser();
|
||||
~ObjFileParser() = default;
|
||||
/// @brief If you want to load in-core data.
|
||||
void setBuffer(std::vector<char> &buffer);
|
||||
/// @brief Model getter.
|
||||
|
|
@ -149,6 +143,7 @@ private:
|
|||
unsigned int m_uiLine;
|
||||
//! Helper buffer
|
||||
char m_buffer[Buffersize];
|
||||
const char *mEnd;
|
||||
/// Pointer to IO system instance.
|
||||
IOSystem *m_pIO;
|
||||
//! Pointer to progress handler
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2021, assimp team
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -51,7 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
namespace Assimp {
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Returns true, if the last entry of the buffer is reached.
|
||||
* @param[in] it Iterator of current position.
|
||||
* @param[in] end Iterator with end of buffer.
|
||||
|
|
@ -67,7 +67,7 @@ inline bool isEndOfBuffer(char_t it, char_t end) {
|
|||
return (it == end);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Returns next word separated by a space
|
||||
* @param[in] pBuffer Pointer to data buffer
|
||||
* @param[in] pEnd Pointer to end of buffer
|
||||
|
|
@ -85,7 +85,7 @@ inline Char_T getNextWord(Char_T pBuffer, Char_T pEnd) {
|
|||
return pBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Returns pointer a next token
|
||||
* @param[in] pBuffer Pointer to data buffer
|
||||
* @param[in] pEnd Pointer to end of buffer
|
||||
|
|
@ -102,7 +102,7 @@ inline Char_T getNextToken(Char_T pBuffer, Char_T pEnd) {
|
|||
return getNextWord(pBuffer, pEnd);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Skips a line
|
||||
* @param[in] it Iterator set to current position
|
||||
* @param[in] end Iterator set to end of scratch buffer for readout
|
||||
|
|
@ -111,6 +111,10 @@ inline Char_T getNextToken(Char_T pBuffer, Char_T pEnd) {
|
|||
*/
|
||||
template <class char_t>
|
||||
inline char_t skipLine(char_t it, char_t end, unsigned int &uiLine) {
|
||||
if (it >= end) {
|
||||
return it;
|
||||
}
|
||||
|
||||
while (!isEndOfBuffer(it, end) && !IsLineEnd(*it)) {
|
||||
++it;
|
||||
}
|
||||
|
|
@ -127,9 +131,9 @@ inline char_t skipLine(char_t it, char_t end, unsigned int &uiLine) {
|
|||
return it;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Get a name from the current line. Preserve space in the middle,
|
||||
* but trim it at the end.
|
||||
* but trim it at the end.
|
||||
* @param[in] it set to current position
|
||||
* @param[in] end set to end of scratch buffer for readout
|
||||
* @param[out] name Separated name
|
||||
|
|
@ -158,13 +162,13 @@ inline char_t getName(char_t it, char_t end, std::string &name) {
|
|||
std::string strName(pStart, &(*it));
|
||||
if (!strName.empty()) {
|
||||
name = strName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return it;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Get a name from the current line. Do not preserve space
|
||||
* in the middle, but trim it at the end.
|
||||
* @param it set to current position
|
||||
|
|
@ -198,11 +202,11 @@ inline char_t getNameNoSpace(char_t it, char_t end, std::string &name) {
|
|||
if (!strName.empty()) {
|
||||
name = strName;
|
||||
}
|
||||
|
||||
|
||||
return it;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Get next word from given line
|
||||
* @param[in] it set to current position
|
||||
* @param[in] end set to end of scratch buffer for readout
|
||||
|
|
@ -226,7 +230,7 @@ inline char_t CopyNextWord(char_t it, char_t end, char *pBuffer, size_t length)
|
|||
return it;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Get next float from given line
|
||||
* @param[in] it set to current position
|
||||
* @param[in] end set to end of scratch buffer for readout
|
||||
|
|
@ -243,22 +247,6 @@ inline char_t getFloat(char_t it, char_t end, ai_real &value) {
|
|||
return it;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Will remove white-spaces for a string.
|
||||
* @param[in] str The string to clean
|
||||
* @return The trimmed string.
|
||||
*/
|
||||
template <class string_type>
|
||||
inline string_type trim_whitespaces(string_type str) {
|
||||
while (!str.empty() && IsSpace(str[0])) {
|
||||
str.erase(0);
|
||||
}
|
||||
while (!str.empty() && IsSpace(str[str.length() - 1])) {
|
||||
str.erase(str.length() - 1);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks for a line-end.
|
||||
* @param[in] it Current iterator in string.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue