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-9d2fd5bffc1f
pull/1/head
aramis_acg 2008-11-04 20:41:11 +00:00
parent 195d9a9cb1
commit 7c50899481
19 changed files with 732 additions and 129 deletions

View File

@ -519,11 +519,13 @@ void Discreet3DSImporter::ConvertMeshes(aiScene* pcOut)
// ------------------------------------------------------------------------------------------------
// 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;
iArray.reserve(3);
aiMatrix4x4 abs;
if (pcIn->mName == "$$$DUMMY")
{
// 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())
{
// 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 mInv = mTrafo;
if (!configSkipPivot)
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->mMeshes = new unsigned int[iArray.size()];
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];
// http://www.zfx.info/DisplayThread.php?MID=235690#235690
const aiVector3D& pivot = pcIn->vPivot;
const aiVector3D* const pvEnd = mesh->mVertices+mesh->mNumVertices;
aiVector3D* pvCurrent = mesh->mVertices;
@ -568,7 +579,6 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Nod
pvCurrent->y -= pivot.y;
pvCurrent->z -= pivot.z;
*pvCurrent = mTrafo * (*pvCurrent);
//std::swap( pvCurrent->y, pvCurrent->z );
++pvCurrent;
}
}
@ -577,22 +587,81 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Nod
{
while (pvCurrent != pvEnd)
{
std::swap( pvCurrent->y, pvCurrent->z );
*pvCurrent = mInv * (*pvCurrent);
++pvCurrent;
}
}
#endif
// Setup the mesh index
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
pcOut->mName.Set(pcIn->mName);
// Setup the transformation matrix of the node
pcOut->mTransformation = aiMatrix4x4();
// Allocate storage for children
pcOut->mNumChildren = (unsigned int)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]->mParent = pcOut;
AddNodeToGraph(pcSOut,pcOut->mChildren[i],pcIn->mChildren[i]);
AddNodeToGraph(pcSOut,pcOut->mChildren[i],pcIn->mChildren[i],abs);
}
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
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
// animation tracks we'll have afterwards
//unsigned int numRot = 0, numScale = 0, numTranslate = 0;
//CountTracks(mRootNode,numRot,numScale,numTranslate);
AddNodeToGraph(pcOut, pcOut->mRootNode, mRootNode);
unsigned int numChannel = 0;
CountTracks(mRootNode,numChannel);
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
@ -694,11 +799,13 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut)
if (pcOut->mRootNode->mName.data[0] == '$' && pcOut->mRootNode->mName.data[1] == '$')
pcOut->mRootNode->mName.Set("<root>");
#if 0
// modify the transformation of the root node to change
// the coordinate system of the whole scene from Max' to OpenGL
pcOut->mRootNode->mTransformation.a3 *= -1.f;
pcOut->mRootNode->mTransformation.b3 *= -1.f;
pcOut->mRootNode->mTransformation.c3 *= -1.f;
#endif
}
// ------------------------------------------------------------------------------------------------

View File

@ -566,11 +566,14 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
// (target animation channels are stored with a
// separate object ID)
D3DS::Node* pcNode = FindNode(mRootNode,name);
if (!pcNode)
if (pcNode)
{
pcNode = new D3DS::Node();
pcNode->mName = name;
// Make this node the current node
mCurrentNode = pcNode;
break;
}
pcNode = new D3DS::Node();
pcNode->mName = name;
// There are two unknown values which we can safely ignore
stream->IncPtr(4);

View File

