mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-13 19:53:48 +00:00
Updated assimp to latest
This commit is contained in:
parent
25ce4477ce
commit
161bf7f83b
461 changed files with 34662 additions and 30165 deletions
|
|
@ -3,7 +3,8 @@
|
|||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2017, assimp team
|
||||
Copyright (c) 2006-2019, assimp team
|
||||
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
|
@ -45,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "ObjFileImporter.h"
|
||||
#include "ObjFileParser.h"
|
||||
#include "ObjFileData.h"
|
||||
#include "IOStreamBuffer.h"
|
||||
#include <assimp/IOStreamBuffer.h>
|
||||
#include <memory>
|
||||
#include <assimp/DefaultIOSystem.h>
|
||||
#include <assimp/Importer.hpp>
|
||||
|
|
@ -75,41 +76,36 @@ using namespace std;
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Default constructor
|
||||
ObjFileImporter::ObjFileImporter() :
|
||||
m_Buffer(),
|
||||
m_pRootObject( NULL ),
|
||||
m_strAbsPath( "" )
|
||||
{
|
||||
ObjFileImporter::ObjFileImporter()
|
||||
: m_Buffer()
|
||||
, m_pRootObject( nullptr )
|
||||
, m_strAbsPath( "" ) {
|
||||
DefaultIOSystem io;
|
||||
m_strAbsPath = io.getOsSeparator();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Destructor.
|
||||
ObjFileImporter::~ObjFileImporter()
|
||||
{
|
||||
ObjFileImporter::~ObjFileImporter() {
|
||||
delete m_pRootObject;
|
||||
m_pRootObject = NULL;
|
||||
m_pRootObject = nullptr;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns true, if file is an obj file.
|
||||
bool ObjFileImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler , bool checkSig ) const
|
||||
{
|
||||
if(!checkSig) //Check File Extension
|
||||
{
|
||||
bool ObjFileImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler , bool checkSig ) const {
|
||||
if(!checkSig) {
|
||||
//Check File Extension
|
||||
return SimpleExtensionCheck(pFile,"obj");
|
||||
}
|
||||
else //Check file Header
|
||||
{
|
||||
} else {
|
||||
// Check file Header
|
||||
static const char *pTokens[] = { "mtllib", "usemtl", "v ", "vt ", "vn ", "o ", "g ", "s ", "f " };
|
||||
return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, pTokens, 9 );
|
||||
return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, pTokens, 9, 200, false, true );
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const aiImporterDesc* ObjFileImporter::GetInfo () const
|
||||
{
|
||||
const aiImporterDesc* ObjFileImporter::GetInfo() const {
|
||||
return &desc;
|
||||
}
|
||||
|
||||
|
|
@ -148,38 +144,6 @@ void ObjFileImporter::InternReadFile( const std::string &file, aiScene* pScene,
|
|||
modelName = file;
|
||||
}
|
||||
|
||||
// This next stage takes ~ 1/3th of the total readFile task
|
||||
// so should amount for 1/3th of the progress
|
||||
// only update every 100KB or it'll be too slow
|
||||
/*unsigned int progress = 0;
|
||||
unsigned int progressCounter = 0;
|
||||
const unsigned int updateProgressEveryBytes = 100 * 1024;
|
||||
const unsigned int progressTotal = static_cast<unsigned int>(3*m_Buffer.size()/updateProgressEveryBytes);*/
|
||||
// process all '\'
|
||||
/*std::vector<char> ::iterator iter = m_Buffer.begin();
|
||||
while (iter != m_Buffer.end())
|
||||
{
|
||||
if (*iter == '\\')
|
||||
{
|
||||
// remove '\'
|
||||
iter = m_Buffer.erase(iter);
|
||||
// remove next character
|
||||
while (*iter == '\r' || *iter == '\n')
|
||||
iter = m_Buffer.erase(iter);
|
||||
}
|
||||
else
|
||||
++iter;
|
||||
|
||||
if (++progressCounter >= updateProgressEveryBytes)
|
||||
{
|
||||
m_progress->UpdateFileRead(++progress, progressTotal);
|
||||
progressCounter = 0;
|
||||
}
|
||||
}*/
|
||||
|
||||
// 1/3rd progress
|
||||
m_progress->UpdateFileRead(1, 3);
|
||||
|
||||
// parse the file into a temporary representation
|
||||
ObjFileParser parser( streamedBuffer, modelName, pIOHandler, m_progress, file);
|
||||
|
||||
|
|
@ -206,36 +170,88 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene
|
|||
|
||||
// Create the root node of the scene
|
||||
pScene->mRootNode = new aiNode;
|
||||
if ( !pModel->m_ModelName.empty() )
|
||||
{
|
||||
if ( !pModel->m_ModelName.empty() ) {
|
||||
// Set the name of the scene
|
||||
pScene->mRootNode->mName.Set(pModel->m_ModelName);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// This is a fatal error, so break down the application
|
||||
ai_assert(false);
|
||||
}
|
||||
|
||||
// Create nodes for the whole scene
|
||||
std::vector<aiMesh*> MeshArray;
|
||||
for (size_t index = 0; index < pModel->m_Objects.size(); index++)
|
||||
{
|
||||
createNodes(pModel, pModel->m_Objects[ index ], pScene->mRootNode, pScene, MeshArray);
|
||||
}
|
||||
if (pModel->m_Objects.size() > 0) {
|
||||
|
||||
// Create mesh pointer buffer for this scene
|
||||
if (pScene->mNumMeshes > 0)
|
||||
{
|
||||
pScene->mMeshes = new aiMesh*[ MeshArray.size() ];
|
||||
for (size_t index =0; index < MeshArray.size(); index++)
|
||||
{
|
||||
pScene->mMeshes[ index ] = MeshArray[ index ];
|
||||
unsigned int meshCount = 0;
|
||||
unsigned int childCount = 0;
|
||||
|
||||
for(size_t index = 0; index < pModel->m_Objects.size(); ++index) {
|
||||
if(pModel->m_Objects[index]) {
|
||||
++childCount;
|
||||
meshCount += (unsigned int)pModel->m_Objects[index]->m_Meshes.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create all materials
|
||||
createMaterials( pModel, pScene );
|
||||
// Allocate space for the child nodes on the root node
|
||||
pScene->mRootNode->mChildren = new aiNode*[ childCount ];
|
||||
|
||||
// Create nodes for the whole scene
|
||||
std::vector<aiMesh*> MeshArray;
|
||||
MeshArray.reserve(meshCount);
|
||||
for (size_t index = 0; index < pModel->m_Objects.size(); ++index) {
|
||||
createNodes(pModel, pModel->m_Objects[index], pScene->mRootNode, pScene, MeshArray);
|
||||
}
|
||||
|
||||
ai_assert(pScene->mRootNode->mNumChildren == childCount);
|
||||
|
||||
// Create mesh pointer buffer for this scene
|
||||
if (pScene->mNumMeshes > 0) {
|
||||
pScene->mMeshes = new aiMesh*[MeshArray.size()];
|
||||
for (size_t index = 0; index < MeshArray.size(); ++index) {
|
||||
pScene->mMeshes[index] = MeshArray[index];
|
||||
}
|
||||
}
|
||||
|
||||
// Create all materials
|
||||
createMaterials(pModel, pScene);
|
||||
}else {
|
||||
if (pModel->m_Vertices.empty()){
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_ptr<aiMesh> mesh( new aiMesh );
|
||||
mesh->mPrimitiveTypes = aiPrimitiveType_POINT;
|
||||
unsigned int n = (unsigned int)pModel->m_Vertices.size();
|
||||
mesh->mNumVertices = n;
|
||||
|
||||
mesh->mVertices = new aiVector3D[n];
|
||||
memcpy(mesh->mVertices, pModel->m_Vertices.data(), n*sizeof(aiVector3D) );
|
||||
|
||||
if ( !pModel->m_Normals.empty() ) {
|
||||
mesh->mNormals = new aiVector3D[n];
|
||||
if (pModel->m_Normals.size() < n) {
|
||||
throw DeadlyImportError("OBJ: vertex normal index out of range");
|
||||
}
|
||||
memcpy(mesh->mNormals, pModel->m_Normals.data(), n*sizeof(aiVector3D));
|
||||
}
|
||||
|
||||
if ( !pModel->m_VertexColors.empty() ){
|
||||
mesh->mColors[0] = new aiColor4D[mesh->mNumVertices];
|
||||
for (unsigned int i = 0; i < n; ++i) {
|
||||
if (i < pModel->m_VertexColors.size() ) {
|
||||
const aiVector3D& color = pModel->m_VertexColors[i];
|
||||
mesh->mColors[0][i] = aiColor4D(color.x, color.y, color.z, 1.0);
|
||||
}else {
|
||||
throw DeadlyImportError("OBJ: vertex color index out of range");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pScene->mRootNode->mNumMeshes = 1;
|
||||
pScene->mRootNode->mMeshes = new unsigned int[1];
|
||||
pScene->mRootNode->mMeshes[0] = 0;
|
||||
pScene->mMeshes = new aiMesh*[1];
|
||||
pScene->mNumMeshes = 1;
|
||||
pScene->mMeshes[0] = mesh.release();
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
|
@ -256,22 +272,23 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model* pModel, const ObjFile
|
|||
pNode->mName = pObject->m_strObjName;
|
||||
|
||||
// If we have a parent node, store it
|
||||
if( pParent != NULL ) {
|
||||
appendChildToParentNode( pParent, pNode );
|
||||
}
|
||||
ai_assert( NULL != pParent );
|
||||
appendChildToParentNode( pParent, pNode );
|
||||
|
||||
for ( size_t i=0; i< pObject->m_Meshes.size(); i++ )
|
||||
{
|
||||
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 && pMesh->mNumFaces > 0 ) {
|
||||
MeshArray.push_back( pMesh );
|
||||
if( pMesh ) {
|
||||
if (pMesh->mNumFaces > 0) {
|
||||
MeshArray.push_back( pMesh );
|
||||
} else {
|
||||
delete pMesh;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create all nodes from the sub-objects stored in the current object
|
||||
if ( !pObject->m_SubObjects.empty() )
|
||||
{
|
||||
if ( !pObject->m_SubObjects.empty() ) {
|
||||
size_t numChilds = pObject->m_SubObjects.size();
|
||||
pNode->mNumChildren = static_cast<unsigned int>( numChilds );
|
||||
pNode->mChildren = new aiNode*[ numChilds ];
|
||||
|
|
@ -281,16 +298,14 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model* pModel, const ObjFile
|
|||
|
||||
// Set mesh instances into scene- and node-instances
|
||||
const size_t meshSizeDiff = MeshArray.size()- oldMeshSize;
|
||||
if ( meshSizeDiff > 0 )
|
||||
{
|
||||
if ( meshSizeDiff > 0 ) {
|
||||
pNode->mMeshes = new unsigned int[ meshSizeDiff ];
|
||||
pNode->mNumMeshes = static_cast<unsigned int>( meshSizeDiff );
|
||||
size_t index = 0;
|
||||
for (size_t i = oldMeshSize; i < MeshArray.size(); i++)
|
||||
{
|
||||
for (size_t i = oldMeshSize; i < MeshArray.size(); ++i ) {
|
||||
pNode->mMeshes[ index ] = pScene->mNumMeshes;
|
||||
pScene->mNumMeshes++;
|
||||
index++;
|
||||
++index;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -317,7 +332,7 @@ aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const Obj
|
|||
return NULL;
|
||||
}
|
||||
|
||||
aiMesh* pMesh = new aiMesh;
|
||||
std::unique_ptr<aiMesh> pMesh(new aiMesh);
|
||||
if( !pObjMesh->m_name.empty() ) {
|
||||
pMesh->mName.Set( pObjMesh->m_name );
|
||||
}
|
||||
|
|
@ -382,9 +397,9 @@ aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const Obj
|
|||
}
|
||||
|
||||
// Create mesh vertices
|
||||
createVertexArray(pModel, pData, meshIndex, pMesh, uiIdxCount);
|
||||
createVertexArray(pModel, pData, meshIndex, pMesh.get(), uiIdxCount);
|
||||
|
||||
return pMesh;
|
||||
return pMesh.release();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
|
@ -411,8 +426,8 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
|
|||
pMesh->mNumVertices = numIndices;
|
||||
if (pMesh->mNumVertices == 0) {
|
||||
throw DeadlyImportError( "OBJ: no vertices" );
|
||||
} else if (pMesh->mNumVertices > AI_MAX_ALLOC(aiVector3D)) {
|
||||
throw DeadlyImportError( "OBJ: Too many vertices, would run out of memory" );
|
||||
} else if (pMesh->mNumVertices > AI_MAX_VERTICES) {
|
||||
throw DeadlyImportError( "OBJ: Too many vertices" );
|
||||
}
|
||||
pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ];
|
||||
|
||||
|
|
@ -432,6 +447,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
|
|||
}
|
||||
|
||||
// Copy vertices, normals and textures into aiMesh instance
|
||||
bool normalsok = true, uvok = true;
|
||||
unsigned int newIndex = 0, outIndex = 0;
|
||||
for ( size_t index=0; index < pObjMesh->m_Faces.size(); index++ ) {
|
||||
// Get source face
|
||||
|
|
@ -444,39 +460,46 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
|
|||
throw DeadlyImportError( "OBJ: vertex index out of range" );
|
||||
}
|
||||
|
||||
if ( pMesh->mNumVertices <= newIndex ) {
|
||||
throw DeadlyImportError("OBJ: bad vertex index");
|
||||
}
|
||||
|
||||
pMesh->mVertices[ newIndex ] = pModel->m_Vertices[ vertex ];
|
||||
|
||||
// Copy all normals
|
||||
if ( !pModel->m_Normals.empty() && vertexIndex < pSourceFace->m_normals.size()) {
|
||||
if ( normalsok && !pModel->m_Normals.empty() && vertexIndex < pSourceFace->m_normals.size()) {
|
||||
const unsigned int normal = pSourceFace->m_normals.at( vertexIndex );
|
||||
if ( normal >= pModel->m_Normals.size() ) {
|
||||
throw DeadlyImportError( "OBJ: vertex normal index out of range" );
|
||||
if ( normal >= pModel->m_Normals.size() )
|
||||
{
|
||||
normalsok = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
pMesh->mNormals[ newIndex ] = pModel->m_Normals[ normal ];
|
||||
}
|
||||
pMesh->mNormals[ newIndex ] = pModel->m_Normals[ normal ];
|
||||
}
|
||||
|
||||
// Copy all vertex colors
|
||||
if ( !pModel->m_VertexColors.empty())
|
||||
{
|
||||
const aiVector3D color = pModel->m_VertexColors[ vertex ];
|
||||
const aiVector3D& color = pModel->m_VertexColors[ vertex ];
|
||||
pMesh->mColors[0][ newIndex ] = aiColor4D(color.x, color.y, color.z, 1.0);
|
||||
}
|
||||
|
||||
// Copy all texture coordinates
|
||||
if ( !pModel->m_TextureCoord.empty() && vertexIndex < pSourceFace->m_texturCoords.size())
|
||||
if ( uvok && !pModel->m_TextureCoord.empty() && vertexIndex < pSourceFace->m_texturCoords.size())
|
||||
{
|
||||
const unsigned int tex = pSourceFace->m_texturCoords.at( vertexIndex );
|
||||
ai_assert( tex < pModel->m_TextureCoord.size() );
|
||||
|
||||
if ( tex >= pModel->m_TextureCoord.size() )
|
||||
throw DeadlyImportError("OBJ: texture coordinate index out of range");
|
||||
|
||||
const aiVector3D &coord3d = pModel->m_TextureCoord[ tex ];
|
||||
pMesh->mTextureCoords[ 0 ][ newIndex ] = aiVector3D( coord3d.x, coord3d.y, coord3d.z );
|
||||
}
|
||||
|
||||
if ( pMesh->mNumVertices <= newIndex ) {
|
||||
throw DeadlyImportError("OBJ: bad vertex index");
|
||||
{
|
||||
uvok = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
const aiVector3D &coord3d = pModel->m_TextureCoord[ tex ];
|
||||
pMesh->mTextureCoords[ 0 ][ newIndex ] = aiVector3D( coord3d.x, coord3d.y, coord3d.z );
|
||||
}
|
||||
}
|
||||
|
||||
// Get destination face
|
||||
|
|
@ -520,6 +543,18 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
|
|||
++newIndex;
|
||||
}
|
||||
}
|
||||
|
||||
if (!normalsok)
|
||||
{
|
||||
delete [] pMesh->mNormals;
|
||||
pMesh->mNormals = nullptr;
|
||||
}
|
||||
|
||||
if (!uvok)
|
||||
{
|
||||
delete [] pMesh->mTextureCoords[0];
|
||||
pMesh->mTextureCoords[0] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
|
@ -563,7 +598,7 @@ void ObjFileImporter::createMaterials(const ObjFile::Model* pModel, aiScene* pSc
|
|||
const unsigned int numMaterials = (unsigned int) pModel->m_MaterialLib.size();
|
||||
pScene->mNumMaterials = 0;
|
||||
if ( pModel->m_MaterialLib.empty() ) {
|
||||
DefaultLogger::get()->debug("OBJ: no materials specified");
|
||||
ASSIMP_LOG_DEBUG("OBJ: no materials specified");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -597,7 +632,7 @@ void ObjFileImporter::createMaterials(const ObjFile::Model* pModel, aiScene* pSc
|
|||
break;
|
||||
default:
|
||||
sm = aiShadingMode_Gouraud;
|
||||
DefaultLogger::get()->error("OBJ: unexpected illumination model (0-2 recognized)");
|
||||
ASSIMP_LOG_ERROR("OBJ: unexpected illumination model (0-2 recognized)");
|
||||
}
|
||||
|
||||
mat->AddProperty<int>( &sm, 1, AI_MATKEY_SHADING_MODEL);
|
||||
|
|
@ -740,25 +775,8 @@ void ObjFileImporter::appendChildToParentNode(aiNode *pParent, aiNode *pChild)
|
|||
// Assign parent to child
|
||||
pChild->mParent = pParent;
|
||||
|
||||
// If already children was assigned to the parent node, store them in a
|
||||
std::vector<aiNode*> temp;
|
||||
if (pParent->mChildren != NULL)
|
||||
{
|
||||
ai_assert( 0 != pParent->mNumChildren );
|
||||
for (size_t index = 0; index < pParent->mNumChildren; index++)
|
||||
{
|
||||
temp.push_back(pParent->mChildren [ index ] );
|
||||
}
|
||||
delete [] pParent->mChildren;
|
||||
}
|
||||
|
||||
// Copy node instances into parent node
|
||||
pParent->mNumChildren++;
|
||||
pParent->mChildren = new aiNode*[ pParent->mNumChildren ];
|
||||
for (size_t index = 0; index < pParent->mNumChildren-1; index++)
|
||||
{
|
||||
pParent->mChildren[ index ] = temp [ index ];
|
||||
}
|
||||
pParent->mChildren[ pParent->mNumChildren-1 ] = pChild;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue