Fixed 3DS, ASE, MD3 and Q3D orientation after Schrompf' recent changes to the RH-LH conversion.
WIP version of animation support in the 3DS loader. Still hoping to find out why the pivots aren't handled correctly ... Added first draft of a B3D loader provided by Mark Sibly. Moved DeterminePType-Step to ScenePreprocessor. Small LWO fix. Still texturing problems. git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@231 67173fc5-114c-0410-ac8e-9d2fd5bffc1fpull/1/head
parent
195d9a9cb1
commit
7c50899481
|
@ -519,11 +519,13 @@ void Discreet3DSImporter::ConvertMeshes(aiScene* pcOut)
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Add a node to the scenegraph and setup its final transformation
|
// Add a node to the scenegraph and setup its final transformation
|
||||||
void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Node* pcIn)
|
void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Node* pcIn,
|
||||||
|
aiMatrix4x4& absTrafo)
|
||||||
{
|
{
|
||||||
std::vector<unsigned int> iArray;
|
std::vector<unsigned int> iArray;
|
||||||
iArray.reserve(3);
|
iArray.reserve(3);
|
||||||
|
|
||||||
|
aiMatrix4x4 abs;
|
||||||
if (pcIn->mName == "$$$DUMMY")
|
if (pcIn->mName == "$$$DUMMY")
|
||||||
{
|
{
|
||||||
// append the "real" name of the dummy to the string
|
// append the "real" name of the dummy to the string
|
||||||
|
@ -542,11 +544,21 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Nod
|
||||||
}
|
}
|
||||||
if (!iArray.empty())
|
if (!iArray.empty())
|
||||||
{
|
{
|
||||||
|
// The matrix should be identical for all meshes.
|
||||||
|
// It HAS to be identical for all meshes ........
|
||||||
aiMatrix4x4& mTrafo = ((D3DS::Mesh*)pcSOut->mMeshes[iArray[0]]->mColors[0])->mMat;
|
aiMatrix4x4& mTrafo = ((D3DS::Mesh*)pcSOut->mMeshes[iArray[0]]->mColors[0])->mMat;
|
||||||
aiMatrix4x4 mInv = mTrafo;
|
aiMatrix4x4 mInv = mTrafo;
|
||||||
if (!configSkipPivot)
|
if (!configSkipPivot)
|
||||||
mInv.Inverse();
|
mInv.Inverse();
|
||||||
|
|
||||||
|
/* abs = mTrafo;
|
||||||
|
pcOut->mTransformation = absTrafo;
|
||||||
|
pcOut->mTransformation = pcOut->mTransformation.Inverse() * mTrafo;
|
||||||
|
const aiVector3D& pivot = pcIn->vPivot;
|
||||||
|
aiMatrix4x4 trans;
|
||||||
|
*/
|
||||||
|
const aiVector3D& pivot = pcIn->vPivot;
|
||||||
|
|
||||||
pcOut->mNumMeshes = (unsigned int)iArray.size();
|
pcOut->mNumMeshes = (unsigned int)iArray.size();
|
||||||
pcOut->mMeshes = new unsigned int[iArray.size()];
|
pcOut->mMeshes = new unsigned int[iArray.size()];
|
||||||
for (unsigned int i = 0;i < iArray.size();++i)
|
for (unsigned int i = 0;i < iArray.size();++i)
|
||||||
|
@ -555,7 +567,6 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Nod
|
||||||
aiMesh* const mesh = pcSOut->mMeshes[iIndex];
|
aiMesh* const mesh = pcSOut->mMeshes[iIndex];
|
||||||
|
|
||||||
// http://www.zfx.info/DisplayThread.php?MID=235690#235690
|
// http://www.zfx.info/DisplayThread.php?MID=235690#235690
|
||||||
const aiVector3D& pivot = pcIn->vPivot;
|
|
||||||
const aiVector3D* const pvEnd = mesh->mVertices+mesh->mNumVertices;
|
const aiVector3D* const pvEnd = mesh->mVertices+mesh->mNumVertices;
|
||||||
aiVector3D* pvCurrent = mesh->mVertices;
|
aiVector3D* pvCurrent = mesh->mVertices;
|
||||||
|
|
||||||
|
@ -568,7 +579,6 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Nod
|
||||||
pvCurrent->y -= pivot.y;
|
pvCurrent->y -= pivot.y;
|
||||||
pvCurrent->z -= pivot.z;
|
pvCurrent->z -= pivot.z;
|
||||||
*pvCurrent = mTrafo * (*pvCurrent);
|
*pvCurrent = mTrafo * (*pvCurrent);
|
||||||
//std::swap( pvCurrent->y, pvCurrent->z );
|
|
||||||
++pvCurrent;
|
++pvCurrent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -577,22 +587,81 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Nod
|
||||||
{
|
{
|
||||||
while (pvCurrent != pvEnd)
|
while (pvCurrent != pvEnd)
|
||||||
{
|
{
|
||||||
std::swap( pvCurrent->y, pvCurrent->z );
|
*pvCurrent = mInv * (*pvCurrent);
|
||||||
++pvCurrent;
|
++pvCurrent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Setup the mesh index
|
||||||
pcOut->mMeshes[i] = iIndex;
|
pcOut->mMeshes[i] = iIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate animation channels for the node
|
||||||
|
if (pcIn->aPositionKeys.size() > 0 || pcIn->aRotationKeys.size() > 0 ||
|
||||||
|
pcIn->aScalingKeys.size() > 0 || pcIn->aCameraRollKeys.size() > 0 ||
|
||||||
|
pcIn->aTargetPositionKeys.size() > 0)
|
||||||
|
{
|
||||||
|
aiAnimation* anim = pcSOut->mAnimations[0];
|
||||||
|
ai_assert(NULL != anim);
|
||||||
|
|
||||||
|
// Allocate a new channel, increment the channel index
|
||||||
|
aiNodeAnim* channel = anim->mChannels[anim->mNumChannels++] = new aiNodeAnim();
|
||||||
|
|
||||||
|
// POSITION keys
|
||||||
|
if (pcIn->aPositionKeys.size() > 0)
|
||||||
|
{
|
||||||
|
// Sort all keys with ascending time values
|
||||||
|
std::sort(pcIn->aPositionKeys.begin(),pcIn->aPositionKeys.end());
|
||||||
|
|
||||||
|
channel->mNumPositionKeys = (unsigned int)pcIn->aPositionKeys.size();
|
||||||
|
channel->mPositionKeys = new aiVectorKey[channel->mNumPositionKeys];
|
||||||
|
::memcpy(channel->mPositionKeys,&pcIn->aPositionKeys[0],
|
||||||
|
sizeof(aiVectorKey)*channel->mNumPositionKeys);
|
||||||
|
|
||||||
|
// Get the maximum key
|
||||||
|
anim->mDuration = std::max(anim->mDuration,channel->
|
||||||
|
mPositionKeys[channel->mNumPositionKeys-1].mTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ROTATION keys
|
||||||
|
if (pcIn->aRotationKeys.size() > 0)
|
||||||
|
{
|
||||||
|
// Sort all keys with ascending time values
|
||||||
|
std::sort(pcIn->aRotationKeys.begin(),pcIn->aRotationKeys.end());
|
||||||
|
|
||||||
|
channel->mNumRotationKeys = (unsigned int)pcIn->aRotationKeys.size();
|
||||||
|
channel->mRotationKeys = new aiQuatKey[channel->mNumRotationKeys];
|
||||||
|
::memcpy(channel->mRotationKeys,&pcIn->aRotationKeys[0],
|
||||||
|
sizeof(aiQuatKey)*channel->mNumRotationKeys);
|
||||||
|
|
||||||
|
// Get the maximum key
|
||||||
|
anim->mDuration = std::max(anim->mDuration,channel->
|
||||||
|
mRotationKeys[channel->mNumRotationKeys-1].mTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
// SCALING keys
|
||||||
|
if (pcIn->aScalingKeys.size() > 0)
|
||||||
|
{
|
||||||
|
// Sort all keys with ascending time values
|
||||||
|
std::sort(pcIn->aScalingKeys.begin(),pcIn->aScalingKeys.end());
|
||||||
|
|
||||||
|
channel->mNumScalingKeys = (unsigned int)pcIn->aScalingKeys.size();
|
||||||
|
channel->mScalingKeys = new aiVectorKey[channel->mNumScalingKeys];
|
||||||
|
::memcpy(channel->mScalingKeys,&pcIn->aScalingKeys[0],
|
||||||
|
sizeof(aiVectorKey)*channel->mNumScalingKeys);
|
||||||
|
|
||||||
|
// Get the maximum key
|
||||||
|
anim->mDuration = std::max(anim->mDuration,channel->
|
||||||
|
mScalingKeys[channel->mNumScalingKeys-1].mTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Setup the name of the node
|
// Setup the name of the node
|
||||||
pcOut->mName.Set(pcIn->mName);
|
pcOut->mName.Set(pcIn->mName);
|
||||||
|
|
||||||
// Setup the transformation matrix of the node
|
|
||||||
pcOut->mTransformation = aiMatrix4x4();
|
|
||||||
|
|
||||||
// Allocate storage for children
|
// Allocate storage for children
|
||||||
pcOut->mNumChildren = (unsigned int)pcIn->mChildren.size();
|
pcOut->mNumChildren = (unsigned int)pcIn->mChildren.size();
|
||||||
pcOut->mChildren = new aiNode*[pcIn->mChildren.size()];
|
pcOut->mChildren = new aiNode*[pcIn->mChildren.size()];
|
||||||
|
@ -602,11 +671,30 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Nod
|
||||||
{
|
{
|
||||||
pcOut->mChildren[i] = new aiNode();
|
pcOut->mChildren[i] = new aiNode();
|
||||||
pcOut->mChildren[i]->mParent = pcOut;
|
pcOut->mChildren[i]->mParent = pcOut;
|
||||||
AddNodeToGraph(pcSOut,pcOut->mChildren[i],pcIn->mChildren[i]);
|
AddNodeToGraph(pcSOut,pcOut->mChildren[i],pcIn->mChildren[i],abs);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Find out how many node animation channels we'll have finally
|
||||||
|
void CountTracks(D3DS::Node* node, unsigned int& cnt)
|
||||||
|
{
|
||||||
|
// We will never generate more than one channel for a node, so
|
||||||
|
// this is rather easy here.
|
||||||
|
|
||||||
|
if (node->aPositionKeys.size() > 0 || node->aRotationKeys.size() > 0 ||
|
||||||
|
node->aScalingKeys.size() > 0 || node->aCameraRollKeys.size() > 0 ||
|
||||||
|
node->aTargetPositionKeys.size() > 0)
|
||||||
|
{
|
||||||
|
++cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recursively process all children
|
||||||
|
for (unsigned int i = 0; i < node->mChildren.size();++i)
|
||||||
|
CountTracks(node->mChildren[i],cnt);
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Generate the output node graph
|
// Generate the output node graph
|
||||||
void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut)
|
void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut)
|
||||||
|
@ -670,9 +758,26 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut)
|
||||||
{
|
{
|
||||||
// First of all: find out how many scaling, rotation and translation
|
// First of all: find out how many scaling, rotation and translation
|
||||||
// animation tracks we'll have afterwards
|
// animation tracks we'll have afterwards
|
||||||
//unsigned int numRot = 0, numScale = 0, numTranslate = 0;
|
unsigned int numChannel = 0;
|
||||||
//CountTracks(mRootNode,numRot,numScale,numTranslate);
|
CountTracks(mRootNode,numChannel);
|
||||||
AddNodeToGraph(pcOut, pcOut->mRootNode, mRootNode);
|
|
||||||
|
if (numChannel)
|
||||||
|
{
|
||||||
|
// Allocate a primary animation channel
|
||||||
|
pcOut->mNumAnimations = 1;
|
||||||
|
pcOut->mAnimations = new aiAnimation*[1];
|
||||||
|
aiAnimation* anim = pcOut->mAnimations[0] = new aiAnimation();
|
||||||
|
|
||||||
|
anim->mName.Set("3DSMasterAnim");
|
||||||
|
|
||||||
|
// Allocate enough storage for all node animation channels,
|
||||||
|
// but don't set the mNumChannels member - we'll use it to
|
||||||
|
// index into the array
|
||||||
|
anim->mChannels = new aiNodeAnim*[numChannel];
|
||||||
|
}
|
||||||
|
|
||||||
|
aiMatrix4x4 m;
|
||||||
|
AddNodeToGraph(pcOut, pcOut->mRootNode, mRootNode,m);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We used the first vertex color set to store some
|
// We used the first vertex color set to store some
|
||||||
|
@ -694,11 +799,13 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut)
|
||||||
if (pcOut->mRootNode->mName.data[0] == '$' && pcOut->mRootNode->mName.data[1] == '$')
|
if (pcOut->mRootNode->mName.data[0] == '$' && pcOut->mRootNode->mName.data[1] == '$')
|
||||||
pcOut->mRootNode->mName.Set("<root>");
|
pcOut->mRootNode->mName.Set("<root>");
|
||||||
|
|
||||||
|
#if 0
|
||||||
// modify the transformation of the root node to change
|
// modify the transformation of the root node to change
|
||||||
// the coordinate system of the whole scene from Max' to OpenGL
|
// the coordinate system of the whole scene from Max' to OpenGL
|
||||||
pcOut->mRootNode->mTransformation.a3 *= -1.f;
|
pcOut->mRootNode->mTransformation.a3 *= -1.f;
|
||||||
pcOut->mRootNode->mTransformation.b3 *= -1.f;
|
pcOut->mRootNode->mTransformation.b3 *= -1.f;
|
||||||
pcOut->mRootNode->mTransformation.c3 *= -1.f;
|
pcOut->mRootNode->mTransformation.c3 *= -1.f;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -566,11 +566,14 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
|
||||||
// (target animation channels are stored with a
|
// (target animation channels are stored with a
|
||||||
// separate object ID)
|
// separate object ID)
|
||||||
D3DS::Node* pcNode = FindNode(mRootNode,name);
|
D3DS::Node* pcNode = FindNode(mRootNode,name);
|
||||||
if (!pcNode)
|
if (pcNode)
|
||||||
{
|
{
|
||||||
pcNode = new D3DS::Node();
|
// Make this node the current node
|
||||||
pcNode->mName = name;
|
mCurrentNode = pcNode;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
pcNode = new D3DS::Node();
|
||||||
|
pcNode->mName = name;
|
||||||
|
|
||||||
// There are two unknown values which we can safely ignore
|
// There are two unknown values which we can safely ignore
|
||||||
stream->IncPtr(4);
|
stream->IncPtr(4);
|
||||||
|
|
|
@ -219,7 +219,8 @@ protected:
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Add a node to the node graph
|
/** Add a node to the node graph
|
||||||
*/
|
*/
|
||||||
void AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Node* pcIn);
|
void AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Node* pcIn,
|
||||||
|
aiMatrix4x4& absTrafo);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Search for a node in the graph.
|
/** Search for a node in the graph.
|
||||||
|
|
|
@ -556,12 +556,15 @@ void ASEImporter::AddNodes (std::vector<BaseNode*>& nodes,
|
||||||
|
|
||||||
// allocate enough space for the child nodes
|
// allocate enough space for the child nodes
|
||||||
pcParent->mNumChildren = (unsigned int)apcNodes.size();
|
pcParent->mNumChildren = (unsigned int)apcNodes.size();
|
||||||
pcParent->mChildren = new aiNode*[apcNodes.size()];
|
if (pcParent->mNumChildren)
|
||||||
|
|
||||||
// now build all nodes for our nice new children
|
|
||||||
for (unsigned int p = 0; p < apcNodes.size();++p)
|
|
||||||
{
|
{
|
||||||
pcParent->mChildren[p] = apcNodes[p];
|
pcParent->mChildren = new aiNode*[apcNodes.size()];
|
||||||
|
|
||||||
|
// now build all nodes for our nice new children
|
||||||
|
for (unsigned int p = 0; p < apcNodes.size();++p)
|
||||||
|
{
|
||||||
|
pcParent->mChildren[p] = apcNodes[p];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -578,7 +581,7 @@ void ASEImporter::BuildNodes()
|
||||||
pcScene->mRootNode->mName.Set("<root>");
|
pcScene->mRootNode->mName.Set("<root>");
|
||||||
|
|
||||||
// Setup the coordinate system transformation
|
// Setup the coordinate system transformation
|
||||||
pcScene->mRootNode->mTransformation.c3 *= -1.f;
|
//pcScene->mRootNode->mTransformation.c3 *= -1.f;
|
||||||
pcScene->mRootNode->mNumChildren = 1;
|
pcScene->mRootNode->mNumChildren = 1;
|
||||||
pcScene->mRootNode->mChildren = new aiNode*[1];
|
pcScene->mRootNode->mChildren = new aiNode*[1];
|
||||||
pcScene->mRootNode->mChildren[0] = new aiNode();
|
pcScene->mRootNode->mChildren[0] = new aiNode();
|
||||||
|
@ -744,7 +747,7 @@ void ASEImporter::BuildUniqueRepresentation(ASE::Mesh& mesh)
|
||||||
if (!mesh.amTexCoords[c].empty())
|
if (!mesh.amTexCoords[c].empty())
|
||||||
{
|
{
|
||||||
amTexCoords[c][iCurrent] = mesh.amTexCoords[c][(*i).amUVIndices[c][n]];
|
amTexCoords[c][iCurrent] = mesh.amTexCoords[c][(*i).amUVIndices[c][n]];
|
||||||
amTexCoords[c][iCurrent].y = 1.0f - amTexCoords[c][iCurrent].y; // DX-to-OGL
|
// amTexCoords[c][iCurrent].y = 1.f- amTexCoords[c][iCurrent].y; // DX-to-OGL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// add vertex colors
|
// add vertex colors
|
||||||
|
|
|
@ -0,0 +1,377 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (ASSIMP)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2008, ASSIMP Development Team
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the following
|
||||||
|
conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the ASSIMP team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the ASSIMP Development Team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file Implementation of the b3d importer class */
|
||||||
|
|
||||||
|
#include "AssimpPCH.h"
|
||||||
|
|
||||||
|
// internal headers
|
||||||
|
#include "B3DImporter.h"
|
||||||
|
#include "TextureTransform.h"
|
||||||
|
|
||||||
|
using namespace Assimp;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
bool B3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler) const{
|
||||||
|
|
||||||
|
int pos=pFile.find_last_of( '.' );
|
||||||
|
if( pos==string::npos ) return false;
|
||||||
|
|
||||||
|
string ext=pFile.substr( pos+1 );
|
||||||
|
if( ext.size()!=3 ) return false;
|
||||||
|
|
||||||
|
return (ext[0]=='b' || ext[0]=='B') && (ext[1]=='3') && (ext[2]=='d' || ext[2]=='D');
|
||||||
|
}
|
||||||
|
|
||||||
|
void B3DImporter::GetExtensionList( std::string& append ){
|
||||||
|
append.append("*.b3d");
|
||||||
|
}
|
||||||
|
|
||||||
|
void B3DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler){
|
||||||
|
|
||||||
|
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
|
||||||
|
|
||||||
|
// Check whether we can read from the file
|
||||||
|
if( file.get() == NULL)
|
||||||
|
throw new ImportErrorException( "Failed to open B3D file " + pFile + ".");
|
||||||
|
|
||||||
|
// check whether the .b3d file is large enough to contain
|
||||||
|
// at least one chunk.
|
||||||
|
size_t fileSize = file->FileSize();
|
||||||
|
if( fileSize < 8) throw new ImportErrorException( "B3D File is too small.");
|
||||||
|
|
||||||
|
_pos=0;
|
||||||
|
_buf.resize( fileSize );
|
||||||
|
file->Read( &_buf[0],1,fileSize );
|
||||||
|
_stack.clear();
|
||||||
|
_textures.clear();
|
||||||
|
_materials.size();
|
||||||
|
_vertices.clear();
|
||||||
|
_meshes.clear();
|
||||||
|
|
||||||
|
ReadBB3D();
|
||||||
|
|
||||||
|
//materials
|
||||||
|
aiMaterial **mats=new aiMaterial*[_materials.size()];
|
||||||
|
for( unsigned i=0;i<_materials.size();++i ){
|
||||||
|
mats[i]=_materials[i];
|
||||||
|
}
|
||||||
|
pScene->mNumMaterials=_materials.size();
|
||||||
|
pScene->mMaterials=mats;
|
||||||
|
|
||||||
|
//meshes
|
||||||
|
aiMesh **meshes=new aiMesh*[_meshes.size()];
|
||||||
|
for( unsigned i=0;i<_meshes.size();++i ){
|
||||||
|
meshes[i]=_meshes[i];
|
||||||
|
}
|
||||||
|
pScene->mNumMeshes=_meshes.size();
|
||||||
|
pScene->mMeshes=meshes;
|
||||||
|
|
||||||
|
//nodes - NOTE: Have to create mMeshes array here or crash 'n' burn.
|
||||||
|
aiNode *node=new aiNode( "root" );
|
||||||
|
node->mNumMeshes=_meshes.size();
|
||||||
|
node->mMeshes=new unsigned[_meshes.size()];
|
||||||
|
for( unsigned i=0;i<_meshes.size();++i ){
|
||||||
|
node->mMeshes[i]=i;
|
||||||
|
}
|
||||||
|
pScene->mRootNode=node;
|
||||||
|
}
|
||||||
|
|
||||||
|
int B3DImporter::ReadByte(){
|
||||||
|
if( _pos<_buf.size() ) return _buf[_pos++];
|
||||||
|
throw new ImportErrorException( "B3D EOF Error" );
|
||||||
|
}
|
||||||
|
|
||||||
|
int B3DImporter::ReadInt(){
|
||||||
|
if( _pos+4<=_buf.size() ){
|
||||||
|
int n=*(int*)&_buf[_pos];
|
||||||
|
_pos+=4;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
throw new ImportErrorException( "B3D EOF Error" );
|
||||||
|
}
|
||||||
|
|
||||||
|
float B3DImporter::ReadFloat(){
|
||||||
|
if( _pos+4<=_buf.size() ){
|
||||||
|
float n=*(float*)&_buf[_pos];
|
||||||
|
_pos+=4;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
throw new ImportErrorException( "B3D EOF Error" );
|
||||||
|
}
|
||||||
|
|
||||||
|
B3DImporter::Vec2 B3DImporter::ReadVec2(){
|
||||||
|
Vec2 t;
|
||||||
|
t.x=ReadFloat();
|
||||||
|
t.y=ReadFloat();
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
B3DImporter::Vec3 B3DImporter::ReadVec3(){
|
||||||
|
Vec3 t;
|
||||||
|
t.x=ReadFloat();
|
||||||
|
t.y=ReadFloat();
|
||||||
|
t.z=ReadFloat();
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
B3DImporter::Vec4 B3DImporter::ReadVec4(){
|
||||||
|
Vec4 t;
|
||||||
|
t.x=ReadFloat();
|
||||||
|
t.y=ReadFloat();
|
||||||
|
t.z=ReadFloat();
|
||||||
|
t.w=ReadFloat();
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
string B3DImporter::ReadString(){
|
||||||
|
string str;
|
||||||
|
while( _pos<_buf.size() ){
|
||||||
|
char c=(char)ReadByte();
|
||||||
|
if( !c ) return str;
|
||||||
|
str+=c;
|
||||||
|
}
|
||||||
|
throw new ImportErrorException( "B3D EOF Error" );
|
||||||
|
}
|
||||||
|
|
||||||
|
string B3DImporter::ReadChunk(){
|
||||||
|
string tag;
|
||||||
|
for( int i=0;i<4;++i ){
|
||||||
|
tag+=char( ReadByte() );
|
||||||
|
}
|
||||||
|
// cout<<"ReadChunk:"<<tag<<endl;
|
||||||
|
unsigned sz=(unsigned)ReadInt();
|
||||||
|
_stack.push_back( _pos+sz );
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
void B3DImporter::ExitChunk(){
|
||||||
|
_pos=_stack.back();
|
||||||
|
_stack.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned B3DImporter::ChunkSize(){
|
||||||
|
return _stack.back()-_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void B3DImporter::ReadTEXS(){
|
||||||
|
while( ChunkSize() ){
|
||||||
|
string name=ReadString();
|
||||||
|
int flags=ReadInt();
|
||||||
|
int blend=ReadInt();
|
||||||
|
Vec2 pos=ReadVec2();
|
||||||
|
Vec2 scale=ReadVec2();
|
||||||
|
float rot=ReadFloat();
|
||||||
|
|
||||||
|
Texture tex;
|
||||||
|
tex.name=name;
|
||||||
|
_textures.push_back( tex );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void B3DImporter::ReadBRUS(){
|
||||||
|
int n_texs=ReadInt();
|
||||||
|
while( ChunkSize() ){
|
||||||
|
string name=ReadString();
|
||||||
|
Vec4 color=ReadVec4();
|
||||||
|
float shiny=ReadFloat();
|
||||||
|
int blend=ReadInt();
|
||||||
|
int fx=ReadInt();
|
||||||
|
|
||||||
|
MaterialHelper *mat=new MaterialHelper;
|
||||||
|
_materials.push_back( mat );
|
||||||
|
|
||||||
|
for( int i=0;i<n_texs;++i ){
|
||||||
|
int texid=ReadInt();
|
||||||
|
if( !i ){
|
||||||
|
//just use tex 0 for now
|
||||||
|
const Texture &tex=_textures[texid];
|
||||||
|
|
||||||
|
aiString texstr;
|
||||||
|
texstr.Set( tex.name );
|
||||||
|
mat->AddProperty( &texstr,AI_MATKEY_TEXTURE_DIFFUSE(0) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void B3DImporter::ReadVRTS(){
|
||||||
|
int vertFlags=ReadInt();
|
||||||
|
int tc_sets=ReadInt();
|
||||||
|
int tc_size=ReadInt();
|
||||||
|
|
||||||
|
if( tc_sets<0 || tc_sets>4 || tc_size<0 || tc_size>4 ) throw new ImportErrorException( "B3D Param Error" );
|
||||||
|
|
||||||
|
while( ChunkSize() ){
|
||||||
|
Vertex vert;
|
||||||
|
|
||||||
|
vert.position=ReadVec3();
|
||||||
|
|
||||||
|
if( vertFlags & 1 ){
|
||||||
|
vert.normal=ReadVec3();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( vertFlags & 2 ){
|
||||||
|
Vec4 color=ReadVec4();
|
||||||
|
}
|
||||||
|
|
||||||
|
for( int i=0;i<tc_sets;++i ){
|
||||||
|
float texcoords[4]={0,0,0,0};
|
||||||
|
for( int j=0;j<tc_size;++j ){
|
||||||
|
texcoords[j]=ReadFloat();
|
||||||
|
}
|
||||||
|
if( !i ) memcpy( &vert.texcoords.x,texcoords,12 );
|
||||||
|
}
|
||||||
|
_vertices.push_back( vert );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void B3DImporter::ReadTRIS(){
|
||||||
|
int matid=ReadInt();
|
||||||
|
|
||||||
|
for( vector<Vertex>::iterator it=_vertices.begin();it!=_vertices.end();++it ){
|
||||||
|
it->index=-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<int> verts,tris;
|
||||||
|
|
||||||
|
while( ChunkSize() ){
|
||||||
|
int i=ReadInt();
|
||||||
|
Vertex &vert=_vertices[i];
|
||||||
|
if( vert.index==-1 ){
|
||||||
|
vert.index=verts.size();
|
||||||
|
verts.push_back( i );
|
||||||
|
}
|
||||||
|
tris.push_back( vert.index );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( verts.empty() || tris.empty() ) return;
|
||||||
|
|
||||||
|
unsigned n_verts=verts.size();
|
||||||
|
unsigned n_tris=tris.size()/3;
|
||||||
|
|
||||||
|
//OK, we have a whole mesh...
|
||||||
|
aiVector3D *mv=new aiVector3D[n_verts];
|
||||||
|
aiVector3D *mn=new aiVector3D[n_verts];
|
||||||
|
aiVector3D *mc=new aiVector3D[n_verts];
|
||||||
|
for( unsigned i=0;i<n_verts;++i ){
|
||||||
|
Vertex &v=_vertices[verts[i]];
|
||||||
|
memcpy( &mv[i].x,&v.position.x,12 );
|
||||||
|
memcpy( &mn[i].x,&v.normal.x,12 );
|
||||||
|
memcpy( &mc[i].x,&v.texcoords.x,12 );
|
||||||
|
}
|
||||||
|
|
||||||
|
aiFace *faces=new aiFace[n_tris];
|
||||||
|
for( unsigned i=0;i<n_tris;++i ){
|
||||||
|
faces[i].mNumIndices=3;
|
||||||
|
unsigned *ip=faces[i].mIndices=new unsigned[3];
|
||||||
|
ip[0]=tris[i*3];
|
||||||
|
ip[1]=tris[i*3+1];
|
||||||
|
ip[2]=tris[i*3+2];
|
||||||
|
}
|
||||||
|
|
||||||
|
aiMesh *mesh=new aiMesh;
|
||||||
|
|
||||||
|
mesh->mMaterialIndex=matid;
|
||||||
|
|
||||||
|
mesh->mNumVertices=n_verts;
|
||||||
|
mesh->mVertices=mv;
|
||||||
|
mesh->mNormals=mn;
|
||||||
|
mesh->mTextureCoords[0]=mc;
|
||||||
|
|
||||||
|
mesh->mNumFaces=n_tris;
|
||||||
|
mesh->mFaces=faces;
|
||||||
|
|
||||||
|
_meshes.push_back( mesh );
|
||||||
|
}
|
||||||
|
|
||||||
|
void B3DImporter::ReadMESH(){
|
||||||
|
int matid=ReadInt();
|
||||||
|
|
||||||
|
_vertices.clear();
|
||||||
|
|
||||||
|
while( ChunkSize() ){
|
||||||
|
string t=ReadChunk();
|
||||||
|
if( t=="VRTS" ){
|
||||||
|
ReadVRTS();
|
||||||
|
}else if( t=="TRIS" ){
|
||||||
|
ReadTRIS();
|
||||||
|
}
|
||||||
|
ExitChunk();
|
||||||
|
}
|
||||||
|
|
||||||
|
_vertices.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void B3DImporter::ReadNODE(){
|
||||||
|
|
||||||
|
string name=ReadString();
|
||||||
|
Vec3 trans=ReadVec3();
|
||||||
|
Vec3 scale=ReadVec3();
|
||||||
|
Vec4 rot=ReadVec4();
|
||||||
|
|
||||||
|
while( ChunkSize() ){
|
||||||
|
string t=ReadChunk();
|
||||||
|
if( t=="MESH" ){
|
||||||
|
ReadMESH();
|
||||||
|
}
|
||||||
|
ExitChunk();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void B3DImporter::ReadBB3D(){
|
||||||
|
string t=ReadChunk();
|
||||||
|
if( t=="BB3D" ){
|
||||||
|
int version=ReadInt();
|
||||||
|
while( ChunkSize() ){
|
||||||
|
string t=ReadChunk();
|
||||||
|
if( t=="TEXS" ){
|
||||||
|
ReadTEXS();
|
||||||
|
}else if( t=="BRUS" ){
|
||||||
|
ReadBRUS();
|
||||||
|
}else if( t=="NODE" ){
|
||||||
|
ReadNODE();
|
||||||
|
}
|
||||||
|
ExitChunk();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ExitChunk();
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
Open Asset Import Library (ASSIMP)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2008, ASSIMP Development Team
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the
|
||||||
|
following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the ASSIMP team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the ASSIMP Development Team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file Definition of the .b3d importer class. */
|
||||||
|
|
||||||
|
#ifndef AI_B3DIMPORTER_H_INC
|
||||||
|
#define AI_B3DIMPORTER_H_INC
|
||||||
|
|
||||||
|
#include "../include/aiTypes.h"
|
||||||
|
#include "../include/aiMesh.h"
|
||||||
|
#include "../include/aiMaterial.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace Assimp{
|
||||||
|
|
||||||
|
class B3DImporter : public BaseImporter{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual bool CanRead( const std::string& pFile, IOSystem* pIOHandler) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual void GetExtensionList(std::string& append);
|
||||||
|
virtual void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
struct Vec2{ float x,y; };
|
||||||
|
struct Vec3{ float x,y,z; };
|
||||||
|
struct Vec4{ float x,y,z,w; };
|
||||||
|
struct Texture{ std::string name; };
|
||||||
|
struct Vertex{ int index;Vec3 position,normal,texcoords; };
|
||||||
|
|
||||||
|
int ReadByte();
|
||||||
|
int ReadInt();
|
||||||
|
float ReadFloat();
|
||||||
|
Vec2 ReadVec2();
|
||||||
|
Vec3 ReadVec3();
|
||||||
|
Vec4 ReadVec4();
|
||||||
|
std::string ReadString();
|
||||||
|
std::string ReadChunk();
|
||||||
|
void ExitChunk();
|
||||||
|
unsigned ChunkSize();
|
||||||
|
|
||||||
|
void ReadTEXS();
|
||||||
|
void ReadBRUS();
|
||||||
|
void ReadVRTS();
|
||||||
|
void ReadTRIS();
|
||||||
|
void ReadMESH();
|
||||||
|
void ReadNODE();
|
||||||
|
void ReadBB3D();
|
||||||
|
|
||||||
|
unsigned _pos;
|
||||||
|
unsigned _size;
|
||||||
|
std::vector<unsigned char> _buf;
|
||||||
|
std::vector<unsigned> _stack;
|
||||||
|
|
||||||
|
std::vector<Texture> _textures;
|
||||||
|
std::vector<MaterialHelper*> _materials;
|
||||||
|
std::vector<Vertex> _vertices;
|
||||||
|
std::vector<aiMesh*> _meshes;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -130,6 +130,29 @@ void IRRImporter::GenerateGraph(Node* root,aiNode* rootOut ,aiScene* scene,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
attach.push_back(AttachmentInfo(scene,rootOut));
|
attach.push_back(AttachmentInfo(scene,rootOut));
|
||||||
|
|
||||||
|
// now combine the material we've loaded for this mesh
|
||||||
|
// with the real meshes 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)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
// delete the old material
|
||||||
|
delete scene->mMaterials[i];
|
||||||
|
|
||||||
|
std::pair<aiMaterial*, unsigned int>& src = root->materials[i];
|
||||||
|
scene->mMaterials[i] = src.first;
|
||||||
|
|
||||||
|
// Process material flags (e.g. lightmapping)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -455,6 +455,7 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
|
||||||
int textMeaning = 0;
|
int textMeaning = 0;
|
||||||
int vertexFormat = 0; // 0 = normal; 1 = 2 tcoords, 2 = tangents
|
int vertexFormat = 0; // 0 = normal; 1 = 2 tcoords, 2 = tangents
|
||||||
bool useColors = false;
|
bool useColors = false;
|
||||||
|
bool needLightMap = false;
|
||||||
|
|
||||||
// Parse the XML file
|
// Parse the XML file
|
||||||
while (reader->read())
|
while (reader->read())
|
||||||
|
@ -752,7 +753,12 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
|
||||||
mat->AddProperty(&curColors[0].a,1,AI_MATKEY_OPACITY);
|
mat->AddProperty(&curColors[0].a,1,AI_MATKEY_OPACITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Add lightmapping support here */
|
// store the material flags for later use
|
||||||
|
curMesh->mNumUVComponents[3] = curMatFlags;
|
||||||
|
if ( curMatFlags & AI_IRRMESH_MAT_lightmap )
|
||||||
|
{
|
||||||
|
needLightMap = true;
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -783,10 +789,22 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
|
||||||
if (materials.empty())
|
if (materials.empty())
|
||||||
throw new ImportErrorException("IRRMESH: Unable to read a mesh from this file");
|
throw new ImportErrorException("IRRMESH: Unable to read a mesh from this file");
|
||||||
|
|
||||||
|
if(needLightMap)
|
||||||
|
{
|
||||||
|
// Compute light map UV coordinates
|
||||||
|
// ComputeLightMapUVCoordinates(meshes,materials);
|
||||||
|
}
|
||||||
|
|
||||||
// now generate the output scene
|
// now generate the output scene
|
||||||
pScene->mNumMeshes = (unsigned int)meshes.size();
|
pScene->mNumMeshes = (unsigned int)meshes.size();
|
||||||
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
|
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
|
||||||
::memcpy(pScene->mMeshes,&meshes[0],sizeof(void*)*pScene->mNumMeshes);
|
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
|
||||||
|
{
|
||||||
|
pScene->mMeshes[i] = meshes[i];
|
||||||
|
|
||||||
|
// clean this value ...
|
||||||
|
pScene->mMeshes[i]->mNumUVComponents[3] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
pScene->mNumMaterials = (unsigned int)materials.size();
|
pScene->mNumMaterials = (unsigned int)materials.size();
|
||||||
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
|
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
|
||||||
|
|
|
@ -126,6 +126,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef AI_BUILD_NO_Q3D_IMPORTER
|
#ifndef AI_BUILD_NO_Q3D_IMPORTER
|
||||||
# include "Q3DLoader.h"
|
# include "Q3DLoader.h"
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef AI_BUILD_NO_B3D_IMPORTER
|
||||||
|
# include "B3DImporter.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// PostProcess-Steps
|
// PostProcess-Steps
|
||||||
|
@ -180,14 +183,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef AI_BUILD_NO_FINDDEGENERATES_PROCESS
|
#ifndef AI_BUILD_NO_FINDDEGENERATES_PROCESS
|
||||||
# include "FindDegenerates.h"
|
# include "FindDegenerates.h"
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef AI_BUILD_NO_SORTBYPTYPE_PROCESS
|
||||||
// NOTE: the preprocessor code has been moved to the header as
|
|
||||||
// we've also declared the DeterminePType process in it, which
|
|
||||||
// can't be removed.
|
|
||||||
|
|
||||||
//#ifndef AI_BUILD_NO_SORTBYPTYPE_PROCESS
|
|
||||||
# include "SortByPTypeProcess.h"
|
# include "SortByPTypeProcess.h"
|
||||||
//#endif
|
#endif
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
|
@ -282,6 +280,9 @@ Importer::Importer() :
|
||||||
#if (!defined AI_BUILD_NO_Q3D_IMPORTER)
|
#if (!defined AI_BUILD_NO_Q3D_IMPORTER)
|
||||||
mImporter.push_back( new Q3DImporter());
|
mImporter.push_back( new Q3DImporter());
|
||||||
#endif
|
#endif
|
||||||
|
#if (!defined AI_BUILD_NO_B3D_IMPORTER)
|
||||||
|
mImporter.push_back( new B3DImporter());
|
||||||
|
#endif
|
||||||
|
|
||||||
// add an instance of each post processing step here in the order
|
// add an instance of each post processing step here in the order
|
||||||
// of sequence it is executed. steps that are added here are not validated -
|
// of sequence it is executed. steps that are added here are not validated -
|
||||||
|
@ -292,8 +293,6 @@ Importer::Importer() :
|
||||||
mPostProcessingSteps.push_back( new ValidateDSProcess());
|
mPostProcessingSteps.push_back( new ValidateDSProcess());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mPostProcessingSteps.push_back( new DeterminePTypeHelperProcess());
|
|
||||||
|
|
||||||
|
|
||||||
#if (!defined AI_BUILD_NO_FINDDEGENERATES_PROCESS)
|
#if (!defined AI_BUILD_NO_FINDDEGENERATES_PROCESS)
|
||||||
mPostProcessingSteps.push_back( new FindDegeneratesProcess());
|
mPostProcessingSteps.push_back( new FindDegeneratesProcess());
|
||||||
|
|
|
@ -143,6 +143,8 @@ void LWOImporter::InternReadFile( const std::string& pFile,
|
||||||
// old lightwave file format (prior to v6)
|
// old lightwave file format (prior to v6)
|
||||||
if (AI_LWO_FOURCC_LWOB == fileType)
|
if (AI_LWO_FOURCC_LWOB == fileType)
|
||||||
{
|
{
|
||||||
|
DefaultLogger::get()->info("LWO file format: LWOB (<= LightWave 5.5)");
|
||||||
|
|
||||||
mIsLWO2 = false;
|
mIsLWO2 = false;
|
||||||
this->LoadLWOBFile();
|
this->LoadLWOBFile();
|
||||||
}
|
}
|
||||||
|
@ -150,6 +152,8 @@ void LWOImporter::InternReadFile( const std::string& pFile,
|
||||||
// new lightwave format
|
// new lightwave format
|
||||||
else if (AI_LWO_FOURCC_LWO2 == fileType)
|
else if (AI_LWO_FOURCC_LWO2 == fileType)
|
||||||
{
|
{
|
||||||
|
DefaultLogger::get()->info("LWO file format: LWO2 (>= LightWave 6)");
|
||||||
|
|
||||||
mIsLWO2 = true;
|
mIsLWO2 = true;
|
||||||
this->LoadLWO2File();
|
this->LoadLWO2File();
|
||||||
}
|
}
|
||||||
|
@ -307,7 +311,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
|
||||||
aiVector3D*& pp = pvUV[w];
|
aiVector3D*& pp = pvUV[w];
|
||||||
const aiVector2D& src = ((aiVector2D*)&layer.mUVChannels[vUVChannelIndices[w]].rawData[0])[idx];
|
const aiVector2D& src = ((aiVector2D*)&layer.mUVChannels[vUVChannelIndices[w]].rawData[0])[idx];
|
||||||
pp->x = src.x;
|
pp->x = src.x;
|
||||||
pp->y = 1.f-src.y; // DX to OGL
|
pp->y = src.y; // DX to OGL
|
||||||
pp++;
|
pp++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -297,14 +297,14 @@ void MD3Importer::InternReadFile(
|
||||||
{
|
{
|
||||||
// read vertices
|
// read vertices
|
||||||
pcMesh->mVertices[iCurrent].x = pcVertices[ pcTriangles->INDEXES[c]].X*AI_MD3_XYZ_SCALE;
|
pcMesh->mVertices[iCurrent].x = pcVertices[ pcTriangles->INDEXES[c]].X*AI_MD3_XYZ_SCALE;
|
||||||
pcMesh->mVertices[iCurrent].y = pcVertices[ pcTriangles->INDEXES[c]].Y*-1.0f*AI_MD3_XYZ_SCALE;
|
pcMesh->mVertices[iCurrent].y = pcVertices[ pcTriangles->INDEXES[c]].Y*AI_MD3_XYZ_SCALE;
|
||||||
pcMesh->mVertices[iCurrent].z = pcVertices[ pcTriangles->INDEXES[c]].Z*AI_MD3_XYZ_SCALE;
|
pcMesh->mVertices[iCurrent].z = pcVertices[ pcTriangles->INDEXES[c]].Z*AI_MD3_XYZ_SCALE;
|
||||||
|
|
||||||
// convert the normal vector to uncompressed float3 format
|
// convert the normal vector to uncompressed float3 format
|
||||||
LatLngNormalToVec3(pcVertices[pcTriangles->INDEXES[c]].NORMAL,
|
LatLngNormalToVec3(pcVertices[pcTriangles->INDEXES[c]].NORMAL,
|
||||||
(float*)&pcMesh->mNormals[iCurrent]);
|
(float*)&pcMesh->mNormals[iCurrent]);
|
||||||
|
|
||||||
pcMesh->mNormals[iCurrent].y *= -1.0f;
|
//pcMesh->mNormals[iCurrent].y *= -1.0f;
|
||||||
|
|
||||||
// read texture coordinates
|
// read texture coordinates
|
||||||
pcMesh->mTextureCoords[0][iCurrent].x = pcUVs[ pcTriangles->INDEXES[c]].U;
|
pcMesh->mTextureCoords[0][iCurrent].x = pcUVs[ pcTriangles->INDEXES[c]].U;
|
||||||
|
|
|
@ -562,11 +562,11 @@ outer:
|
||||||
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
|
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
|
||||||
pScene->mRootNode->mMeshes[i] = i;
|
pScene->mRootNode->mMeshes[i] = i;
|
||||||
|
|
||||||
pScene->mRootNode->mTransformation *= aiMatrix4x4(
|
/*pScene->mRootNode->mTransformation *= aiMatrix4x4(
|
||||||
1.f, 0.f, 0.f, 0.f,
|
1.f, 0.f, 0.f, 0.f,
|
||||||
0.f, -1.f,0.f, 0.f,
|
0.f, -1.f,0.f, 0.f,
|
||||||
0.f, 0.f, 1.f, 0.f,
|
0.f, 0.f, 1.f, 0.f,
|
||||||
0.f, 0.f, 0.f, 1.f);
|
0.f, 0.f, 0.f, 1.f);*/
|
||||||
|
|
||||||
// Add cameras and light sources to the scene root node
|
// Add cameras and light sources to the scene root node
|
||||||
pScene->mRootNode->mNumChildren = pScene->mNumLights+pScene->mNumCameras;
|
pScene->mRootNode->mNumChildren = pScene->mNumLights+pScene->mNumCameras;
|
||||||
|
|
|
@ -48,7 +48,10 @@ void ScenePreprocessor::ProcessScene (aiScene* _scene)
|
||||||
{
|
{
|
||||||
scene = _scene;
|
scene = _scene;
|
||||||
|
|
||||||
// - nothing to do for meshes for the moment
|
// Process all meshes
|
||||||
|
for (unsigned int i = 0; i < scene->mNumMeshes;++i)
|
||||||
|
ProcessMesh(scene->mMeshes[i]);
|
||||||
|
|
||||||
// - nothing to do for materials for the moment
|
// - nothing to do for materials for the moment
|
||||||
// - nothing to do for nodes for the moment
|
// - nothing to do for nodes for the moment
|
||||||
// - nothing to do for textures for the moment
|
// - nothing to do for textures for the moment
|
||||||
|
@ -60,6 +63,37 @@ void ScenePreprocessor::ProcessScene (aiScene* _scene)
|
||||||
ProcessAnimation(scene->mAnimations[i]);
|
ProcessAnimation(scene->mAnimations[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
aiFace& face = mesh->mFaces[a];
|
||||||
|
switch (face.mNumIndices)
|
||||||
|
{
|
||||||
|
case 3u:
|
||||||
|
mesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2u:
|
||||||
|
mesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1u:
|
||||||
|
mesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
void ScenePreprocessor::ProcessAnimation (aiAnimation* anim)
|
void ScenePreprocessor::ProcessAnimation (aiAnimation* anim)
|
||||||
|
|
|
@ -64,6 +64,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void ProcessAnimation (aiAnimation* anim);
|
void ProcessAnimation (aiAnimation* anim);
|
||||||
|
void ProcessMesh (aiMesh* mesh);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
|
@ -51,64 +51,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Constructor to be privately used by Importer
|
|
||||||
DeterminePTypeHelperProcess ::DeterminePTypeHelperProcess()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
DeterminePTypeHelperProcess::~DeterminePTypeHelperProcess()
|
|
||||||
{
|
|
||||||
// nothing to do here
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Returns whether the processing step is present in the given flag field.
|
|
||||||
bool DeterminePTypeHelperProcess::IsActive( unsigned int pFlags) const
|
|
||||||
{
|
|
||||||
// this step is always active
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Executes the post processing step on the given imported data.
|
|
||||||
void DeterminePTypeHelperProcess::Execute( aiScene* pScene)
|
|
||||||
{
|
|
||||||
DefaultLogger::get()->debug("DeterminePTypeHelper begin");
|
|
||||||
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
|
|
||||||
{
|
|
||||||
aiMesh* mesh = pScene->mMeshes[i];
|
|
||||||
if (!mesh->mPrimitiveTypes)
|
|
||||||
{
|
|
||||||
for (unsigned int a = 0; a < mesh->mNumFaces; ++a)
|
|
||||||
{
|
|
||||||
aiFace& face = mesh->mFaces[a];
|
|
||||||
switch (face.mNumIndices)
|
|
||||||
{
|
|
||||||
case 3u:
|
|
||||||
mesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2u:
|
|
||||||
mesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1u:
|
|
||||||
mesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DefaultLogger::get()->debug("DeterminePTypeHelper finished");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -50,35 +50,6 @@ class SortByPTypeProcessTest;
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
/** DeterminePTypeHelperProcess: If aiMesh::mPrimitiveTypes is 0,
|
|
||||||
* this step determines the types of primitive a mesh consists of.
|
|
||||||
*/
|
|
||||||
class ASSIMP_API DeterminePTypeHelperProcess : public BaseProcess
|
|
||||||
{
|
|
||||||
friend class Importer;
|
|
||||||
friend class ::SortByPTypeProcessTest; // grant the unit test full access to us
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/** Constructor to be privately used by Importer */
|
|
||||||
DeterminePTypeHelperProcess();
|
|
||||||
|
|
||||||
/** Destructor, private as well */
|
|
||||||
~DeterminePTypeHelperProcess();
|
|
||||||
|
|
||||||
public:
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
bool IsActive( unsigned int pFlags) const;
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
void Execute( aiScene* pScene);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#if (!defined AI_BUILD_NO_SORTBYPTYPE_PROCESS)
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** SortByPTypeProcess: Sorts meshes by the types of primitives they contain.
|
/** SortByPTypeProcess: Sorts meshes by the types of primitives they contain.
|
||||||
* A mesh with 5 lines, 3 points and 145 triangles would be split in 3
|
* A mesh with 5 lines, 3 points and 145 triangles would be split in 3
|
||||||
|
@ -111,7 +82,6 @@ private:
|
||||||
int configRemoveMeshes;
|
int configRemoveMeshes;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,8 @@ SOURCES = AssimpPCH.cpp \
|
||||||
IRRMeshLoader.cpp \
|
IRRMeshLoader.cpp \
|
||||||
IRRLoader.cpp \
|
IRRLoader.cpp \
|
||||||
Q3DLoader.cpp \
|
Q3DLoader.cpp \
|
||||||
ScenePreprocessor.cpp
|
ScenePreprocessor.cpp \
|
||||||
|
B3DImporter.cpp
|
||||||
|
|
||||||
OBJECTS = $(SOURCES:.cpp=.o)
|
OBJECTS = $(SOURCES:.cpp=.o)
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,9 @@ SOURCES = AssimpPCH.cpp \
|
||||||
IRRMeshLoader.cpp \
|
IRRMeshLoader.cpp \
|
||||||
IRRLoader.cpp \
|
IRRLoader.cpp \
|
||||||
Q3DLoader.cpp \
|
Q3DLoader.cpp \
|
||||||
ScenePreprocessor.cpp
|
ScenePreprocessor.cpp \
|
||||||
|
B3DImporter.cpp
|
||||||
|
|
||||||
|
|
||||||
OBJECTS = $(SOURCES:.cpp=.o)
|
OBJECTS = $(SOURCES:.cpp=.o)
|
||||||
|
|
||||||
|
|
|
@ -1402,6 +1402,18 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="B3D"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\code\B3DImporter.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\code\B3DImporter.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="PostProcess"
|
Name="PostProcess"
|
||||||
|
|
Loading…
Reference in New Issue