- changing Assimp's coordinate system from RH z-up to RH y-up
 - fixing coordinate system for LWO, 3DS, ASE, MD5, MDL, B3D, IRR, IRRMESH 
 - converttolh moved to three separate steps -> flipuv, flipwinding, makelh

LWO 
 - fixing texture coordinate generation -> mapping axis is correct now 
 - fixing z-fighting bug

ASE 
 - fixing crash due to invalid normal setup 
 - fixing parenting bug 
 - code cleanup

IRR 
 - code cleanup
 - fixing placement of externally loaded meshes 

MDL 
 - fixing texture coordinate space

PLY 
 - cleanup 
 - two-sided maat property is now set 

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@366 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
This commit is contained in:
aramis_acg
2009-03-15 00:40:30 +00:00
parent 68d7e43056
commit c2d8881549
48 changed files with 1518 additions and 1802 deletions
+4 -11
View File
@@ -774,20 +774,13 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut)
AddNodeToGraph(pcOut, pcOut->mRootNode, mRootNode,m);
}
// We used the first vertex color set to store some
// temporary values so we need to cleanup here
// We used the first vertex color set to store some emporary values so we need to cleanup here
for (unsigned int a = 0; a < pcOut->mNumMeshes;++a)
pcOut->mMeshes[a]->mColors[0] = NULL;
// if the root node has only one child ... set the child as root node
if (1 == pcOut->mRootNode->mNumChildren)
{
aiNode* pcOld = pcOut->mRootNode;
pcOut->mRootNode = pcOut->mRootNode->mChildren[0];
pcOut->mRootNode->mParent = NULL;
pcOld->mChildren[0] = NULL;
delete pcOld;
}
// Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
pcOut->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f,
0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f) * pcOut->mRootNode->mTransformation;
// If the root node is unnamed name it "<3DSRoot>"
if (::strstr( pcOut->mRootNode->mName.data, "UNNAMED" ) ||
+178 -312
View File
File diff suppressed because it is too large Load Diff
+14 -14
View File
@@ -1889,18 +1889,20 @@ void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh& sMesh)
sMesh.mNormals.resize(sMesh.mFaces.size()*3,aiVector3D( 0.f, 0.f, 0.f ));
unsigned int index, faceIdx = 0xffffffff;
// FIXME: rewrite this and find out how to interpret the normals
// correctly. This is crap.
// Smooth the vertex and face normals together. The result
// will be edgy then, but otherwise everything would be soft ...
while (true)
{
if ('*' == *filePtr)
{
while (true) {
if ('*' == *filePtr) {
++filePtr;
if (faceIdx != 0xffffffff && TokenMatch(filePtr,"MESH_VERTEXNORMAL",17))
{
if (faceIdx != 0xffffffff && TokenMatch(filePtr,"MESH_VERTEXNORMAL",17)) {
aiVector3D vNormal;
ParseLV4MeshFloatTriple(&vNormal.x,index);
if (faceIdx >= sMesh.mFaces.size())
continue;
// Make sure we assign it to the correct face
const ASE::Face& face = sMesh.mFaces[faceIdx];
if (index == face.mIndices[0])
@@ -1909,29 +1911,27 @@ void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh& sMesh)
index = 1;
else if (index == face.mIndices[2])
index = 2;
else
{
else {
DefaultLogger::get()->error("ASE: Invalid vertex index in MESH_VERTEXNORMAL section");
continue;
}
// We'll renormalize later
sMesh.mNormals[faceIdx*3+index] += vNormal;
continue;
}
if (TokenMatch(filePtr,"MESH_FACENORMAL",15))
{
if (TokenMatch(filePtr,"MESH_FACENORMAL",15)) {
aiVector3D vNormal;
ParseLV4MeshFloatTriple(&vNormal.x,faceIdx);
if (faceIdx >= sMesh.mFaces.size())
{
if (faceIdx >= sMesh.mFaces.size()) {
DefaultLogger::get()->error("ASE: Invalid vertex index in MESH_FACENORMAL section");
continue;
}
// We'll renormalize later
sMesh.mNormals[faceIdx*3] += vNormal;
sMesh.mNormals[faceIdx*3+1] += vNormal;
sMesh.mNormals[faceIdx*3+2] += vNormal;
continue;
}
}
+6 -6
View File
@@ -49,6 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// internal headers
#include "B3DImporter.h"
#include "TextureTransform.h"
#include "ConvertToLHProcess.h"
using namespace Assimp;
using namespace std;
@@ -119,11 +120,6 @@ void B3DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
//create root node
aiNode *node=new aiNode( "root" );
node->mTransformation=aiMatrix4x4(
1,0,0,0,
0,0,1,0,
0,1,0,0,
0,0,0,1 );
node->mNumMeshes=_meshes.size();
node->mMeshes=new unsigned[_meshes.size()];
@@ -131,6 +127,10 @@ void B3DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
node->mMeshes[i]=i;
}
pScene->mRootNode=node;
// convert to RH
MakeLeftHandedProcess monster_maker;
monster_maker.Execute(pScene);
}
// ------------------------------------------------------------------------------------------------
@@ -348,8 +348,8 @@ void B3DImporter::ReadTRIS(){
unsigned *ip=face->mIndices=new unsigned[3];
int v[3];
v[0]=ReadInt();
v[2]=ReadInt();
v[1]=ReadInt();
v[2]=ReadInt();
for( unsigned j=0;j<3;++j ){
int k=v[j];
const Vertex &v=_vertices[k];
+219 -161
View File
@@ -39,136 +39,220 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
/** @file Implementation of the post processing step to convert all imported data
* to a left-handed coordinate system.
/** @file MakeLeftHandedProcess.cpp
* @brief Implementation of the post processing step to convert all
* imported data to a left-handed coordinate system.
*
* Face order & UV flip are also implemented here, for the sake of a
* better location.
*/
#include "AssimpPCH.h"
#include "ConvertToLHProcess.h"
using namespace Assimp;
// The transformation matrix to convert from DirectX coordinates to OpenGL coordinates.
const aiMatrix3x3 Assimp::ConvertToLHProcess::sToOGLTransform(
1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f
);
// The transformation matrix to convert from OpenGL coordinates to DirectX coordinates.
const aiMatrix3x3 Assimp::ConvertToLHProcess::sToDXTransform(
1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f
);
#ifndef ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
ConvertToLHProcess::ConvertToLHProcess()
{
bTransformVertices = false;
}
MakeLeftHandedProcess::MakeLeftHandedProcess()
{}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
ConvertToLHProcess::~ConvertToLHProcess()
{
// nothing to do here
}
MakeLeftHandedProcess::~MakeLeftHandedProcess()
{}
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool ConvertToLHProcess::IsActive( unsigned int pFlags) const
bool MakeLeftHandedProcess::IsActive( unsigned int pFlags) const
{
if (pFlags & aiProcess_ConvertToLeftHanded)
{
bTransformVertices = (0 != (pFlags & aiProcess_PreTransformVertices) ? true : false);
return true;
}
return false;
return 0 != (pFlags & aiProcess_MakeLeftHanded);
}
// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
void ConvertToLHProcess::Execute( aiScene* pScene)
void MakeLeftHandedProcess::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;
}
ai_assert(pScene->mRootNode != NULL);
DefaultLogger::get()->debug("MakeLeftHandedProcess begin");
DefaultLogger::get()->debug("ConvertToLHProcess begin");
// recursively convert all the nodes
ProcessNode( pScene->mRootNode, aiMatrix4x4());
// transform vertex by vertex or change the root transform?
// We can't do the coordinate system transformation earlier
// in the pipeline - most steps assume that we're in OGL
// space. So we need to transform all vertices a second time
// here.
if (bTransformVertices)
{
aiMatrix4x4 mTransform;
ConvertToDX(mTransform);
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
{
aiMesh* pcMesh = pScene->mMeshes[i];
// transform all vertices
for (unsigned int n = 0; n < pcMesh->mNumVertices;++n)
pcMesh->mVertices[n] = mTransform * pcMesh->mVertices[n];
// transform all normals
if (pcMesh->HasNormals())
{
for (unsigned int n = 0; n < pcMesh->mNumVertices;++n)
pcMesh->mNormals[n] = mTransform * pcMesh->mNormals[n];
}
// transform all tangents and all bitangents
if (pcMesh->HasTangentsAndBitangents())
{
for (unsigned int n = 0; n < pcMesh->mNumVertices;++n)
{
pcMesh->mTangents[n] = mTransform * pcMesh->mTangents[n];
pcMesh->mBitangents[n] = mTransform * pcMesh->mBitangents[n];
}
}
}
}
else
{
// transform the root node of the scene, the other nodes will follow then
ConvertToDX( pScene->mRootNode->mTransformation);
}
// transform all meshes accordingly
for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
// process the meshes accordingly
for( unsigned int a = 0; a < pScene->mNumMeshes; ++a)
ProcessMesh( pScene->mMeshes[a]);
// process all materials - we need to adjust UV transformations
for( unsigned int a = 0; a < pScene->mNumMaterials; a++)
// process the materials accordingly
for( unsigned int a = 0; a < pScene->mNumMaterials; ++a)
ProcessMaterial( pScene->mMaterials[a]);
// transform all animation channels affecting the root node as well
// transform all animation channels as well
for( unsigned int a = 0; a < pScene->mNumAnimations; a++)
{
aiAnimation* anim = pScene->mAnimations[a];
for( unsigned int b = 0; b < anim->mNumChannels; b++)
{
aiNodeAnim* nodeAnim = anim->mChannels[b];
if( strcmp( nodeAnim->mNodeName.data, pScene->mRootNode->mName.data) == 0)
ProcessAnimation( nodeAnim);
ProcessAnimation( nodeAnim);
}
}
DefaultLogger::get()->debug("ConvertToLHProcess finished");
// flipping a single vector component means inverting face order ...
FlipWindingOrderProcess flipper;
flipper.Execute(pScene);
DefaultLogger::get()->debug("MakeLeftHandedProcess finished");
}
// ------------------------------------------------------------------------------------------------
// Recursively converts a node, all of its children and all of its meshes
void MakeLeftHandedProcess::ProcessNode( aiNode* pNode, const aiMatrix4x4& pParentGlobalRotation)
{
// mirror all base vectors at the local Z axis
pNode->mTransformation.c1 = -pNode->mTransformation.c1;
pNode->mTransformation.c2 = -pNode->mTransformation.c2;
pNode->mTransformation.c3 = -pNode->mTransformation.c3;
pNode->mTransformation.c4 = -pNode->mTransformation.c4;
// now invert the Z axis again to keep the matrix determinant positive.
// The local meshes will be inverted accordingly so that the result should look just fine again.
pNode->mTransformation.a3 = -pNode->mTransformation.a3;
pNode->mTransformation.b3 = -pNode->mTransformation.b3;
pNode->mTransformation.c3 = -pNode->mTransformation.c3;
pNode->mTransformation.d3 = -pNode->mTransformation.d3; // useless, but anyways...
// continue for all children
for( size_t a = 0; a < pNode->mNumChildren; ++a)
ProcessNode( pNode->mChildren[a], pParentGlobalRotation * pNode->mTransformation);
}
// ------------------------------------------------------------------------------------------------
// Converts a single mesh to left handed coordinates.
void MakeLeftHandedProcess::ProcessMesh( aiMesh* pMesh)
{
// mirror positions, normals and stuff along the Z axis
for( size_t a = 0; a < pMesh->mNumVertices; ++a)
{
pMesh->mVertices[a].z *= -1.0f;
if( pMesh->HasNormals())
pMesh->mNormals[a].z *= -1.0f;
if( pMesh->HasTangentsAndBitangents())
{
pMesh->mTangents[a].z *= -1.0f;
pMesh->mBitangents[a].z *= -1.0f;
}
}
// mirror offset matrices of all bones
for( size_t a = 0; a < pMesh->mNumBones; ++a)
{
aiBone* bone = pMesh->mBones[a];
bone->mOffsetMatrix.a3 = -bone->mOffsetMatrix.a3;
bone->mOffsetMatrix.b3 = -bone->mOffsetMatrix.b3;
bone->mOffsetMatrix.d3 = -bone->mOffsetMatrix.d3;
bone->mOffsetMatrix.c1 = -bone->mOffsetMatrix.c1;
bone->mOffsetMatrix.c2 = -bone->mOffsetMatrix.c2;
bone->mOffsetMatrix.c4 = -bone->mOffsetMatrix.c4;
}
// mirror bitangents as well as they're derived from the texture coords
if( pMesh->HasTangentsAndBitangents())
{
for( unsigned int a = 0; a < pMesh->mNumVertices; a++)
pMesh->mBitangents[a] *= -1.0f;
}
}
// ------------------------------------------------------------------------------------------------
// Converts a single material to left handed coordinates.
void ConvertToLHProcess::ProcessMaterial (aiMaterial* mat)
void MakeLeftHandedProcess::ProcessMaterial( aiMaterial* _mat)
{
for (unsigned int a = 0; a < mat->mNumProperties;++a)
{
MaterialHelper* mat = (MaterialHelper*)_mat;
for (unsigned int a = 0; a < mat->mNumProperties;++a) {
aiMaterialProperty* prop = mat->mProperties[a];
if (!::strcmp( prop->mKey.data, "$tex.uvtrafo"))
{
ai_assert( prop->mDataLength >= sizeof(aiUVTransform));
// Mapping axis for UV mappings?
if (!::strcmp( prop->mKey.data, "$tex.mapaxis")) {
ai_assert( prop->mDataLength >= sizeof(aiVector3D)); /* something is wrong with the validation if we end up here */
aiVector3D* pff = (aiVector3D*)prop->mData;
pff->z *= -1.f;
}
}
}
// ------------------------------------------------------------------------------------------------
// Converts the given animation to LH coordinates.
void MakeLeftHandedProcess::ProcessAnimation( aiNodeAnim* pAnim)
{
// position keys
for( unsigned int a = 0; a < pAnim->mNumPositionKeys; a++)
pAnim->mPositionKeys[a].mValue.z *= -1.0f;
// rotation keys
for( unsigned int a = 0; a < pAnim->mNumRotationKeys; a++)
{
/* That's the safe version, but the float errors add up. So we try the short version instead
aiMatrix3x3 rotmat = pAnim->mRotationKeys[a].mValue.GetMatrix();
rotmat.a3 = -rotmat.a3; rotmat.b3 = -rotmat.b3;
rotmat.c1 = -rotmat.c1; rotmat.c2 = -rotmat.c2;
aiQuaternion rotquat( rotmat);
pAnim->mRotationKeys[a].mValue = rotquat;
*/
pAnim->mRotationKeys[a].mValue.x *= -1.0f;
pAnim->mRotationKeys[a].mValue.y *= -1.0f;
}
}
#endif // !! ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS
#ifndef ASSIMP_BUILD_NO_FLIPUVS_PROCESS
// # FlipUVsProcess
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
FlipUVsProcess::FlipUVsProcess()
{}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
FlipUVsProcess::~FlipUVsProcess()
{}
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool FlipUVsProcess::IsActive( unsigned int pFlags) const
{
return 0 != (pFlags & aiProcess_FlipUVs);
}
// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
void FlipUVsProcess::Execute( aiScene* pScene)
{
DefaultLogger::get()->debug("FlipUVsProcess begin");
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
ProcessMesh(pScene->mMeshes[i]);
for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
ProcessMaterial(pScene->mMaterials[i]);
DefaultLogger::get()->debug("FlipUVsProcess finished");
}
// ------------------------------------------------------------------------------------------------
// Converts a single material
void FlipUVsProcess::ProcessMaterial (aiMaterial* _mat)
{
MaterialHelper* mat = (MaterialHelper*)_mat;
for (unsigned int a = 0; a < mat->mNumProperties;++a) {
aiMaterialProperty* prop = mat->mProperties[a];
// UV transformation key?
if (!::strcmp( prop->mKey.data, "$tex.uvtrafo")) {
ai_assert( prop->mDataLength >= sizeof(aiUVTransform)); /* something is wrong with the validation if we end up here */
aiUVTransform* uv = (aiUVTransform*)prop->mData;
// just flip it, that's everything
@@ -179,8 +263,53 @@ void ConvertToLHProcess::ProcessMaterial (aiMaterial* mat)
}
// ------------------------------------------------------------------------------------------------
// Converts a single mesh to left handed coordinates.
void ConvertToLHProcess::ProcessMesh( aiMesh* pMesh)
// Converts a single mesh
void FlipUVsProcess::ProcessMesh( aiMesh* pMesh)
{
// mirror texture y coordinate
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
if( !pMesh->HasTextureCoords( a))
break;
for( unsigned int b = 0; b < pMesh->mNumVertices; b++)
pMesh->mTextureCoords[a][b].y = 1.0f - pMesh->mTextureCoords[a][b].y;
}
}
#endif // !ASSIMP_BUILD_NO_FLIPUVS_PROCESS
#ifndef ASSIMP_BUILD_NO_FLIPWINDING_PROCESS
// # FlipWindingOrderProcess
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
FlipWindingOrderProcess::FlipWindingOrderProcess()
{}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
FlipWindingOrderProcess::~FlipWindingOrderProcess()
{}
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool FlipWindingOrderProcess::IsActive( unsigned int pFlags) const
{
return 0 != (pFlags & aiProcess_FlipWindingOrder);
}
// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
void FlipWindingOrderProcess::Execute( aiScene* pScene)
{
DefaultLogger::get()->debug("FlipWindingOrderProcess begin");
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
ProcessMesh(pScene->mMeshes[i]);
DefaultLogger::get()->debug("FlipWindingOrderProcess finished");
}
// ------------------------------------------------------------------------------------------------
// Converts a single mesh
void FlipWindingOrderProcess::ProcessMesh( aiMesh* pMesh)
{
// invert the order of all faces in this mesh
for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
@@ -189,77 +318,6 @@ void ConvertToLHProcess::ProcessMesh( aiMesh* pMesh)
for( unsigned int b = 0; b < face.mNumIndices / 2; b++)
std::swap( face.mIndices[b], face.mIndices[ face.mNumIndices - 1 - b]);
}
// mirror texture y coordinate
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++)
{
if( pMesh->HasTextureCoords( a))
{
for( unsigned int b = 0; b < pMesh->mNumVertices; b++)
pMesh->mTextureCoords[a][b].y = 1.0f - pMesh->mTextureCoords[a][b].y;
}
}
// mirror bitangents as well as they're derived from the texture coords
if( pMesh->HasTangentsAndBitangents())
{
for( unsigned int a = 0; a < pMesh->mNumVertices; a++)
pMesh->mBitangents[a] = -pMesh->mBitangents[a];
}
}
// ------------------------------------------------------------------------------------------------
// Converts the given animation to LH coordinates.
void ConvertToLHProcess::ProcessAnimation( aiNodeAnim* pAnim)
{
// position keys
for( unsigned int a = 0; a < pAnim->mNumPositionKeys; a++)
ConvertToDX( pAnim->mPositionKeys[a].mValue);
return;
// rotation keys
for( unsigned int a = 0; a < pAnim->mNumRotationKeys; a++)
{
aiMatrix3x3 rotmat = pAnim->mRotationKeys[a].mValue.GetMatrix();
ConvertToDX( rotmat);
pAnim->mRotationKeys[a].mValue = aiQuaternion( rotmat);
}
}
// ------------------------------------------------------------------------------------------------
// Static helper function to convert a vector/matrix from DX to OGL coords
void ConvertToLHProcess::ConvertToOGL( aiVector3D& poVector)
{
poVector = sToOGLTransform * poVector;
}
// ------------------------------------------------------------------------------------------------
void ConvertToLHProcess::ConvertToOGL( aiMatrix3x3& poMatrix)
{
poMatrix = sToOGLTransform * poMatrix;
}
// ------------------------------------------------------------------------------------------------
void ConvertToLHProcess::ConvertToOGL( aiMatrix4x4& poMatrix)
{
poMatrix = aiMatrix4x4( sToOGLTransform) * poMatrix;
}
// ------------------------------------------------------------------------------------------------
// Static helper function to convert a vector/matrix from OGL back to DX coords
void ConvertToLHProcess::ConvertToDX( aiVector3D& poVector)
{
poVector = sToDXTransform * poVector;
}
// ------------------------------------------------------------------------------------------------
void ConvertToLHProcess::ConvertToDX( aiMatrix3x3& poMatrix)
{
poMatrix = sToDXTransform * poMatrix;
}
// ------------------------------------------------------------------------------------------------
void ConvertToLHProcess::ConvertToDX( aiMatrix4x4& poMatrix)
{
poMatrix = aiMatrix4x4(sToDXTransform) * poMatrix;
}
#endif // !! ASSIMP_BUILD_NO_FLIPWINDING_PROCESS
+80 -50
View File
@@ -38,7 +38,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/** @file Defines a post processing step to convert all data to a left-handed coordinate system.*/
/** @file MakeLeftHandedProcess.h
* @brief Defines a bunch of post-processing steps to handle
* coordinate system conversions.
*
* - LH to RH
* - UV origin upper-left to lower-left
* - face order cw to ccw
*/
#ifndef AI_CONVERTTOLHPROCESS_H_INC
#define AI_CONVERTTOLHPROCESS_H_INC
@@ -48,72 +55,55 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct aiMesh;
struct aiNodeAnim;
namespace Assimp
{
namespace Assimp {
// ---------------------------------------------------------------------------
/** The ConvertToLHProcess converts all imported data to a left-handed coordinate
* system. This implies inverting the Z axis for all transformation matrices
* invert the orientation of all faces, and adapting skinning and animation
* data in a similar way.
// -----------------------------------------------------------------------------------
/** @brief The MakeLeftHandedProcess converts all imported data to a left-handed
* coordinate system.
*
* This implies a mirroring of the Z axis of the coordinate system. But to keep
* transformation matrices free from reflections we shift the reflection to other
* places. We mirror the meshes and adapt the rotations.
*
* @note RH-LH and LH-RH is the same, so this class can be used for both
*/
class ASSIMP_API ConvertToLHProcess : public BaseProcess
class ASSIMP_API MakeLeftHandedProcess : public BaseProcess
{
friend class Importer;
protected:
public:
/** Constructor to be privately used by Importer */
ConvertToLHProcess();
MakeLeftHandedProcess();
/** Destructor, private as well */
~ConvertToLHProcess();
~MakeLeftHandedProcess();
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);
// -------------------------------------------------------------------
/** Static helper function to convert a vector/matrix from DX coords to OGL coords.
* @param poMatrix The matrix to convert.
*/
static void ConvertToOGL( aiVector3D& poVector);
static void ConvertToOGL( aiMatrix3x3& poMatrix);
static void ConvertToOGL( aiMatrix4x4& poMatrix);
// -------------------------------------------------------------------
/** Static helper function to convert a vector/matrix from OGL coords back to DX coords.
* @param poMatrix The matrix to convert.
*/
static void ConvertToDX( aiVector3D& poVector);
static void ConvertToDX( aiMatrix3x3& poMatrix);
static void ConvertToDX( aiMatrix4x4& poMatrix);
protected:
// -------------------------------------------------------------------
/** Recursively converts a node and all of its children
*/
void ProcessNode( aiNode* pNode, const aiMatrix4x4& pParentGlobalRotation);
// -------------------------------------------------------------------
/** Converts a single mesh to left handed coordinates.
* This simply means the order of all faces is inverted.
* This means that positions, normals and tangents are mirrored at
* the local Z axis and the order of all faces are inverted.
* @param pMesh The mesh to convert.
*/
void ProcessMesh( aiMesh* pMesh);
// -------------------------------------------------------------------
/** Converts a single material to left handed coordinates.
* This simply means all UV offsets are inverted.
* @param mat The material to convert.
/** Converts a single material to left-handed coordinates
* @param pMat Material to convert
*/
void ProcessMaterial (aiMaterial* mat);
void ProcessMaterial( aiMaterial* pMat);
// -------------------------------------------------------------------
/** Converts the given animation to LH coordinates.
@@ -122,16 +112,56 @@ protected:
* @param pAnim The bone animation to transform
*/
void ProcessAnimation( aiNodeAnim* pAnim);
};
//! true if the transformation matrix for the OGL-to-DX is
//! directly used to transform all vertices.
mutable bool bTransformVertices;
// ---------------------------------------------------------------------------
/** Postprocessing step to flip the face order of the imported data
*/
class ASSIMP_API FlipWindingOrderProcess : public BaseProcess
{
friend class Importer;
public:
/** The transformation matrix to convert from DirectX coordinates to OpenGL coordinates. */
static const aiMatrix3x3 sToOGLTransform;
/** The transformation matrix to convert from OpenGL coordinates to DirectX coordinates. */
static const aiMatrix3x3 sToDXTransform;
/** Constructor to be privately used by Importer */
FlipWindingOrderProcess();
/** Destructor, private as well */
~FlipWindingOrderProcess();
// -------------------------------------------------------------------
bool IsActive( unsigned int pFlags) const;
// -------------------------------------------------------------------
void Execute( aiScene* pScene);
protected:
void ProcessMesh( aiMesh* pMesh);
};
// ---------------------------------------------------------------------------
/** Postprocessing step to flip the UV coordinate system of the import data
*/
class ASSIMP_API FlipUVsProcess : public BaseProcess
{
friend class Importer;
public:
/** Constructor to be privately used by Importer */
FlipUVsProcess();
/** Destructor, private as well */
~FlipUVsProcess();
// -------------------------------------------------------------------
bool IsActive( unsigned int pFlags) const;
// -------------------------------------------------------------------
void Execute( aiScene* pScene);
protected:
void ProcessMesh( aiMesh* pMesh);
void ProcessMaterial( aiMaterial* mat);
};
} // end of namespace Assimp
+61 -98
View File
@@ -84,16 +84,12 @@ aiColor4D g_clrInvalid = aiColor4D(get_qnan(),0.f,0.f,1.f);
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
DXFImporter::DXFImporter()
{
// nothing to do here
}
{}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
DXFImporter::~DXFImporter()
{
// nothing to do here
}
{}
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
@@ -103,6 +99,7 @@ bool DXFImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
}
// ------------------------------------------------------------------------------------------------
// Get a list of all supported file extensions
void DXFImporter::GetExtensionList(std::string& append)
{
append.append("*.dxf");
@@ -115,8 +112,7 @@ bool DXFImporter::GetNextLine()
if(!SkipLine(&buffer))
return false;
if(!SkipSpaces(&buffer))return GetNextLine();
else if (*buffer == '{')
{
else if (*buffer == '{') {
// some strange meta data ...
while (true)
{
@@ -135,8 +131,7 @@ bool DXFImporter::GetNextLine()
// Get the next token in the file
bool DXFImporter::GetNextToken()
{
if (bRepeat)
{
if (bRepeat) {
bRepeat = false;
return true;
}
@@ -181,26 +176,23 @@ void DXFImporter::InternReadFile( const std::string& pFile,
throw new ImportErrorException("DXF: Binary files are not supported at the moment");
// now get all lines of the file
while (GetNextToken())
{
if (2 == groupCode)
{
while (GetNextToken()) {
if (2 == groupCode) {
// ENTITIES and BLOCKS sections - skip the whole rest, no need to waste our time with them
if (!::strcmp(cursor,"ENTITIES") || !::strcmp(cursor,"BLOCKS"))
if (!ParseEntities())break; else bRepeat = true;
// other sections - skip them to make sure there will be no name conflicts
else
{
while (GetNextToken())
{
else {
while (GetNextToken()) {
if (!groupCode && !::strcmp(cursor,"ENDSEC"))break;
}
}
}
// print comment strings
else if (999 == groupCode)
{
else if (999 == groupCode) {
DefaultLogger::get()->info(std::string( cursor ));
}
else if (!groupCode && !::strcmp(cursor,"EOF"))
@@ -208,9 +200,7 @@ void DXFImporter::InternReadFile( const std::string& pFile,
}
// find out how many valud layers we have
for (std::vector<LayerInfo>::const_iterator it = mLayers.begin(),end = mLayers.end();
it != end;++it)
{
for (std::vector<LayerInfo>::const_iterator it = mLayers.begin(),end = mLayers.end(); it != end;++it) {
if (!(*it).vPositions.empty())++pScene->mNumMeshes;
}
@@ -219,11 +209,10 @@ void DXFImporter::InternReadFile( const std::string& pFile,
pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes ];
m = 0;
for (std::vector<LayerInfo>::const_iterator it = mLayers.begin(),end = mLayers.end();
it != end;++it)
{
if ((*it).vPositions.empty())continue;
for (std::vector<LayerInfo>::const_iterator it = mLayers.begin(),end = mLayers.end();it != end;++it) {
if ((*it).vPositions.empty()) {
continue;
}
// generate the output mesh
aiMesh* pMesh = pScene->mMeshes[m++] = new aiMesh();
const std::vector<aiVector3D>& vPositions = (*it).vPositions;
@@ -232,11 +221,9 @@ void DXFImporter::InternReadFile( const std::string& pFile,
// check whether we need vertex colors here
aiColor4D* clrOut = NULL;
const aiColor4D* clr = NULL;
for (std::vector<aiColor4D>::const_iterator it2 = (*it).vColors.begin(), end2 = (*it).vColors.end();
it2 != end2; ++it2)
{
if ((*it2).r == (*it2).r) // check against qnan
{
for (std::vector<aiColor4D>::const_iterator it2 = (*it).vColors.begin(), end2 = (*it).vColors.end();it2 != end2; ++it2) {
if ((*it2).r == (*it2).r) /* qnan? */ {
clrOut = pMesh->mColors[0] = new aiColor4D[vPositions.size()];
for (unsigned int i = 0; i < vPositions.size();++i)
clrOut[i] = aiColor4D(0.6f,0.6f,0.6f,1.0f);
@@ -252,30 +239,25 @@ void DXFImporter::InternReadFile( const std::string& pFile,
aiVector3D* vpOut = pMesh->mVertices = new aiVector3D[vPositions.size()];
const aiVector3D* vp = &vPositions[0];
for (unsigned int i = 0; i < pMesh->mNumFaces;++i)
{
for (unsigned int i = 0; i < pMesh->mNumFaces;++i) {
aiFace& face = pMesh->mFaces[i];
// check whether we need four, three or two indices here
if (vp[1] == vp[2])
{
if (vp[1] == vp[2]) {
face.mNumIndices = 2;
}
else if (vp[3] == vp[2])
{
else if (vp[3] == vp[2]) {
face.mNumIndices = 3;
}
else face.mNumIndices = 4;
face.mIndices = new unsigned int[face.mNumIndices];
for (unsigned int a = 0; a < face.mNumIndices;++a)
{
for (unsigned int a = 0; a < face.mNumIndices;++a) {
*vpOut++ = vp[a];
if (clr)
{
if (is_not_qnan( clr[a].r ))
if (clr) {
if (is_not_qnan( clr[a].r )) {
*clrOut = clr[a];
}
++clrOut;
}
face.mIndices[a] = pMesh->mNumVertices++;
@@ -288,16 +270,14 @@ void DXFImporter::InternReadFile( const std::string& pFile,
pScene->mRootNode = new aiNode();
pScene->mRootNode->mName.Set("<DXF_ROOT>");
if (1 == pScene->mNumMeshes)
{
if (1 == pScene->mNumMeshes) {
pScene->mRootNode->mMeshes = new unsigned int[ pScene->mRootNode->mNumMeshes = 1 ];
pScene->mRootNode->mMeshes[0] = 0;
}
else
{
pScene->mRootNode->mChildren = new aiNode*[ pScene->mRootNode->mNumChildren = pScene->mNumMeshes ];
for (m = 0; m < pScene->mRootNode->mNumChildren;++m)
{
for (m = 0; m < pScene->mRootNode->mNumChildren;++m) {
aiNode* p = pScene->mRootNode->mChildren[m] = new aiNode();
p->mName.length = ::strlen( mLayers[m].name );
::strcpy(p->mName.data, mLayers[m].name);
@@ -333,10 +313,8 @@ void DXFImporter::InternReadFile( const std::string& pFile,
// ------------------------------------------------------------------------------------------------
bool DXFImporter::ParseEntities()
{
while (GetNextToken())
{
if (!groupCode)
{
while (GetNextToken()) {
if (!groupCode) {
if (!::strcmp(cursor,"3DFACE") || !::strcmp(cursor,"LINE") || !::strcmp(cursor,"3DLINE"))
if (!Parse3DFace()) return false; else bRepeat = true;
@@ -353,17 +331,13 @@ bool DXFImporter::ParseEntities()
// ------------------------------------------------------------------------------------------------
void DXFImporter::SetLayer(LayerInfo*& out)
{
for (std::vector<LayerInfo>::iterator it = mLayers.begin(),end = mLayers.end();
it != end;++it)
{
if (!::strcmp( (*it).name, cursor ))
{
for (std::vector<LayerInfo>::iterator it = mLayers.begin(),end = mLayers.end();it != end;++it) {
if (!::strcmp( (*it).name, cursor )) {
out = &(*it);
break;
}
}
if (!out)
{
if (!out) {
// we don't have this layer yet
mLayers.push_back(LayerInfo());
out = &mLayers.back();
@@ -374,8 +348,7 @@ void DXFImporter::SetLayer(LayerInfo*& out)
// ------------------------------------------------------------------------------------------------
void DXFImporter::SetDefaultLayer(LayerInfo*& out)
{
if (!mDefaultLayer)
{
if (!mDefaultLayer) {
mLayers.push_back(LayerInfo());
mDefaultLayer = &mLayers.back();
}
@@ -393,27 +366,22 @@ bool DXFImporter::ParsePolyLine()
std::vector<unsigned int> indices;
unsigned int flags = 0;
while (GetNextToken())
{
while (GetNextToken()) {
switch (groupCode)
{
case 0:
{
if (!::strcmp(cursor,"VERTEX"))
{
if (!::strcmp(cursor,"VERTEX")) {
aiVector3D v;aiColor4D clr(g_clrInvalid);
unsigned int idx[4] = {0xffffffff,0xffffffff,0xffffffff,0xffffffff};
ParsePolyLineVertex(v, clr, idx);
if (0xffffffff == idx[0])
{
if (0xffffffff == idx[0]) {
positions.push_back(v);
colors.push_back(clr);
}
else
{
else {
// check whether we have a fourth coordinate
if (0xffffffff == idx[3])
{
if (0xffffffff == idx[3]) {
idx[3] = idx[2];
}
@@ -423,8 +391,7 @@ bool DXFImporter::ParsePolyLine()
}
bRepeat = true;
}
else if (!::strcmp(cursor,"ENDSEQ"))
{
else if (!::strcmp(cursor,"ENDSEQ")) {
ret = true;
}
break;
@@ -433,8 +400,7 @@ bool DXFImporter::ParsePolyLine()
// flags --- important that we know whether it is a polyface mesh
case 70:
{
if (!flags)
{
if (!flags) {
flags = strtol10(cursor);
}
break;
@@ -462,32 +428,29 @@ bool DXFImporter::ParsePolyLine()
}
}
}
if (!(flags & 64))
{
if (!(flags & 64)) {
DefaultLogger::get()->warn("DXF: Only polyface meshes are currently supported");
return ret;
}
if (positions.size() < 3 || indices.size() < 3)
{
if (positions.size() < 3 || indices.size() < 3) {
DefaultLogger::get()->warn("DXF: Unable to parse POLYLINE element - not enough vertices");
return ret;
}
// use a default layer if necessary
if (!out)SetDefaultLayer(out);
if (!out) {
SetDefaultLayer(out);
}
flags = (unsigned int)(out->vPositions.size()+indices.size());
out->vPositions.reserve(flags);
out->vColors.reserve(flags);
// generate unique vertices
for (std::vector<unsigned int>::const_iterator it = indices.begin(), end = indices.end();
it != end; ++it)
{
for (std::vector<unsigned int>::const_iterator it = indices.begin(), end = indices.end();it != end; ++it) {
unsigned int idx = *it;
if (idx > positions.size() || !idx)
{
if (idx > positions.size() || !idx) {
DefaultLogger::get()->error("DXF: Polyface mesh index os out of range");
idx = (unsigned int) positions.size();
}
@@ -502,11 +465,11 @@ bool DXFImporter::ParsePolyLine()
bool DXFImporter::ParsePolyLineVertex(aiVector3D& out,aiColor4D& clr, unsigned int* outIdx)
{
bool ret = false;
while (GetNextToken())
{
while (GetNextToken()) {
switch (groupCode)
{
case 0: ret = true;break;
case 0: ret = true;
break;
// todo - handle the correct layer for the vertex
// At the moment it is assumed that all vertices of
@@ -530,7 +493,9 @@ bool DXFImporter::ParsePolyLineVertex(aiVector3D& out,aiColor4D& clr, unsigned i
// color
case 62: clr = g_aclrDxfIndexColors[strtol10(cursor) % AI_DXF_NUM_INDEX_COLORS]; break;
};
if (ret)break;
if (ret) {
break;
}
}
return ret;
}
@@ -547,15 +512,12 @@ bool DXFImporter::Parse3DFace()
// this is also used for for parsing line entities
bool bThird = false;
while (GetNextToken())
{
switch (groupCode)
{
while (GetNextToken()) {
switch (groupCode) {
case 0: ret = true;break;
// 8 specifies the layer
case 8:
{
case 8: {
SetLayer(out);
break;
}
@@ -611,8 +573,9 @@ bool DXFImporter::Parse3DFace()
if (!bThird)vip[2] = vip[1];
// use a default layer if necessary
if (!out)SetDefaultLayer(out);
if (!out) {
SetDefaultLayer(out);
}
// add the faces to the face list for this layer
out->vPositions.push_back(vip[0]);
out->vPositions.push_back(vip[1]);
+157 -334
View File
@@ -70,16 +70,12 @@ using namespace boost::math;
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
IRRImporter::IRRImporter()
{
// nothing to do here
}
{}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
IRRImporter::~IRRImporter()
{
// nothing to do here
}
{}
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
@@ -174,17 +170,14 @@ aiMesh* IRRImporter::BuildSingleQuadMesh(const SkyboxVertex& v1,
*vec++ = v2.uv;
*vec++ = v3.uv;
*vec = v4.uv;
return out;
}
// ------------------------------------------------------------------------------------------------
void IRRImporter::BuildSkybox(std::vector<aiMesh*>& meshes, std::vector<aiMaterial*> materials)
{
// Update the material of the skybox - replace the name
// and disable shading for skyboxes.
for (unsigned int i = 0; i < 6;++i)
{
// Update the material of the skybox - replace the name and disable shading for skyboxes.
for (unsigned int i = 0; i < 6;++i) {
MaterialHelper* out = ( MaterialHelper* ) (*(materials.end()-(6-i)));
aiString s;
@@ -256,8 +249,7 @@ void IRRImporter::CopyMaterial(std::vector<aiMaterial*>& materials,
unsigned int& defMatIdx,
aiMesh* mesh)
{
if (inmaterials.empty())
{
if (inmaterials.empty()) {
// Do we have a default material? If not we need to create one
if (0xffffffff == defMatIdx)
{
@@ -274,8 +266,7 @@ void IRRImporter::CopyMaterial(std::vector<aiMaterial*>& materials,
mesh->mMaterialIndex = defMatIdx;
return;
}
else if (inmaterials.size() > 1)
{
else if (inmaterials.size() > 1) {
DefaultLogger::get()->info("IRR: Skipping additional materials");
}
@@ -307,24 +298,20 @@ void IRRImporter::ComputeAnimations(Node* root, aiNode* real, std::vector<aiNode
{
ai_assert(NULL != root && NULL != real);
if (root->animators.empty())return;
// const aiMatrix4x4& transform = real->mTransformation;
if (root->animators.empty()) {
return;
}
unsigned int total = 0;
for (std::list<Animator>::iterator it = root->animators.begin();
it != root->animators.end(); ++it)
{
if ((*it).type == Animator::UNKNOWN || (*it).type == Animator::OTHER)
{
for (std::list<Animator>::iterator it = root->animators.begin();it != root->animators.end(); ++it) {
if ((*it).type == Animator::UNKNOWN || (*it).type == Animator::OTHER) {
DefaultLogger::get()->warn("IRR: Skipping unknown or unsupported animator");
continue;
}
++total;
}
if (!total)return;
else if (1 == total)
{
DefaultLogger::get()->warn("IRR: Generating dummy nodes to simulate multiple animators");
else if (1 == total) {
DefaultLogger::get()->warn("IRR: Adding dummy nodes to simulate multiple animators");
}
// NOTE: 1 tick == i millisecond
@@ -338,8 +325,7 @@ void IRRImporter::ComputeAnimations(Node* root, aiNode* real, std::vector<aiNode
Animator& in = *it ;
aiNodeAnim* anim = new aiNodeAnim();
if (cur != total-1)
{
if (cur != total-1) {
// Build a new name - a prefix instead of a suffix because it is
// easier to check against
anim->mNodeName.length = ::sprintf(anim->mNodeName.data,
@@ -367,8 +353,7 @@ void IRRImporter::ComputeAnimations(Node* root, aiNode* real, std::vector<aiNode
else anim->mNodeName.Set(root->name);
++cur;
switch (in.type)
{
switch (in.type) {
case Animator::ROTATION:
{
// -----------------------------------------------------
@@ -463,8 +448,7 @@ void IRRImporter::ComputeAnimations(Node* root, aiNode* real, std::vector<aiNode
// from Irrlicht, what else should we do than copying it?
aiVector3D vecU,vecV;
if (in.direction.y)
{
if (in.direction.y) {
vecV = aiVector3D(50,0,0) ^ in.direction;
}
else vecV = aiVector3D(0,50,00) ^ in.direction;
@@ -472,8 +456,7 @@ void IRRImporter::ComputeAnimations(Node* root, aiNode* real, std::vector<aiNode
vecU = (vecV ^ in.direction).Normalize();
// build the output keys
for (unsigned int i = 0; i < anim->mNumPositionKeys;++i)
{
for (unsigned int i = 0; i < anim->mNumPositionKeys;++i) {
aiVectorKey& key = anim->mPositionKeys[i];
key.mTime = i * tdelta;
@@ -502,8 +485,7 @@ void IRRImporter::ComputeAnimations(Node* root, aiNode* real, std::vector<aiNode
const double timeFactor = lengthOfWay / in.timeForWay;
// build the output keys
for (unsigned int i = 0; i < anim->mNumPositionKeys;++i)
{
for (unsigned int i = 0; i < anim->mNumPositionKeys;++i) {
aiVectorKey& key = anim->mPositionKeys[i];
key.mTime = i * tdelta;
key.mValue = in.circleCenter + diff * float(timeFactor * key.mTime);
@@ -516,16 +498,14 @@ void IRRImporter::ComputeAnimations(Node* root, aiNode* real, std::vector<aiNode
// repeat outside the defined time range
anim->mPostState = anim->mPreState = aiAnimBehaviour_REPEAT;
const int size = (int)in.splineKeys.size();
if (!size)
{
if (!size) {
// We have no point in the spline. That's bad. Really bad.
DefaultLogger::get()->warn("IRR: Spline animators with no points defined");
delete anim;anim = NULL;
break;
}
else if (size == 1)
{
else if (size == 1) {
// We have just one point in the spline so we don't need the full calculation
anim->mNumPositionKeys = 1;
anim->mPositionKeys = new aiVectorKey[anim->mNumPositionKeys];
@@ -576,8 +556,7 @@ void IRRImporter::ComputeAnimations(Node* root, aiNode* real, std::vector<aiNode
}
break;
};
if (anim)
{
if (anim) {
anims.push_back(anim);
++total;
}
@@ -598,8 +577,7 @@ void SetupMapping (MaterialHelper* mat, aiTextureMapping mode, const aiVector3D&
for (unsigned int i = 0; i < mat->mNumProperties;++i)
{
aiMaterialProperty* prop = mat->mProperties[i];
if (!::strcmp( prop->mKey.data, "$tex.file"))
{
if (!::strcmp( prop->mKey.data, "$tex.file")) {
// Setup the mapping key
aiMaterialProperty* m = new aiMaterialProperty();
m->mKey.Set("$tex.mapping");
@@ -615,9 +593,7 @@ void SetupMapping (MaterialHelper* mat, aiTextureMapping mode, const aiVector3D&
p.push_back(m);
// Setup the mapping axis
if (mode == aiTextureMapping_CYLINDER || mode == aiTextureMapping_PLANE ||
mode == aiTextureMapping_SPHERE)
{
if (mode == aiTextureMapping_CYLINDER || mode == aiTextureMapping_PLANE || mode == aiTextureMapping_SPHERE) {
m = new aiMaterialProperty();
m->mKey.Set("$tex.mapaxis");
m->mIndex = prop->mIndex;
@@ -674,63 +650,24 @@ void IRRImporter::GenerateGraph(Node* root,aiNode* rootOut ,aiScene* scene,
// the list of all scenes to be attached to the
// graph we're currently building
aiScene* scene = batch.GetImport(root->id);
if (!scene)
{
DefaultLogger::get()->error("IRR: Unable to load external file: "
+ root->meshPath);
if (!scene) {
DefaultLogger::get()->error("IRR: Unable to load external file: " + root->meshPath);
break;
}
attach.push_back(AttachmentInfo(scene,rootOut));
#if 0 /* currently unused */
meshTrafoAssign = 1;
// If the root node of the scene is animated - and *this* node
// is animated, too, we need to insert a dummy node into the
// hierarchy in order to avoid interferences with animations
for (unsigned int i = 0; i < scene->mNumAnimations;++i)
{
aiAnimation* anim = scene->mAnimations[i];
for (unsigned int a = 0; a < anim->mNumChannels;++a) {
if (scene->mRootNode->mName == anim->mChannels[a]->mNodeName) {
if (root->animators.empty()) {
meshTrafoAssign = 2;
}
else {
meshTrafoAssign = 3;
aiNode* dummy = new aiNode();
dummy->mName.Set("$CSpaceSeam$");
dummy->mNumChildren = 1;
dummy->mChildren = new aiNode*[1];
dummy->mChildren[0] = scene->mRootNode;
scene->mRootNode->mParent = dummy;
scene->mRootNode = dummy;
scene->mRootNode->mTransformation = AI_TO_IRR_MATRIX;
}
break;
}
}
}
#endif
// if (1 == meshTrafoAssign)
// scene->mRootNode->mTransformation = AI_TO_IRR_MATRIX * scene->mRootNode->mTransformation;
// Now combine the material we've loaded for this mesh
// with the real materials we got from the file. As we
// don't execute any pp-steps on the file, the numbers
// should be equal. If they are not, we can impossibly
// do this ...
if (root->materials.size() != (unsigned int)scene->mNumMaterials)
{
if (root->materials.size() != (unsigned int)scene->mNumMaterials) {
DefaultLogger::get()->warn("IRR: Failed to match imported materials "
"with the materials found in the IRR scene file");
break;
}
for (unsigned int i = 0; i < scene->mNumMaterials;++i)
{
for (unsigned int i = 0; i < scene->mNumMaterials;++i) {
// Delete the old material, we don't need it anymore
delete scene->mMaterials[i];
@@ -741,8 +678,7 @@ void IRRImporter::GenerateGraph(Node* root,aiNode* rootOut ,aiScene* scene,
// NOTE: Each mesh should have exactly one material assigned,
// but we do it in a separate loop if this behaviour changes
// in future.
for (unsigned int i = 0; i < scene->mNumMeshes;++i)
{
for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
// Process material flags
aiMesh* mesh = scene->mMeshes[i];
@@ -751,25 +687,21 @@ void IRRImporter::GenerateGraph(Node* root,aiNode* rootOut ,aiScene* scene,
// and check whether they have a common alpha value. This is quite
// often the case so we can simply extract it to a shared oacity
// value.
std::pair<aiMaterial*, unsigned int>& src = root->materials[
mesh->mMaterialIndex];
std::pair<aiMaterial*, unsigned int>& src = root->materials[mesh->mMaterialIndex];
MaterialHelper* mat = (MaterialHelper*)src.first;
if (mesh->HasVertexColors(0) && src.second & AI_IRRMESH_MAT_trans_vertex_alpha)
{
bool bdo = true;
for (unsigned int a = 1; a < mesh->mNumVertices;++a)
{
if (mesh->mColors[0][a].a != mesh->mColors[0][a-1].a)
{
for (unsigned int a = 1; a < mesh->mNumVertices;++a) {
if (mesh->mColors[0][a].a != mesh->mColors[0][a-1].a) {
bdo = false;
break;
}
}
if (bdo)
{
DefaultLogger::get()->info("IRR: Replacing mesh vertex "
"alpha with common opacity");
if (bdo) {
DefaultLogger::get()->info("IRR: Replacing mesh vertex alpha with common opacity");
for (unsigned int a = 0; a < mesh->mNumVertices;++a)
mesh->mColors[0][a].a = 1.f;
@@ -782,8 +714,8 @@ void IRRImporter::GenerateGraph(Node* root,aiNode* rootOut ,aiScene* scene,
// (either lightmap, normalmap, 2layered material) we need to
// setup the correct UV index for it. The texture can either
// be diffuse (lightmap & 2layer) or a normal map (normal & parallax)
if (mesh->HasTextureCoords(1))
{
if (mesh->HasTextureCoords(1)) {
int idx = 1;
if (src.second & (AI_IRRMESH_MAT_solid_2layer | AI_IRRMESH_MAT_lightmap)) {
mat->AddProperty(&idx,1,AI_MATKEY_UVWSRC_DIFFUSE(0));
@@ -852,11 +784,8 @@ void IRRImporter::GenerateGraph(Node* root,aiNode* rootOut ,aiScene* scene,
case Node::SKYBOX:
{
// A skybox is defined by six materials
if (root->materials.size() < 6)
{
DefaultLogger::get()->error("IRR: There should be six materials "
"for a skybox");
if (root->materials.size() < 6) {
DefaultLogger::get()->error("IRR: There should be six materials for a skybox");
break;
}
@@ -888,8 +817,8 @@ void IRRImporter::GenerateGraph(Node* root,aiNode* rootOut ,aiScene* scene,
// Check whether we added a mesh (or more than one ...). In this case
// we'll also need to attach it to the node
if (oldMeshSize != (unsigned int) meshes.size())
{
if (oldMeshSize != (unsigned int) meshes.size()) {
rootOut->mNumMeshes = (unsigned int)meshes.size() - oldMeshSize;
rootOut->mMeshes = new unsigned int[rootOut->mNumMeshes];
@@ -904,7 +833,7 @@ void IRRImporter::GenerateGraph(Node* root,aiNode* rootOut ,aiScene* scene,
// Now compute the final local transformation matrix of the
// node from the given translation, rotation and scaling values.
// (the rotation is given in Euler angles, XYZ order)
std::swap((float&)root->rotation.z,(float&)root->rotation.y);
//std::swap((float&)root->rotation.z,(float&)root->rotation.y);
rootOut->mTransformation.FromEulerAnglesXYZ(AI_DEG_TO_RAD(root->rotation) );
// apply scaling
@@ -912,20 +841,17 @@ void IRRImporter::GenerateGraph(Node* root,aiNode* rootOut ,aiScene* scene,
mat.a1 *= root->scaling.x;
mat.b1 *= root->scaling.x;
mat.c1 *= root->scaling.x;
mat.a2 *= root->scaling.z;
mat.b2 *= root->scaling.z;
mat.c2 *= root->scaling.z;
mat.a3 *= root->scaling.y;
mat.b3 *= root->scaling.y;
mat.c3 *= root->scaling.y;
mat.a2 *= root->scaling.y;
mat.b2 *= root->scaling.y;
mat.c2 *= root->scaling.y;
mat.a3 *= root->scaling.z;
mat.b3 *= root->scaling.z;
mat.c3 *= root->scaling.z;
// apply translation
mat.a4 += root->position.x;
mat.b4 += root->position.z;
mat.c4 += root->position.y;
//if (meshTrafoAssign == 2)
// mat *= AI_TO_IRR_MATRIX;
mat.b4 += root->position.y;
mat.c4 += root->position.z;
// now compute animations for the node
ComputeAnimations(root,rootOut, anims);
@@ -933,11 +859,11 @@ void IRRImporter::GenerateGraph(Node* root,aiNode* rootOut ,aiScene* scene,
// Add all children recursively. First allocate enough storage
// for them, then call us again
rootOut->mNumChildren = (unsigned int)root->children.size();
if (rootOut->mNumChildren)
{
if (rootOut->mNumChildren) {
rootOut->mChildren = new aiNode*[rootOut->mNumChildren];
for (unsigned int i = 0; i < rootOut->mNumChildren;++i)
{
for (unsigned int i = 0; i < rootOut->mNumChildren;++i) {
aiNode* node = rootOut->mChildren[i] = new aiNode();
node->mParent = rootOut;
GenerateGraph(root->children[i],node,scene,batch,meshes,
@@ -989,14 +915,11 @@ void IRRImporter::InternReadFile( const std::string& pFile,
unsigned int guessedAnimCnt = 0, guessedMeshCnt = 0, guessedMatCnt = 0;
// Parse the XML file
while (reader->read())
{
switch (reader->getNodeType())
{
while (reader->read()) {
switch (reader->getNodeType()) {
case EXN_ELEMENT:
if (!ASSIMP_stricmp(reader->getNodeName(),"node"))
{
if (!ASSIMP_stricmp(reader->getNodeName(),"node")) {
// ***********************************************************************
/* What we're going to do with the node depends
* on its type:
@@ -1019,24 +942,20 @@ void IRRImporter::InternReadFile( const std::string& pFile,
// ***********************************************************************
const char* sz = reader->getAttributeValueSafe("type");
Node* nd;
if (!ASSIMP_stricmp(sz,"mesh") || !ASSIMP_stricmp(sz,"octTree"))
{
if (!ASSIMP_stricmp(sz,"mesh") || !ASSIMP_stricmp(sz,"octTree")) {
// OctTree's and meshes are treated equally
nd = new Node(Node::MESH);
}
else if (!ASSIMP_stricmp(sz,"cube"))
{
else if (!ASSIMP_stricmp(sz,"cube")) {
nd = new Node(Node::CUBE);
++guessedMeshCnt;
// meshes.push_back(StandardShapes::MakeMesh(&StandardShapes::MakeHexahedron));
}
else if (!ASSIMP_stricmp(sz,"skybox"))
{
else if (!ASSIMP_stricmp(sz,"skybox")) {
nd = new Node(Node::SKYBOX);
guessedMeshCnt += 6;
}
else if (!ASSIMP_stricmp(sz,"camera"))
{
else if (!ASSIMP_stricmp(sz,"camera")) {
nd = new Node(Node::CAMERA);
// Setup a temporary name for the camera
@@ -1044,8 +963,7 @@ void IRRImporter::InternReadFile( const std::string& pFile,
cam->mName.Set( nd->name );
cameras.push_back(cam);
}
else if (!ASSIMP_stricmp(sz,"light"))
{
else if (!ASSIMP_stricmp(sz,"light")) {
nd = new Node(Node::LIGHT);
// Setup a temporary name for the light
@@ -1053,31 +971,25 @@ void IRRImporter::InternReadFile( const std::string& pFile,
cam->mName.Set( nd->name );
lights.push_back(cam);
}
else if (!ASSIMP_stricmp(sz,"sphere"))
{
else if (!ASSIMP_stricmp(sz,"sphere")) {
nd = new Node(Node::SPHERE);
++guessedMeshCnt;
}
else if (!ASSIMP_stricmp(sz,"animatedMesh"))
{
else if (!ASSIMP_stricmp(sz,"animatedMesh")) {
nd = new Node(Node::ANIMMESH);
}
else if (!ASSIMP_stricmp(sz,"empty"))
{
else if (!ASSIMP_stricmp(sz,"empty")) {
nd = new Node(Node::DUMMY);
}
else if (!ASSIMP_stricmp(sz,"terrain"))
{
else if (!ASSIMP_stricmp(sz,"terrain")) {
nd = new Node(Node::TERRAIN);
}
else if (!ASSIMP_stricmp(sz,"billBoard"))
{
else if (!ASSIMP_stricmp(sz,"billBoard")) {
// We don't support billboards, so ignore them
DefaultLogger::get()->error("IRR: Billboards are not supported by Assimp");
nd = new Node(Node::DUMMY);
}
else
{
else {
DefaultLogger::get()->warn("IRR: Found unknown node: " + std::string(sz));
/* We skip the contents of nodes we don't know.
@@ -1093,21 +1005,17 @@ void IRRImporter::InternReadFile( const std::string& pFile,
nd->parent = curParent;
curParent->children.push_back(nd);
}
else if (!ASSIMP_stricmp(reader->getNodeName(),"materials"))
{
else if (!ASSIMP_stricmp(reader->getNodeName(),"materials")) {
inMaterials = true;
}
else if (!ASSIMP_stricmp(reader->getNodeName(),"animators"))
{
else if (!ASSIMP_stricmp(reader->getNodeName(),"animators")) {
inAnimator = true;
}
else if (!ASSIMP_stricmp(reader->getNodeName(),"attributes"))
{
else if (!ASSIMP_stricmp(reader->getNodeName(),"attributes")) {
/* We should have a valid node here
* FIX: no ... the scene root node is also contained in an attributes block
*/
if (!curNode)
{
if (!curNode) {
#if 0
DefaultLogger::get()->error("IRR: Encountered <attributes> element, but "
"there is no node active");
@@ -1118,8 +1026,7 @@ void IRRImporter::InternReadFile( const std::string& pFile,
Animator* curAnim = NULL;
// Materials can occur for nearly any type of node
if (inMaterials && curNode->type != Node::DUMMY)
{
if (inMaterials && curNode->type != Node::DUMMY) {
/* This is a material description - parse it!
*/
curNode->materials.push_back(std::pair< aiMaterial*, unsigned int > () );
@@ -1130,8 +1037,7 @@ void IRRImporter::InternReadFile( const std::string& pFile,
++guessedMatCnt;
continue;
}
else if (inAnimator)
{
else if (inAnimator) {
/* This is an animation path - add a new animator
* to the list.
*/
@@ -1144,28 +1050,21 @@ void IRRImporter::InternReadFile( const std::string& pFile,
/* Parse all elements in the attributes block
* and process them.
*/
while (reader->read())
{
if (reader->getNodeType() == EXN_ELEMENT)
{
if (!ASSIMP_stricmp(reader->getNodeName(),"vector3d"))
{
while (reader->read()) {
if (reader->getNodeType() == EXN_ELEMENT) {
if (!ASSIMP_stricmp(reader->getNodeName(),"vector3d")) {
VectorProperty prop;
ReadVectorProperty(prop);
if (inAnimator)
{
if (curAnim->type == Animator::ROTATION && prop.name == "Rotation")
{
if (inAnimator) {
if (curAnim->type == Animator::ROTATION && prop.name == "Rotation") {
// We store the rotation euler angles in 'direction'
curAnim->direction = prop.value;
}
else if (curAnim->type == Animator::FOLLOW_SPLINE)
{
else if (curAnim->type == Animator::FOLLOW_SPLINE) {
// Check whether the vector follows the PointN naming scheme,
// here N is the ONE-based index of the point
if (prop.name.length() >= 6 && prop.name.substr(0,5) == "Point")
{
if (prop.name.length() >= 6 && prop.name.substr(0,5) == "Point") {
// Add a new key to the list
curAnim->splineKeys.push_back(aiVectorKey());
aiVectorKey& key = curAnim->splineKeys.back();
@@ -1175,203 +1074,158 @@ void IRRImporter::InternReadFile( const std::string& pFile,
key.mTime = strtol10(&prop.name[5]);
}
}
else if (curAnim->type == Animator::FLY_CIRCLE)
{
if (prop.name == "Center")
{
else if (curAnim->type == Animator::FLY_CIRCLE) {
if (prop.name == "Center") {
curAnim->circleCenter = prop.value;
}
else if (prop.name == "Direction")
{
else if (prop.name == "Direction") {
curAnim->direction = prop.value;
// From Irrlicht source - a workaround for backward
// compatibility with Irrlicht 1.1
if (curAnim->direction == aiVector3D())
{
// From Irrlicht's source - a workaround for backward compatibility with Irrlicht 1.1
if (curAnim->direction == aiVector3D()) {
curAnim->direction = aiVector3D(0.f,1.f,0.f);
}
else curAnim->direction.Normalize();
}
}
else if (curAnim->type == Animator::FLY_STRAIGHT)
{
if (prop.name == "Start")
{
else if (curAnim->type == Animator::FLY_STRAIGHT) {
if (prop.name == "Start") {
// We reuse the field here
curAnim->circleCenter = prop.value;
}
else if (prop.name == "End")
{
else if (prop.name == "End") {
// We reuse the field here
curAnim->direction = prop.value;
}
}
}
else
{
if (prop.name == "Position")
{
else {
if (prop.name == "Position") {
curNode->position = prop.value;
}
else if (prop.name == "Rotation")
{
else if (prop.name == "Rotation") {
curNode->rotation = prop.value;
}
else if (prop.name == "Scale")
{
else if (prop.name == "Scale") {
curNode->scaling = prop.value;
}
else if (Node::CAMERA == curNode->type)
{
aiCamera* cam = cameras.back();
if (prop.name == "Target")
{
if (prop.name == "Target") {
cam->mLookAt = prop.value;
}
else if (prop.name == "UpVector")
{
else if (prop.name == "UpVector") {
cam->mUp = prop.value;
}
}
}
}
else if (!ASSIMP_stricmp(reader->getNodeName(),"bool"))
{
else if (!ASSIMP_stricmp(reader->getNodeName(),"bool")) {
BoolProperty prop;
ReadBoolProperty(prop);
if (inAnimator && curAnim->type == Animator::FLY_CIRCLE && prop.name == "Loop")
{
if (inAnimator && curAnim->type == Animator::FLY_CIRCLE && prop.name == "Loop") {
curAnim->loop = prop.value;
}
}
else if (!ASSIMP_stricmp(reader->getNodeName(),"float"))
{
else if (!ASSIMP_stricmp(reader->getNodeName(),"float")) {
FloatProperty prop;
ReadFloatProperty(prop);
if (inAnimator)
{
if (inAnimator) {
// The speed property exists for several animators
if (prop.name == "Speed")
{
if (prop.name == "Speed") {
curAnim->speed = prop.value;
}
else if (curAnim->type == Animator::FLY_CIRCLE && prop.name == "Radius")
{
else if (curAnim->type == Animator::FLY_CIRCLE && prop.name == "Radius") {
curAnim->circleRadius = prop.value;
}
else if (curAnim->type == Animator::FOLLOW_SPLINE && prop.name == "Tightness")
{
else if (curAnim->type == Animator::FOLLOW_SPLINE && prop.name == "Tightness") {
curAnim->tightness = prop.value;
}
}
else
{
if (prop.name == "FramesPerSecond" &&
Node::ANIMMESH == curNode->type)
{
else {
if (prop.name == "FramesPerSecond" && Node::ANIMMESH == curNode->type) {
curNode->framesPerSecond = prop.value;
}
else if (Node::CAMERA == curNode->type)
{
else if (Node::CAMERA == curNode->type) {
/* This is the vertical, not the horizontal FOV.
* We need to compute the right FOV from the
* screen aspect which we don't know yet.
*/
if (prop.name == "Fovy")
{
if (prop.name == "Fovy") {
cameras.back()->mHorizontalFOV = prop.value;
}
else if (prop.name == "Aspect")
{
else if (prop.name == "Aspect") {
cameras.back()->mAspect = prop.value;
}
else if (prop.name == "ZNear")
{
else if (prop.name == "ZNear") {
cameras.back()->mClipPlaneNear = prop.value;
}
else if (prop.name == "ZFar")
{
else if (prop.name == "ZFar") {
cameras.back()->mClipPlaneFar = prop.value;
}
}
else if (Node::LIGHT == curNode->type)
{
else if (Node::LIGHT == curNode->type) {
/* Additional light information
*/
if (prop.name == "Attenuation")
{
if (prop.name == "Attenuation") {
lights.back()->mAttenuationLinear = prop.value;
}
else if (prop.name == "OuterCone")
{
else if (prop.name == "OuterCone") {
lights.back()->mAngleOuterCone = AI_DEG_TO_RAD( prop.value );
}
else if (prop.name == "InnerCone")
{
else if (prop.name == "InnerCone") {
lights.back()->mAngleInnerCone = AI_DEG_TO_RAD( prop.value );
}
}
// radius of the sphere to be generated -
// or alternatively, size of the cube
else if (Node::SPHERE == curNode->type && prop.name == "Radius" ||
Node::CUBE == curNode->type && prop.name == "Size" )
{
curNode->sphereRadius = prop.value;
else if (Node::SPHERE == curNode->type && prop.name == "Radius"
|| Node::CUBE == curNode->type && prop.name == "Size" ) {
curNode->sphereRadius = prop.value;
}
}
}
else if (!ASSIMP_stricmp(reader->getNodeName(),"int"))
{
else if (!ASSIMP_stricmp(reader->getNodeName(),"int")) {
IntProperty prop;
ReadIntProperty(prop);
if (inAnimator)
{
if (curAnim->type == Animator::FLY_STRAIGHT && prop.name == "TimeForWay")
{
if (inAnimator) {
if (curAnim->type == Animator::FLY_STRAIGHT && prop.name == "TimeForWay") {
curAnim->timeForWay = prop.value;
}
}
else
{
else {
// sphere polgon numbers in each direction
if (Node::SPHERE == curNode->type)
{
if (prop.name == "PolyCountX")
{
if (Node::SPHERE == curNode->type) {
if (prop.name == "PolyCountX") {
curNode->spherePolyCountX = prop.value;
}
else if (prop.name == "PolyCountY")
{
else if (prop.name == "PolyCountY") {
curNode->spherePolyCountY = prop.value;
}
}
}
}
else if (!ASSIMP_stricmp(reader->getNodeName(),"string") ||
!ASSIMP_stricmp(reader->getNodeName(),"enum"))
{
else if (!ASSIMP_stricmp(reader->getNodeName(),"string") ||!ASSIMP_stricmp(reader->getNodeName(),"enum")) {
StringProperty prop;
ReadStringProperty(prop);
if (prop.value.length())
{
if (prop.name == "Name")
{
if (prop.value.length()) {
if (prop.name == "Name") {
curNode->name = prop.value;
/* If we're either a camera or a light source
* we need to update the name in the aiLight/
* aiCamera structure, too.
*/
if (Node::CAMERA == curNode->type)
{
if (Node::CAMERA == curNode->type) {
cameras.back()->mName.Set(prop.value);
}
else if (Node::LIGHT == curNode->type)
{
else if (Node::LIGHT == curNode->type) {
lights.back()->mName.Set(prop.value);
}
}
@@ -1404,10 +1258,9 @@ void IRRImporter::InternReadFile( const std::string& pFile,
unsigned int pp = 0;
BatchLoader::PropertyMap map;
/* If the mesh is a static one remove all animations
/* If the mesh is a static one remove all animations from the impor data
*/
if (Node::ANIMMESH != curNode->type)
{
if (Node::ANIMMESH != curNode->type) {
pp |= aiProcess_RemoveComponent;
SetGenericProperty<int>(map.ints,AI_CONFIG_PP_RVC_FLAGS,
aiComponent_ANIMATIONS | aiComponent_BONEWEIGHTS);
@@ -1419,51 +1272,33 @@ void IRRImporter::InternReadFile( const std::string& pFile,
* file referencing each other *could* cause the system to
* recurse forever.
*/
std::string::size_type pos = prop.value.find_last_of('.');
// no file extension - can't read, so we don't need to try it
if( pos == std::string::npos)
{
DefaultLogger::get()->error("IRR: Can't load files without a file extension");
const std::string extension = GetExtension(prop.value);
if ("irr" == extension) {
DefaultLogger::get()->error("IRR: Can't load another IRR file recursively");
}
else
{
std::string extension = prop.value.substr( pos);
for (std::string::iterator i = extension.begin(); i != extension.end();++i)
*i = ::tolower(*i);
if (".irr" == prop.value)
{
DefaultLogger::get()->error("IRR: Can't load another IRR file recursively");
}
else
{
curNode->id = batch.AddLoadRequest(prop.value,pp,&map);
curNode->meshPath = prop.value;
}
curNode->id = batch.AddLoadRequest(prop.value,pp,&map);
curNode->meshPath = prop.value;
}
}
else if (inAnimator && prop.name == "Type")
{
// type of the animator
if (prop.value == "rotation")
{
if (prop.value == "rotation") {
curAnim->type = Animator::ROTATION;
}
else if (prop.value == "flyCircle")
{
else if (prop.value == "flyCircle") {
curAnim->type = Animator::FLY_CIRCLE;
}
else if (prop.value == "flyStraight")
{
else if (prop.value == "flyStraight") {
curAnim->type = Animator::FLY_CIRCLE;
}
else if (prop.value == "followSpline")
{
else if (prop.value == "followSpline") {
curAnim->type = Animator::FOLLOW_SPLINE;
}
else
{
else {
DefaultLogger::get()->warn("IRR: Ignoring unknown animator: "
+ prop.value);
@@ -1473,9 +1308,7 @@ void IRRImporter::InternReadFile( const std::string& pFile,
}
}
}
else if (reader->getNodeType() == EXN_ELEMENT_END &&
!ASSIMP_stricmp(reader->getNodeName(),"attributes"))
{
else if (reader->getNodeType() == EXN_ELEMENT_END && !ASSIMP_stricmp(reader->getNodeName(),"attributes")) {
break;
}
}
@@ -1485,14 +1318,11 @@ void IRRImporter::InternReadFile( const std::string& pFile,
case EXN_ELEMENT_END:
// If we reached the end of a node, we need to continue processing its parent
if (!ASSIMP_stricmp(reader->getNodeName(),"node"))
{
if (!curNode)
{
if (!ASSIMP_stricmp(reader->getNodeName(),"node")) {
if (!curNode) {
// currently is no node set. We need to go
// back in the node hierarchy
if (!curParent)
{
if (!curParent) {
curParent = root;
DefaultLogger::get()->error("IRR: Too many closing <node> elements");
}
@@ -1501,12 +1331,10 @@ void IRRImporter::InternReadFile( const std::string& pFile,
else curNode = NULL;
}
// clear all flags
else if (!ASSIMP_stricmp(reader->getNodeName(),"materials"))
{
else if (!ASSIMP_stricmp(reader->getNodeName(),"materials")) {
inMaterials = false;
}
else if (!ASSIMP_stricmp(reader->getNodeName(),"animators"))
{
else if (!ASSIMP_stricmp(reader->getNodeName(),"animators")) {
inAnimator = false;
}
break;
@@ -1519,11 +1347,11 @@ void IRRImporter::InternReadFile( const std::string& pFile,
/* Now iterate through all cameras and compute their final (horizontal) FOV
*/
for (std::vector<aiCamera*>::iterator it = cameras.begin(), end = cameras.end();
it != end; ++it) {
for (std::vector<aiCamera*>::iterator it = cameras.begin(), end = cameras.end();it != end; ++it) {
aiCamera* cam = *it;
if (cam->mAspect) // screen aspect could be missing
{
// screen aspect could be missing
if (cam->mAspect) {
cam->mHorizontalFOV *= cam->mAspect;
}
else DefaultLogger::get()->warn("IRR: Camera aspect is not given, can't compute horizontal FOV");
@@ -1539,8 +1367,7 @@ void IRRImporter::InternReadFile( const std::string& pFile,
/* Copy the cameras to the output array
*/
if (!cameras.empty())
{
if (!cameras.empty()) {
tempScene->mNumCameras = (unsigned int)cameras.size();
tempScene->mCameras = new aiCamera*[tempScene->mNumCameras];
::memcpy(tempScene->mCameras,&cameras[0],sizeof(void*)*tempScene->mNumCameras);
@@ -1548,8 +1375,7 @@ void IRRImporter::InternReadFile( const std::string& pFile,
/* Copy the light sources to the output array
*/
if (!lights.empty())
{
if (!lights.empty()) {
tempScene->mNumLights = (unsigned int)lights.size();
tempScene->mLights = new aiLight*[tempScene->mNumLights];
::memcpy(tempScene->mLights,&lights[0],sizeof(void*)*tempScene->mNumLights);
@@ -1593,8 +1419,7 @@ void IRRImporter::InternReadFile( const std::string& pFile,
an->mChannels = new aiNodeAnim*[an->mNumChannels];
::memcpy(an->mChannels, & anims [0], sizeof(void*)*an->mNumChannels);
}
if (!meshes.empty())
{
if (!meshes.empty()) {
// copy all meshes to the temporary scene
tempScene->mNumMeshes = (unsigned int)meshes.size();
tempScene->mMeshes = new aiMesh*[tempScene->mNumMeshes];
@@ -1604,8 +1429,7 @@ void IRRImporter::InternReadFile( const std::string& pFile,
/* Copy all materials to the output array
*/
if (!materials.empty())
{
if (!materials.empty()) {
tempScene->mNumMaterials = (unsigned int)materials.size();
tempScene->mMaterials = new aiMaterial*[tempScene->mNumMaterials];
::memcpy(tempScene->mMaterials,&materials[0],sizeof(void*)*
@@ -1624,8 +1448,7 @@ void IRRImporter::InternReadFile( const std::string& pFile,
* scene flag. This is necessary if we failed to load all
* models from external files
*/
if (!pScene->mNumMeshes || !pScene->mNumMaterials)
{
if (!pScene->mNumMeshes || !pScene->mNumMaterials) {
DefaultLogger::get()->warn("IRR: No meshes loaded, setting AI_SCENE_FLAGS_INCOMPLETE");
pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
}
+41 -89
View File
@@ -54,16 +54,12 @@ using namespace irr::io;
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
IRRMeshImporter::IRRMeshImporter()
{
// nothing to do here
}
{}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
IRRMeshImporter::~IRRMeshImporter()
{
// nothing to do here
}
{}
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
@@ -134,23 +130,18 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
bool useColors = false;
// Parse the XML file
while (reader->read())
{
switch (reader->getNodeType())
{
while (reader->read()) {
switch (reader->getNodeType()) {
case EXN_ELEMENT:
if (!ASSIMP_stricmp(reader->getNodeName(),"buffer") && (curMat || curMesh))
{
if (!ASSIMP_stricmp(reader->getNodeName(),"buffer") && (curMat || curMesh)) {
// end of previous buffer. A material and a mesh should be there
if ( !curMat || !curMesh)
{
if ( !curMat || !curMesh) {
DefaultLogger::get()->error("IRRMESH: A buffer must contain a mesh and a material");
delete curMat;
delete curMesh;
}
else
{
else {
materials.push_back(curMat);
meshes.push_back(curMesh);
}
@@ -167,10 +158,8 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
}
if (!ASSIMP_stricmp(reader->getNodeName(),"material"))
{
if (curMat)
{
if (!ASSIMP_stricmp(reader->getNodeName(),"material")) {
if (curMat) {
DefaultLogger::get()->warn("IRRMESH: Only one material description per buffer, please");
delete curMat;curMat = NULL;
}
@@ -180,11 +169,8 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
{
int num = reader->getAttributeValueAsInt("vertexCount");
if (!num)
{
// This is possible ... remove the mesh from the list
// and skip further reading
if (!num) {
// This is possible ... remove the mesh from the list and skip further reading
DefaultLogger::get()->warn("IRRMESH: Found mesh with zero vertices");
delete curMat;curMat = NULL;
@@ -201,13 +187,11 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
// Determine the file format
const char* t = reader->getAttributeValueSafe("type");
if (!ASSIMP_stricmp("2tcoords", t))
{
if (!ASSIMP_stricmp("2tcoords", t)) {
curUV2s.reserve (num);
vertexFormat = 1;
if (curMatFlags & AI_IRRMESH_EXTRA_2ND_TEXTURE)
{
if (curMatFlags & AI_IRRMESH_EXTRA_2ND_TEXTURE) {
// *********************************************************
// We have a second texture! So use this UV channel
// for it. The 2nd texture can be either a normal
@@ -228,24 +212,20 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
}
}
}
else if (!ASSIMP_stricmp("tangents", t))
{
else if (!ASSIMP_stricmp("tangents", t)) {
curTangents.reserve (num);
curBitangents.reserve (num);
vertexFormat = 2;
}
else if (ASSIMP_stricmp("standard", t))
{
else if (ASSIMP_stricmp("standard", t)) {
delete curMat;
DefaultLogger::get()->warn("IRRMESH: Unknown vertex format");
}
else vertexFormat = 0;
textMeaning = 1;
}
else if (!ASSIMP_stricmp(reader->getNodeName(),"indices"))
{
if (curVertices.empty() && curMat)
{
else if (!ASSIMP_stricmp(reader->getNodeName(),"indices")) {
if (curVertices.empty() && curMat) {
delete curMat;
throw new ImportErrorException("IRRMESH: indices must come after vertices");
}
@@ -257,11 +237,8 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
// allocate storage for all faces
curMesh->mNumVertices = reader->getAttributeValueAsInt("indexCount");
if (!curMesh->mNumVertices)
{
// This is possible ... remove the mesh from the list
// and skip further reading
if (!curMesh->mNumVertices) {
// This is possible ... remove the mesh from the list and skip further reading
DefaultLogger::get()->warn("IRRMESH: Found mesh with zero indices");
// mesh - away
@@ -274,8 +251,7 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
continue;
}
if (curMesh->mNumVertices % 3)
{
if (curMesh->mNumVertices % 3) {
DefaultLogger::get()->warn("IRRMESH: Number if indices isn't divisible by 3");
}
@@ -289,28 +265,22 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
// allocate storage for all vertices
curMesh->mVertices = new aiVector3D[curMesh->mNumVertices];
if (curNormals.size() == curVertices.size())
{
if (curNormals.size() == curVertices.size()) {
curMesh->mNormals = new aiVector3D[curMesh->mNumVertices];
}
if (curTangents.size() == curVertices.size())
{
if (curTangents.size() == curVertices.size()) {
curMesh->mTangents = new aiVector3D[curMesh->mNumVertices];
}
if (curBitangents.size() == curVertices.size())
{
if (curBitangents.size() == curVertices.size()) {
curMesh->mBitangents = new aiVector3D[curMesh->mNumVertices];
}
if (curColors.size() == curVertices.size() && useColors)
{
if (curColors.size() == curVertices.size() && useColors) {
curMesh->mColors[0] = new aiColor4D[curMesh->mNumVertices];
}
if (curUVs.size() == curVertices.size())
{
if (curUVs.size() == curVertices.size()) {
curMesh->mTextureCoords[0] = new aiVector3D[curMesh->mNumVertices];
}
if (curUV2s.size() == curVertices.size())
{
if (curUV2s.size() == curVertices.size()) {
curMesh->mTextureCoords[1] = new aiVector3D[curMesh->mNumVertices];
}
}
@@ -319,13 +289,11 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
case EXN_TEXT:
{
const char* sz = reader->getNodeData();
if (textMeaning == 1)
{
if (textMeaning == 1) {
textMeaning = 0;
// read vertices
do
{
do {
SkipSpacesAndLineEnd(&sz);
aiVector3D temp;aiColor4D c;
@@ -373,8 +341,7 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
curUVs.push_back(temp);
// read the (optional) second UV coordinate set
if (vertexFormat == 1)
{
if (vertexFormat == 1) {
sz = fast_atof_move(sz,(float&)temp.x);
SkipSpaces(&sz);
@@ -383,8 +350,7 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
curUV2s.push_back(temp);
}
// read optional tangent and bitangent vectors
else if (vertexFormat == 2)
{
else if (vertexFormat == 2) {
// tangents
sz = fast_atof_move(sz,(float&)temp.x);
SkipSpaces(&sz);
@@ -418,8 +384,7 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
while (SkipLine(&sz));
}
else if (textMeaning == 2)
{
else if (textMeaning == 2) {
textMeaning = 0;
// read indices
@@ -436,22 +401,18 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
unsigned int curIdx = 0;
unsigned int total = 0;
while(SkipSpacesAndLineEnd(&sz))
{
if (curFace >= faceEnd)
{
while(SkipSpacesAndLineEnd(&sz)) {
if (curFace >= faceEnd) {
DefaultLogger::get()->error("IRRMESH: Too many indices");
break;
}
if (!curIdx)
{
if (!curIdx) {
curFace->mNumIndices = 3;
curFace->mIndices = new unsigned int[3];
}
unsigned int idx = strtol10(sz,&sz);
if (idx >= curVertices.size())
{
if (idx >= curVertices.size()) {
DefaultLogger::get()->error("IRRMESH: Index out of range");
idx = 0;
}
@@ -466,8 +427,7 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
if (pcT0)*pcT0++ = curUVs[idx];
if (pcT1)*pcT1++ = curUV2s[idx];
if (++curIdx == 3)
{
if (++curIdx == 3) {
++curFace;
curIdx = 0;
}
@@ -477,8 +437,7 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
DefaultLogger::get()->error("IRRMESH: Not enough indices");
// Finish processing the mesh - do some small material workarounds
if (curMatFlags & AI_IRRMESH_MAT_trans_vertex_alpha && !useColors)
{
if (curMatFlags & AI_IRRMESH_MAT_trans_vertex_alpha && !useColors) {
// Take the opacity value of the current material
// from the common vertex color alpha
MaterialHelper* mat = (MaterialHelper*)curMat;
@@ -496,16 +455,13 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
}
// End of the last buffer. A material and a mesh should be there
if (curMat || curMesh)
{
if ( !curMat || !curMesh)
{
if (curMat || curMesh) {
if ( !curMat || !curMesh) {
DefaultLogger::get()->error("IRRMESH: A buffer must contain a mesh and a material");
delete curMat;
delete curMesh;
}
else
{
else {
materials.push_back(curMat);
meshes.push_back(curMesh);
}
@@ -518,8 +474,7 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
// now generate the output scene
pScene->mNumMeshes = (unsigned int)meshes.size();
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
{
for (unsigned int i = 0; i < pScene->mNumMeshes;++i) {
pScene->mMeshes[i] = meshes[i];
// clean this value ...
@@ -538,9 +493,6 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
pScene->mRootNode->mMeshes[i] = i;
// transformation matrix to convert from IRRMESH to ASSIMP coordinates
pScene->mRootNode->mTransformation *= AI_TO_IRR_MATRIX;
// clean up and return
delete reader;
AI_DEBUG_INVALIDATE_PTR(reader);
+9 -3
View File
@@ -167,7 +167,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_BUILD_NO_JOINVERTICES_PROCESS
# include "JoinVerticesProcess.h"
#endif
#ifndef AI_BUILD_NO_CONVERTTOLH_PROCESS
#if !(defined AI_BUILD_NO_MAKELEFTHANDED_PROCESS && defined AI_BUILD_NO_FLIPUVS_PROCESS && defined AI_BUILD_NO_FLIPWINDINGORDER_PROCESS)
# include "ConvertToLHProcess.h"
#endif
#ifndef AI_BUILD_NO_TRIANGULATE_PROCESS
@@ -436,8 +436,14 @@ Importer::Importer()
#if (!defined AI_BUILD_NO_SPLITLARGEMESHES_PROCESS)
mPostProcessingSteps.push_back( new SplitLargeMeshesProcess_Vertex());
#endif
#if (!defined AI_BUILD_NO_CONVERTTOLH_PROCESS)
mPostProcessingSteps.push_back( new ConvertToLHProcess());
#if (!defined AI_BUILD_NO_MAKELEFTHANDED_PROCESS)
mPostProcessingSteps.push_back( new MakeLeftHandedProcess());
#endif
#if (!defined AI_BUILD_NO_FLIPUVS_PROCESS)
mPostProcessingSteps.push_back( new FlipUVsProcess());
#endif
#if (!defined AI_BUILD_NO_FLIPWINDINGORDER_PROCESS)
mPostProcessingSteps.push_back( new FlipWindingOrderProcess());
#endif
#if (!defined AI_BUILD_NO_LIMITBONEWEIGHTS_PROCESS)
mPostProcessingSteps.push_back( new LimitBoneWeightsProcess());
+1 -1
View File
@@ -549,7 +549,7 @@ void AnimResolver::ExtractAnimChannel(aiNodeAnim** out, unsigned int flags /*= 0
for (unsigned int i = 0; i < anim->mNumRotationKeys; ++i) {
aiQuatKey& qk = anim->mRotationKeys[i];
qk.mTime = keys[i].mTime;
qk.mValue = aiQuaternion( keys[i].mValue.x ,keys[i].mValue.y ,keys[i].mValue.z );
qk.mValue = aiQuaternion( keys[i].mValue.x ,keys[i].mValue.z ,keys[i].mValue.y );
}
}
+17 -21
View File
@@ -53,6 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "SGSpatialSort.h"
#include "ByteSwap.h"
#include "ProcessHelper.h"
#include "ConvertToLHProcess.h"
using namespace Assimp;
@@ -314,24 +315,20 @@ void LWOImporter::InternReadFile( const std::string& pFile,
// now convert all faces
unsigned int vert = 0;
std::vector<unsigned int>::iterator outIt = smoothingGroups.begin();
for (it = sorted.begin(); it != end;++it,++outIt)
{
for (it = sorted.begin(); it != end;++it,++outIt) {
const LWO::Face& face = layer.mFaces[*it];
*outIt = face.smoothGroup;
// copy all vertices
for (unsigned int q = 0; q < face.mNumIndices;++q)
{
for (unsigned int q = 0; q < face.mNumIndices;++q,++vert) {
register unsigned int idx = face.mIndices[q];
*pv = layer.mTempPoints[idx] + layer.mPivot;
pv->z *= -1.0f; // DX to OGL
//std::swap(pv->z,pv->y);
pv++;
// process UV coordinates
for (unsigned int w = 0; w < AI_MAX_NUMBER_OF_TEXTURECOORDS;++w)
{
if (0xffffffff == vUVChannelIndices[w])break;
for (unsigned int w = 0; w < AI_MAX_NUMBER_OF_TEXTURECOORDS;++w) {
if (0xffffffff == vUVChannelIndices[w])
break;
aiVector3D*& pp = pvUV[w];
const aiVector2D& src = ((aiVector2D*)&layer.mUVChannels[vUVChannelIndices[w]].rawData[0])[idx];
pp->x = src.x;
@@ -345,9 +342,9 @@ void LWOImporter::InternReadFile( const std::string& pFile,
}
// process vertex colors
for (unsigned int w = 0; w < AI_MAX_NUMBER_OF_COLOR_SETS;++w)
{
if (0xffffffff == vVColorIndices[w])break;
for (unsigned int w = 0; w < AI_MAX_NUMBER_OF_COLOR_SETS;++w) {
if (0xffffffff == vVColorIndices[w])
break;
*pvVC[w] = ((aiColor4D*)&layer.mVColorChannels[vVColorIndices[w]].rawData[0])[idx];
// If a RGB color map is explicitly requested delete the
@@ -364,10 +361,8 @@ void LWOImporter::InternReadFile( const std::string& pFile,
{
}
#endif
face.mIndices[q] = vert + (face.mNumIndices-q-1);
face.mIndices[q] = vert;
}
vert += face.mNumIndices;
pf->mIndices = face.mIndices;
pf->mNumIndices = face.mNumIndices;
unsigned int** p = (unsigned int**)&face.mIndices;*p = NULL; // make sure it won't be deleted
@@ -568,8 +563,7 @@ void LWOImporter::GenerateNodeGraph(std::vector<aiNode*>& apcNodes)
for (unsigned int i = 0; i < apcNodes.size();++i)
if (apcNodes[i] && apcNodes[i]->mNumMeshes)++extra;
if (extra)
{
if (extra) {
// we need to add extra nodes to the root
const unsigned int newSize = extra + pScene->mRootNode->mNumChildren;
aiNode** const apcNewNodes = new aiNode*[newSize];
@@ -596,15 +590,17 @@ void LWOImporter::GenerateNodeGraph(std::vector<aiNode*>& apcNodes)
if (!pScene->mRootNode->mNumChildren)
throw new ImportErrorException("LWO: Unable to build a valid node graph");
// remove a single root node
// TODO: implement directly in the above loop, no need to deallocate here
if (1 == pScene->mRootNode->mNumChildren)
{
// Remove a single root node with no meshes assigned ...
if (1 == pScene->mRootNode->mNumChildren) {
aiNode* pc = pScene->mRootNode->mChildren[0];
pc->mParent = pScene->mRootNode->mChildren[0] = NULL;
delete pScene->mRootNode;
pScene->mRootNode = pc;
}
// convert the whole stuff to RH
MakeLeftHandedProcess maker;
maker.Execute(pScene);
}
// ------------------------------------------------------------------------------------------------
+3 -6
View File
@@ -136,12 +136,10 @@ bool LWOImporter::HandleTextures(MaterialHelper* pcMat, const TextureList& in, a
break;
};
if (mapping != aiTextureMapping_UV)
{
if (mapping != aiTextureMapping_UV) {
// Setup the main axis
aiVector3D v;
switch ((*it).majorAxis)
{
switch ((*it).majorAxis) {
case Texture::AXIS_X:
v = aiVector3D(1.f,0.f,0.f);
break;
@@ -156,8 +154,7 @@ bool LWOImporter::HandleTextures(MaterialHelper* pcMat, const TextureList& in, a
pcMat->AddProperty(&v,1,AI_MATKEY_TEXMAP_AXIS(type,cur));
// Setup UV scalings for cylindric and spherical projections
if (mapping == aiTextureMapping_CYLINDER || mapping == aiTextureMapping_SPHERE)
{
if (mapping == aiTextureMapping_CYLINDER || mapping == aiTextureMapping_SPHERE) {
aiUVTransform trafo;
trafo.mScaling.x = (*it).wrapAmountW;
trafo.mScaling.y = (*it).wrapAmountH;
+6
View File
@@ -52,6 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "SceneCombiner.h"
#include "GenericProperty.h"
#include "SkeletonMeshBuilder.h"
#include "ConvertToLHProcess.h"
using namespace Assimp;
@@ -858,6 +859,10 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
std::copy(anims.begin(),anims.end(),anim->mChannels);
}
// convert the master scene to RH
MakeLeftHandedProcess monster_cheat;
monster_cheat.Execute(master);
// OK ... finally build the output graph
SceneCombiner::MergeScenes(&pScene,master,attach,
AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES | (!configSpeedFlag ? (
@@ -872,4 +877,5 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
SkeletonMeshBuilder builder(pScene);
}
}
}
+17 -10
View File
@@ -144,7 +144,11 @@ void MD5Importer::InternReadFile( const std::string& pFile,
// make sure we have at least one file
if (!bHadMD5Mesh && !bHadMD5Anim && !bHadMD5Camera)
throw new ImportErrorException("Failed to read valid contents from this MD5 data set");
throw new ImportErrorException("Failed to read valid contents from this MD5* file");
// Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
pScene->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f,
0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f);
// the output scene wouldn't pass the validation without this flag
if (!bHadMD5Mesh)
@@ -156,7 +160,6 @@ void MD5Importer::InternReadFile( const std::string& pFile,
void MD5Importer::LoadFileIntoMemory (IOStream* file)
{
ai_assert(NULL != file);
fileSize = (unsigned int)file->FileSize();
// allocate storage and copy the contents of the file to a memory buffer
@@ -211,6 +214,8 @@ void MD5Importer::MakeDataUnique (MD5::MeshDesc& meshSrc)
}
else abHad[face.mIndices[i]] = true;
}
// swap face order
std::swap(face.mIndices[0],face.mIndices[2]);
}
}
@@ -443,8 +448,7 @@ void MD5Importer::LoadMD5MeshFile ()
}
// process bone weights
for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights;++w)
{
for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights;++w) {
if (w >= meshSrc.mWeights.size())
throw new ImportErrorException("MD5MESH: Invalid weight index");
@@ -478,8 +482,7 @@ void MD5Importer::LoadMD5MeshFile ()
// (however, take care that the aiFace destructor doesn't delete the mIndices array)
mesh->mNumFaces = (unsigned int)meshSrc.mFaces.size();
mesh->mFaces = new aiFace[mesh->mNumFaces];
for (unsigned int c = 0; c < mesh->mNumFaces;++c)
{
for (unsigned int c = 0; c < mesh->mNumFaces;++c) {
mesh->mFaces[c].mNumIndices = 3;
mesh->mFaces[c].mIndices = meshSrc.mFaces[c].mIndices;
meshSrc.mFaces[c].mIndices = NULL;
@@ -621,6 +624,7 @@ void MD5Importer::LoadMD5AnimFile ()
if (!pScene->mRootNode) {
pScene->mRootNode = new aiNode();
pScene->mRootNode->mName.Set("<MD5_Hierarchy>");
AttachChilds_Anim(-1,pScene->mRootNode,animParser.mAnimatedBones,(const aiNodeAnim**)anim->mChannels);
// Call SkeletonMeshBuilder to construct a mesh to represent the shape
@@ -659,14 +663,17 @@ void MD5Importer::LoadMD5CameraFile ()
std::vector<unsigned int>& cuts = cameraParser.cuts;
std::vector<MD5::CameraAnimFrameDesc>& frames = cameraParser.frames;
// Construct output graph - a simple dummy node
aiNode* root = pScene->mRootNode = new aiNode();
root->mName.Set("<MD5Camera>");
// Construct output graph - a simple root with a dummy child.
// The root node performs the coordinate system conversion
aiNode* root = pScene->mRootNode = new aiNode("<MD5CameraRoot>");
root->mChildren = new aiNode*[root->mNumChildren = 1];
root->mChildren[0] = new aiNode("<MD5Camera>");
root->mChildren[0]->mParent = root;
// ... but with one camera assigned to it
pScene->mCameras = new aiCamera*[pScene->mNumCameras = 1];
aiCamera* cam = pScene->mCameras[0] = new aiCamera();
cam->mName = root->mName;
cam->mName = "<MD5Camera>";
// FIXME: Fov is currently set to the first frame's value
cam->mHorizontalFOV = AI_DEG_TO_RAD( frames.front().fFOV );
+276 -394
View File
File diff suppressed because it is too large Load Diff
+22 -27
View File
@@ -338,23 +338,18 @@ void PLYImporter::ReplaceDefaultMaterial(std::vector<PLY::Face>* avFaces,
{
bool bNeedDefaultMat = false;
for (std::vector<PLY::Face>::iterator
i = avFaces->begin();i != avFaces->end();++i)
{
if (0xFFFFFFFF == (*i).iMaterialIndex)
{
for (std::vector<PLY::Face>::iterator i = avFaces->begin();i != avFaces->end();++i) {
if (0xFFFFFFFF == (*i).iMaterialIndex) {
bNeedDefaultMat = true;
(*i).iMaterialIndex = (unsigned int)avMaterials->size();
}
else if ((*i).iMaterialIndex >= avMaterials->size() )
{
else if ((*i).iMaterialIndex >= avMaterials->size() ) {
// clamp the index
(*i).iMaterialIndex = (unsigned int)avMaterials->size()-1;
}
}
if (bNeedDefaultMat)
{
if (bNeedDefaultMat) {
// generate a default material
MaterialHelper* pcHelper = new MaterialHelper();
@@ -370,6 +365,11 @@ void PLYImporter::ReplaceDefaultMaterial(std::vector<PLY::Face>* avFaces,
clr.b = clr.g = clr.r = 0.05f;
pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
// The face order is absolutely undefined for PLY, so we have to
// use two-sided rendering to be sure it's ok.
const int two_sided = 1;
pcHelper->AddProperty(&two_sided,1,AI_MATKEY_TWOSIDED);
avMaterials->push_back(pcHelper);
}
}
@@ -997,11 +997,8 @@ void PLYImporter::LoadMaterial(std::vector<MaterialHelper*>* pvOut)
}
}
// check whether we have a valid source for the material data
if (NULL != pcList)
{
for (std::vector<ElementInstance>::const_iterator i = pcList->alInstances.begin();
i != pcList->alInstances.end();++i)
{
if (NULL != pcList) {
for (std::vector<ElementInstance>::const_iterator i = pcList->alInstances.begin();i != pcList->alInstances.end();++i) {
aiColor4D clrOut;
MaterialHelper* pcHelper = new MaterialHelper();
@@ -1019,16 +1016,12 @@ void PLYImporter::LoadMaterial(std::vector<MaterialHelper*>* pvOut)
// handle phong power and shading mode
int iMode;
if (0xFFFFFFFF != iPhong)
{
float fSpec = PLY::PropertyInstance::ConvertTo<float>(
(*i).alProperties[iPhong].avList.front(),ePhong);
if (0xFFFFFFFF != iPhong) {
float fSpec = PLY::PropertyInstance::ConvertTo<float>((*i).alProperties[iPhong].avList.front(),ePhong);
// if shininess is 0 (and the pow() calculation would therefore always
// become 1, not depending on the angle) use gouraud lighting
if (fSpec)
{
// become 1, not depending on the angle), use gouraud lighting
if (fSpec) {
// scale this with 15 ... hopefully this is correct
fSpec *= 15;
pcHelper->AddProperty<float>(&fSpec, 1, AI_MATKEY_SHININESS);
@@ -1041,14 +1034,16 @@ void PLYImporter::LoadMaterial(std::vector<MaterialHelper*>* pvOut)
pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
// handle opacity
if (0xFFFFFFFF != iOpacity)
{
float fOpacity = PLY::PropertyInstance::ConvertTo<float>(
(*i).alProperties[iPhong].avList.front(),eOpacity);
if (0xFFFFFFFF != iOpacity) {
float fOpacity = PLY::PropertyInstance::ConvertTo<float>((*i).alProperties[iPhong].avList.front(),eOpacity);
pcHelper->AddProperty<float>(&fOpacity, 1, AI_MATKEY_OPACITY);
}
// The face order is absolutely undefined for PLY, so we have to
// use two-sided rendering to be sure it's ok.
const int two_sided = 1;
pcHelper->AddProperty(&two_sided,1,AI_MATKEY_TWOSIDED);
// add the newly created material instance to the list
pvOut->push_back(pcHelper);
}
+22 -41
View File
@@ -62,8 +62,7 @@ void ScenePreprocessor::ProcessScene ()
ProcessAnimation(scene->mAnimations[i]);
// Generate a default material if none was specified
if (!scene->mNumMaterials && scene->mNumMeshes)
{
if (!scene->mNumMaterials && scene->mNumMeshes) {
scene->mMaterials = new aiMaterial*[2];
MaterialHelper* helper;
@@ -76,13 +75,11 @@ void ScenePreprocessor::ProcessScene ()
if (scene->mMeshes[i]->mTextureCoords[0]) {
if (mat0 == 0xffffffff) {
scene->mMaterials[scene->mNumMaterials] = helper = new MaterialHelper();
// dummy texture
name.Set("texture.png");
scene->mMaterials[scene->mNumMaterials] = helper = new MaterialHelper();
name.Set("$texture.png");
helper->AddProperty(&name,AI_MATKEY_TEXTURE_DIFFUSE(0));
// setup default name
name.Set(AI_DEFAULT_TEXTURED_MATERIAL_NAME);
helper->AddProperty(&name,AI_MATKEY_NAME);
@@ -94,16 +91,11 @@ void ScenePreprocessor::ProcessScene ()
else
{
if (mat1 == 0xffffffff) {
scene->mMaterials[scene->mNumMaterials] = helper = new MaterialHelper();
// gray
scene->mMaterials[scene->mNumMaterials] = helper = new MaterialHelper();
aiColor3D clr(0.6f,0.6f,0.6f);
helper->AddProperty(&clr,1,AI_MATKEY_COLOR_DIFFUSE);
// add a small ambient color value
clr = aiColor3D(0.05f,0.05f,0.05f);
helper->AddProperty(&clr,1,AI_MATKEY_COLOR_AMBIENT);
// setup the default name
name.Set(AI_DEFAULT_MATERIAL_NAME);
helper->AddProperty(&name,AI_MATKEY_NAME);
@@ -121,8 +113,7 @@ void ScenePreprocessor::ProcessScene ()
void ScenePreprocessor::ProcessMesh (aiMesh* mesh)
{
// If aiMesh::mNumUVComponents is *not* set assign the default value of 2
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i)
{
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
if (!mesh->mTextureCoords[i])
mesh->mNumUVComponents[i] = 0;
@@ -146,10 +137,8 @@ void ScenePreprocessor::ProcessMesh (aiMesh* mesh)
// If the information which primitive types are there in the
// mesh is currently not available, compute it.
if (!mesh->mPrimitiveTypes)
{
for (unsigned int a = 0; a < mesh->mNumFaces; ++a)
{
if (!mesh->mPrimitiveTypes) {
for (unsigned int a = 0; a < mesh->mNumFaces; ++a) {
aiFace& face = mesh->mFaces[a];
switch (face.mNumIndices)
{
@@ -173,8 +162,8 @@ void ScenePreprocessor::ProcessMesh (aiMesh* mesh)
}
// If tangents and normals are given but no bitangents compute them
if (mesh->mTangents && mesh->mNormals && !mesh->mBitangents)
{
if (mesh->mTangents && mesh->mNormals && !mesh->mBitangents) {
mesh->mBitangents = new aiVector3D[mesh->mNumVertices];
for (unsigned int i = 0; i < mesh->mNumVertices;++i) {
mesh->mBitangents[i] = mesh->mNormals[i] ^ mesh->mTangents[i];
@@ -186,34 +175,30 @@ void ScenePreprocessor::ProcessMesh (aiMesh* mesh)
void ScenePreprocessor::ProcessAnimation (aiAnimation* anim)
{
double first = 10e10, last = -10e10;
for (unsigned int i = 0; i < anim->mNumChannels;++i)
{
for (unsigned int i = 0; i < anim->mNumChannels;++i) {
aiNodeAnim* channel = anim->mChannels[i];
/* If the exact duration of the animation is not given
* compute it now.
*/
if (anim->mDuration == -1.)
{
if (anim->mDuration == -1.) {
// Position keys
for (unsigned int i = 0; i < channel->mNumPositionKeys;++i)
{
for (unsigned int i = 0; i < channel->mNumPositionKeys;++i) {
aiVectorKey& key = channel->mPositionKeys[i];
first = std::min (first, key.mTime);
last = std::max (last, key.mTime);
}
// Scaling keys
for (unsigned int i = 0; i < channel->mNumScalingKeys;++i)
{
for (unsigned int i = 0; i < channel->mNumScalingKeys;++i) {
aiVectorKey& key = channel->mScalingKeys[i];
first = std::min (first, key.mTime);
last = std::max (last, key.mTime);
}
// Rotation keys
for (unsigned int i = 0; i < channel->mNumRotationKeys;++i)
{
for (unsigned int i = 0; i < channel->mNumRotationKeys;++i) {
aiQuatKey& key = channel->mRotationKeys[i];
first = std::min (first, key.mTime);
last = std::max (last, key.mTime);
@@ -225,8 +210,7 @@ void ScenePreprocessor::ProcessAnimation (aiAnimation* anim)
* track from the information we have in the transformation
* matrix of the corresponding node.
*/
if (!channel->mNumRotationKeys || !channel->mNumPositionKeys || !channel->mNumScalingKeys)
{
if (!channel->mNumRotationKeys || !channel->mNumPositionKeys || !channel->mNumScalingKeys) {
// Find the node that belongs to this animation
aiNode* node = scene->mRootNode->FindNode(channel->mNodeName);
if (node) // ValidateDS will complain later if 'node' is NULL
@@ -238,8 +222,7 @@ void ScenePreprocessor::ProcessAnimation (aiAnimation* anim)
node->mTransformation.Decompose(scaling, rotation,position);
// No rotation keys? Generate a dummy track
if (!channel->mNumRotationKeys)
{
if (!channel->mNumRotationKeys) {
channel->mNumRotationKeys = 1;
channel->mRotationKeys = new aiQuatKey[1];
aiQuatKey& q = channel->mRotationKeys[0];
@@ -251,8 +234,7 @@ void ScenePreprocessor::ProcessAnimation (aiAnimation* anim)
}
// No scaling keys? Generate a dummy track
if (!channel->mNumScalingKeys)
{
if (!channel->mNumScalingKeys) {
channel->mNumScalingKeys = 1;
channel->mScalingKeys = new aiVectorKey[1];
aiVectorKey& q = channel->mScalingKeys[0];
@@ -264,8 +246,7 @@ void ScenePreprocessor::ProcessAnimation (aiAnimation* anim)
}
// No position keys? Generate a dummy track
if (!channel->mNumPositionKeys)
{
if (!channel->mNumPositionKeys) {
channel->mNumPositionKeys = 1;
channel->mPositionKeys = new aiVectorKey[1];
aiVectorKey& q = channel->mPositionKeys[0];
@@ -278,9 +259,9 @@ void ScenePreprocessor::ProcessAnimation (aiAnimation* anim)
}
}
}
if (anim->mDuration == -1.)
{
DefaultLogger::get()->debug("Setting animation duration");
if (anim->mDuration == -1.) {
DefaultLogger::get()->debug("ScenePreprocessor: Setting animation duration");
anim->mDuration = last - std::min( first, 0. );
}
}
+29 -53
View File
@@ -54,6 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "StreamReader.h"
#include "ParsingUtils.h"
#include "fast_atof.h"
#include "ConvertToLHProcess.h"
using namespace Assimp;
@@ -107,14 +108,10 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
// For any of the 3 files being passed get the three correct paths
// First of all, determine file extension
std::string::size_type pos = pFile.find_last_of('.');
std::string extension = pFile.substr( pos);
for( std::string::iterator it = extension.begin(); it != extension.end(); ++it)
*it = tolower( *it);
std::string extension = GetExtension(pFile);
std::string d_path,a_path,uc_path;
if (extension == ".3d")
{
if (extension == "3d") {
// jjjj_d.3d
// jjjj_a.3d
pos = pFile.find_last_of('_');
@@ -123,8 +120,7 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
}
extension = pFile.substr(0,pos);
}
else // if (extension == ".uc")
{
else {
extension = pFile.substr(0,pos);
}
@@ -154,16 +150,13 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
// collect triangles
std::vector<Unreal::Triangle> triangles(numTris);
for (std::vector<Unreal::Triangle>::iterator it = triangles.begin(), end = triangles.end();
it != end; ++it)
{
for (std::vector<Unreal::Triangle>::iterator it = triangles.begin(), end = triangles.end();it != end; ++it) {
Unreal::Triangle& tri = *it;
for (unsigned int i = 0; i < 3;++i)
{
for (unsigned int i = 0; i < 3;++i) {
tri.mVertex[i] = d_reader.GetI2();
if (tri.mVertex[i] >= numTris)
{
if (tri.mVertex[i] >= numTris) {
DefaultLogger::get()->warn("UNREAL: vertex index out of range");
tri.mVertex[i] = 0;
}
@@ -208,9 +201,7 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
// collect vertices
std::vector<aiVector3D> vertices(numVert);
for (std::vector<aiVector3D>::iterator it = vertices.begin(), end = vertices.end();
it != end; ++it)
{
for (std::vector<aiVector3D>::iterator it = vertices.begin(), end = vertices.end(); it != end; ++it) {
int32_t val = a_reader.GetI4();
Unreal::DecompressVertex(*it,val);
}
@@ -236,8 +227,7 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
std::vector< std::pair< std::string,std::string > > tempTextures;
// do a quick search in the UC file for some known, usually texture-related, tags
for (;*data;++data)
{
for (;*data;++data) {
if (TokenMatchI(data,"#exec",5)) {
SkipSpacesAndLineEnd(&data);
@@ -245,20 +235,16 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
if (TokenMatchI(data,"TEXTURE",7)) {
SkipSpacesAndLineEnd(&data);
if (TokenMatchI(data,"IMPORT",6))
{
if (TokenMatchI(data,"IMPORT",6)) {
tempTextures.push_back(std::pair< std::string,std::string >());
std::pair< std::string,std::string >& me = tempTextures.back();
for (;!IsLineEnd(*data);++data)
{
if (!::ASSIMP_strincmp(data,"NAME=",5))
{
for (;!IsLineEnd(*data);++data) {
if (!::ASSIMP_strincmp(data,"NAME=",5)) {
const char *d = data+=5;
for (;!IsSpaceOrNewLine(*data);++data);
me.first = std::string(d,(size_t)(data-d));
}
else if (!::ASSIMP_strincmp(data,"FILE=",5))
{
else if (!::ASSIMP_strincmp(data,"FILE=",5)) {
const char *d = data+=5;
for (;!IsSpaceOrNewLine(*data);++data);
me.second = std::string(d,(size_t)(data-d));
@@ -279,13 +265,11 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
std::pair<unsigned int, std::string>& me = textures.back();
for (;!IsLineEnd(*data);++data) {
if (!::ASSIMP_strincmp(data,"NUM=",4))
{
if (!::ASSIMP_strincmp(data,"NUM=",4)) {
data += 4;
me.first = strtol10(data,&data);
}
else if (!::ASSIMP_strincmp(data,"TEXTURE=",8))
{
else if (!::ASSIMP_strincmp(data,"TEXTURE=",8)) {
data += 8;
const char *d = data;
for (;!IsSpaceOrNewLine(*data);++data);
@@ -293,10 +277,8 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
// try to find matching path names, doesn't care if we don't find them
for (std::vector< std::pair< std::string,std::string > >::const_iterator it = tempTextures.begin();
it != tempTextures.end(); ++it)
{
if ((*it).first == me.second)
{
it != tempTextures.end(); ++it) {
if ((*it).first == me.second) {
me.second = (*it).second;
break;
}
@@ -330,9 +312,7 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
materials.reserve(textures.size()*2+5);
// find out how many output meshes and materials we'll have and build material indices
for (std::vector<Unreal::Triangle>::iterator it = triangles.begin(), end = triangles.end();
it != end; ++it)
{
for (std::vector<Unreal::Triangle>::iterator it = triangles.begin(), end = triangles.end();it != end; ++it) {
Unreal::Triangle& tri = *it;
Unreal::TempMat mat(tri);
std::vector<Unreal::TempMat>::iterator nt = std::find(materials.begin(),materials.end(),mat);
@@ -389,8 +369,7 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
else ::strcat(s.data,"os_");
// make TRANS faces 90% opaque that RemRedundantMaterials won't catch us
if (materials[i].type == Unreal::MF_NORMAL_TRANS_TS)
{
if (materials[i].type == Unreal::MF_NORMAL_TRANS_TS) {
const float opac = 0.9f;
mat->AddProperty(&opac,1,AI_MATKEY_OPACITY);
::strcat(s.data,"tran_");
@@ -398,8 +377,7 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
else ::strcat(s.data,"opaq_");
// a special name for the weapon attachment point
if (materials[i].type == Unreal::MF_WEAPON_PLACEHOLDER)
{
if (materials[i].type == Unreal::MF_WEAPON_PLACEHOLDER) {
s.length = ::sprintf(s.data,"$WeaponTag$");
color = aiColor3D(0.f,0.f,0.f);
}
@@ -411,11 +389,8 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
// set texture, if any
const unsigned int tex = materials[i].tex;
for (std::vector< std::pair< unsigned int, std::string > >::const_iterator it = textures.begin();
it != textures.end();++it)
{
if ((*it).first == tex)
{
for (std::vector< std::pair< unsigned int, std::string > >::const_iterator it = textures.begin();it != textures.end();++it) {
if ((*it).first == tex) {
s.Set((*it).second);
mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(0));
break;
@@ -424,9 +399,7 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
}
// fill them.
for (std::vector<Unreal::Triangle>::iterator it = triangles.begin(), end = triangles.end();
it != end; ++it)
{
for (std::vector<Unreal::Triangle>::iterator it = triangles.begin(), end = triangles.end();it != end; ++it) {
Unreal::Triangle& tri = *it;
Unreal::TempMat mat(tri);
std::vector<Unreal::TempMat>::iterator nt = std::find(materials.begin(),materials.end(),mat);
@@ -435,14 +408,17 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
aiFace& f = mesh->mFaces[mesh->mNumFaces++];
f.mIndices = new unsigned int[f.mNumIndices = 3];
for (unsigned int i = 0; i < 3;++i,mesh->mNumVertices++)
{
for (unsigned int i = 0; i < 3;++i,mesh->mNumVertices++) {
f.mIndices[i] = mesh->mNumVertices;
mesh->mVertices[mesh->mNumVertices] = vertices[ tri.mVertex[i] ];
mesh->mTextureCoords[0][mesh->mNumVertices] = aiVector3D( tri.mTex[i][0] / 255.f, 1.f - tri.mTex[i][1] / 255.f, 0.f);
}
}
// convert to RH
MakeLeftHandedProcess hero;
hero.Execute(pScene);
}
#endif // !! AI_BUILD_NO_3D_IMPORTER
+8 -20
View File
@@ -47,7 +47,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "XFileImporter.h"
#include "XFileParser.h"
#include "MaterialSystem.h"
#include "ConvertToLHProcess.h"
using namespace Assimp;
@@ -141,9 +140,9 @@ void XFileImporter::CreateDataRepresentationFromImport( aiScene* pScene, const X
CreateMeshes( pScene, pScene->mRootNode, pData->mGlobalMeshes);
}
// convert the root node's transformation to OGL coords
if( pScene->mRootNode)
ConvertToLHProcess::ConvertToOGL( pScene->mRootNode->mTransformation);
// Convert everything to OpenGL space... it's the same operation as the conversion back, so we can reuse the step directly
MakeLeftHandedProcess convertProcess;
convertProcess.Execute( pScene);
// finally: create a dummy material if not material was imported
if( pScene->mNumMaterials == 0)
@@ -305,7 +304,7 @@ void XFileImporter::CreateMeshes( aiScene* pScene, aiNode* pNode, const std::vec
// collect vertex data for indices of this face
for( unsigned int d = 0; d < df.mNumIndices; d++)
{
df.mIndices[df.mNumIndices - 1 - d] = newIndex; // inverted face orientation for OGL
df.mIndices[d] = newIndex;
orgPoints[newIndex] = pf.mIndices[d];
// Position
@@ -313,6 +312,7 @@ void XFileImporter::CreateMeshes( aiScene* pScene, aiNode* pNode, const std::vec
// Normal, if present
if( mesh->HasNormals())
mesh->mNormals[newIndex] = sourceMesh->mNormals[sourceMesh->mNormFaces[f].mIndices[d]];
// texture coord sets
for( unsigned int e = 0; e < AI_MAX_NUMBER_OF_TEXTURECOORDS; e++)
{
@@ -413,9 +413,9 @@ void XFileImporter::CreateAnimations( aiScene* pScene, const XFile::Scene* pData
for( unsigned int a = 0; a < pData->mAnims.size(); a++)
{
const XFile::Animation* anim = pData->mAnims[a];
// some exporters mock me with empty animation tags.
if( anim->mAnims.size() == 0)
continue;
// some exporters mock me with empty animation tags.
if( anim->mAnims.size() == 0)
continue;
// create a new animation to hold the data
aiAnimation* nanim = new aiAnimation;
@@ -434,9 +434,6 @@ void XFileImporter::CreateAnimations( aiScene* pScene, const XFile::Scene* pData
nbone->mNodeName.Set( bone->mBoneName);
nanim->mChannels[b] = nbone;
// apply the LH->RH conversion if the animation affects the root bone
bool isRootAnim = (bone->mBoneName == pScene->mRootNode->mName.data);
// keyframes are given as combined transformation matrix keys
if( bone->mTrafoKeys.size() > 0)
{
@@ -455,8 +452,6 @@ void XFileImporter::CreateAnimations( aiScene* pScene, const XFile::Scene* pData
// extract position
aiVector3D pos( trafo.a4, trafo.b4, trafo.c4);
if( isRootAnim)
ConvertToLHProcess::ConvertToOGL( pos);
nbone->mPositionKeys[c].mTime = time;
nbone->mPositionKeys[c].mValue = pos;
@@ -475,9 +470,6 @@ void XFileImporter::CreateAnimations( aiScene* pScene, const XFile::Scene* pData
trafo.b1 / scale.x, trafo.b2 / scale.y, trafo.b3 / scale.z,
trafo.c1 / scale.x, trafo.c2 / scale.y, trafo.c3 / scale.z);
if( isRootAnim)
ConvertToLHProcess::ConvertToOGL( rotmat);
// and convert it into a quaternion
nbone->mRotationKeys[c].mTime = time;
nbone->mRotationKeys[c].mValue = aiQuaternion( rotmat);
@@ -493,8 +485,6 @@ void XFileImporter::CreateAnimations( aiScene* pScene, const XFile::Scene* pData
for( unsigned int c = 0; c < nbone->mNumPositionKeys; c++)
{
aiVector3D pos = bone->mPosKeys[c].mValue;
if( isRootAnim)
ConvertToLHProcess::ConvertToOGL( pos);
nbone->mPositionKeys[c].mTime = bone->mPosKeys[c].mTime;
nbone->mPositionKeys[c].mValue = pos;
@@ -506,8 +496,6 @@ void XFileImporter::CreateAnimations( aiScene* pScene, const XFile::Scene* pData
for( unsigned int c = 0; c < nbone->mNumRotationKeys; c++)
{
aiMatrix3x3 rotmat = bone->mRotKeys[c].mValue.GetMatrix();
if( isRootAnim)
ConvertToLHProcess::ConvertToOGL( rotmat);
nbone->mRotationKeys[c].mTime = bone->mRotKeys[c].mTime;
nbone->mRotationKeys[c].mValue = aiQuaternion( rotmat);