- Major update to the viewer. A little bit buggy now, but I'll fix that
- 2/3 of the viewer code are no wrapped in helper classes - ByteSwap.h header added - Bugfix in the 3DS loader: Texture blend mode was read incorrectly - Bugfix in the X-Loader. Assets with specular_exp == 0 use gouraud lighting now - Added new helper functions to MaterialHelper - Added aiMaterialGetTexture() function to allow easy access to all properties of a texture git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@16 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
This commit is contained in:
+3
-3
@@ -380,7 +380,7 @@ struct Material
|
||||
{
|
||||
static int iCnt = 0;
|
||||
std::stringstream ss(mName);
|
||||
ss << "%%_UNNAMED_" << iCnt++ << "_%%";
|
||||
ss << "$$_UNNAMED_" << iCnt++ << "_$$";
|
||||
}
|
||||
|
||||
//! Name of the material
|
||||
@@ -433,7 +433,7 @@ struct Mesh
|
||||
{
|
||||
static int iCnt = 0;
|
||||
std::stringstream ss(mName);
|
||||
ss << "%%_UNNAMED_" << iCnt++ << "_%%";
|
||||
ss << "$$_UNNAMED_" << iCnt++ << "_$$";
|
||||
}
|
||||
|
||||
//! Name of the mesh
|
||||
@@ -468,7 +468,7 @@ struct Node
|
||||
{
|
||||
static int iCnt = 0;
|
||||
std::stringstream ss(mName);
|
||||
ss << "%%_UNNAMED_" << iCnt++ << "_%%";
|
||||
ss << "$$_UNNAMED_" << iCnt++ << "_$$";
|
||||
|
||||
mHierarchyPos = 0;
|
||||
mHierarchyIndex = 0;
|
||||
|
||||
+1
-1
@@ -1213,7 +1213,7 @@ void Dot3DSImporter::ParseTextureChunk(int* piRemaining,Dot3DS::Texture* pcOut)
|
||||
break;
|
||||
// manually parse the blend factor
|
||||
case Dot3DSFile::CHUNK_PERCENTW:
|
||||
pcOut->mTextureBlend = (float)(*((short*)this->mCurrent)) / (float)0xFFFF;
|
||||
pcOut->mTextureBlend = (float)(*((short*)this->mCurrent)) / (float)100;
|
||||
break;
|
||||
|
||||
case Dot3DSFile::CHUNK_MAT_MAP_USCALE:
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ class BaseProcess
|
||||
{
|
||||
friend class Importer;
|
||||
|
||||
protected:
|
||||
public:
|
||||
/** Constructor to be privately used by Importer */
|
||||
BaseProcess();
|
||||
|
||||
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
Free Asset Import Library (ASSIMP)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2008, ASSIMP Development Team
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the ASSIMP team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the ASSIMP Development Team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file Helper class tp perform various byte oder swappings
|
||||
(e.g. little to big endian) */
|
||||
#ifndef AI_BYTESWAP_H_INC
|
||||
#define AI_BYTESWAP_H_INC
|
||||
|
||||
#include "..\include\aiAssert.h"
|
||||
|
||||
namespace Assimp
|
||||
{
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** \brief Defines some useful byte order swap routines.
|
||||
*
|
||||
* This can e.g. be used for the conversion from and to littel and big endian.
|
||||
* This is required by some loaders since some model formats
|
||||
*/
|
||||
class ByteSwap
|
||||
{
|
||||
ByteSwap() {}
|
||||
|
||||
public:
|
||||
//! Swap the byte oder of 2 byte of data
|
||||
//! \param szOut Buffer to be swapped
|
||||
static inline void Swap2(char* szOut)
|
||||
{
|
||||
ai_assert(NULL != szOut);
|
||||
std::swap(szOut[0],szOut[1]);
|
||||
}
|
||||
|
||||
//! Swap the byte oder of 4 byte of data
|
||||
//! \param szOut Buffer to be swapped
|
||||
static inline void Swap4(char* szOut)
|
||||
{
|
||||
ai_assert(NULL != szOut);
|
||||
std::swap(szOut[0],szOut[3]);
|
||||
std::swap(szOut[1],szOut[2]);
|
||||
}
|
||||
|
||||
//! Swap the byte oder of 8 byte of data
|
||||
//! \param szOut Buffer to be swapped
|
||||
static inline void Swap8(char* szOut)
|
||||
{
|
||||
ai_assert(NULL != szOut);
|
||||
std::swap(szOut[0],szOut[7]);
|
||||
std::swap(szOut[1],szOut[6]);
|
||||
std::swap(szOut[2],szOut[5]);
|
||||
std::swap(szOut[3],szOut[4]);
|
||||
}
|
||||
|
||||
//! Swap a single precision float
|
||||
//! \param fOut Float value to be swapped
|
||||
static inline void Swap(float* fOut)
|
||||
{
|
||||
Swap4((char*)fOut);
|
||||
}
|
||||
|
||||
//! Swap a double precision float
|
||||
//! \param fOut Double value to be swapped
|
||||
static inline void Swap(double* fOut)
|
||||
{
|
||||
Swap8((char*)fOut);
|
||||
}
|
||||
|
||||
//! Swap a 16 bit integer
|
||||
//! \param fOut Integer to be swapped
|
||||
static inline void Swap(int16_t* fOut)
|
||||
{
|
||||
Swap2((char*)fOut);
|
||||
}
|
||||
|
||||
//! Swap a 32 bit integer
|
||||
//! \param fOut Integer to be swapped
|
||||
static inline void Swap(int32_t* fOut)
|
||||
{
|
||||
Swap4((char*)fOut);
|
||||
}
|
||||
|
||||
//! Swap a 64 bit integer
|
||||
//! \param fOut Integer to be swapped
|
||||
static inline void Swap(int64_t* fOut)
|
||||
{
|
||||
Swap8((char*)fOut);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#endif //!! AI_BYTESWAP_H_INC
|
||||
@@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <vector>
|
||||
#include <assert.h>
|
||||
#include "DefaultLogger.h"
|
||||
#include "CalcTangentsProcess.h"
|
||||
#include "SpatialSort.h"
|
||||
#include "../include/aiPostProcess.h"
|
||||
@@ -78,8 +79,12 @@ bool CalcTangentsProcess::IsActive( unsigned int pFlags) const
|
||||
// Executes the post processing step on the given imported data.
|
||||
void CalcTangentsProcess::Execute( aiScene* pScene)
|
||||
{
|
||||
DefaultLogger::get()->debug("CalcTangentsProcess begin");
|
||||
|
||||
for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
|
||||
ProcessMesh( pScene->mMeshes[a]);
|
||||
|
||||
DefaultLogger::get()->debug("CalcTangentsProcess finished");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -39,7 +39,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
/** @file Defines a post processing step to calculate tangents and bitangents on all imported meshes.*/
|
||||
/** @file Defines a post processing step to calculate tangents and
|
||||
bitangents on all imported meshes.*/
|
||||
#ifndef AI_CALCTANGENTSPROCESS_H_INC
|
||||
#define AI_CALCTANGENTSPROCESS_H_INC
|
||||
|
||||
@@ -53,14 +54,14 @@ namespace Assimp
|
||||
// ---------------------------------------------------------------------------
|
||||
/** The CalcTangentsProcess calculates the tangent and bitangent for any vertex
|
||||
* of all meshes. It is expected to be run before the JoinVerticesProcess runs
|
||||
* because the joining of vertices also considers tangents and bitangents for uniqueness.
|
||||
|
||||
* because the joining of vertices also considers tangents and bitangents for
|
||||
* uniqueness.
|
||||
*/
|
||||
class CalcTangentsProcess : public BaseProcess
|
||||
{
|
||||
friend class Importer;
|
||||
|
||||
protected:
|
||||
public:
|
||||
/** Constructor to be privately used by Importer */
|
||||
CalcTangentsProcess();
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* to a left-handed coordinate system.
|
||||
*/
|
||||
#include "ConvertToLHProcess.h"
|
||||
#include "DefaultLogger.h"
|
||||
#include "../include/aiPostProcess.h"
|
||||
#include "../include/aiMesh.h"
|
||||
#include "../include/aiAnim.h"
|
||||
@@ -46,7 +47,12 @@ void ConvertToLHProcess::Execute( aiScene* pScene)
|
||||
{
|
||||
// Check for an existent root node to proceed
|
||||
if (NULL == pScene->mRootNode)
|
||||
{
|
||||
DefaultLogger::get()->error("ConvertToLHProcess fails, there is no root node");
|
||||
return;
|
||||
}
|
||||
|
||||
DefaultLogger::get()->debug("ConvertToLHProcess begin");
|
||||
|
||||
// transform the root node of the scene, the other nodes will follow then
|
||||
ConvertToDX( pScene->mRootNode->mTransformation);
|
||||
@@ -66,6 +72,7 @@ void ConvertToLHProcess::Execute( aiScene* pScene)
|
||||
ProcessAnimation( boneAnim);
|
||||
}
|
||||
}
|
||||
DefaultLogger::get()->debug("ConvertToLHProcess finished");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
+42
-1
@@ -1,3 +1,44 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Free Asset Import Library (ASSIMP)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2008, ASSIMP Development Team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the ASSIMP team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the ASSIMP Development Team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "DefaultLogger.h"
|
||||
#include "aiAssert.h"
|
||||
#include "DefaultIOSystem.h"
|
||||
@@ -142,11 +183,11 @@ void DefaultLogger::detatchStream( LogStream *pStream, unsigned int severity )
|
||||
DefaultLogger::DefaultLogger( const std::string &name, LogSeverity severity ) :
|
||||
m_Severity( severity )
|
||||
{
|
||||
m_Streams.push_back( new Win32DebugLogStream() );
|
||||
if (name.empty())
|
||||
return;
|
||||
|
||||
m_Streams.push_back( new FileLogStream( name ) );
|
||||
m_Streams.push_back( new Win32DebugLogStream() );
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -1,3 +1,43 @@
|
||||
/*
|
||||
Free Asset Import Library (ASSIMP)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2008, ASSIMP Development Team
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the ASSIMP team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the ASSIMP Development Team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "Logger.h"
|
||||
#include <vector>
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* normals for all imported faces.
|
||||
*/
|
||||
#include "GenFaceNormalsProcess.h"
|
||||
#include "DefaultLogger.h"
|
||||
#include "../include/aiPostProcess.h"
|
||||
#include "../include/aiMesh.h"
|
||||
#include "../include/aiScene.h"
|
||||
@@ -71,23 +72,35 @@ bool GenFaceNormalsProcess::IsActive( unsigned int pFlags) const
|
||||
// Executes the post processing step on the given imported data.
|
||||
void GenFaceNormalsProcess::Execute( aiScene* pScene)
|
||||
{
|
||||
DefaultLogger::get()->debug("GenFaceNormalsProcess begin");
|
||||
|
||||
bool bHas = false;
|
||||
for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
|
||||
this->GenMeshFaceNormals( pScene->mMeshes[a]);
|
||||
{
|
||||
if(this->GenMeshFaceNormals( pScene->mMeshes[a]))
|
||||
bHas = true;
|
||||
}
|
||||
if (bHas)
|
||||
{
|
||||
DefaultLogger::get()->info("GenFaceNormalsProcess finished. "
|
||||
"Face normals have been calculated");
|
||||
}
|
||||
else DefaultLogger::get()->debug("GenFaceNormalsProcess finished. "
|
||||
"There was nothing to do");
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Executes the post processing step on the given imported data.
|
||||
void GenFaceNormalsProcess::GenMeshFaceNormals (aiMesh* pMesh)
|
||||
bool GenFaceNormalsProcess::GenMeshFaceNormals (aiMesh* pMesh)
|
||||
{
|
||||
if (NULL != pMesh->mNormals)return;
|
||||
if (NULL != pMesh->mNormals)return false;
|
||||
|
||||
pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
|
||||
|
||||
for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
|
||||
{
|
||||
const aiFace& face = pMesh->mFaces[a];
|
||||
|
||||
// assume it is a triangle
|
||||
|
||||
aiVector3D* pV1 = &pMesh->mVertices[face.mIndices[0]];
|
||||
aiVector3D* pV2 = &pMesh->mVertices[face.mIndices[1]];
|
||||
aiVector3D* pV3 = &pMesh->mVertices[face.mIndices[2]];
|
||||
@@ -95,14 +108,11 @@ void GenFaceNormalsProcess::GenMeshFaceNormals (aiMesh* pMesh)
|
||||
aiVector3D pDelta1 = *pV2 - *pV1;
|
||||
aiVector3D pDelta2 = *pV3 - *pV1;
|
||||
aiVector3D vNor = pDelta1 ^ pDelta2;
|
||||
|
||||
// NOTE: Never normalize here. Causes problems ...
|
||||
//float fLength = vNor.Length();
|
||||
//if (0.0f != fLength)vNor /= fLength;
|
||||
|
||||
pMesh->mNormals[face.mIndices[0]] = vNor;
|
||||
pMesh->mNormals[face.mIndices[1]] = vNor;
|
||||
pMesh->mNormals[face.mIndices[2]] = vNor;
|
||||
for (unsigned int i = 0;i < face.mNumIndices;++i)
|
||||
{
|
||||
pMesh->mNormals[face.mIndices[i]] = vNor;
|
||||
}
|
||||
}
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
@@ -55,7 +55,7 @@ class GenFaceNormalsProcess : public BaseProcess
|
||||
{
|
||||
friend class Importer;
|
||||
|
||||
protected:
|
||||
public:
|
||||
/** Constructor to be privately used by Importer */
|
||||
GenFaceNormalsProcess();
|
||||
|
||||
@@ -80,7 +80,7 @@ public:
|
||||
|
||||
|
||||
private:
|
||||
void GenMeshFaceNormals (aiMesh* pcMesh);
|
||||
bool GenMeshFaceNormals (aiMesh* pcMesh);
|
||||
};
|
||||
|
||||
} // end of namespace Assimp
|
||||
|
||||
@@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "GenVertexNormalsProcess.h"
|
||||
#include "SpatialSort.h"
|
||||
#include "DefaultLogger.h"
|
||||
#include "../include/aiPostProcess.h"
|
||||
#include "../include/aiMesh.h"
|
||||
#include "../include/aiScene.h"
|
||||
@@ -72,22 +73,35 @@ bool GenVertexNormalsProcess::IsActive( unsigned int pFlags) const
|
||||
// Executes the post processing step on the given imported data.
|
||||
void GenVertexNormalsProcess::Execute( aiScene* pScene)
|
||||
{
|
||||
DefaultLogger::get()->debug("GenVertexNormalsProcess begin");
|
||||
|
||||
bool bHas = false;
|
||||
for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
|
||||
this->GenMeshVertexNormals( pScene->mMeshes[a]);
|
||||
{
|
||||
if(this->GenMeshVertexNormals( pScene->mMeshes[a]))
|
||||
bHas = true;
|
||||
}
|
||||
|
||||
if (bHas)
|
||||
{
|
||||
DefaultLogger::get()->info("GenVertexNormalsProcess finished. "
|
||||
"Vertex normals have been calculated");
|
||||
}
|
||||
else DefaultLogger::get()->debug("GenVertexNormalsProcess finished. "
|
||||
"There was nothing to do");
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Executes the post processing step on the given imported data.
|
||||
void GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh)
|
||||
bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh)
|
||||
{
|
||||
if (NULL != pMesh->mNormals)return;
|
||||
if (NULL != pMesh->mNormals)return false;
|
||||
|
||||
pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
|
||||
for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
|
||||
{
|
||||
const aiFace& face = pMesh->mFaces[a];
|
||||
|
||||
// assume it is a triangle
|
||||
aiVector3D* pV1 = &pMesh->mVertices[face.mIndices[0]];
|
||||
aiVector3D* pV2 = &pMesh->mVertices[face.mIndices[1]];
|
||||
aiVector3D* pV3 = &pMesh->mVertices[face.mIndices[2]];
|
||||
@@ -95,12 +109,11 @@ void GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh)
|
||||
aiVector3D pDelta1 = *pV2 - *pV1;
|
||||
aiVector3D pDelta2 = *pV3 - *pV1;
|
||||
aiVector3D vNor = pDelta1 ^ pDelta2;
|
||||
float fLength = vNor.Length();
|
||||
if (0.0f != fLength)vNor /= fLength;
|
||||
|
||||
pMesh->mNormals[face.mIndices[0]] = vNor;
|
||||
pMesh->mNormals[face.mIndices[1]] = vNor;
|
||||
pMesh->mNormals[face.mIndices[2]] = vNor;
|
||||
for (unsigned int i = 0;i < face.mNumIndices;++i)
|
||||
{
|
||||
pMesh->mNormals[face.mIndices[i]] = vNor;
|
||||
}
|
||||
}
|
||||
|
||||
// calculate the position bounds so we have a reliable epsilon to
|
||||
@@ -141,5 +154,5 @@ void GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh)
|
||||
delete pMesh->mNormals;
|
||||
pMesh->mNormals = pcNew;
|
||||
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
@@ -47,41 +47,41 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
namespace Assimp
|
||||
{
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** The GenFaceNormalsProcess computes vertex normals for all vertizes of all meshes
|
||||
// ---------------------------------------------------------------------------
|
||||
/** The GenFaceNormalsProcess computes vertex normals for all vertizes of all meshes
|
||||
*/
|
||||
class GenVertexNormalsProcess : public BaseProcess
|
||||
{
|
||||
friend class Importer;
|
||||
|
||||
public:
|
||||
/** Constructor to be privately used by Importer */
|
||||
GenVertexNormalsProcess();
|
||||
|
||||
/** Destructor, private as well */
|
||||
~GenVertexNormalsProcess();
|
||||
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
/** Returns whether the processing step is present in the given flag field.
|
||||
* @param pFlags The processing flags the importer was called with. A bitwise
|
||||
* combination of #aiPostProcessSteps.
|
||||
* @return true if the process is present in this flag fields, false if not.
|
||||
*/
|
||||
class GenVertexNormalsProcess : public BaseProcess
|
||||
{
|
||||
friend class Importer;
|
||||
bool IsActive( unsigned int pFlags) const;
|
||||
|
||||
protected:
|
||||
/** Constructor to be privately used by Importer */
|
||||
GenVertexNormalsProcess();
|
||||
|
||||
/** Destructor, private as well */
|
||||
~GenVertexNormalsProcess();
|
||||
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
/** Returns whether the processing step is present in the given flag field.
|
||||
* @param pFlags The processing flags the importer was called with. A bitwise
|
||||
* combination of #aiPostProcessSteps.
|
||||
* @return true if the process is present in this flag fields, false if not.
|
||||
*/
|
||||
bool IsActive( unsigned int pFlags) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Executes the post processing step on the given imported data.
|
||||
* At the moment a process is not supposed to fail.
|
||||
* @param pScene The imported data to work at.
|
||||
*/
|
||||
void Execute( aiScene* pScene);
|
||||
// -------------------------------------------------------------------
|
||||
/** Executes the post processing step on the given imported data.
|
||||
* At the moment a process is not supposed to fail.
|
||||
* @param pScene The imported data to work at.
|
||||
*/
|
||||
void Execute( aiScene* pScene);
|
||||
|
||||
|
||||
private:
|
||||
void GenMeshVertexNormals (aiMesh* pcMesh);
|
||||
};
|
||||
private:
|
||||
bool GenMeshVertexNormals (aiMesh* pcMesh);
|
||||
};
|
||||
|
||||
} // end of namespace Assimp
|
||||
}; // end of namespace Assimp
|
||||
|
||||
#endif // !!AI_GENVERTEXNORMALPROCESS_H_INC
|
||||
@@ -86,6 +86,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "GenVertexNormalsProcess.h"
|
||||
#include "KillNormalsProcess.h"
|
||||
#include "SplitLargeMeshes.h"
|
||||
#include "DefaultLogger.h"
|
||||
|
||||
using namespace Assimp;
|
||||
|
||||
@@ -96,6 +97,10 @@ Importer::Importer() :
|
||||
mScene(NULL),
|
||||
mErrorString("")
|
||||
{
|
||||
// construct a new logger
|
||||
/*DefaultLogger::create( "test.log", DefaultLogger::VERBOSE );
|
||||
DefaultLogger::get()->info("Start logging");*/
|
||||
|
||||
// allocate a default IO handler
|
||||
mIOHandler = new DefaultIOSystem;
|
||||
|
||||
@@ -181,6 +186,7 @@ const aiScene* Importer::ReadFile( const std::string& pFile, unsigned int pFlags
|
||||
if( !mIOHandler->Exists( pFile))
|
||||
{
|
||||
mErrorString = "Unable to open file \"" + pFile + "\".";
|
||||
DefaultLogger::get()->error(mErrorString);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -199,6 +205,7 @@ const aiScene* Importer::ReadFile( const std::string& pFile, unsigned int pFlags
|
||||
if( !imp)
|
||||
{
|
||||
mErrorString = "No suitable reader found for the file format of file \"" + pFile + "\".";
|
||||
DefaultLogger::get()->error(mErrorString);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <assert.h>
|
||||
#include "JoinVerticesProcess.h"
|
||||
#include "SpatialSort.h"
|
||||
#include "DefaultLogger.h"
|
||||
#include "../include/aiPostProcess.h"
|
||||
#include "../include/aiMesh.h"
|
||||
#include "../include/aiScene.h"
|
||||
@@ -78,13 +79,21 @@ bool JoinVerticesProcess::IsActive( unsigned int pFlags) const
|
||||
// Executes the post processing step on the given imported data.
|
||||
void JoinVerticesProcess::Execute( aiScene* pScene)
|
||||
{
|
||||
DefaultLogger::get()->debug("JoinVerticesProcess begin");
|
||||
|
||||
bool bHas = false;
|
||||
for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
|
||||
ProcessMesh( pScene->mMeshes[a]);
|
||||
{
|
||||
if( this->ProcessMesh( pScene->mMeshes[a]))
|
||||
bHas = true;
|
||||
}
|
||||
if (bHas)DefaultLogger::get()->info("JoinVerticesProcess finished. Found vertices to join");
|
||||
else DefaultLogger::get()->debug("JoinVerticesProcess finished. There was nothing to do.");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Unites identical vertices in the given mesh
|
||||
void JoinVerticesProcess::ProcessMesh( aiMesh* pMesh)
|
||||
bool JoinVerticesProcess::ProcessMesh( aiMesh* pMesh)
|
||||
{
|
||||
// helper structure to hold all the data a single vertex can possibly have
|
||||
typedef struct Vertex vertex;
|
||||
@@ -100,6 +109,8 @@ void JoinVerticesProcess::ProcessMesh( aiMesh* pMesh)
|
||||
std::vector<Vertex> uniqueVertices;
|
||||
uniqueVertices.reserve( pMesh->mNumVertices);
|
||||
|
||||
unsigned int iOldVerts = pMesh->mNumVertices;
|
||||
|
||||
// For each vertex the index of the vertex it was replaced by.
|
||||
std::vector<unsigned int> replaceIndex( pMesh->mNumVertices, 0xffffffff);
|
||||
// for each vertex whether it was replaced by an existing unique vertex (true) or a new vertex was created for it (false)
|
||||
@@ -300,4 +311,5 @@ void JoinVerticesProcess::ProcessMesh( aiMesh* pMesh)
|
||||
bone->mWeights = new aiVertexWeight[bone->mNumWeights];
|
||||
memcpy( bone->mWeights, &newWeights[0], bone->mNumWeights * sizeof( aiVertexWeight));
|
||||
}
|
||||
return (iOldVerts != pMesh->mNumVertices);
|
||||
}
|
||||
|
||||
@@ -38,9 +38,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file Defines a post processing step to join identical vertices on all imported meshes.*/
|
||||
/** @file Defines a post processing step to join identical vertices
|
||||
on all imported meshes.*/
|
||||
#ifndef AI_JOINVERTICESPROCESS_H_INC
|
||||
#define AI_CALCTANGENTSPROCESS_H_INC
|
||||
#define AI_JOINVERTICESPROCESS_H_INC
|
||||
|
||||
#include "BaseProcess.h"
|
||||
#include "../include/aiTypes.h"
|
||||
@@ -62,7 +63,7 @@ class JoinVerticesProcess : public BaseProcess
|
||||
{
|
||||
friend class Importer;
|
||||
|
||||
protected:
|
||||
public:
|
||||
/** Constructor to be privately used by Importer */
|
||||
JoinVerticesProcess();
|
||||
|
||||
@@ -90,12 +91,19 @@ protected:
|
||||
/** Unites identical vertices in the given mesh.
|
||||
* @param pMesh The mesh to process.
|
||||
*/
|
||||
void ProcessMesh( aiMesh* pMesh);
|
||||
bool ProcessMesh( aiMesh* pMesh);
|
||||
|
||||
/** Little helper function to calculate the quadratic difference of two colours. */
|
||||
// -------------------------------------------------------------------
|
||||
/** Little helper function to calculate the quadratic difference
|
||||
* of two colours.
|
||||
* @param pColor1 First color
|
||||
* @param pColor2 second color
|
||||
* @return Quadratic color difference
|
||||
*/
|
||||
float GetColorDifference( const aiColor4D& pColor1, const aiColor4D& pColor2) const
|
||||
{
|
||||
aiColor4D c( pColor1.r - pColor2.r, pColor1.g - pColor2.g, pColor1.b - pColor2.b, pColor1.a - pColor2.a);
|
||||
aiColor4D c( pColor1.r - pColor2.r, pColor1.g - pColor2.g,
|
||||
pColor1.b - pColor2.b, pColor1.a - pColor2.a);
|
||||
return c.r*c.r + c.g*c.g + c.b*c.b + c.a*c.a;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -41,6 +41,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
/** @file Implementation of the post processing step tokill mesh normals
|
||||
*/
|
||||
#include "KillNormalsProcess.h"
|
||||
#include "DefaultLogger.h"
|
||||
#include "../include/aiPostProcess.h"
|
||||
#include "../include/aiMesh.h"
|
||||
#include "../include/aiScene.h"
|
||||
@@ -69,15 +70,25 @@ bool KillNormalsProcess::IsActive( unsigned int pFlags) const
|
||||
// Executes the post processing step on the given imported data.
|
||||
void KillNormalsProcess::Execute( aiScene* pScene)
|
||||
{
|
||||
DefaultLogger::get()->debug("KillNormalsProcess begin");
|
||||
|
||||
bool bHas = false;
|
||||
for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
|
||||
this->KillMeshNormals( pScene->mMeshes[a]);
|
||||
{
|
||||
if( this->KillMeshNormals( pScene->mMeshes[a]))
|
||||
bHas = true;
|
||||
}
|
||||
if (bHas)DefaultLogger::get()->info("KillNormalsProcess finished. Found normals to kill");
|
||||
else DefaultLogger::get()->debug("KillNormalsProcess finished. There was nothing to do.");
|
||||
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Executes the post processing step on the given imported data.
|
||||
void KillNormalsProcess::KillMeshNormals(aiMesh* pMesh)
|
||||
bool KillNormalsProcess::KillMeshNormals(aiMesh* pMesh)
|
||||
{
|
||||
if (!pMesh->mNormals)return false;
|
||||
delete[] pMesh->mNormals;
|
||||
pMesh->mNormals = NULL;
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
+31
-32
@@ -47,41 +47,40 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
namespace Assimp
|
||||
{
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** KillNormalsProcess: Class to kill all normals loaded
|
||||
// ---------------------------------------------------------------------------
|
||||
/** KillNormalsProcess: Class to kill all normals loaded
|
||||
*/
|
||||
class KillNormalsProcess : public BaseProcess
|
||||
{
|
||||
friend class Importer;
|
||||
|
||||
protected:
|
||||
/** Constructor to be privately used by Importer */
|
||||
KillNormalsProcess();
|
||||
|
||||
/** Destructor, private as well */
|
||||
~KillNormalsProcess();
|
||||
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
/** Returns whether the processing step is present in the given flag field.
|
||||
* @param pFlags The processing flags the importer was called with. A bitwise
|
||||
* combination of #aiPostProcessSteps.
|
||||
* @return true if the process is present in this flag fields, false if not.
|
||||
*/
|
||||
class KillNormalsProcess : public BaseProcess
|
||||
{
|
||||
friend class Importer;
|
||||
bool IsActive( unsigned int pFlags) const;
|
||||
|
||||
protected:
|
||||
/** Constructor to be privately used by Importer */
|
||||
KillNormalsProcess();
|
||||
|
||||
/** Destructor, private as well */
|
||||
~KillNormalsProcess();
|
||||
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
/** Returns whether the processing step is present in the given flag field.
|
||||
* @param pFlags The processing flags the importer was called with. A bitwise
|
||||
* combination of #aiPostProcessSteps.
|
||||
* @return true if the process is present in this flag fields, false if not.
|
||||
*/
|
||||
bool IsActive( unsigned int pFlags) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Executes the post processing step on the given imported data.
|
||||
* At the moment a process is not supposed to fail.
|
||||
* @param pScene The imported data to work at.
|
||||
*/
|
||||
void Execute( aiScene* pScene);
|
||||
// -------------------------------------------------------------------
|
||||
/** Executes the post processing step on the given imported data.
|
||||
* At the moment a process is not supposed to fail.
|
||||
* @param pScene The imported data to work at.
|
||||
*/
|
||||
void Execute( aiScene* pScene);
|
||||
|
||||
|
||||
private:
|
||||
void KillMeshNormals (aiMesh* pcMesh);
|
||||
};
|
||||
|
||||
} // end of namespace Assimp
|
||||
private:
|
||||
bool KillMeshNormals (aiMesh* pcMesh);
|
||||
};
|
||||
}; // end of namespace Assimp
|
||||
|
||||
#endif // !!AI_KILLNORMALPROCESS_H_INC
|
||||
@@ -95,6 +95,12 @@ namespace MDL
|
||||
#define AI_MDL_MAGIC_NUMBER_BE_GS7 'MDL7'
|
||||
#define AI_MDL_MAGIC_NUMBER_LE_GS7 '7LDM'
|
||||
|
||||
// magic bytes used in Half Life 2 MDL models
|
||||
#define AI_MDL_MAGIC_NUMBER_BE_HL2a 'IDST'
|
||||
#define AI_MDL_MAGIC_NUMBER_LE_HL2a 'TSDI'
|
||||
#define AI_MDL_MAGIC_NUMBER_BE_HL2b 'IDSQ'
|
||||
#define AI_MDL_MAGIC_NUMBER_LE_HL2b 'QSDI'
|
||||
|
||||
// common limitations for Quake1 meshes. The loader does not check them,
|
||||
// but models should not exceed these limits.
|
||||
#if (!defined AI_MDL_VERSION)
|
||||
@@ -210,6 +216,87 @@ struct Header_MDL7
|
||||
uint16_t frame_stc_size;
|
||||
} PACK_STRUCT;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** \struct Header_HL2
|
||||
* \brief Data structure for the HL2 main header
|
||||
*/
|
||||
// ---------------------------------------------------------------------------
|
||||
struct Header_HL2
|
||||
{
|
||||
//! magic number: "IDST"/"IDSQ"
|
||||
char ident[4];
|
||||
|
||||
//! Version number
|
||||
int32_t version;
|
||||
|
||||
//! Original file name in pak ?
|
||||
char name[64];
|
||||
|
||||
//! Length of file name/length of file?
|
||||
int32_t length;
|
||||
|
||||
//! For viewer, ignored
|
||||
aiVector3D eyeposition;
|
||||
aiVector3D min;
|
||||
aiVector3D max;
|
||||
|
||||
//! AABB of the model
|
||||
aiVector3D bbmin;
|
||||
aiVector3D bbmax;
|
||||
|
||||
// File flags
|
||||
int32_t flags;
|
||||
|
||||
//! NUmber of bones contained in the file
|
||||
int32_t numbones;
|
||||
int32_t boneindex;
|
||||
|
||||
//! Number of bone controllers for bone animation
|
||||
int32_t numbonecontrollers;
|
||||
int32_t bonecontrollerindex;
|
||||
|
||||
//! More bounding boxes ...
|
||||
int32_t numhitboxes;
|
||||
int32_t hitboxindex;
|
||||
|
||||
//! Animation sequences in the file
|
||||
int32_t numseq;
|
||||
int32_t seqindex;
|
||||
|
||||
//! Loaded sequences. Ignored
|
||||
int32_t numseqgroups;
|
||||
int32_t seqgroupindex;
|
||||
|
||||
//! Raw texture data
|
||||
int32_t numtextures;
|
||||
int32_t textureindex;
|
||||
int32_t texturedataindex;
|
||||
|
||||
//! Number of skins (=textures?)
|
||||
int32_t numskinref;
|
||||
int32_t numskinfamilies;
|
||||
int32_t skinindex;
|
||||
|
||||
//! Number of parts
|
||||
int32_t numbodyparts;
|
||||
int32_t bodypartindex;
|
||||
|
||||
//! attachable points for gameplay and physics
|
||||
int32_t numattachments;
|
||||
int32_t attachmentindex;
|
||||
|
||||
//! Table of sound effects associated with the model
|
||||
int32_t soundtable;
|
||||
int32_t soundindex;
|
||||
int32_t soundgroups;
|
||||
int32_t soundgroupindex;
|
||||
|
||||
//! Number of animation transitions
|
||||
int32_t numtransitions;
|
||||
int32_t transitionindex;
|
||||
} PACK_STRUCT;
|
||||
|
||||
#define AI_MDL7_MAX_BONENAMESIZE 20
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
+76
-26
@@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "MaterialSystem.h"
|
||||
#include "MDLLoader.h"
|
||||
#include "MDLDefaultColorMap.h"
|
||||
#include "DefaultLogger.h"
|
||||
|
||||
#include "../include/IOStream.h"
|
||||
#include "../include/IOSystem.h"
|
||||
@@ -640,7 +641,8 @@ void MDLImporter::InternReadFile_Quake1( )
|
||||
if (iIndex >= (unsigned int)this->m_pcHeader->num_verts)
|
||||
{
|
||||
iIndex = this->m_pcHeader->num_verts-1;
|
||||
// LOG
|
||||
|
||||
DefaultLogger::get()->warn("Index overflow in Q1-MDL vertex list.");
|
||||
}
|
||||
|
||||
aiVector3D& vec = pcMesh->mVertices[iCurrent];
|
||||
@@ -809,7 +811,7 @@ void MDLImporter::InternReadFile_GameStudio( )
|
||||
if (iIndex >= (unsigned int)this->m_pcHeader->num_verts)
|
||||
{
|
||||
iIndex = this->m_pcHeader->num_verts-1;
|
||||
// LOG
|
||||
DefaultLogger::get()->warn("Index overflow in MDL3/4/5/6 vertex list");
|
||||
}
|
||||
|
||||
aiVector3D& vec = vPositions[iCurrent];
|
||||
@@ -838,7 +840,7 @@ void MDLImporter::InternReadFile_GameStudio( )
|
||||
if (iIndex >= (unsigned int)this->m_pcHeader->synctype)
|
||||
{
|
||||
iIndex = this->m_pcHeader->synctype-1;
|
||||
// LOG
|
||||
DefaultLogger::get()->warn("Index overflow in MDL3/4/5/6 UV coord list");
|
||||
}
|
||||
|
||||
float s = (float)pcTexCoords[iIndex].u;
|
||||
@@ -886,7 +888,7 @@ void MDLImporter::InternReadFile_GameStudio( )
|
||||
if (iIndex >= (unsigned int)this->m_pcHeader->num_verts)
|
||||
{
|
||||
iIndex = this->m_pcHeader->num_verts-1;
|
||||
// LOG
|
||||
DefaultLogger::get()->warn("Index overflow in MDL3/4/5/6 vertex list");
|
||||
}
|
||||
|
||||
aiVector3D& vec = vPositions[iCurrent];
|
||||
@@ -914,7 +916,7 @@ void MDLImporter::InternReadFile_GameStudio( )
|
||||
if (iIndex >= (unsigned int) this->m_pcHeader->synctype)
|
||||
{
|
||||
iIndex = this->m_pcHeader->synctype-1;
|
||||
// LOG
|
||||
DefaultLogger::get()->warn("Index overflow in MDL3/4/5/6 UV coord list");
|
||||
}
|
||||
|
||||
float s = (float)pcTexCoords[iIndex].u;
|
||||
@@ -1029,7 +1031,8 @@ void MDLImporter::ParseSkinLump_GameStudioA7(
|
||||
// ***** EMBEDDED DDS FILE *****
|
||||
if (1 != pcSkin->height)
|
||||
{
|
||||
// LOG
|
||||
DefaultLogger::get()->warn("Found a reference to an embedded DDS texture, "
|
||||
"but texture height is not equal to 1, which is not supported by MED");
|
||||
}
|
||||
|
||||
pcNew = new aiTexture();
|
||||
@@ -1048,7 +1051,8 @@ void MDLImporter::ParseSkinLump_GameStudioA7(
|
||||
// ***** REFERENCE TO EXTERNAL FILE FILE *****
|
||||
if (1 != pcSkin->height)
|
||||
{
|
||||
// LOG
|
||||
DefaultLogger::get()->warn("Found a reference to an external texture, "
|
||||
"but texture height is not equal to 1, which is not supported by MED");
|
||||
}
|
||||
|
||||
aiString szFile;
|
||||
@@ -1058,29 +1062,52 @@ void MDLImporter::ParseSkinLump_GameStudioA7(
|
||||
memcpy(szFile.data,(const char*)szCurrent,iLen2);
|
||||
szFile.length = iLen;
|
||||
|
||||
szCurrent += iLen2;
|
||||
|
||||
// place this as diffuse texture
|
||||
pcMatOut->AddProperty<aiString>(&szFile,1,AI_MATKEY_TEXTURE_DIFFUSE(0));
|
||||
pcMatOut->AddProperty(&szFile,AI_MATKEY_TEXTURE_DIFFUSE(0));
|
||||
}
|
||||
else if (0 != iMasked)
|
||||
else if (0 != iMasked || 0 == pcSkin->typ)
|
||||
{
|
||||
// ***** STANDARD COLOR TEXTURE *****
|
||||
pcNew = new aiTexture();
|
||||
if (0 == pcSkin->height || 0 == pcSkin->width)
|
||||
{
|
||||
// LOG
|
||||
DefaultLogger::get()->warn("Found embedded texture, but its width "
|
||||
"an height are both 0. Is this a joke?");
|
||||
|
||||
// generate an empty chess pattern
|
||||
pcNew->mWidth = pcNew->mHeight = 8;
|
||||
pcNew->pcData = new aiTexel[64];
|
||||
for (unsigned int x = 0; x < 8;++x)
|
||||
{
|
||||
for (unsigned int y = 0; y < 8;++y)
|
||||
{
|
||||
bool bSet = false;
|
||||
if (0 == x % 2 && 0 != y % 2 ||
|
||||
0 != x % 2 && 0 == y % 2)bSet = true;
|
||||
|
||||
aiTexel* pc = &pcNew->pcData[y * 8 + x];
|
||||
if (bSet)pc->r = pc->b = pc->g = 0xFF;
|
||||
else pc->r = pc->b = pc->g = 0;
|
||||
pc->a = 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// it is a standard color texture. Fill in width and height
|
||||
// and call the same function we used for loading MDL5 files
|
||||
|
||||
// it is a standard color texture. Fill in width and height
|
||||
// and call the same function we used for loading MDL5 files
|
||||
pcNew->mWidth = pcSkin->width;
|
||||
pcNew->mHeight = pcSkin->height;
|
||||
|
||||
pcNew = new aiTexture();
|
||||
pcNew->mWidth = pcSkin->width;
|
||||
pcNew->mHeight = pcSkin->height;
|
||||
unsigned int iSkip = 0;
|
||||
this->ParseTextureColorData(szCurrent,iMasked,&iSkip,pcNew);
|
||||
|
||||
unsigned int iSkip = 0;
|
||||
this->ParseTextureColorData(szCurrent,iMasked,&iSkip,pcNew);
|
||||
|
||||
// skip length of texture data
|
||||
szCurrent += iSkip;
|
||||
// skip length of texture data
|
||||
szCurrent += iSkip;
|
||||
}
|
||||
}
|
||||
|
||||
// check whether a material definition is contained in the skin
|
||||
@@ -1169,6 +1196,17 @@ void MDLImporter::ParseSkinLump_GameStudioA7(
|
||||
delete[] pc;
|
||||
}
|
||||
|
||||
// place the name of the skin in the material
|
||||
const size_t iLen = strlen(pcSkin->texture_name);
|
||||
if (0 != iLen)
|
||||
{
|
||||
aiString szFile;
|
||||
memcpy(szFile.data,pcSkin->texture_name,sizeof(pcSkin->texture_name));
|
||||
szFile.length = iLen;
|
||||
|
||||
pcMatOut->AddProperty(&szFile,AI_MATKEY_NAME);
|
||||
}
|
||||
|
||||
*szCurrentOut = szCurrent;
|
||||
return;
|
||||
}
|
||||
@@ -1243,7 +1281,8 @@ void MDLImporter::InternReadFile_GameStudioA7( )
|
||||
if (1 != pcGroup->typ)
|
||||
{
|
||||
// Not a triangle-based mesh
|
||||
// LOGWRITE("[3DGS MDL7] Mesh group is no basing in triangles. Continuing happily");
|
||||
DefaultLogger::get()->warn("[3DGS MDL7] Mesh group is not basing on"
|
||||
"triangles. Continuing happily");
|
||||
}
|
||||
|
||||
// read all skins
|
||||
@@ -1315,6 +1354,8 @@ void MDLImporter::InternReadFile_GameStudioA7( )
|
||||
{
|
||||
// LOG
|
||||
iIndex = pcGroup->numverts-1;
|
||||
|
||||
DefaultLogger::get()->warn("Index overflow in MDL7 vertex list");
|
||||
}
|
||||
unsigned int iOutIndex = iTriangle * 3 + c;
|
||||
|
||||
@@ -1439,7 +1480,10 @@ void MDLImporter::InternReadFile_GameStudioA7( )
|
||||
// use the last material instead
|
||||
aiSplit[iNumMaterials-1]->push_back(iFace);
|
||||
|
||||
// LOG
|
||||
// sometimes MED writes -1, but normally only if there is only
|
||||
// one skin assigned. No warning in this case
|
||||
if(0xFFFFFFFF != pcFaces[iFace].iMatIndex[0])
|
||||
DefaultLogger::get()->warn("Index overflow in MDL7 material list [#0]");
|
||||
}
|
||||
else aiSplit[pcFaces[iFace].iMatIndex[0]]->push_back(iFace);
|
||||
}
|
||||
@@ -1464,13 +1508,19 @@ void MDLImporter::InternReadFile_GameStudioA7( )
|
||||
if (iMatIndex >= iNumMaterials)
|
||||
{
|
||||
iMatIndex = iNumMaterials-1;
|
||||
// LOG
|
||||
|
||||
// sometimes MED writes -1, but normally only if there is only
|
||||
// one skin assigned. No warning in this case
|
||||
if(0xFFFFFFFF != iMatIndex)
|
||||
DefaultLogger::get()->warn("Index overflow in MDL7 material list [#1]");
|
||||
}
|
||||
unsigned int iMatIndex2 = pcFaces[iFace].iMatIndex[1];
|
||||
if (iMatIndex2 >= iNumMaterials)
|
||||
{
|
||||
iMatIndex2 = iNumMaterials-1;
|
||||
// LOG
|
||||
// sometimes MED writes -1, but normally only if there is only
|
||||
// one skin assigned. No warning in this case
|
||||
if(0xFFFFFFFF != iMatIndex2)
|
||||
DefaultLogger::get()->warn("Index overflow in MDL7 material list [#2]");
|
||||
}
|
||||
|
||||
// do a slow O(log(n)*n) seach in the list ...
|
||||
@@ -1563,7 +1613,7 @@ void MDLImporter::InternReadFile_GameStudioA7( )
|
||||
|
||||
if (((unsigned int)szCurrent - (unsigned int)pcHeader) + iAdd > (unsigned int)pcHeader->data_size)
|
||||
{
|
||||
// LOG
|
||||
DefaultLogger::get()->warn("Index overflow in frame area. Ignoring frames");
|
||||
// don't parse more groups if we can't even read one
|
||||
goto __BREAK_OUT;
|
||||
}
|
||||
|
||||
@@ -232,6 +232,34 @@ aiReturn aiGetMaterialString(const aiMaterial* pMat,
|
||||
return AI_FAILURE;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
aiReturn MaterialHelper::RemoveProperty (const char* pKey)
|
||||
{
|
||||
ai_assert(NULL != pKey);
|
||||
|
||||
for (unsigned int i = 0; i < this->mNumProperties;++i)
|
||||
{
|
||||
if (NULL != this->mProperties[i])
|
||||
{
|
||||
if (0 == ASSIMP_stricmp( this->mProperties[i]->mKey->data, pKey ))
|
||||
{
|
||||
// delete this entry
|
||||
delete[] this->mProperties[i]->mData;
|
||||
delete this->mProperties[i];
|
||||
|
||||
// collapse the array behind --.
|
||||
--this->mNumProperties;
|
||||
for (unsigned int a = i; a < this->mNumProperties;++a)
|
||||
{
|
||||
this->mProperties[a] = this->mProperties[a+1];
|
||||
}
|
||||
return AI_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return AI_FAILURE;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
aiReturn MaterialHelper::AddBinaryProperty (const void* pInput,
|
||||
const unsigned int pSizeInBytes,
|
||||
const char* pKey,
|
||||
@@ -241,6 +269,23 @@ aiReturn MaterialHelper::AddBinaryProperty (const void* pInput,
|
||||
ai_assert (pKey != NULL);
|
||||
ai_assert (0 != pSizeInBytes);
|
||||
|
||||
// first search the list whether there is already an entry
|
||||
// with this name.
|
||||
unsigned int iOutIndex = 0xFFFFFFFF;
|
||||
for (unsigned int i = 0; i < this->mNumProperties;++i)
|
||||
{
|
||||
if (NULL != this->mProperties[i])
|
||||
{
|
||||
if (0 == ASSIMP_stricmp( this->mProperties[i]->mKey->data, pKey ))
|
||||
{
|
||||
// delete this entry
|
||||
delete[] this->mProperties[i]->mData;
|
||||
delete this->mProperties[i];
|
||||
iOutIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aiMaterialProperty* pcNew = new aiMaterialProperty();
|
||||
|
||||
// fill this
|
||||
@@ -255,6 +300,12 @@ aiReturn MaterialHelper::AddBinaryProperty (const void* pInput,
|
||||
ai_assert ( MAXLEN > pcNew->mKey->length);
|
||||
strcpy( pcNew->mKey->data, pKey );
|
||||
|
||||
if (0xFFFFFFFF != iOutIndex)
|
||||
{
|
||||
this->mProperties[iOutIndex] = pcNew;
|
||||
return AI_SUCCESS;
|
||||
}
|
||||
|
||||
// resize the array ... allocate
|
||||
// storage for 5 other properties
|
||||
if (this->mNumProperties == this->mNumAllocated)
|
||||
@@ -373,6 +424,12 @@ aiReturn aiGetMaterialTexture(const aiMaterial* pcMat,
|
||||
szBlendBase = AI_MATKEY_TEXBLEND_SHININESS_;
|
||||
szOpBase = AI_MATKEY_TEXOP_SHININESS_;
|
||||
break;
|
||||
case AI_TEXTYPE_OPACITY:
|
||||
szPathBase = AI_MATKEY_TEXTURE_OPACITY_;
|
||||
szUVBase = AI_MATKEY_UVWSRC_OPACITY_;
|
||||
szBlendBase = AI_MATKEY_TEXBLEND_OPACITY_;
|
||||
szOpBase = AI_MATKEY_TEXOP_OPACITY_;
|
||||
break;
|
||||
default: return AI_FAILURE;
|
||||
};
|
||||
|
||||
@@ -404,6 +461,7 @@ aiReturn aiGetMaterialTexture(const aiMaterial* pcMat,
|
||||
|
||||
*pfBlendFactor = fBlend;
|
||||
}
|
||||
|
||||
// get the texture operation of the texture
|
||||
if (peTextureOp)
|
||||
{
|
||||
|
||||
@@ -60,6 +60,11 @@ namespace Assimp
|
||||
// ---------------------------------------------------------------------------
|
||||
inline int ASSIMP_stricmp(const char *s1, const char *s2)
|
||||
{
|
||||
#if (defined _MSC_VER)
|
||||
|
||||
return _stricmp(s1,s2);
|
||||
|
||||
#else
|
||||
const char *a1, *a2;
|
||||
a1 = s1;
|
||||
a2 = s2;
|
||||
@@ -74,6 +79,7 @@ inline int ASSIMP_stricmp(const char *s1, const char *s2)
|
||||
++a1;
|
||||
++a2;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -90,6 +96,11 @@ inline int ASSIMP_stricmp(const char *s1, const char *s2)
|
||||
// ---------------------------------------------------------------------------
|
||||
inline int ASSIMP_strincmp(const char *s1, const char *s2, unsigned int n)
|
||||
{
|
||||
#if (defined _MSC_VER)
|
||||
|
||||
return _strnicmp(s1,s2,n);
|
||||
|
||||
#else
|
||||
const char *a1, *a2;
|
||||
a1 = s1;
|
||||
a2 = s2;
|
||||
@@ -109,6 +120,7 @@ inline int ASSIMP_strincmp(const char *s1, const char *s2, unsigned int n)
|
||||
++a2;
|
||||
++p;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -159,6 +171,15 @@ public:
|
||||
const unsigned int pNumValues,
|
||||
const char* pKey);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Remove a given key from the list
|
||||
* The function fails if the key isn't found
|
||||
*
|
||||
* \param pKey Key/Usage to be deleted
|
||||
*/
|
||||
aiReturn RemoveProperty (const char* pKey);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Copy the property list of a material
|
||||
* \param pcDest Destination material
|
||||
|
||||
@@ -26,8 +26,6 @@ ObjFileImporter::ObjFileImporter() :
|
||||
m_pRootObject(NULL),
|
||||
m_strAbsPath("\\")
|
||||
{
|
||||
DefaultLogger::create( "test.log", DefaultLogger::VERBOSE );
|
||||
DefaultLogger::get()->info("Start logging");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -40,8 +38,6 @@ ObjFileImporter::~ObjFileImporter()
|
||||
delete m_pRootObject;
|
||||
m_pRootObject = NULL;
|
||||
}
|
||||
|
||||
DefaultLogger::kill();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
+5
-3
@@ -108,7 +108,9 @@ void PLYImporter::InternReadFile(
|
||||
|
||||
// allocate storage and copy the contents of the file to a memory buffer
|
||||
// (terminate it with zero)
|
||||
this->mBuffer = new unsigned char[fileSize+1];
|
||||
// FIX: Allocate an extra buffer of 12.5% to be sure we won't crash
|
||||
// if an overrun occurs.
|
||||
this->mBuffer = new unsigned char[fileSize+1 + (fileSize>>3)];
|
||||
file->Read( (void*)mBuffer, 1, fileSize);
|
||||
this->mBuffer[fileSize] = '\0';
|
||||
|
||||
@@ -131,7 +133,7 @@ void PLYImporter::InternReadFile(
|
||||
{
|
||||
szMe += 6;
|
||||
SkipLine(szMe,(const char**)&szMe);
|
||||
if(!PLY::DOM::ParseInstance(szMe,&sPlyDom))
|
||||
if(!PLY::DOM::ParseInstance(szMe,&sPlyDom, fileSize))
|
||||
{
|
||||
throw new ImportErrorException( "Invalid .ply file: Unable to build DOM (#1)");
|
||||
}
|
||||
@@ -151,7 +153,7 @@ void PLYImporter::InternReadFile(
|
||||
|
||||
// skip the line, parse the rest of the header and build the DOM
|
||||
SkipLine(szMe,(const char**)&szMe);
|
||||
if(!PLY::DOM::ParseInstanceBinary(szMe,&sPlyDom,bIsBE))
|
||||
if(!PLY::DOM::ParseInstanceBinary(szMe,&sPlyDom,bIsBE, fileSize))
|
||||
{
|
||||
throw new ImportErrorException( "Invalid .ply file: Unable to build DOM (#2)");
|
||||
}
|
||||
|
||||
+271
-59
@@ -44,6 +44,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "PLYLoader.h"
|
||||
#include "MaterialSystem.h"
|
||||
#include "fast_atof.h"
|
||||
#include "DefaultLogger.h"
|
||||
#include "ByteSwap.h"
|
||||
|
||||
#include "../include/IOStream.h"
|
||||
#include "../include/IOSystem.h"
|
||||
@@ -55,9 +57,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
using namespace Assimp;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ValidateOut(const char* szCur, const char* szMax)
|
||||
{
|
||||
if (szCur > szMax)
|
||||
{
|
||||
throw new ImportErrorException("Buffer overflow. PLY file contains invalid indices");
|
||||
}
|
||||
return;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
PLY::EDataType PLY::Property::ParseDataType(const char* p_szIn,const char** p_szOut)
|
||||
{
|
||||
ai_assert(NULL != p_szIn);
|
||||
ai_assert(NULL != p_szOut);
|
||||
|
||||
const char* szMax = *p_szOut;
|
||||
|
||||
PLY::EDataType eOut = PLY::EDT_INVALID;
|
||||
|
||||
if (0 == ASSIMP_strincmp(p_szIn,"char",4) ||
|
||||
@@ -134,12 +150,22 @@ PLY::EDataType PLY::Property::ParseDataType(const char* p_szIn,const char** p_sz
|
||||
{
|
||||
eOut = PLY::EDT_INVALID;
|
||||
}
|
||||
if (PLY::EDT_INVALID == eOut)
|
||||
{
|
||||
DefaultLogger::get()->info("Found unknown data type in PLY file. This is OK");
|
||||
}
|
||||
*p_szOut = p_szIn;
|
||||
ValidateOut(p_szIn,szMax);
|
||||
return eOut;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
PLY::ESemantic PLY::Property::ParseSemantic(const char* p_szIn,const char** p_szOut)
|
||||
{
|
||||
ai_assert(NULL != p_szIn);
|
||||
ai_assert(NULL != p_szOut);
|
||||
|
||||
const char* szMax = *p_szOut;
|
||||
|
||||
PLY::ESemantic eOut = PLY::EST_INVALID;
|
||||
if (0 == ASSIMP_strincmp(p_szIn,"red",3))
|
||||
{
|
||||
@@ -298,6 +324,8 @@ PLY::ESemantic PLY::Property::ParseSemantic(const char* p_szIn,const char** p_sz
|
||||
}
|
||||
else
|
||||
{
|
||||
DefaultLogger::get()->info("Found unknown property in file. This is ok");
|
||||
|
||||
// ... find the next space or new line
|
||||
while (*p_szIn != ' ' && *p_szIn != '\t' &&
|
||||
*p_szIn != '\r' && *p_szIn != '\0' && *p_szIn != '\n')p_szIn++;
|
||||
@@ -307,6 +335,7 @@ PLY::ESemantic PLY::Property::ParseSemantic(const char* p_szIn,const char** p_sz
|
||||
{
|
||||
eOut = PLY::EST_INVALID;
|
||||
}
|
||||
ValidateOut(p_szIn,szMax);
|
||||
*p_szOut = p_szIn;
|
||||
return eOut;
|
||||
}
|
||||
@@ -315,9 +344,13 @@ bool PLY::Property::ParseProperty (const char* p_szIn,
|
||||
const char** p_szOut,
|
||||
PLY::Property* pOut)
|
||||
{
|
||||
ai_assert(NULL != p_szIn);
|
||||
ai_assert(NULL != p_szOut);
|
||||
|
||||
// Forms supported:
|
||||
// "property float x"
|
||||
// "property list uchar int vertex_index"
|
||||
const char* szMax = *p_szOut;
|
||||
*p_szOut = p_szIn;
|
||||
|
||||
// skip leading spaces
|
||||
@@ -339,46 +372,56 @@ bool PLY::Property::ParseProperty (const char* p_szIn,
|
||||
|
||||
// seems to be a list.
|
||||
p_szIn += 5;
|
||||
if(EDT_INVALID == (pOut->eFirstType = PLY::Property::ParseDataType(p_szIn, &p_szIn)))
|
||||
const char* szPass = szMax;
|
||||
if(EDT_INVALID == (pOut->eFirstType = PLY::Property::ParseDataType(p_szIn, &szPass)))
|
||||
{
|
||||
// unable to parse list size data type
|
||||
SkipLine(p_szIn,&p_szIn);
|
||||
*p_szOut = p_szIn;
|
||||
return false;
|
||||
}
|
||||
p_szIn = szPass;
|
||||
if (!SkipSpaces(p_szIn,&p_szIn))return false;
|
||||
if(EDT_INVALID == (pOut->eType = PLY::Property::ParseDataType(p_szIn, &p_szIn)))
|
||||
szPass = szMax;
|
||||
if(EDT_INVALID == (pOut->eType = PLY::Property::ParseDataType(p_szIn, &szPass)))
|
||||
{
|
||||
// unable to parse list data type
|
||||
SkipLine(p_szIn,&p_szIn);
|
||||
*p_szOut = p_szIn;
|
||||
return false;
|
||||
}
|
||||
p_szIn = szPass;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(EDT_INVALID == (pOut->eType = PLY::Property::ParseDataType(p_szIn, &p_szIn)))
|
||||
const char* szPass = szMax;
|
||||
if(EDT_INVALID == (pOut->eType = PLY::Property::ParseDataType(p_szIn, &szPass)))
|
||||
{
|
||||
// unable to parse data type. Skip the property
|
||||
SkipLine(p_szIn,&p_szIn);
|
||||
*p_szOut = p_szIn;
|
||||
return false;
|
||||
}
|
||||
p_szIn = szPass;
|
||||
}
|
||||
|
||||
if (!SkipSpaces(p_szIn,&p_szIn))return false;
|
||||
const char* szCur = p_szIn;
|
||||
pOut->Semantic = PLY::Property::ParseSemantic(p_szIn, &p_szIn);
|
||||
const char* szPass = szMax;
|
||||
pOut->Semantic = PLY::Property::ParseSemantic(p_szIn, &szPass);
|
||||
p_szIn = szPass;
|
||||
|
||||
if (PLY::EST_INVALID == pOut->Semantic)
|
||||
{
|
||||
// store the name of the semantic
|
||||
uintptr_t iDiff = (uintptr_t)p_szIn - (uintptr_t)szCur;
|
||||
|
||||
DefaultLogger::get()->info("Found unknown semantic in PLY file. This is OK");
|
||||
pOut->szName = std::string(szCur,iDiff);
|
||||
}
|
||||
|
||||
SkipSpacesAndLineEnd(p_szIn,&p_szIn);
|
||||
ValidateOut(p_szIn,szMax);
|
||||
*p_szOut = p_szIn;
|
||||
return true;
|
||||
}
|
||||
@@ -386,6 +429,11 @@ bool PLY::Property::ParseProperty (const char* p_szIn,
|
||||
PLY::EElementSemantic PLY::Element::ParseSemantic(const char* p_szIn,
|
||||
const char** p_szOut)
|
||||
{
|
||||
ai_assert(NULL != p_szIn);
|
||||
ai_assert(NULL != p_szOut);
|
||||
|
||||
const char* szMax = *p_szOut;
|
||||
|
||||
PLY::EElementSemantic eOut = PLY::EEST_INVALID;
|
||||
if (0 == ASSIMP_strincmp(p_szIn,"vertex",6))
|
||||
{
|
||||
@@ -425,6 +473,7 @@ PLY::EElementSemantic PLY::Element::ParseSemantic(const char* p_szIn,
|
||||
{
|
||||
eOut = PLY::EEST_INVALID;
|
||||
}
|
||||
ValidateOut(p_szIn,szMax);
|
||||
*p_szOut = p_szIn;
|
||||
return eOut;
|
||||
}
|
||||
@@ -433,7 +482,12 @@ bool PLY::Element::ParseElement (const char* p_szIn,
|
||||
const char** p_szOut,
|
||||
PLY::Element* pOut)
|
||||
{
|
||||
ai_assert(NULL != p_szIn);
|
||||
ai_assert(NULL != p_szOut);
|
||||
ai_assert(NULL != pOut);
|
||||
|
||||
// Example format: "element vertex 8"
|
||||
const char* szMax = *p_szOut;
|
||||
*p_szOut = p_szIn;
|
||||
|
||||
// skip leading spaces
|
||||
@@ -451,7 +505,9 @@ bool PLY::Element::ParseElement (const char* p_szIn,
|
||||
|
||||
// parse the semantic of the element
|
||||
const char* szCur = p_szIn;
|
||||
pOut->eSemantic = PLY::Element::ParseSemantic(p_szIn,&p_szIn);
|
||||
const char* szPass = szMax;
|
||||
pOut->eSemantic = PLY::Element::ParseSemantic(p_szIn,&szPass);
|
||||
p_szIn = szPass;
|
||||
|
||||
if (PLY::EEST_INVALID == pOut->eSemantic)
|
||||
{
|
||||
@@ -476,11 +532,15 @@ bool PLY::Element::ParseElement (const char* p_szIn,
|
||||
PLY::DOM::SkipComments(p_szIn,&p_szIn);
|
||||
|
||||
PLY::Property* prop = new PLY::Property();
|
||||
if(!PLY::Property::ParseProperty(p_szIn,&p_szIn,prop))break;
|
||||
|
||||
const char* szPass = szMax;
|
||||
if(!PLY::Property::ParseProperty(p_szIn,&szPass,prop))break;
|
||||
p_szIn = szPass;
|
||||
|
||||
// add the property to the property list
|
||||
pOut->alProperties.push_back(prop);
|
||||
}
|
||||
ValidateOut(p_szIn,szMax);
|
||||
*p_szOut = p_szIn;
|
||||
return true;
|
||||
}
|
||||
@@ -488,6 +548,10 @@ bool PLY::Element::ParseElement (const char* p_szIn,
|
||||
bool PLY::DOM::SkipComments (const char* p_szIn,
|
||||
const char** p_szOut)
|
||||
{
|
||||
ai_assert(NULL != p_szIn);
|
||||
ai_assert(NULL != p_szOut);
|
||||
|
||||
const char* szMax = *p_szOut;
|
||||
*p_szOut = p_szIn;
|
||||
|
||||
// skip spaces
|
||||
@@ -503,12 +567,20 @@ bool PLY::DOM::SkipComments (const char* p_szIn,
|
||||
*p_szOut = p_szIn;
|
||||
return true;
|
||||
}
|
||||
ValidateOut(p_szIn,szMax);
|
||||
*p_szOut = p_szIn;
|
||||
return false;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool PLY::DOM::ParseHeader (const char* p_szIn,const char** p_szOut)
|
||||
{
|
||||
ai_assert(NULL != p_szIn);
|
||||
ai_assert(NULL != p_szOut);
|
||||
|
||||
DefaultLogger::get()->debug("PLY::DOM::ParseHeader() begin");
|
||||
|
||||
// after ply and format line
|
||||
const char* szMax = *p_szOut;
|
||||
*p_szOut = p_szIn;
|
||||
|
||||
// parse all elements
|
||||
@@ -518,8 +590,11 @@ bool PLY::DOM::ParseHeader (const char* p_szIn,const char** p_szOut)
|
||||
PLY::DOM::SkipComments(p_szIn,&p_szIn);
|
||||
|
||||
PLY::Element* out = new PLY::Element();
|
||||
if(PLY::Element::ParseElement(p_szIn,&p_szIn,out))
|
||||
const char* szPass = szMax;
|
||||
if(PLY::Element::ParseElement(p_szIn,&szPass,out))
|
||||
{
|
||||
p_szIn = szPass;
|
||||
|
||||
// add the element to the list of elements
|
||||
this->alElements.push_back(out);
|
||||
}
|
||||
@@ -532,7 +607,10 @@ bool PLY::DOM::ParseHeader (const char* p_szIn,const char** p_szOut)
|
||||
// ignore unknown header elements
|
||||
}
|
||||
SkipSpacesAndLineEnd(p_szIn,&p_szIn);
|
||||
ValidateOut(p_szIn,szMax);
|
||||
*p_szOut = p_szIn;
|
||||
|
||||
DefaultLogger::get()->debug("PLY::DOM::ParseHeader() succeeded");
|
||||
return true;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -540,6 +618,14 @@ bool PLY::DOM::ParseElementInstanceLists (
|
||||
const char* p_szIn,
|
||||
const char** p_szOut)
|
||||
{
|
||||
ai_assert(NULL != p_szIn);
|
||||
ai_assert(NULL != p_szOut);
|
||||
|
||||
DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceLists() begin");
|
||||
|
||||
const char* szMax = *p_szOut;
|
||||
*p_szOut = p_szIn;
|
||||
|
||||
this->alElementData.resize(this->alElements.size());
|
||||
|
||||
std::vector<PLY::Element*>::const_iterator i = this->alElements.begin();
|
||||
@@ -549,8 +635,15 @@ bool PLY::DOM::ParseElementInstanceLists (
|
||||
for (;i != this->alElements.end();++i,++a)
|
||||
{
|
||||
*a = new PLY::ElementInstanceList((*i)); // reserve enough storage
|
||||
PLY::ElementInstanceList::ParseInstanceList(p_szIn,&p_szIn,(*i),(*a));
|
||||
|
||||
const char* szPass = szMax;
|
||||
PLY::ElementInstanceList::ParseInstanceList(p_szIn,&szPass,(*i),(*a));
|
||||
p_szIn = szPass;
|
||||
}
|
||||
|
||||
DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceLists() succeeded");
|
||||
ValidateOut(p_szIn,szMax);
|
||||
*p_szOut = p_szIn;
|
||||
return true;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -559,6 +652,14 @@ bool PLY::DOM::ParseElementInstanceListsBinary (
|
||||
const char** p_szOut,
|
||||
bool p_bBE)
|
||||
{
|
||||
ai_assert(NULL != p_szIn);
|
||||
ai_assert(NULL != p_szOut);
|
||||
|
||||
DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceListsBinary() begin");
|
||||
|
||||
const char* szMax = *p_szOut;
|
||||
*p_szOut = p_szIn;
|
||||
|
||||
this->alElementData.resize(this->alElements.size());
|
||||
|
||||
std::vector<PLY::Element*>::const_iterator i = this->alElements.begin();
|
||||
@@ -568,40 +669,80 @@ bool PLY::DOM::ParseElementInstanceListsBinary (
|
||||
for (;i != this->alElements.end();++i,++a)
|
||||
{
|
||||
*a = new PLY::ElementInstanceList((*i)); // reserve enough storage
|
||||
PLY::ElementInstanceList::ParseInstanceListBinary(p_szIn,&p_szIn,(*i),(*a),p_bBE);
|
||||
const char* szPass = szMax;
|
||||
PLY::ElementInstanceList::ParseInstanceListBinary(p_szIn,&szPass,(*i),(*a),p_bBE);
|
||||
p_szIn = szPass;
|
||||
}
|
||||
|
||||
DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceListsBinary() succeeded");
|
||||
ValidateOut(p_szIn,szMax);
|
||||
*p_szOut = p_szIn;
|
||||
return true;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool PLY::DOM::ParseInstanceBinary (const char* p_szIn,DOM* p_pcOut,bool p_bBE)
|
||||
bool PLY::DOM::ParseInstanceBinary (const char* p_szIn,DOM* p_pcOut,bool p_bBE,unsigned int iSize)
|
||||
{
|
||||
if(!p_pcOut->ParseHeader(p_szIn,&p_szIn))
|
||||
ai_assert(NULL != p_szIn);
|
||||
ai_assert(NULL != p_pcOut);
|
||||
|
||||
DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() begin");
|
||||
|
||||
const char* szMax = p_szIn + iSize;
|
||||
const char* szPass = szMax;
|
||||
if(!p_pcOut->ParseHeader(p_szIn,&szPass))
|
||||
{
|
||||
DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() failure");
|
||||
return false;
|
||||
}
|
||||
if(!p_pcOut->ParseElementInstanceListsBinary(p_szIn,&p_szIn,p_bBE))
|
||||
p_szIn = szPass;
|
||||
szPass = szMax;
|
||||
if(!p_pcOut->ParseElementInstanceListsBinary(p_szIn,&szPass,p_bBE))
|
||||
{
|
||||
DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() failure");
|
||||
return false;
|
||||
}
|
||||
DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() succeeded");
|
||||
return true;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool PLY::DOM::ParseInstance (const char* p_szIn,DOM* p_pcOut)
|
||||
bool PLY::DOM::ParseInstance (const char* p_szIn,DOM* p_pcOut,unsigned int iSize)
|
||||
{
|
||||
if(!p_pcOut->ParseHeader(p_szIn,&p_szIn))
|
||||
ai_assert(NULL != p_szIn);
|
||||
ai_assert(NULL != p_pcOut);
|
||||
|
||||
DefaultLogger::get()->debug("PLY::DOM::ParseInstance() begin");
|
||||
|
||||
const char* szMax = p_szIn + iSize;
|
||||
const char* szPass = szMax;
|
||||
if(!p_pcOut->ParseHeader(p_szIn,&szPass))
|
||||
{
|
||||
DefaultLogger::get()->debug("PLY::DOM::ParseInstance() failure");
|
||||
return false;
|
||||
}
|
||||
if(!p_pcOut->ParseElementInstanceLists(p_szIn,&p_szIn))
|
||||
p_szIn = szPass;
|
||||
szPass = szMax;
|
||||
if(!p_pcOut->ParseElementInstanceLists(p_szIn,&szPass))
|
||||
{
|
||||
DefaultLogger::get()->debug("PLY::DOM::ParseInstance() failure");
|
||||
return false;
|
||||
}
|
||||
DefaultLogger::get()->debug("PLY::DOM::ParseInstance() succeeded");
|
||||
return true;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool PLY::ElementInstanceList::ParseInstanceList (const char* p_szIn,const char** p_szOut,
|
||||
const PLY::Element* pcElement, PLY::ElementInstanceList* p_pcOut)
|
||||
bool PLY::ElementInstanceList::ParseInstanceList (
|
||||
const char* p_szIn,
|
||||
const char** p_szOut,
|
||||
const PLY::Element* pcElement,
|
||||
PLY::ElementInstanceList* p_pcOut)
|
||||
{
|
||||
ai_assert(NULL != p_szIn);
|
||||
ai_assert(NULL != p_szOut);
|
||||
ai_assert(NULL != pcElement);
|
||||
ai_assert(NULL != p_pcOut);
|
||||
|
||||
const char* szMax = *p_szOut;
|
||||
|
||||
if (EEST_INVALID == pcElement->eSemantic)
|
||||
{
|
||||
// if the element has an unknown semantic we can skip all lines
|
||||
@@ -621,11 +762,15 @@ bool PLY::ElementInstanceList::ParseInstanceList (const char* p_szIn,const char*
|
||||
PLY::DOM::SkipComments(p_szIn,&p_szIn);
|
||||
|
||||
PLY::ElementInstance* out = new PLY::ElementInstance();
|
||||
PLY::ElementInstance::ParseInstance(p_szIn, &p_szIn,pcElement, out);
|
||||
|
||||
const char* szPass = szMax;
|
||||
PLY::ElementInstance::ParseInstance(p_szIn, &szPass,pcElement, out);
|
||||
p_szIn = szPass;
|
||||
// add it to the list
|
||||
p_pcOut->alInstances[i] = out;
|
||||
}
|
||||
}
|
||||
ValidateOut(p_szIn,szMax);
|
||||
*p_szOut = p_szIn;
|
||||
return true;
|
||||
}
|
||||
@@ -637,6 +782,14 @@ bool PLY::ElementInstanceList::ParseInstanceListBinary (
|
||||
PLY::ElementInstanceList* p_pcOut,
|
||||
bool p_bBE /* = false */)
|
||||
{
|
||||
ai_assert(NULL != p_szIn);
|
||||
ai_assert(NULL != p_szOut);
|
||||
ai_assert(NULL != pcElement);
|
||||
ai_assert(NULL != p_pcOut);
|
||||
|
||||
const char* szMax = *p_szOut;
|
||||
*p_szOut = p_szIn;
|
||||
|
||||
// we can add special handling code for unknown element semantics since
|
||||
// we can't skip it as a whole block (we don't know its exact size
|
||||
// due to the fact that lists could be contained in the property list
|
||||
@@ -644,10 +797,13 @@ bool PLY::ElementInstanceList::ParseInstanceListBinary (
|
||||
for (unsigned int i = 0; i < pcElement->NumOccur;++i)
|
||||
{
|
||||
PLY::ElementInstance* out = new PLY::ElementInstance();
|
||||
const char* szPass = szMax;
|
||||
PLY::ElementInstance::ParseInstanceBinary(p_szIn, &p_szIn,pcElement, out, p_bBE);
|
||||
p_szIn = szPass;
|
||||
// add it to the list
|
||||
p_pcOut->alInstances[i] = out;
|
||||
}
|
||||
ValidateOut(p_szIn,szMax);
|
||||
*p_szOut = p_szIn;
|
||||
return true;
|
||||
}
|
||||
@@ -658,25 +814,38 @@ bool PLY::ElementInstance::ParseInstance (
|
||||
const PLY::Element* pcElement,
|
||||
PLY::ElementInstance* p_pcOut)
|
||||
{
|
||||
ai_assert(NULL != p_szIn);
|
||||
ai_assert(NULL != p_szOut);
|
||||
ai_assert(NULL != pcElement);
|
||||
ai_assert(NULL != p_pcOut);
|
||||
|
||||
if (!SkipSpaces(p_szIn, &p_szIn))return false;
|
||||
|
||||
// allocate enough storage
|
||||
p_pcOut->alProperties.resize(pcElement->alProperties.size());
|
||||
|
||||
const char* szMax = *p_szOut;
|
||||
*p_szOut = p_szIn;
|
||||
|
||||
std::vector<PLY::PropertyInstance>::iterator i = p_pcOut->alProperties.begin();
|
||||
std::vector<PLY::Property*>::const_iterator a = pcElement->alProperties.begin();
|
||||
for (;i != p_pcOut->alProperties.end();++i,++a)
|
||||
{
|
||||
if(!(PLY::PropertyInstance::ParseInstance(p_szIn, &p_szIn,(*a),&(*i))))
|
||||
const char* szPass = szMax;
|
||||
if(!(PLY::PropertyInstance::ParseInstance(p_szIn, &szPass,(*a),&(*i))))
|
||||
{
|
||||
DefaultLogger::get()->warn("Unable to parse property instance. "
|
||||
"Skipping this element instance");
|
||||
|
||||
// skip the rest of the instance
|
||||
SkipLine(p_szIn, &p_szIn);
|
||||
|
||||
PLY::PropertyInstance::ValueUnion v = PLY::PropertyInstance::DefaultValue((*a)->eType);
|
||||
(*i).avList.push_back(v);
|
||||
}
|
||||
p_szIn = szPass;
|
||||
}
|
||||
ValidateOut(p_szIn,szMax);
|
||||
*p_szOut = p_szIn;
|
||||
return true;
|
||||
}
|
||||
@@ -688,20 +857,33 @@ bool PLY::ElementInstance::ParseInstanceBinary (
|
||||
PLY::ElementInstance* p_pcOut,
|
||||
bool p_bBE /* = false */)
|
||||
{
|
||||
ai_assert(NULL != p_szIn);
|
||||
ai_assert(NULL != p_szOut);
|
||||
ai_assert(NULL != pcElement);
|
||||
ai_assert(NULL != p_pcOut);
|
||||
|
||||
const char* szMax = *p_szOut;
|
||||
*p_szOut = p_szIn;
|
||||
|
||||
// allocate enough storage
|
||||
p_pcOut->alProperties.resize(pcElement->alProperties.size());
|
||||
|
||||
*p_szOut = p_szIn;
|
||||
std::vector<PLY::PropertyInstance>::iterator i = p_pcOut->alProperties.begin();
|
||||
std::vector<PLY::Property*>::const_iterator a = pcElement->alProperties.begin();
|
||||
for (;i != p_pcOut->alProperties.end();++i,++a)
|
||||
{
|
||||
if(!(PLY::PropertyInstance::ParseInstance(p_szIn, &p_szIn,(*a),&(*i))))
|
||||
const char* szPass = szMax;
|
||||
if(!(PLY::PropertyInstance::ParseInstanceBinary(p_szIn, &szPass,(*a),&(*i),p_bBE)))
|
||||
{
|
||||
DefaultLogger::get()->warn("Unable to parse binary property instance. "
|
||||
"Skipping this element instance");
|
||||
|
||||
PLY::PropertyInstance::ValueUnion v = PLY::PropertyInstance::DefaultValue((*a)->eType);
|
||||
(*i).avList.push_back(v);
|
||||
}
|
||||
p_szIn = szPass;
|
||||
}
|
||||
ValidateOut(p_szIn,szMax);
|
||||
*p_szOut = p_szIn;
|
||||
return true;
|
||||
}
|
||||
@@ -709,6 +891,12 @@ bool PLY::ElementInstance::ParseInstanceBinary (
|
||||
bool PLY::PropertyInstance::ParseInstance (const char* p_szIn,const char** p_szOut,
|
||||
const PLY::Property* prop, PLY::PropertyInstance* p_pcOut)
|
||||
{
|
||||
ai_assert(NULL != p_szIn);
|
||||
ai_assert(NULL != p_szOut);
|
||||
ai_assert(NULL != prop);
|
||||
ai_assert(NULL != p_pcOut);
|
||||
|
||||
const char* szMax = *p_szOut;
|
||||
*p_szOut = p_szIn;
|
||||
|
||||
// skip spaces at the beginning
|
||||
@@ -718,7 +906,10 @@ bool PLY::PropertyInstance::ParseInstance (const char* p_szIn,const char** p_szO
|
||||
{
|
||||
// parse the number of elements in the list
|
||||
PLY::PropertyInstance::ValueUnion v;
|
||||
PLY::PropertyInstance::ParseValue(p_szIn, &p_szIn,prop->eFirstType,&v);
|
||||
|
||||
const char* szPass = szMax;
|
||||
PLY::PropertyInstance::ParseValue(p_szIn, &szPass,prop->eFirstType,&v);
|
||||
p_szIn = szPass;
|
||||
|
||||
// convert to unsigned int
|
||||
unsigned int iNum = PLY::PropertyInstance::ConvertTo<unsigned int>(v,prop->eFirstType);
|
||||
@@ -728,7 +919,9 @@ bool PLY::PropertyInstance::ParseInstance (const char* p_szIn,const char** p_szO
|
||||
{
|
||||
if (!SkipSpaces(p_szIn, &p_szIn))return false;
|
||||
|
||||
PLY::PropertyInstance::ParseValue(p_szIn, &p_szIn,prop->eType,&v);
|
||||
const char* szPass = szMax;
|
||||
PLY::PropertyInstance::ParseValue(p_szIn, &szPass,prop->eType,&v);
|
||||
p_szIn = szPass;
|
||||
p_pcOut->avList.push_back(v);
|
||||
}
|
||||
}
|
||||
@@ -736,10 +929,14 @@ bool PLY::PropertyInstance::ParseInstance (const char* p_szIn,const char** p_szO
|
||||
{
|
||||
// parse the property
|
||||
PLY::PropertyInstance::ValueUnion v;
|
||||
PLY::PropertyInstance::ParseValue(p_szIn, &p_szIn,prop->eType,&v);
|
||||
|
||||
const char* szPass = szMax;
|
||||
PLY::PropertyInstance::ParseValue(p_szIn, &szPass,prop->eType,&v);
|
||||
p_szIn = szPass;
|
||||
p_pcOut->avList.push_back(v);
|
||||
}
|
||||
SkipSpacesAndLineEnd(p_szIn, &p_szIn);
|
||||
ValidateOut(p_szIn,szMax);
|
||||
*p_szOut = p_szIn;
|
||||
return true;
|
||||
}
|
||||
@@ -747,13 +944,21 @@ bool PLY::PropertyInstance::ParseInstance (const char* p_szIn,const char** p_szO
|
||||
bool PLY::PropertyInstance::ParseInstanceBinary (const char* p_szIn,const char** p_szOut,
|
||||
const PLY::Property* prop, PLY::PropertyInstance* p_pcOut,bool p_bBE)
|
||||
{
|
||||
ai_assert(NULL != p_szIn);
|
||||
ai_assert(NULL != p_szOut);
|
||||
ai_assert(NULL != prop);
|
||||
ai_assert(NULL != p_pcOut);
|
||||
|
||||
const char* szMax = *p_szOut;
|
||||
*p_szOut = p_szIn;
|
||||
|
||||
if (prop->bIsList)
|
||||
{
|
||||
// parse the number of elements in the list
|
||||
PLY::PropertyInstance::ValueUnion v;
|
||||
PLY::PropertyInstance::ParseValueBinary(p_szIn, &p_szIn,prop->eFirstType,&v,p_bBE);
|
||||
const char* szPass = szMax;
|
||||
PLY::PropertyInstance::ParseValueBinary(p_szIn, &szPass,prop->eFirstType,&v,p_bBE);
|
||||
p_szIn = szPass;
|
||||
|
||||
// convert to unsigned int
|
||||
unsigned int iNum = PLY::PropertyInstance::ConvertTo<unsigned int>(v,prop->eFirstType);
|
||||
@@ -761,7 +966,9 @@ bool PLY::PropertyInstance::ParseInstanceBinary (const char* p_szIn,const char**
|
||||
// parse all list elements
|
||||
for (unsigned int i = 0; i < iNum;++i)
|
||||
{
|
||||
PLY::PropertyInstance::ParseValueBinary(p_szIn, &p_szIn,prop->eType,&v,p_bBE);
|
||||
const char* szPass = szMax;
|
||||
PLY::PropertyInstance::ParseValueBinary(p_szIn, &szPass,prop->eType,&v,p_bBE);
|
||||
p_szIn = szPass;
|
||||
p_pcOut->avList.push_back(v);
|
||||
}
|
||||
}
|
||||
@@ -769,9 +976,12 @@ bool PLY::PropertyInstance::ParseInstanceBinary (const char* p_szIn,const char**
|
||||
{
|
||||
// parse the property
|
||||
PLY::PropertyInstance::ValueUnion v;
|
||||
PLY::PropertyInstance::ParseValueBinary(p_szIn, &p_szIn,prop->eType,&v,p_bBE);
|
||||
const char* szPass = szMax;
|
||||
PLY::PropertyInstance::ParseValueBinary(p_szIn, &szPass,prop->eType,&v,p_bBE);
|
||||
p_szIn = szPass;
|
||||
p_pcOut->avList.push_back(v);
|
||||
}
|
||||
ValidateOut(p_szIn,szMax);
|
||||
*p_szOut = p_szIn;
|
||||
return true;
|
||||
}
|
||||
@@ -798,6 +1008,11 @@ PLY::PropertyInstance::ValueUnion PLY::PropertyInstance::DefaultValue(
|
||||
bool PLY::PropertyInstance::ParseValue(const char* p_szIn,const char** p_szOut,
|
||||
PLY::EDataType eType,PLY::PropertyInstance::ValueUnion* out)
|
||||
{
|
||||
ai_assert(NULL != p_szIn);
|
||||
ai_assert(NULL != p_szOut);
|
||||
ai_assert(NULL != out);
|
||||
|
||||
const char* szMax = *p_szOut;
|
||||
*p_szOut = p_szIn;
|
||||
|
||||
switch (eType)
|
||||
@@ -846,13 +1061,23 @@ bool PLY::PropertyInstance::ParseValue(const char* p_szIn,const char** p_szOut,
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
ValidateOut(p_szIn,szMax);
|
||||
*p_szOut = p_szIn;
|
||||
return true;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool PLY::PropertyInstance::ParseValueBinary(const char* p_szIn,const char** p_szOut,
|
||||
PLY::EDataType eType,PLY::PropertyInstance::ValueUnion* out, bool p_bBE)
|
||||
bool PLY::PropertyInstance::ParseValueBinary(
|
||||
const char* p_szIn,
|
||||
const char** p_szOut,
|
||||
PLY::EDataType eType,
|
||||
PLY::PropertyInstance::ValueUnion* out,
|
||||
bool p_bBE)
|
||||
{
|
||||
ai_assert(NULL != p_szIn);
|
||||
ai_assert(NULL != p_szOut);
|
||||
ai_assert(NULL != out);
|
||||
|
||||
const char* szMax = *p_szOut;
|
||||
*p_szOut = p_szIn;
|
||||
|
||||
switch (eType)
|
||||
@@ -863,8 +1088,7 @@ bool PLY::PropertyInstance::ParseValueBinary(const char* p_szIn,const char** p_s
|
||||
|
||||
if (p_bBE)
|
||||
{
|
||||
std::swap(((unsigned char*)(&out->iUInt))[0],((unsigned char*)(&out->iUInt))[3]);
|
||||
std::swap(((unsigned char*)(&out->iUInt))[1],((unsigned char*)(&out->iUInt))[2]);
|
||||
ByteSwap::Swap((int32_t*)&out->iUInt);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -873,7 +1097,7 @@ bool PLY::PropertyInstance::ParseValueBinary(const char* p_szIn,const char** p_s
|
||||
uint16_t i = *((uint16_t*)p_szIn);
|
||||
if (p_bBE)
|
||||
{
|
||||
std::swap(((unsigned char*)(&i))[0],((unsigned char*)(&i))[1]);
|
||||
ByteSwap::Swap((int16_t*)&i);
|
||||
}
|
||||
out->iUInt = (uint32_t)i;
|
||||
p_szIn += 2;
|
||||
@@ -884,7 +1108,7 @@ bool PLY::PropertyInstance::ParseValueBinary(const char* p_szIn,const char** p_s
|
||||
{
|
||||
uint8_t i = *((uint8_t*)p_szIn);
|
||||
out->iUInt = (uint32_t)i;
|
||||
p_szIn += 2;
|
||||
p_szIn ++;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -894,8 +1118,7 @@ bool PLY::PropertyInstance::ParseValueBinary(const char* p_szIn,const char** p_s
|
||||
|
||||
if (p_bBE)
|
||||
{
|
||||
std::swap(((unsigned char*)(&out->iInt))[0],((unsigned char*)(&out->iInt))[3]);
|
||||
std::swap(((unsigned char*)(&out->iInt))[1],((unsigned char*)(&out->iInt))[2]);
|
||||
ByteSwap::Swap((int32_t*)&out->iInt);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -904,7 +1127,7 @@ bool PLY::PropertyInstance::ParseValueBinary(const char* p_szIn,const char** p_s
|
||||
int16_t i = *((int16_t*)p_szIn);
|
||||
if (p_bBE)
|
||||
{
|
||||
std::swap(((unsigned char*)(&i))[0],((unsigned char*)(&i))[1]);
|
||||
ByteSwap::Swap((int16_t*)&i);
|
||||
}
|
||||
out->iInt = (int32_t)i;
|
||||
p_szIn += 2;
|
||||
@@ -913,46 +1136,35 @@ bool PLY::PropertyInstance::ParseValueBinary(const char* p_szIn,const char** p_s
|
||||
|
||||
case EDT_Char:
|
||||
out->iInt = (int32_t)*((int8_t*)p_szIn);
|
||||
p_szIn += 1;
|
||||
p_szIn ++;
|
||||
break;
|
||||
|
||||
case EDT_Float:
|
||||
{
|
||||
int32_t* pf = (int32_t*)p_szIn;
|
||||
if (p_bBE)
|
||||
{
|
||||
union {char szArray[4]; float fValue; } _X;
|
||||
|
||||
_X.szArray[0] = ((unsigned char*)p_szIn)[3];
|
||||
_X.szArray[1] = ((unsigned char*)p_szIn)[2];
|
||||
_X.szArray[2] = ((unsigned char*)p_szIn)[1];
|
||||
_X.szArray[3] = ((unsigned char*)p_szIn)[0];
|
||||
out->fFloat = _X.fValue;
|
||||
ByteSwap::Swap((int32_t*)&pf);
|
||||
}
|
||||
else out->fFloat = *((float*)p_szIn);
|
||||
p_szIn += 4;
|
||||
out->fFloat = *((float*)&pf);
|
||||
break;
|
||||
|
||||
}
|
||||
case EDT_Double:
|
||||
{
|
||||
int64_t* pf = (int64_t*)p_szIn;
|
||||
if (p_bBE)
|
||||
{
|
||||
union {char szArray[8]; double fValue; } _X;
|
||||
|
||||
_X.szArray[0] = ((unsigned char*)p_szIn)[7];
|
||||
_X.szArray[1] = ((unsigned char*)p_szIn)[6];
|
||||
_X.szArray[2] = ((unsigned char*)p_szIn)[5];
|
||||
_X.szArray[3] = ((unsigned char*)p_szIn)[4];
|
||||
_X.szArray[4] = ((unsigned char*)p_szIn)[3];
|
||||
_X.szArray[5] = ((unsigned char*)p_szIn)[2];
|
||||
_X.szArray[6] = ((unsigned char*)p_szIn)[1];
|
||||
_X.szArray[7] = ((unsigned char*)p_szIn)[0];
|
||||
out->fDouble = _X.fValue;
|
||||
ByteSwap::Swap((int64_t*)&pf);
|
||||
}
|
||||
else out->fDouble = *((double*)p_szIn);
|
||||
p_szIn += 8;
|
||||
out->fDouble = *((double*)&pf);
|
||||
break;
|
||||
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
ValidateOut(p_szIn,szMax);
|
||||
*p_szOut = p_szIn;
|
||||
return true;
|
||||
}
|
||||
|
||||
+3
-3
@@ -411,7 +411,7 @@ public:
|
||||
ElementInstanceList (const Element* pc)
|
||||
{
|
||||
// reserve enough storage to speedup the process
|
||||
alInstances.reserve(pc->NumOccur);
|
||||
alInstances.resize(pc->NumOccur);
|
||||
}
|
||||
|
||||
//! Destructor. Dallocates all storage
|
||||
@@ -479,9 +479,9 @@ public:
|
||||
|
||||
//! Parse the DOM for a PLY file. The input string is assumed
|
||||
//! to be terminated with zero
|
||||
static bool ParseInstance (const char* p_szIn,DOM* p_pcOut);
|
||||
static bool ParseInstance (const char* p_szIn,DOM* p_pcOut, unsigned int iLen);
|
||||
static bool ParseInstanceBinary (const char* p_szIn,
|
||||
DOM* p_pcOut,bool p_bBE);
|
||||
DOM* p_pcOut,bool p_bBE, unsigned int iLen);
|
||||
|
||||
//! Skip all comment lines after this
|
||||
static bool SkipComments (const char* p_szIn,const char** p_szOut);
|
||||
|
||||
@@ -42,6 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
/** @file Implementation of the SplitLargeMeshes postprocessing step
|
||||
*/
|
||||
#include "SplitLargeMeshes.h"
|
||||
#include "DefaultLogger.h"
|
||||
#include "../include/aiPostProcess.h"
|
||||
#include "../include/aiMesh.h"
|
||||
#include "../include/aiScene.h"
|
||||
@@ -63,6 +64,7 @@ aiReturn aiSetVertexSplitLimit(unsigned int pLimit)
|
||||
}
|
||||
|
||||
SplitLargeMeshesProcess_Vertex::LIMIT = pLimit;
|
||||
//DefaultLogger::get()->debug("aiSetVertexSplitLimit() - vertex split limit was changed");
|
||||
return AI_SUCCESS;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -75,6 +77,7 @@ aiReturn aiSetTriangleSplitLimit(unsigned int pLimit)
|
||||
}
|
||||
|
||||
SplitLargeMeshesProcess_Triangle::LIMIT = pLimit;
|
||||
//DefaultLogger::get()->debug("aiSetTriangleSplitLimit() - triangle split limit was changed");
|
||||
return AI_SUCCESS;
|
||||
}
|
||||
}; //! extern "C"
|
||||
@@ -99,6 +102,7 @@ bool SplitLargeMeshesProcess_Triangle::IsActive( unsigned int pFlags) const
|
||||
// Executes the post processing step on the given imported data.
|
||||
void SplitLargeMeshesProcess_Triangle::Execute( aiScene* pScene)
|
||||
{
|
||||
DefaultLogger::get()->debug("SplitLargeMeshesProcess_Triangle begin");
|
||||
std::vector<std::pair<aiMesh*, unsigned int> > avList;
|
||||
|
||||
for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
|
||||
@@ -116,7 +120,9 @@ void SplitLargeMeshesProcess_Triangle::Execute( aiScene* pScene)
|
||||
|
||||
// now we need to update all nodes
|
||||
this->UpdateNode(pScene->mRootNode,avList);
|
||||
DefaultLogger::get()->info("SplitLargeMeshesProcess_Triangle finished. Meshes have been splitted");
|
||||
}
|
||||
else DefaultLogger::get()->debug("SplitLargeMeshesProcess_Triangle finished. There was nothing to do");
|
||||
return;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -160,8 +166,10 @@ void SplitLargeMeshesProcess_Triangle::SplitMesh(
|
||||
aiMesh* pMesh,
|
||||
std::vector<std::pair<aiMesh*, unsigned int> >& avList)
|
||||
{
|
||||
if (pMesh->mNumFaces > LIMIT)
|
||||
if (pMesh->mNumFaces > SplitLargeMeshesProcess_Triangle::LIMIT)
|
||||
{
|
||||
DefaultLogger::get()->info("Mesh exceeds the triangle limit. It will be split ...");
|
||||
|
||||
// we need to split this mesh into sub meshes
|
||||
// determine the size of a submesh
|
||||
const unsigned int iSubMeshes = (pMesh->mNumFaces / LIMIT) + 1;
|
||||
@@ -318,6 +326,7 @@ void SplitLargeMeshesProcess_Vertex::Execute( aiScene* pScene)
|
||||
{
|
||||
std::vector<std::pair<aiMesh*, unsigned int> > avList;
|
||||
|
||||
DefaultLogger::get()->debug("SplitLargeMeshesProcess_Vertex begin");
|
||||
for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
|
||||
this->SplitMesh(a, pScene->mMeshes[a],avList);
|
||||
|
||||
@@ -333,7 +342,9 @@ void SplitLargeMeshesProcess_Vertex::Execute( aiScene* pScene)
|
||||
|
||||
// now we need to update all nodes
|
||||
SplitLargeMeshesProcess_Triangle::UpdateNode(pScene->mRootNode,avList);
|
||||
DefaultLogger::get()->info("SplitLargeMeshesProcess_Vertex finished. Meshes have been splitted");
|
||||
}
|
||||
else DefaultLogger::get()->debug("SplitLargeMeshesProcess_Vertex finished. There was nothing to do");
|
||||
return;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -510,7 +521,8 @@ void SplitLargeMeshesProcess_Vertex::SplitMesh(
|
||||
|
||||
// now delete the old mesh data
|
||||
delete pMesh;
|
||||
return;
|
||||
}
|
||||
else avList.push_back(std::pair<aiMesh*, unsigned int>(pMesh,a));
|
||||
avList.push_back(std::pair<aiMesh*, unsigned int>(pMesh,a));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <vector>
|
||||
#include <assert.h>
|
||||
#include "TriangulateProcess.h"
|
||||
#include "DefaultLogger.h"
|
||||
#include "../include/aiPostProcess.h"
|
||||
#include "../include/aiMesh.h"
|
||||
#include "../include/aiScene.h"
|
||||
@@ -35,14 +36,33 @@ bool TriangulateProcess::IsActive( unsigned int pFlags) const
|
||||
// Executes the post processing step on the given imported data.
|
||||
void TriangulateProcess::Execute( aiScene* pScene)
|
||||
{
|
||||
DefaultLogger::get()->debug("TriangulateProcess begin");
|
||||
|
||||
bool bHas = false;
|
||||
for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
|
||||
TriangulateMesh( pScene->mMeshes[a]);
|
||||
{
|
||||
if( TriangulateMesh( pScene->mMeshes[a]))
|
||||
bHas = true;
|
||||
}
|
||||
if (bHas)DefaultLogger::get()->info("TriangulateProcess finished. Found polygons to triangulate");
|
||||
else DefaultLogger::get()->debug("TriangulateProcess finished. There was nothing to do.");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Triangulates the given mesh.
|
||||
void TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
|
||||
bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
|
||||
{
|
||||
// check whether we will need to do something ...
|
||||
for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
|
||||
{
|
||||
const aiFace& face = pMesh->mFaces[a];
|
||||
if( face.mNumIndices != 3)
|
||||
{
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<aiFace> newFaces;
|
||||
newFaces.reserve( pMesh->mNumFaces*2);
|
||||
for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
|
||||
@@ -57,7 +77,8 @@ void TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
|
||||
nface.mNumIndices = face.mNumIndices;
|
||||
nface.mIndices = new unsigned int[nface.mNumIndices];
|
||||
memcpy( nface.mIndices, face.mIndices, nface.mNumIndices * sizeof( unsigned int));
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( face.mNumIndices > 3);
|
||||
for( unsigned int b = 0; b < face.mNumIndices - 2; b++)
|
||||
@@ -80,4 +101,6 @@ void TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
|
||||
pMesh->mFaces = new aiFace[pMesh->mNumFaces];
|
||||
for( unsigned int a = 0; a < newFaces.size(); a++)
|
||||
pMesh->mFaces[a] = newFaces[a];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ protected:
|
||||
/** Triangulates the given mesh.
|
||||
* @param pMesh The mesh to triangulate.
|
||||
*/
|
||||
void TriangulateMesh( aiMesh* pMesh);
|
||||
bool TriangulateMesh( aiMesh* pMesh);
|
||||
};
|
||||
|
||||
} // end of namespace Assimp
|
||||
|
||||
@@ -561,8 +561,13 @@ void XFileImporter::ConvertMaterials( aiScene* pScene, const std::vector<XFile::
|
||||
aiString name;
|
||||
name.Set( oldMat.mName);
|
||||
mat->AddProperty( &name, AI_MATKEY_NAME);
|
||||
|
||||
// Shading model: hardcoded to PHONG, there is no such information in an XFile
|
||||
int shadeMode = (int) aiShadingMode_Phong;
|
||||
// FIX (aramis): If the specular exponent is 0, use gouraud shading. This is a bugfix
|
||||
// for some models in the SDK (e.g. good old tiny.x)
|
||||
int shadeMode = (int)oldMat.mSpecularExponent == 0.0f
|
||||
? aiShadingMode_Gouraud : aiShadingMode_Phong;
|
||||
|
||||
mat->AddProperty<int>( &shadeMode, 1, AI_MATKEY_SHADING_MODEL);
|
||||
// material colours
|
||||
mat->AddProperty( &oldMat.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE);
|
||||
|
||||
Reference in New Issue
Block a user