General
- 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:
+4
-11
@@ -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
File diff suppressed because it is too large
Load Diff
+14
-14
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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());
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+22
-27
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user