@ -219,7 +219,8 @@ protected:
// -------------------------------------------------------------------
/** 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.

View File

@ -556,12 +556,15 @@ void ASEImporter::AddNodes (std::vector<BaseNode*>& nodes,
// allocate enough space for the child nodes
pcParent->mNumChildren = (unsigned int)apcNodes.size();
pcParent->mChildren = new aiNode*[apcNodes.size()];
// now build all nodes for our nice new children
for (unsigned int p = 0; p < apcNodes.size();++p)
if (pcParent->mNumChildren)
{
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;
}
@ -578,7 +581,7 @@ void ASEImporter::BuildNodes()
pcScene->mRootNode->mName.Set("<root>");
// Setup the coordinate system transformation
pcScene->mRootNode->mTransformation.c3 *= -1.f;
//pcScene->mRootNode->mTransformation.c3 *= -1.f;
pcScene->mRootNode->mNumChildren = 1;
pcScene->mRootNode->mChildren = new aiNode*[1];
pcScene->mRootNode->mChildren[0] = new aiNode();
@ -744,7 +747,7 @@ void ASEImporter::BuildUniqueRepresentation(ASE::Mesh& mesh)
if (!mesh.amTexCoords[c].empty())
{
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

View File

@ -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();
}

106
code/B3DImporter.h 100644
View File

@ -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

View File

@ -130,6 +130,29 @@ void IRRImporter::GenerateGraph(Node* root,aiNode* rootOut ,aiScene* scene,
break;
}
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;

View File

@ -455,6 +455,7 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
int textMeaning = 0;
int vertexFormat = 0; // 0 = normal; 1 = 2 tcoords, 2 = tangents
bool useColors = false;
bool needLightMap = false;
// Parse the XML file
while (reader->read())
@ -752,7 +753,12 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
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;
@ -783,10 +789,22 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
if (materials.empty())
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
pScene->mNumMeshes = (unsigned int)meshes.size();
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->mMaterials = new aiMaterial*[pScene->mNumMaterials];

View File

@ -126,6 +126,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_BUILD_NO_Q3D_IMPORTER
# include "Q3DLoader.h"
#endif
#ifndef AI_BUILD_NO_B3D_IMPORTER
# include "B3DImporter.h"
#endif
// PostProcess-Steps
@ -180,14 +183,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_BUILD_NO_FINDDEGENERATES_PROCESS
# include "FindDegenerates.h"
#endif
// 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
#ifndef AI_BUILD_NO_SORTBYPTYPE_PROCESS
# include "SortByPTypeProcess.h"
//#endif
#endif
using namespace Assimp;
@ -282,6 +280,9 @@ Importer::Importer() :
#if (!defined AI_BUILD_NO_Q3D_IMPORTER)
mImporter.push_back( new Q3DImporter());
#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
// of sequence it is executed. steps that are added here are not validated -
@ -292,8 +293,6 @@ Importer::Importer() :
mPostProcessingSteps.push_back( new ValidateDSProcess());
#endif
mPostProcessingSteps.push_back( new DeterminePTypeHelperProcess());
#if (!defined AI_BUILD_NO_FINDDEGENERATES_PROCESS)
mPostProcessingSteps.push_back( new FindDegeneratesProcess());

View File

@ -143,6 +143,8 @@ void LWOImporter::InternReadFile( const std::string& pFile,
// old lightwave file format (prior to v6)
if (AI_LWO_FOURCC_LWOB == fileType)
{
DefaultLogger::get()->info("LWO file format: LWOB (<= LightWave 5.5)");
mIsLWO2 = false;
this->LoadLWOBFile();
}
@ -150,6 +152,8 @@ void LWOImporter::InternReadFile( const std::string& pFile,
// new lightwave format
else if (AI_LWO_FOURCC_LWO2 == fileType)
{
DefaultLogger::get()->info("LWO file format: LWO2 (>= LightWave 6)");
mIsLWO2 = true;
this->LoadLWO2File();
}
@ -307,7 +311,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
aiVector3D*& pp = pvUV[w];
const aiVector2D& src = ((aiVector2D*)&layer.mUVChannels[vUVChannelIndices[w]].rawData[0])[idx];
pp->x = src.x;
pp->y = 1.f-src.y; // DX to OGL
pp->y = src.y; // DX to OGL
pp++;
}

View File

@ -297,14 +297,14 @@ void MD3Importer::InternReadFile(
{
// read vertices
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;
// convert the normal vector to uncompressed float3 format
LatLngNormalToVec3(pcVertices[pcTriangles->INDEXES[c]].NORMAL,
(float*)&pcMesh->mNormals[iCurrent]);
pcMesh->mNormals[iCurrent].y *= -1.0f;
//pcMesh->mNormals[iCurrent].y *= -1.0f;
// read texture coordinates
pcMesh->mTextureCoords[0][iCurrent].x = pcUVs[ pcTriangles->INDEXES[c]].U;

View File

@ -562,11 +562,11 @@ outer:
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
pScene->mRootNode->mMeshes[i] = i;
pScene->mRootNode->mTransformation *= aiMatrix4x4(
/*pScene->mRootNode->mTransformation *= aiMatrix4x4(
1.f, 0.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, 0.f, 1.f);
0.f, 0.f, 0.f, 1.f);*/
// Add cameras and light sources to the scene root node
pScene->mRootNode->mNumChildren = pScene->mNumLights+pScene->mNumCameras;

View File

@ -48,7 +48,10 @@ void ScenePreprocessor::ProcessScene (aiScene* _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 nodes for the moment
// - nothing to do for textures for the moment
@ -60,6 +63,37 @@ void ScenePreprocessor::ProcessScene (aiScene* _scene)
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)

View File

@ -64,6 +64,7 @@ public:
protected:
void ProcessAnimation (aiAnimation* anim);
void ProcessMesh (aiMesh* mesh);
protected:

View File

@ -51,64 +51,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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");
}
// ------------------------------------------------------------------------------------------------

View File

@ -50,35 +50,6 @@ class SortByPTypeProcessTest;
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.
* A mesh with 5 lines, 3 points and 145 triangles would be split in 3
@ -111,7 +82,6 @@ private:
int configRemoveMeshes;
};
#endif
} // end of namespace Assimp

View File

@ -72,7 +72,8 @@ SOURCES = AssimpPCH.cpp \
IRRMeshLoader.cpp \
IRRLoader.cpp \
Q3DLoader.cpp \
ScenePreprocessor.cpp
ScenePreprocessor.cpp \
B3DImporter.cpp
OBJECTS = $(SOURCES:.cpp=.o)

View File

@ -72,7 +72,9 @@ SOURCES = AssimpPCH.cpp \
IRRMeshLoader.cpp \
IRRLoader.cpp \
Q3DLoader.cpp \
ScenePreprocessor.cpp
ScenePreprocessor.cpp \
B3DImporter.cpp
OBJECTS = $(SOURCES:.cpp=.o)

View File

@ -1402,6 +1402,18 @@
>
</File>
</Filter>
<Filter
Name="B3D"
>
<File
RelativePath="..\..\code\B3DImporter.cpp"
>
</File>
<File
RelativePath="..\..\code\B3DImporter.h"
>
</File>
</Filter>
</Filter>
<Filter
Name="PostProcess"