Rewrote 3DS loader to support BE - added temporary light & camera & animation support. few models not working anymore, transformation bug still unsolved.

Fixed normal vector handling in the ASE loader. Improved animation & camera & light support - as for the 3DS Loader, still in the works.
Fixed AC - Loader. It is now able to load models with complex hierarchies correctly. Added a small workaround for Quick3D, which writes invalid AC files.
DXF-Loader skips {...} blocks produced by 3DS Max & AutoCad correctly now.
DefaultLogger doesn't repeat identical log messages now.
FindInvalidData-Process removes empty or dummy animation tracks now.
LWO-Loader recognizes complex shaders (such as Fresnel) correctly now. Other LLWO bugs still unsolved.
Fixed bugs in the Ply parser, causing non-triangular faces to crash.
Added some additional helperutilities to StreamReader.
Fixed a bug in ProcessHelper.h causing SPlitLargeMeses and SortBxPType to crash for meshes containing many bones.
Changed OB default material from black to gray.
Added additional test fils: ply (bugfix), ase (animation), QUick3D & Irr (in the works), STL (export from 3DS Max)

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@210 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
pull/1/head
aramis_acg 2008-10-31 19:32:00 +00:00
parent 2888a1099e
commit a7088d6263
47 changed files with 3628 additions and 1342 deletions

View File

@ -46,50 +46,55 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// internal headers // internal headers
#include "3DSLoader.h" #include "3DSLoader.h"
#include "MaterialSystem.h"
#include "TextureTransform.h" #include "TextureTransform.h"
#include "StringComparison.h"
#include "qnan.h"
using namespace Assimp; using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Dot3DSImporter::ReplaceDefaultMaterial() // Setup final material indices, generae a default material if necessary
void Discreet3DSImporter::ReplaceDefaultMaterial()
{ {
// *******************************************************************
// try to find an existing material that matches the // try to find an existing material that matches the
// typical default material setting: // typical default material setting:
// - no textures // - no textures
// - diffuse color (in grey!) // - diffuse color (in grey!)
// NOTE: This is here to workaround the fact that some // NOTE: This is here to workaround the fact that some
// exporters are writing a default material, too. // exporters are writing a default material, too.
unsigned int iIndex = 0xcdcdcdcd; // *******************************************************************
for (unsigned int i = 0; i < this->mScene->mMaterials.size();++i) unsigned int idx = 0xcdcdcdcd;
for (unsigned int i = 0; i < mScene->mMaterials.size();++i)
{ {
if (std::string::npos == this->mScene->mMaterials[i].mName.find("default") && std::string s = mScene->mMaterials[i].mName;
std::string::npos == this->mScene->mMaterials[i].mName.find("DEFAULT"))continue; for (std::string::iterator it = s.begin(); it != s.end(); ++it)
*it = ::tolower(*it);
if (this->mScene->mMaterials[i].mDiffuse.r != if (std::string::npos == s.find("default"))continue;
this->mScene->mMaterials[i].mDiffuse.g ||
this->mScene->mMaterials[i].mDiffuse.r !=
this->mScene->mMaterials[i].mDiffuse.b)continue;
if (this->mScene->mMaterials[i].sTexDiffuse.mMapName.length() != 0 || if (mScene->mMaterials[i].mDiffuse.r !=
this->mScene->mMaterials[i].sTexBump.mMapName.length()!= 0 || mScene->mMaterials[i].mDiffuse.g ||
this->mScene->mMaterials[i].sTexOpacity.mMapName.length() != 0 || mScene->mMaterials[i].mDiffuse.r !=
this->mScene->mMaterials[i].sTexEmissive.mMapName.length() != 0 || mScene->mMaterials[i].mDiffuse.b)continue;
this->mScene->mMaterials[i].sTexSpecular.mMapName.length() != 0 ||
this->mScene->mMaterials[i].sTexShininess.mMapName.length() != 0 )continue;
iIndex = i; if (mScene->mMaterials[i].sTexDiffuse.mMapName.length() != 0 ||
mScene->mMaterials[i].sTexBump.mMapName.length() != 0 ||
mScene->mMaterials[i].sTexOpacity.mMapName.length() != 0 ||
mScene->mMaterials[i].sTexEmissive.mMapName.length() != 0 ||
mScene->mMaterials[i].sTexSpecular.mMapName.length() != 0 ||
mScene->mMaterials[i].sTexShininess.mMapName.length() != 0 )
{
continue;
}
idx = i;
} }
if (0xcdcdcdcd == iIndex)iIndex = (unsigned int)this->mScene->mMaterials.size(); if (0xcdcdcdcd == idx)idx = (unsigned int)mScene->mMaterials.size();
// now iterate through all meshes and through all faces and // now iterate through all meshes and through all faces and
// find all faces that are using the default material // find all faces that are using the default material
unsigned int iCnt = 0; unsigned int cnt = 0;
for (std::vector<Dot3DS::Mesh>::iterator for (std::vector<D3DS::Mesh>::iterator
i = this->mScene->mMeshes.begin(); i = mScene->mMeshes.begin();
i != this->mScene->mMeshes.end();++i) i != mScene->mMeshes.end();++i)
{ {
for (std::vector<unsigned int>::iterator for (std::vector<unsigned int>::iterator
a = (*i).mFaceMaterials.begin(); a = (*i).mFaceMaterials.begin();
@ -99,32 +104,35 @@ void Dot3DSImporter::ReplaceDefaultMaterial()
// some exporters seem to generate invalid data here // some exporters seem to generate invalid data here
if (0xcdcdcdcd == (*a)) if (0xcdcdcdcd == (*a))
{ {
(*a) = iIndex; (*a) = idx;
++iCnt; ++cnt;
} }
else if ( (*a) >= this->mScene->mMaterials.size()) else if ( (*a) >= mScene->mMaterials.size())
{ {
(*a) = iIndex; (*a) = idx;
++iCnt;
DefaultLogger::get()->warn("Material index overflow in 3DS file. Using default material"); DefaultLogger::get()->warn("Material index overflow in 3DS file. Using default material");
++cnt;
} }
} }
} }
if (iCnt && iIndex == this->mScene->mMaterials.size()) if (cnt && idx == mScene->mMaterials.size())
{ {
// we need to create our own default material // We need to create our own default material
Dot3DS::Material sMat; D3DS::Material sMat;
sMat.mDiffuse = aiColor3D(0.3f,0.3f,0.3f); sMat.mDiffuse = aiColor3D(0.3f,0.3f,0.3f);
sMat.mName = "%%%DEFAULT"; sMat.mName = "%%%DEFAULT";
this->mScene->mMaterials.push_back(sMat); mScene->mMaterials.push_back(sMat);
DefaultLogger::get()->info("3DS: Generating default material");
} }
return; return;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Dot3DSImporter::CheckIndices(Dot3DS::Mesh& sMesh) // Check whether all indices are valid. Otherwise we'd crash before the validation step was reached
void Discreet3DSImporter::CheckIndices(D3DS::Mesh& sMesh)
{ {
for (std::vector< Dot3DS::Face >::iterator for (std::vector< D3DS::Face >::iterator
i = sMesh.mFaces.begin(); i = sMesh.mFaces.begin();
i != sMesh.mFaces.end();++i) i != sMesh.mFaces.end();++i)
{ {
@ -133,23 +141,28 @@ void Dot3DSImporter::CheckIndices(Dot3DS::Mesh& sMesh)
{ {
if ((*i).mIndices[a] >= sMesh.mPositions.size()) if ((*i).mIndices[a] >= sMesh.mPositions.size())
{ {
DefaultLogger::get()->warn("3DS: Face index overflow)"); DefaultLogger::get()->warn("3DS: Vertex index overflow)");
(*i).mIndices[a] = (uint32_t)sMesh.mPositions.size()-1; (*i).mIndices[a] = (uint32_t)sMesh.mPositions.size()-1;
} }
if ( !sMesh.mTexCoords.empty() && (*i).mIndices[a] >= sMesh.mTexCoords.size())
{
DefaultLogger::get()->warn("3DS: Texture coordinate index overflow)");
(*i).mIndices[a] = (uint32_t)sMesh.mTexCoords.size()-1;
}
} }
} }
return; return;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Dot3DSImporter::MakeUnique(Dot3DS::Mesh& sMesh) // Generate out unique verbose format representation
void Discreet3DSImporter::MakeUnique(D3DS::Mesh& sMesh)
{ {
unsigned int iBase = 0; unsigned int iBase = 0;
std::vector<aiVector3D> vNew; // Allocate output storage
std::vector<aiVector3D> vNew (sMesh.mFaces.size() * 3);
std::vector<aiVector2D> vNew2; std::vector<aiVector2D> vNew2;
vNew.resize(sMesh.mFaces.size() * 3);
if (sMesh.mTexCoords.size())vNew2.resize(sMesh.mFaces.size() * 3); if (sMesh.mTexCoords.size())vNew2.resize(sMesh.mFaces.size() * 3);
for (unsigned int i = 0; i < sMesh.mFaces.size();++i) for (unsigned int i = 0; i < sMesh.mFaces.size();++i)
@ -181,26 +194,27 @@ void Dot3DSImporter::MakeUnique(Dot3DS::Mesh& sMesh)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Dot3DSImporter::ConvertMaterial(Dot3DS::Material& oldMat, // Convert a 3DS material to an aiMaterial
void Discreet3DSImporter::ConvertMaterial(D3DS::Material& oldMat,
MaterialHelper& mat) MaterialHelper& mat)
{ {
// NOTE: Pass the background image to the viewer by bypassing the // NOTE: Pass the background image to the viewer by bypassing the
// material system. This is an evil hack, never do it again! // material system. This is an evil hack, never do it again!
if (0 != this->mBackgroundImage.length() && this->bHasBG) if (0 != mBackgroundImage.length() && bHasBG)
{ {
aiString tex; aiString tex;
tex.Set( this->mBackgroundImage); tex.Set( mBackgroundImage);
mat.AddProperty( &tex, AI_MATKEY_GLOBAL_BACKGROUND_IMAGE); mat.AddProperty( &tex, AI_MATKEY_GLOBAL_BACKGROUND_IMAGE);
// be sure this is only done for the first material // be sure this is only done for the first material
this->mBackgroundImage = std::string(""); mBackgroundImage = std::string("");
} }
// At first add the base ambient color of the // At first add the base ambient color of the
// scene to the material // scene to the material
oldMat.mAmbient.r += this->mClrAmbient.r; oldMat.mAmbient.r += mClrAmbient.r;
oldMat.mAmbient.g += this->mClrAmbient.g; oldMat.mAmbient.g += mClrAmbient.g;
oldMat.mAmbient.b += this->mClrAmbient.b; oldMat.mAmbient.b += mClrAmbient.b;
aiString name; aiString name;
name.Set( oldMat.mName); name.Set( oldMat.mName);
@ -213,12 +227,12 @@ void Dot3DSImporter::ConvertMaterial(Dot3DS::Material& oldMat,
mat.AddProperty( &oldMat.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE); mat.AddProperty( &oldMat.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE);
// phong shininess and shininess strength // phong shininess and shininess strength
if (Dot3DS::Dot3DSFile::Phong == oldMat.mShading || if (D3DS::Discreet3DS::Phong == oldMat.mShading ||
Dot3DS::Dot3DSFile::Metal == oldMat.mShading) D3DS::Discreet3DS::Metal == oldMat.mShading)
{ {
if (!oldMat.mSpecularExponent || !oldMat.mShininessStrength) if (!oldMat.mSpecularExponent || !oldMat.mShininessStrength)
{ {
oldMat.mShading = Dot3DS::Dot3DSFile::Gouraud; oldMat.mShading = D3DS::Discreet3DS::Gouraud;
} }
else else
{ {
@ -244,31 +258,31 @@ void Dot3DSImporter::ConvertMaterial(Dot3DS::Material& oldMat,
aiShadingMode eShading = aiShadingMode_NoShading; aiShadingMode eShading = aiShadingMode_NoShading;
switch (oldMat.mShading) switch (oldMat.mShading)
{ {
case Dot3DS::Dot3DSFile::Flat: case D3DS::Discreet3DS::Flat:
eShading = aiShadingMode_Flat; break; eShading = aiShadingMode_Flat; break;
// I don't know what "Wire" shading should be, // I don't know what "Wire" shading should be,
// assume it is simple lambertian diffuse (L dot N) shading // assume it is simple lambertian diffuse (L dot N) shading
case Dot3DS::Dot3DSFile::Wire: case D3DS::Discreet3DS::Wire:
case Dot3DS::Dot3DSFile::Gouraud: case D3DS::Discreet3DS::Gouraud:
eShading = aiShadingMode_Gouraud; break; eShading = aiShadingMode_Gouraud; break;
// assume cook-torrance shading for metals. // assume cook-torrance shading for metals.
case Dot3DS::Dot3DSFile::Phong : case D3DS::Discreet3DS::Phong :
eShading = aiShadingMode_Phong; break; eShading = aiShadingMode_Phong; break;
case Dot3DS::Dot3DSFile::Metal : case D3DS::Discreet3DS::Metal :
eShading = aiShadingMode_CookTorrance; break; eShading = aiShadingMode_CookTorrance; break;
// FIX to workaround a warning with GCC 4 who complained // FIX to workaround a warning with GCC 4 who complained
// about a missing case Blinn: here - Blinn isn't a valid // about a missing case Blinn: here - Blinn isn't a valid
// value in the 3DS Loader, it is just needed for ASE // value in the 3DS Loader, it is just needed for ASE
case Dot3DS::Dot3DSFile::Blinn : case D3DS::Discreet3DS::Blinn :
eShading = aiShadingMode_Blinn; break; eShading = aiShadingMode_Blinn; break;
} }
mat.AddProperty<int>( (int*)&eShading,1,AI_MATKEY_SHADING_MODEL); mat.AddProperty<int>( (int*)&eShading,1,AI_MATKEY_SHADING_MODEL);
if (Dot3DS::Dot3DSFile::Wire == oldMat.mShading) if (D3DS::Discreet3DS::Wire == oldMat.mShading)
{ {
// set the wireframe flag // set the wireframe flag
unsigned int iWire = 1; unsigned int iWire = 1;
@ -276,6 +290,7 @@ void Dot3DSImporter::ConvertMaterial(Dot3DS::Material& oldMat,
} }
// texture, if there is one // texture, if there is one
// DIFFUSE texture
if( oldMat.sTexDiffuse.mMapName.length() > 0) if( oldMat.sTexDiffuse.mMapName.length() > 0)
{ {
aiString tex; aiString tex;
@ -292,6 +307,7 @@ void Dot3DSImporter::ConvertMaterial(Dot3DS::Material& oldMat,
mat.AddProperty<int>(&i,1,AI_MATKEY_MAPPINGMODE_V_DIFFUSE(0)); mat.AddProperty<int>(&i,1,AI_MATKEY_MAPPINGMODE_V_DIFFUSE(0));
} }
} }
// SPECULAR texture
if( oldMat.sTexSpecular.mMapName.length() > 0) if( oldMat.sTexSpecular.mMapName.length() > 0)
{ {
aiString tex; aiString tex;
@ -308,6 +324,7 @@ void Dot3DSImporter::ConvertMaterial(Dot3DS::Material& oldMat,
mat.AddProperty<int>(&i,1,AI_MATKEY_MAPPINGMODE_V_SPECULAR(0)); mat.AddProperty<int>(&i,1,AI_MATKEY_MAPPINGMODE_V_SPECULAR(0));
} }
} }
// OPACITY texture
if( oldMat.sTexOpacity.mMapName.length() > 0) if( oldMat.sTexOpacity.mMapName.length() > 0)
{ {
aiString tex; aiString tex;
@ -323,6 +340,7 @@ void Dot3DSImporter::ConvertMaterial(Dot3DS::Material& oldMat,
mat.AddProperty<int>(&i,1,AI_MATKEY_MAPPINGMODE_V_OPACITY(0)); mat.AddProperty<int>(&i,1,AI_MATKEY_MAPPINGMODE_V_OPACITY(0));
} }
} }
// EMISSIVE texture
if( oldMat.sTexEmissive.mMapName.length() > 0) if( oldMat.sTexEmissive.mMapName.length() > 0)
{ {
aiString tex; aiString tex;
@ -338,6 +356,7 @@ void Dot3DSImporter::ConvertMaterial(Dot3DS::Material& oldMat,
mat.AddProperty<int>(&i,1,AI_MATKEY_MAPPINGMODE_V_EMISSIVE(0)); mat.AddProperty<int>(&i,1,AI_MATKEY_MAPPINGMODE_V_EMISSIVE(0));
} }
} }
// BUMP texturee
if( oldMat.sTexBump.mMapName.length() > 0) if( oldMat.sTexBump.mMapName.length() > 0)
{ {
aiString tex; aiString tex;
@ -353,6 +372,7 @@ void Dot3DSImporter::ConvertMaterial(Dot3DS::Material& oldMat,
mat.AddProperty<int>(&i,1,AI_MATKEY_MAPPINGMODE_V_HEIGHT(0)); mat.AddProperty<int>(&i,1,AI_MATKEY_MAPPINGMODE_V_HEIGHT(0));
} }
} }
// SHININESS texture
if( oldMat.sTexShininess.mMapName.length() > 0) if( oldMat.sTexShininess.mMapName.length() > 0)
{ {
aiString tex; aiString tex;
@ -369,7 +389,7 @@ void Dot3DSImporter::ConvertMaterial(Dot3DS::Material& oldMat,
} }
} }
// store the name of the material itself, too // Store the name of the material itself, too
if( oldMat.mName.length()) if( oldMat.mName.length())
{ {
aiString tex; aiString tex;
@ -378,31 +398,31 @@ void Dot3DSImporter::ConvertMaterial(Dot3DS::Material& oldMat,
} }
return; return;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Dot3DSImporter::ConvertMeshes(aiScene* pcOut) // Split meshes by their materials and generate output aiMesh'es
void Discreet3DSImporter::ConvertMeshes(aiScene* pcOut)
{ {
std::vector<aiMesh*> avOutMeshes; std::vector<aiMesh*> avOutMeshes;
avOutMeshes.reserve(this->mScene->mMeshes.size() * 2); avOutMeshes.reserve(mScene->mMeshes.size() * 2);
unsigned int iFaceCnt = 0; unsigned int iFaceCnt = 0;
// we need to split all meshes by their materials // we need to split all meshes by their materials
for (std::vector<Dot3DS::Mesh>::iterator for (std::vector<D3DS::Mesh>::iterator i = mScene->mMeshes.begin();
i = this->mScene->mMeshes.begin(); i != mScene->mMeshes.end();++i)
i != this->mScene->mMeshes.end();++i)
{ {
std::vector<unsigned int>* aiSplit = new std::vector<unsigned int>[ std::vector<unsigned int>* aiSplit = new std::vector<unsigned int>[
this->mScene->mMaterials.size()]; mScene->mMaterials.size()];
unsigned int iNum = 0; unsigned int iNum = 0;
for (std::vector<unsigned int>::const_iterator for (std::vector<unsigned int>::const_iterator a = (*i).mFaceMaterials.begin();
a = (*i).mFaceMaterials.begin();
a != (*i).mFaceMaterials.end();++a,++iNum) a != (*i).mFaceMaterials.end();++a,++iNum)
{ {
aiSplit[*a].push_back(iNum); aiSplit[*a].push_back(iNum);
} }
// now generate submeshes // now generate submeshes
for (unsigned int p = 0; p < this->mScene->mMaterials.size();++p) for (unsigned int p = 0; p < mScene->mMaterials.size();++p)
{ {
if (aiSplit[p].size() != 0) if (aiSplit[p].size() != 0)
{ {
@ -438,15 +458,15 @@ void Dot3DSImporter::ConvertMeshes(aiScene* pcOut)
p_pcOut->mFaces[q].mNumIndices = 3; p_pcOut->mFaces[q].mNumIndices = 3;
p_pcOut->mFaces[q].mIndices[2] = iBase; p_pcOut->mFaces[q].mIndices[2] = iBase;
p_pcOut->mVertices[iBase] = (*i).mPositions[(*i).mFaces[iIndex].mIndices[0]]; p_pcOut->mVertices[iBase] = (*i).mPositions[(*i).mFaces[iIndex].mIndices[0]];
p_pcOut->mNormals[iBase++] = (*i).mNormals[(*i).mFaces[iIndex].mIndices[0]]; p_pcOut->mNormals[iBase++] = (*i).mNormals[(*i).mFaces[iIndex].mIndices[0]];
p_pcOut->mFaces[q].mIndices[1] = iBase; p_pcOut->mFaces[q].mIndices[1] = iBase;
p_pcOut->mVertices[iBase] = (*i).mPositions[(*i).mFaces[iIndex].mIndices[1]]; p_pcOut->mVertices[iBase] = (*i).mPositions[(*i).mFaces[iIndex].mIndices[1]];
p_pcOut->mNormals[iBase++] = (*i).mNormals[(*i).mFaces[iIndex].mIndices[1]]; p_pcOut->mNormals[iBase++] = (*i).mNormals[(*i).mFaces[iIndex].mIndices[1]];
p_pcOut->mFaces[q].mIndices[0] = iBase; p_pcOut->mFaces[q].mIndices[0] = iBase;
p_pcOut->mVertices[iBase] = (*i).mPositions[(*i).mFaces[iIndex].mIndices[2]]; p_pcOut->mVertices[iBase] = (*i).mPositions[(*i).mFaces[iIndex].mIndices[2]];
p_pcOut->mNormals[iBase++] = (*i).mNormals[(*i).mFaces[iIndex].mIndices[2]]; p_pcOut->mNormals[iBase++] = (*i).mNormals[(*i).mFaces[iIndex].mIndices[2]];
} }
} }
@ -460,51 +480,60 @@ void Dot3DSImporter::ConvertMeshes(aiScene* pcOut)
{ {
unsigned int iIndex2 = aiSplit[p][q]; unsigned int iIndex2 = aiSplit[p][q];
unsigned int iIndex = (*i).mFaces[iIndex2].mIndices[0]; aiVector2D* pc = &(*i).mTexCoords[(*i).mFaces[iIndex2].mIndices[0]];
aiVector2D& pc = (*i).mTexCoords[iIndex]; p_pcOut->mTextureCoords[0][iBase++] = aiVector3D(pc->x,pc->y,0.0f);
p_pcOut->mTextureCoords[0][iBase++] = aiVector3D(pc.x,pc.y,0.0f);
iIndex = (*i).mFaces[iIndex2].mIndices[1]; pc = &(*i).mTexCoords[(*i).mFaces[iIndex2].mIndices[1]];
pc = (*i).mTexCoords[iIndex]; p_pcOut->mTextureCoords[0][iBase++] = aiVector3D(pc->x,pc->y,0.0f);
p_pcOut->mTextureCoords[0][iBase++] = aiVector3D(pc.x,pc.y,0.0f);
iIndex = (*i).mFaces[iIndex2].mIndices[2]; pc = &(*i).mTexCoords[(*i).mFaces[iIndex2].mIndices[2]];
pc = (*i).mTexCoords[iIndex]; p_pcOut->mTextureCoords[0][iBase++] = aiVector3D(pc->x,pc->y,0.0f);
p_pcOut->mTextureCoords[0][iBase++] = aiVector3D(pc.x,pc.y,0.0f);
} }
// apply texture coordinate scalings // apply texture coordinate scalings
TextureTransform::BakeScaleNOffset ( p_pcOut, &this->mScene->mMaterials[ TextureTransform::BakeScaleNOffset ( p_pcOut, &mScene->mMaterials[
p_pcOut->mMaterialIndex] ); p_pcOut->mMaterialIndex] );
} }
} }
} }
delete[] aiSplit; delete[] aiSplit;
} }
// Copy them to the output array
pcOut->mNumMeshes = (unsigned int)avOutMeshes.size(); pcOut->mNumMeshes = (unsigned int)avOutMeshes.size();
pcOut->mMeshes = new aiMesh*[pcOut->mNumMeshes](); pcOut->mMeshes = new aiMesh*[pcOut->mNumMeshes]();
for (unsigned int a = 0; a < pcOut->mNumMeshes;++a) for (unsigned int a = 0; a < pcOut->mNumMeshes;++a)
pcOut->mMeshes[a] = avOutMeshes[a]; pcOut->mMeshes[a] = avOutMeshes[a];
if (!iFaceCnt)throw new ImportErrorException("No faces loaded. The mesh is empty"); // We should have at least one face here
if (!iFaceCnt)
throw new ImportErrorException("No faces loaded. The mesh is empty");
// for each material in the scene we need to setup the UV source // for each material in the scene we need to setup the UV source
// set for each texture // set for each texture
for (unsigned int a = 0; a < pcOut->mNumMaterials;++a) for (unsigned int a = 0; a < pcOut->mNumMaterials;++a)
TextureTransform::SetupMatUVSrc( pcOut->mMaterials[a], &this->mScene->mMaterials[a] ); {
TextureTransform::SetupMatUVSrc( pcOut->mMaterials[a], &mScene->mMaterials[a] );
}
return; return;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Dot3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,Dot3DS::Node* pcIn) // Add a node to the scenegraph and setup its final transformation
void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Node* pcIn)
{ {
std::vector<unsigned int> iArray; std::vector<unsigned int> iArray;
iArray.reserve(3); iArray.reserve(3);
if (pcIn->mName != "$$$DUMMY") if (pcIn->mName == "$$$DUMMY")
{
// append the "real" name of the dummy to the string
pcIn->mName.append(pcIn->mDummyName);
}
else // if (pcIn->mName != "$$$DUMMY")
{ {
for (unsigned int a = 0; a < pcSOut->mNumMeshes;++a) for (unsigned int a = 0; a < pcSOut->mNumMeshes;++a)
{ {
const Dot3DS::Mesh* pcMesh = (const Dot3DS::Mesh*)pcSOut->mMeshes[a]->mColors[0]; const D3DS::Mesh* pcMesh = (const D3DS::Mesh*)pcSOut->mMeshes[a]->mColors[0];
ai_assert(NULL != pcMesh); ai_assert(NULL != pcMesh);
// do case independent comparisons here, just for safety // do case independent comparisons here, just for safety
@ -513,12 +542,11 @@ void Dot3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,Dot3DS::Node*
} }
if (!iArray.empty()) if (!iArray.empty())
{ {
aiMatrix4x4& mTrafo = ((Dot3DS::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 (!this->configSkipPivot) if (!configSkipPivot)
mInv.Inverse(); mInv.Inverse();
pcOut->mName.Set(pcIn->mName);
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)
@ -531,7 +559,7 @@ void Dot3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,Dot3DS::Node*
const aiVector3D* const pvEnd = mesh->mVertices+mesh->mNumVertices; const aiVector3D* const pvEnd = mesh->mVertices+mesh->mNumVertices;
aiVector3D* pvCurrent = mesh->mVertices; aiVector3D* pvCurrent = mesh->mVertices;
if(pivot.x || pivot.y || pivot.z && !this->configSkipPivot) if(pivot.x || pivot.y || pivot.z && !configSkipPivot)
{ {
while (pvCurrent != pvEnd) while (pvCurrent != pvEnd)
{ {
@ -558,63 +586,90 @@ void Dot3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,Dot3DS::Node*
} }
} }
} }
// Setup the name of the node
pcOut->mName.Set(pcIn->mName);
// Setup the transformation matrix of the node
pcOut->mTransformation = aiMatrix4x4(); pcOut->mTransformation = aiMatrix4x4();
// 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()];
// Recursively process all children
for (unsigned int i = 0; i < pcIn->mChildren.size();++i) for (unsigned int i = 0; i < pcIn->mChildren.size();++i)
{ {
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], AddNodeToGraph(pcSOut,pcOut->mChildren[i],pcIn->mChildren[i]);
pcIn->mChildren[i]);
} }
return; return;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Dot3DSImporter::GenerateNodeGraph(aiScene* pcOut) // Generate the output node graph
void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut)
{ {
pcOut->mRootNode = new aiNode(); pcOut->mRootNode = new aiNode();
if (0 == this->mRootNode->mChildren.size()) if (0 == mRootNode->mChildren.size())
{ {
// seems the file has not even a hierarchy. // seems the file has not even a hierarchy.
// generate a flat hiearachy which looks like this: // generate a flat hiearachy which looks like this:
// //
// ROOT_NODE // ROOT_NODE
// | // |
// ---------------------------------------- // ----------------------------------------
// | | | | // | | | | |
// MESH_0 MESH_1 MESH_2 ... MESH_N // MESH_0 MESH_1 MESH_2 ... MESH_N CAMERA_0 ....
// //
DefaultLogger::get()->warn("No hierarchy information has been found in the file. "); DefaultLogger::get()->warn("No hierarchy information has been found in the file. ");
pcOut->mRootNode->mNumChildren = pcOut->mNumMeshes; pcOut->mRootNode->mNumChildren = pcOut->mNumMeshes +
pcOut->mRootNode->mChildren = new aiNode* [ pcOut->mNumMeshes ]; mScene->mCameras.size() + mScene->mLights.size();
for (unsigned int i = 0; i < pcOut->mNumMeshes;++i) pcOut->mRootNode->mChildren = new aiNode* [ pcOut->mRootNode->mNumChildren ];
{ pcOut->mRootNode->mName.Set("<3DSDummyRoot>");
aiNode* pcNode = new aiNode();
// Build dummy nodes for all meshes
unsigned int a = 0;
for (unsigned int i = 0; i < pcOut->mNumMeshes;++i,++a)
{
aiNode* pcNode = pcOut->mRootNode->mChildren[a] = new aiNode();
pcNode->mParent = pcOut->mRootNode; pcNode->mParent = pcOut->mRootNode;
pcNode->mNumChildren = 0;
pcNode->mChildren = 0;
pcNode->mMeshes = new unsigned int[1]; pcNode->mMeshes = new unsigned int[1];
pcNode->mMeshes[0] = i; pcNode->mMeshes[0] = i;
pcNode->mNumMeshes = 1; pcNode->mNumMeshes = 1;
char szBuffer[128]; // Build a name for the node
int iLen; pcNode->mName.length = sprintf(pcNode->mName.data,"3DSMesh_%i",i);
iLen = sprintf(szBuffer,"UNNAMED_%i",i);
ai_assert(0 < iLen);
::memcpy(pcNode->mName.data,szBuffer,iLen);
pcNode->mName.data[iLen] = '\0';
pcNode->mName.length = iLen;
// add the new child to the parent node
pcOut->mRootNode->mChildren[i] = pcNode;
}
} }
else this->AddNodeToGraph(pcOut, pcOut->mRootNode, this->mRootNode);
// Build dummy nodes for all cameras
for (unsigned int i = 0; i < (unsigned int )mScene->mCameras.size();++i,++a)
{
aiNode* pcNode = pcOut->mRootNode->mChildren[a] = new aiNode();
pcNode->mParent = pcOut->mRootNode;
// Build a name for the node
pcNode->mName = mScene->mCameras[i]->mName;
}
// Build dummy nodes for all lights
for (unsigned int i = 0; i < (unsigned int )mScene->mLights.size();++i,++a)
{
aiNode* pcNode = pcOut->mRootNode->mChildren[a] = new aiNode();
pcNode->mParent = pcOut->mRootNode;
// Build a name for the node
pcNode->mName = mScene->mLights[i]->mName;
}
}
else AddNodeToGraph(pcOut, pcOut->mRootNode, mRootNode);
// We used the first vertex color set to store some
// temporary values, so we need to cleanup here
for (unsigned int a = 0; a < pcOut->mNumMeshes;++a) for (unsigned int a = 0; a < pcOut->mNumMeshes;++a)
pcOut->mMeshes[a]->mColors[0] = NULL; pcOut->mMeshes[a]->mColors[0] = NULL;
@ -631,19 +686,48 @@ void Dot3DSImporter::GenerateNodeGraph(aiScene* pcOut)
// if the root node is a default node setup a name for it // if the root node is a default node setup a name for it
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>");
}
// ------------------------------------------------------------------------------------------------
void Dot3DSImporter::ConvertScene(aiScene* pcOut)
{
pcOut->mNumMaterials = (unsigned int)this->mScene->mMaterials.size();
pcOut->mMaterials = new aiMaterial*[pcOut->mNumMaterials];
// 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;
}
// ------------------------------------------------------------------------------------------------
// Convert all meshes in the scene and generate the final output scene.
void Discreet3DSImporter::ConvertScene(aiScene* pcOut)
{
// Allocate enough storage for all output materials
pcOut->mNumMaterials = (unsigned int)mScene->mMaterials.size();
pcOut->mMaterials = new aiMaterial*[pcOut->mNumMaterials];
// ... and convert the 3DS materials to aiMaterial's
for (unsigned int i = 0; i < pcOut->mNumMaterials;++i) for (unsigned int i = 0; i < pcOut->mNumMaterials;++i)
{ {
MaterialHelper* pcNew = new MaterialHelper(); MaterialHelper* pcNew = new MaterialHelper();
this->ConvertMaterial(this->mScene->mMaterials[i],*pcNew); ConvertMaterial(mScene->mMaterials[i],*pcNew);
pcOut->mMaterials[i] = pcNew; pcOut->mMaterials[i] = pcNew;
} }
this->ConvertMeshes(pcOut);
// Generate the output mesh list
ConvertMeshes(pcOut);
// Now copy all light sources to the output scene
pcOut->mNumLights = (unsigned int)mScene->mLights.size();
if (pcOut->mNumLights)
{
pcOut->mLights = new aiLight*[pcOut->mNumLights];
::memcpy(pcOut->mLights,&mScene->mLights[0],sizeof(void*)*pcOut->mNumLights);
}
// Now copy all cameras to the output scene
pcOut->mNumCameras = (unsigned int)mScene->mCameras.size();
if (pcOut->mNumCameras)
{
pcOut->mCameras = new aiCamera*[pcOut->mNumCameras];
::memcpy(pcOut->mCameras,&mScene->mCameras[0],sizeof(void*)*pcOut->mNumCameras);
}
return; return;
} }

View File

@ -58,19 +58,19 @@ http://www.jalix.org/ressources/graphics/3DS/_unofficials/3ds-unofficial.txt */
#include "SmoothingGroups.h" #include "SmoothingGroups.h"
namespace Assimp { namespace Assimp {
namespace Dot3DS { namespace D3DS {
#include "./../include/Compiler/pushpack1.h" #include "./../include/Compiler/pushpack1.h"
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Dot3DSFile class: Helper class for loading 3ds files. Defines chunks /** Discreet3DS class: Helper class for loading 3ds files. Defines chunks
* and data structures. * and data structures.
*/ */
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
class Dot3DSFile class Discreet3DS
{ {
public: public:
inline Dot3DSFile() {} inline Discreet3DS() {}
//! data structure for a single chunk in a .3ds file //! data structure for a single chunk in a .3ds file
struct Chunk struct Chunk
@ -241,12 +241,7 @@ public:
// Specular map. Seems to influence the specular color // Specular map. Seems to influence the specular color
CHUNK_MAT_SPECMAP = 0xA204, CHUNK_MAT_SPECMAP = 0xA204,
// Holds shininess data. I assume the specular exponent is // Holds shininess data.
// calculated like this:
//
// s[x,y] = stex[x,y] * base_shininess;
// I also assume the data in the texture must be renormalized
// (normally by dividing / 255) after loading.
CHUNK_MAT_MAT_SHINMAP = 0xA33C, CHUNK_MAT_MAT_SHINMAP = 0xA33C,
// Scaling in U/V direction. // Scaling in U/V direction.
@ -281,6 +276,7 @@ public:
// Supported sub chunks // Supported sub chunks
CHUNK_TRACKINFO = 0xB002, CHUNK_TRACKINFO = 0xB002,
CHUNK_TRACKOBJNAME = 0xB010, CHUNK_TRACKOBJNAME = 0xB010,
CHUNK_TRACKDUMMYOBJNAME = 0xB011,
CHUNK_TRACKPIVOT = 0xB013, CHUNK_TRACKPIVOT = 0xB013,
CHUNK_TRACKPOS = 0xB020, CHUNK_TRACKPOS = 0xB020,
CHUNK_TRACKROTATE = 0xB021, CHUNK_TRACKROTATE = 0xB021,
@ -288,7 +284,7 @@ public:
// ******************************************************************** // ********************************************************************
// Keyframes for various other stuff in the file // Keyframes for various other stuff in the file
// Ignored // Partially ignored
CHUNK_AMBIENTKEY = 0xB001, CHUNK_AMBIENTKEY = 0xB001,
CHUNK_TRACKMORPH = 0xB026, CHUNK_TRACKMORPH = 0xB026,
CHUNK_TRACKHIDE = 0xB029, CHUNK_TRACKHIDE = 0xB029,
@ -359,9 +355,10 @@ struct Material
//! Default constructor. Builds a default name for the material //! Default constructor. Builds a default name for the material
Material() Material()
: :
mDiffuse (0.6f,0.6f,0.6f), // FIX ... we won't want object to be black
mSpecularExponent (0.0f), mSpecularExponent (0.0f),
mShininessStrength (1.0f), mShininessStrength (1.0f),
mShading(Dot3DSFile::Gouraud), mShading(Discreet3DS::Gouraud),
mTransparency (1.0f), mTransparency (1.0f),
mBumpHeight (1.0f), mBumpHeight (1.0f),
mTwoSided (false), mTwoSided (false),
@ -388,7 +385,7 @@ struct Material
//! Ambient color of the material //! Ambient color of the material
aiColor3D mAmbient; aiColor3D mAmbient;
//! Shading type to be used //! Shading type to be used
Dot3DSFile::shadetype3ds mShading; Discreet3DS::shadetype3ds mShading;
//! Opacity of the material //! Opacity of the material
float mTransparency; float mTransparency;
//! Diffuse texture channel //! Diffuse texture channel
@ -419,7 +416,7 @@ struct Material
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Helper structure to represent a 3ds file mesh */ /** Helper structure to represent a 3ds file mesh */
struct Mesh : public MeshWithSmoothingGroups<Dot3DS::Face> struct Mesh : public MeshWithSmoothingGroups<D3DS::Face>
{ {
//! Default constructor //! Default constructor
Mesh() Mesh()
@ -443,6 +440,9 @@ struct Mesh : public MeshWithSmoothingGroups<Dot3DS::Face>
//! Local transformation matrix //! Local transformation matrix
aiMatrix4x4 mMat; aiMatrix4x4 mMat;
}; };
typedef std::pair<double, float> aiFloatKey;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Helper structure to represent a 3ds file node */ /** Helper structure to represent a 3ds file node */
struct Node struct Node
@ -458,11 +458,9 @@ struct Node
::sprintf(szTemp,"UNNAMED_%i",iCnt++); ::sprintf(szTemp,"UNNAMED_%i",iCnt++);
mName = szTemp; mName = szTemp;
#ifdef AI_3DS_KEYFRAME_ANIMATION aRotationKeys.reserve (20);
aRotationKeys.reserve(10); aPositionKeys.reserve (20);
aPositionKeys.reserve(10); aScalingKeys.reserve (20);
aScalingKeys.reserve(10);
#endif
} }
//! Pointer to the parent node //! Pointer to the parent node
@ -474,13 +472,16 @@ struct Node
//! Name of the node //! Name of the node
std::string mName; std::string mName;
//! Dummy nodes: real name to be combined with the $$$DUMMY
std::string mDummyName;
//! Position of the node in the hierarchy (tree depth) //! Position of the node in the hierarchy (tree depth)
int16_t mHierarchyPos; int16_t mHierarchyPos;
//! Index of the node //! Index of the node
int16_t mHierarchyIndex; int16_t mHierarchyIndex;
#ifdef AI_3DS_KEYFRAME_ANIMATION
//! Rotation keys loaded from the file //! Rotation keys loaded from the file
std::vector<aiQuatKey> aRotationKeys; std::vector<aiQuatKey> aRotationKeys;
@ -489,7 +490,14 @@ struct Node
//! Scaling keys loaded from the file //! Scaling keys loaded from the file
std::vector<aiVectorKey> aScalingKeys; std::vector<aiVectorKey> aScalingKeys;
#endif
// For target lights (spot lights and directional lights):
// The position of the target
std::vector< aiVectorKey > aTargetPositionKeys;
// For cameras: the camera roll angle
std::vector< aiFloatKey > aCameraRollKeys;
//! Pivot position loaded from the file //! Pivot position loaded from the file
aiVector3D vPivot; aiVector3D vPivot;
@ -516,12 +524,18 @@ struct Scene
//! List of all meshes loaded //! List of all meshes loaded
std::vector<Mesh> mMeshes; std::vector<Mesh> mMeshes;
//! List of all cameras loaded
std::vector<aiCamera*> mCameras;
//! List of all lights loaded
std::vector<aiLight*> mLights;
//! Pointer to the root node of the scene //! Pointer to the root node of the scene
Node* pcRootNode; Node* pcRootNode;
}; };
} // end of namespace Dot3DS } // end of namespace D3DS
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_XFILEHELPER_H_INC #endif // AI_XFILEHELPER_H_INC

File diff suppressed because it is too large Load Diff

View File

@ -53,22 +53,22 @@ namespace Assimp
{ {
class MaterialHelper; class MaterialHelper;
using namespace Dot3DS; using namespace D3DS;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** The Dot3DSImporter is a worker class capable of importing a scene from a /** The Discreet3DSImporter is a worker class capable of importing a scene from a
* 3ds Max 4/5 Files (.3ds) * 3ds Max 4/5 Files (.3ds)
*/ */
class Dot3DSImporter : public BaseImporter class Discreet3DSImporter : public BaseImporter
{ {
friend class Importer; friend class Importer;
protected: protected:
/** Constructor to be privately used by Importer */ /** Constructor to be privately used by Importer */
Dot3DSImporter(); Discreet3DSImporter();
/** Destructor, private as well */ /** Destructor, private as well */
~Dot3DSImporter(); ~Discreet3DSImporter();
public: public:
@ -105,15 +105,15 @@ protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Converts a temporary material to the outer representation /** Converts a temporary material to the outer representation
*/ */
void ConvertMaterial(Dot3DS::Material& p_cMat, void ConvertMaterial(D3DS::Material& p_cMat,
MaterialHelper& p_pcOut); MaterialHelper& p_pcOut);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Read a chunk, get a pointer to it /** Read a chunk
* The mCurrent pointer will be increased by sizeof(Dot3DSFile::Chunk), *
* thus pointing directly to the data of the chunk * @param pcOut Receives the current chunk
*/ */
void ReadChunk(const Dot3DSFile::Chunk** p_ppcOut); void ReadChunk(Discreet3DS::Chunk* pcOut);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a percentage chunk. mCurrent will point to the next /** Parse a percentage chunk. mCurrent will point to the next
@ -144,52 +144,57 @@ protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a main top-level chunk in the file /** Parse a main top-level chunk in the file
*/ */
void ParseMainChunk(int& piRemaining); void ParseMainChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a top-level chunk in the file /** Parse a top-level chunk in the file
*/ */
void ParseChunk(int& piRemaining); void ParseChunk(const char* name, unsigned int num);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a top-level editor chunk in the file /** Parse a top-level editor chunk in the file
*/ */
void ParseEditorChunk(int& piRemaining); void ParseEditorChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a top-level object chunk in the file /** Parse a top-level object chunk in the file
*/ */
void ParseObjectChunk(int& piRemaining); void ParseObjectChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a material chunk in the file /** Parse a material chunk in the file
*/ */
void ParseMaterialChunk(int& piRemaining); void ParseMaterialChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a mesh chunk in the file /** Parse a mesh chunk in the file
*/ */
void ParseMeshChunk(int& piRemaining); void ParseMeshChunk();
// -------------------------------------------------------------------
/** Parse a light chunk in the file
*/
void ParseLightChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a face list chunk in the file /** Parse a face list chunk in the file
*/ */
void ParseFaceChunk(int& piRemaining); void ParseFaceChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a keyframe chunk in the file /** Parse a keyframe chunk in the file
*/ */
void ParseKeyframeChunk(int& piRemaining); void ParseKeyframeChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a hierarchy chunk in the file /** Parse a hierarchy chunk in the file
*/ */
void ParseHierarchyChunk(int& piRemaining); void ParseHierarchyChunk(uint16_t parent);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a texture chunk in the file /** Parse a texture chunk in the file
*/ */
void ParseTextureChunk(int& piRemaining,Dot3DS::Texture* pcOut); void ParseTextureChunk(D3DS::Texture* pcOut);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Convert the meshes in the file /** Convert the meshes in the file
@ -209,18 +214,18 @@ protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** generate unique vertices for a mesh /** generate unique vertices for a mesh
*/ */
void MakeUnique(Dot3DS::Mesh& sMesh); void MakeUnique(D3DS::Mesh& sMesh);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Add a node to the node graph /** Add a node to the node graph
*/ */
void AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,Dot3DS::Node* pcIn); void AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Node* pcIn);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Search for a node in the graph. /** Search for a node in the graph.
* Called recursively * Called recursively
*/ */
void InverseNodeSearch(Dot3DS::Node* pcNode,Dot3DS::Node* pcCurrent); void InverseNodeSearch(D3DS::Node* pcNode,D3DS::Node* pcCurrent);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Apply the master scaling factor to the mesh /** Apply the master scaling factor to the mesh
@ -230,7 +235,7 @@ protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Clamp all indices in the file to a valid range /** Clamp all indices in the file to a valid range
*/ */
void CheckIndices(Dot3DS::Mesh& sMesh); void CheckIndices(D3DS::Mesh& sMesh);
protected: protected:
@ -238,23 +243,17 @@ protected:
/** Configuration option: skip pivot chunks */ /** Configuration option: skip pivot chunks */
bool configSkipPivot; bool configSkipPivot;
/** Buffer to hold the loaded file */ /** Stream to read from */
unsigned char* mBuffer; StreamReaderLE* stream;
/** Pointer to the current read position */
const unsigned char* mCurrent;
/** Used to store old chunk addresses to jump back in the file*/
const unsigned char* mLast;
/** Last touched node index */ /** Last touched node index */
short mLastNodeIndex; short mLastNodeIndex;
/** Current node, root node */ /** Current node, root node */
Dot3DS::Node* mCurrentNode, *mRootNode; D3DS::Node* mCurrentNode, *mRootNode;
/** Scene under construction */ /** Scene under construction */
Dot3DS::Scene* mScene; D3DS::Scene* mScene;
/** Ambient base color of the scene */ /** Ambient base color of the scene */
aiColor3D mClrAmbient; aiColor3D mClrAmbient;

View File

@ -65,7 +65,7 @@ using namespace Assimp;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// read a string enclosed in double quotation marks. buffer must point to " // read a string (may be enclosed in double quotation marks). buffer must point to "
#define AI_AC_GET_STRING(out) \ #define AI_AC_GET_STRING(out) \
++buffer; \ ++buffer; \
const char* sz = buffer; \ const char* sz = buffer; \
@ -167,7 +167,8 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
{ {
// load the children of this object recursively // load the children of this object recursively
obj.children.reserve(num); obj.children.reserve(num);
LoadObjectSection(obj.children); for (unsigned int i = 0; i < num; ++i)
LoadObjectSection(obj.children);
} }
return; return;
} }
@ -218,12 +219,16 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
obj.vertices.push_back(aiVector3D()); obj.vertices.push_back(aiVector3D());
aiVector3D& v = obj.vertices.back(); aiVector3D& v = obj.vertices.back();
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,3,&v.x); AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,3,&v.x);
//std::swap(v.z,v.y);
v.z *= -1.f;
} }
} }
else if (TokenMatch(buffer,"numsurf",7)) else if (TokenMatch(buffer,"numsurf",7))
{ {
SkipSpaces(&buffer); SkipSpaces(&buffer);
bool Q3DWorkAround = false;
const unsigned int t = strtol10(buffer,&buffer); const unsigned int t = strtol10(buffer,&buffer);
obj.surfaces.reserve(t); obj.surfaces.reserve(t);
for (unsigned int i = 0; i < t;++i) for (unsigned int i = 0; i < t;++i)
@ -231,9 +236,17 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
GetNextLine(); GetNextLine();
if (!TokenMatch(buffer,"SURF",4)) if (!TokenMatch(buffer,"SURF",4))
{ {
DefaultLogger::get()->error("AC3D: SURF token was expected"); // FIX: this can occur for some files - Quick 3D for
// example writes no surf chunks
if (!Q3DWorkAround)
{
DefaultLogger::get()->warn("AC3D: SURF token was expected");
DefaultLogger::get()->debug("Continuing with Quick3D Workaround enabled");
}
--buffer; // make sure the line is processed a second time --buffer; // make sure the line is processed a second time
break; // break; --- see fix notes above
Q3DWorkAround = true;
} }
SkipSpaces(&buffer); SkipSpaces(&buffer);
obj.surfaces.push_back(Surface()); obj.surfaces.push_back(Surface());
@ -254,6 +267,16 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
} }
else if (TokenMatch(buffer,"refs",4)) else if (TokenMatch(buffer,"refs",4))
{ {
// --- see fix notes above
if (Q3DWorkAround)
{
if (!surf.entries.empty())
{
buffer -= 6;
break;
}
}
SkipSpaces(&buffer); SkipSpaces(&buffer);
const unsigned int m = strtol10(buffer); const unsigned int m = strtol10(buffer);
surf.entries.reserve(m); surf.entries.reserve(m);
@ -612,11 +635,7 @@ void AC3DImporter::InternReadFile( const std::string& pFile,
// print the file format version to the console // print the file format version to the console
unsigned int version = HexDigitToDecimal( buffer[4] ); unsigned int version = HexDigitToDecimal( buffer[4] );
char msg[3]; char msg[3];
#if defined(_MSC_VER) itoa10(msg,3,version);
::_itoa(version,msg,10);
#else
snprintf(msg, 3, "%d", version); //itoa is not available under linux
#endif
DefaultLogger::get()->info(std::string("AC3D file format version: ") + msg); DefaultLogger::get()->info(std::string("AC3D file format version: ") + msg);
std::vector<Material> materials; std::vector<Material> materials;
@ -685,6 +704,7 @@ void AC3DImporter::InternReadFile( const std::string& pFile,
// build output arrays // build output arrays
if (meshes.empty()) if (meshes.empty())
{ {
throw new ImportErrorException("An unknown error occured during converting");
} }
pScene->mNumMeshes = (unsigned int)meshes.size(); pScene->mNumMeshes = (unsigned int)meshes.size();
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]; pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];

View File

@ -49,6 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "MaterialSystem.h" #include "MaterialSystem.h"
#include "StringComparison.h" #include "StringComparison.h"
#include "TextureTransform.h" #include "TextureTransform.h"
#include "SkeletonMeshBuilder.h"
// utilities // utilities
#include "fast_atof.h" #include "fast_atof.h"
@ -78,12 +79,13 @@ bool ASEImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler) const
return false; return false;
std::string extension = pFile.substr( pos); std::string extension = pFile.substr( pos);
// Either ASE or ASK // Either ASE, ASC or ASK
return !(extension.length() < 4 || extension[0] != '.' || return !(extension.length() < 4 || extension[0] != '.' ||
extension[1] != 'a' && extension[1] != 'A' || extension[1] != 'a' && extension[1] != 'A' ||
extension[2] != 's' && extension[2] != 'S' || extension[2] != 's' && extension[2] != 'S' ||
extension[3] != 'e' && extension[3] != 'E' && extension[3] != 'e' && extension[3] != 'E' &&
extension[3] != 'k' && extension[3] != 'K'); extension[3] != 'k' && extension[3] != 'K' &&
extension[3] != 'c' && extension[3] != 'C');
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -96,8 +98,8 @@ void ASEImporter::SetupProperties(const Importer* pImp)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure. // Imports the given file into the given scene structure.
void ASEImporter::InternReadFile( void ASEImporter::InternReadFile( const std::string& pFile,
const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) aiScene* pScene, IOSystem* pIOHandler)
{ {
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb")); boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
@ -122,53 +124,77 @@ void ASEImporter::InternReadFile(
mParser = &parser; mParser = &parser;
mParser->Parse(); mParser->Parse();
// if absolutely no material has been loaded from the file // Check whether we loaded at least one mesh. If we did - generate
// we need to generate a default material // materials and copy meshes.
GenerateDefaultMaterial(); if ( !mParser->m_vMeshes.empty())
// process all meshes
bool tookNormals = false;
std::vector<aiMesh*> avOutMeshes;
avOutMeshes.reserve(mParser->m_vMeshes.size()*2);
for (std::vector<ASE::Mesh>::iterator
i = mParser->m_vMeshes.begin();
i != mParser->m_vMeshes.end();++i)
{ {
if ((*i).bSkip)continue; // if absolutely no material has been loaded from the file
// we need to generate a default material
GenerateDefaultMaterial();
TransformVertices(*i); // process all meshes
bool tookNormals = false;
std::vector<aiMesh*> avOutMeshes;
avOutMeshes.reserve(mParser->m_vMeshes.size()*2);
for (std::vector<ASE::Mesh>::iterator
i = mParser->m_vMeshes.begin();
i != mParser->m_vMeshes.end();++i)
{
if ((*i).bSkip)continue;
// now we need to create proper meshes from the import we need to // now we need to create proper meshes from the import we
// split them by materials, build valid vertex/face lists ... // need to split them by materials, build valid vertex/
BuildUniqueRepresentation(*i); // face lists ...
BuildUniqueRepresentation(*i);
// need to generate proper vertex normals if necessary // need to generate proper vertex normals if necessary
if(GenerateNormals(*i))tookNormals = true; if(GenerateNormals(*i))
tookNormals = true;
// convert all meshes to aiMesh objects // convert all meshes to aiMesh objects
ConvertMeshes(*i,avOutMeshes); ConvertMeshes(*i,avOutMeshes);
} }
if (tookNormals) if (tookNormals)
{ {
DefaultLogger::get()->debug("ASE: Taking normals from the file. Use " DefaultLogger::get()->debug("ASE: Taking normals from the file. Use "
"the AI_CONFIG_IMPORT_ASE_RECONSTRUCT_NORMALS option if you " "the AI_CONFIG_IMPORT_ASE_RECONSTRUCT_NORMALS option if you "
"experience problems"); "experience problems");
}
// now build the output mesh list. Remove dummies
pScene->mNumMeshes = (unsigned int)avOutMeshes.size();
aiMesh** pp = pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
for (std::vector<aiMesh*>::const_iterator
i = avOutMeshes.begin();
i != avOutMeshes.end();++i)
{
if (!(*i)->mNumFaces)continue;
*pp++ = *i;
}
pScene->mNumMeshes = (unsigned int)(pp - pScene->mMeshes);
// build final material indices (remove submaterials and setup
// the final list)
BuildMaterialIndices();
} }
// now build the output mesh list. remove dummies // Copy all scene graph nodes - lights, cameras, dummies and meshes
pScene->mNumMeshes = (unsigned int)avOutMeshes.size(); // into one large array
aiMesh** pp = pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]; nodes.reserve(mParser->m_vMeshes.size() +mParser->m_vLights.size()
for (std::vector<aiMesh*>::const_iterator + mParser->m_vCameras.size() + mParser->m_vDummies.size());
i = avOutMeshes.begin();
i != avOutMeshes.end();++i)
{
if (!(*i)->mNumFaces)continue;
*pp++ = *i;
}
pScene->mNumMeshes = (unsigned int)(pp - pScene->mMeshes);
// buil final material indices (remove submaterials and make the final list) for (std::vector<ASE::Light>::iterator it = mParser->m_vLights.begin(),
BuildMaterialIndices(); end = mParser->m_vLights.end();it != end; ++it)nodes.push_back(&(*it));
for (std::vector<ASE::Camera>::iterator it = mParser->m_vCameras.begin(),
end = mParser->m_vCameras.end();it != end; ++it)nodes.push_back(&(*it));
for (std::vector<ASE::Mesh>::iterator it = mParser->m_vMeshes.begin(),
end = mParser->m_vMeshes.end();it != end; ++it)nodes.push_back(&(*it));
for (std::vector<ASE::Dummy>::iterator it = mParser->m_vDummies.begin(),
end = mParser->m_vDummies.end();it != end; ++it)nodes.push_back(&(*it));
// process target cameras and target lights (
// generate animation channels for them and adjust the node graph)
// ProcessTargets();
// build the final node graph // build the final node graph
BuildNodes(); BuildNodes();
@ -181,6 +207,15 @@ void ASEImporter::InternReadFile(
// build output lights // build output lights
BuildLights(); BuildLights();
// TODO: STRANGE RESULTS ATM
// If we have no meshes use the SkeletonMeshBuilder helper class
// to build a mesh for the animation skeleton
if (!pScene->mNumMeshes)
{
pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
SkeletonMeshBuilder skeleton(pScene);
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ASEImporter::GenerateDefaultMaterial() void ASEImporter::GenerateDefaultMaterial()
@ -208,7 +243,7 @@ void ASEImporter::GenerateDefaultMaterial()
mat.mDiffuse = aiColor3D(0.6f,0.6f,0.6f); mat.mDiffuse = aiColor3D(0.6f,0.6f,0.6f);
mat.mSpecular = aiColor3D(1.0f,1.0f,1.0f); mat.mSpecular = aiColor3D(1.0f,1.0f,1.0f);
mat.mAmbient = aiColor3D(0.05f,0.05f,0.05f); mat.mAmbient = aiColor3D(0.05f,0.05f,0.05f);
mat.mShading = Dot3DSFile::Gouraud; mat.mShading = Discreet3DS::Gouraud;
mat.mName = AI_DEFAULT_MATERIAL_NAME; mat.mName = AI_DEFAULT_MATERIAL_NAME;
} }
} }
@ -217,48 +252,69 @@ void ASEImporter::GenerateDefaultMaterial()
void ASEImporter::BuildAnimations() void ASEImporter::BuildAnimations()
{ {
// check whether we have at least one mesh which has animations // check whether we have at least one mesh which has animations
std::vector<ASE::Mesh>::iterator i = mParser->m_vMeshes.begin(); std::vector<ASE::BaseNode*>::iterator i = nodes.begin();
unsigned int iNum = 0; unsigned int iNum = 0;
for (;i != mParser->m_vMeshes.end();++i) for (;i != nodes.end();++i)
{ {
if ((*i).bSkip)continue; // TODO: Implement Bezier & TCB support
if ((*i).mAnim.akeyPositions.size() > 1 || (*i).mAnim.akeyRotations.size() > 1) if ((*i)->mAnim.mPositionType != ASE::Animation::TRACK)
{
DefaultLogger::get()->warn("ASE: Position controller uses Bezier/TCB keys. "
"This is not supported.");
}
if ((*i)->mAnim.mRotationType != ASE::Animation::TRACK)
{
DefaultLogger::get()->warn("ASE: Rotation controller uses Bezier/TCB keys. "
"This is not supported.");
}
if ((*i)->mAnim.mScalingType != ASE::Animation::TRACK)
{
DefaultLogger::get()->warn("ASE: Position controller uses Bezier/TCB keys. "
"This is not supported.");
}
// We compare against 1 here - firstly one key is not
// really an animation and secondly MAX writes dummies
// that represent the node transformation.
if ((*i)->mAnim.akeyPositions.size() > 1 ||
(*i)->mAnim.akeyRotations.size() > 1 ||
(*i)->mAnim.akeyScaling.size() > 1)
{
++iNum; ++iNum;
}
} }
if (iNum) if (iNum)
{ {
// Generate a new animation channel and setup everything for it // Generate a new animation channel and setup everything for it
pcScene->mNumAnimations = 1; pcScene->mNumAnimations = 1;
pcScene->mAnimations = new aiAnimation*[1]; pcScene->mAnimations = new aiAnimation*[1];
aiAnimation* pcAnim = pcScene->mAnimations[0] = new aiAnimation(); aiAnimation* pcAnim = pcScene->mAnimations[0] = new aiAnimation();
pcAnim->mNumChannels = iNum; pcAnim->mNumChannels = iNum;
pcAnim->mChannels = new aiNodeAnim*[iNum]; pcAnim->mChannels = new aiNodeAnim*[iNum];
pcAnim->mTicksPerSecond = mParser->iFrameSpeed * mParser->iTicksPerFrame; pcAnim->mTicksPerSecond = mParser->iFrameSpeed * mParser->iTicksPerFrame;
iNum = 0; iNum = 0;
i = mParser->m_vMeshes.begin();
// Now iterate through all meshes and collect all data we can find // Now iterate through all meshes and collect all data we can find
for (;i != mParser->m_vMeshes.end();++i) for (i = nodes.begin();i != nodes.end();++i)
{ {
if ((*i).bSkip)continue; // mesh unreferenced? if ((*i)->mAnim.akeyPositions.size() > 1 || (*i)->mAnim.akeyRotations.size() > 1)
if ((*i).mAnim.akeyPositions.size() > 1 || (*i).mAnim.akeyRotations.size() > 1)
{ {
// Begin a new node animation channel for this node // Begin a new node animation channel for this node
aiNodeAnim* pcNodeAnim = pcAnim->mChannels[iNum++] = new aiNodeAnim(); aiNodeAnim* pcNodeAnim = pcAnim->mChannels[iNum++] = new aiNodeAnim();
pcNodeAnim->mNodeName.Set((*i).mName); pcNodeAnim->mNodeName.Set((*i)->mName);
// copy position keys // copy position keys
if ((*i).mAnim.akeyPositions.size() > 1 ) if ((*i)->mAnim.akeyPositions.size() > 1 )
{ {
// Allocate the key array and fill it // Allocate the key array and fill it
pcNodeAnim->mNumPositionKeys = (unsigned int) (*i).mAnim.akeyPositions.size(); pcNodeAnim->mNumPositionKeys = (unsigned int) (*i)->mAnim.akeyPositions.size();
pcNodeAnim->mPositionKeys = new aiVectorKey[pcNodeAnim->mNumPositionKeys]; pcNodeAnim->mPositionKeys = new aiVectorKey[pcNodeAnim->mNumPositionKeys];
::memcpy(pcNodeAnim->mPositionKeys,&(*i).mAnim.akeyPositions[0], ::memcpy(pcNodeAnim->mPositionKeys,&(*i)->mAnim.akeyPositions[0],
pcNodeAnim->mNumPositionKeys * sizeof(aiVectorKey)); pcNodeAnim->mNumPositionKeys * sizeof(aiVectorKey));
// get the longest node anim here // get the longest node anim channel
for (unsigned int qq = 0; qq < pcNodeAnim->mNumPositionKeys;++qq) for (unsigned int qq = 0; qq < pcNodeAnim->mNumPositionKeys;++qq)
{ {
pcAnim->mDuration = std::max(pcAnim->mDuration, pcAnim->mDuration = std::max(pcAnim->mDuration,
@ -266,23 +322,39 @@ void ASEImporter::BuildAnimations()
} }
} }
// copy rotation keys // copy rotation keys
if ((*i).mAnim.akeyRotations.size() > 1 ) if ((*i)->mAnim.akeyRotations.size() > 1 )
{ {
// Allocate the key array and fill it // Allocate the key array and fill it
pcNodeAnim->mNumRotationKeys = (unsigned int) (*i).mAnim.akeyPositions.size(); pcNodeAnim->mNumRotationKeys = (unsigned int) (*i)->mAnim.akeyRotations.size();
pcNodeAnim->mRotationKeys = new aiQuatKey[pcNodeAnim->mNumPositionKeys]; pcNodeAnim->mRotationKeys = new aiQuatKey[pcNodeAnim->mNumRotationKeys];
::memcpy(pcNodeAnim->mRotationKeys,&(*i).mAnim.akeyRotations[0], ::memcpy(pcNodeAnim->mRotationKeys,&(*i)->mAnim.akeyRotations[0],
pcNodeAnim->mNumRotationKeys * sizeof(aiQuatKey)); pcNodeAnim->mNumRotationKeys * sizeof(aiQuatKey));
// get the longest node anim here // get the longest node anim channel
for (unsigned int qq = 0; qq < pcNodeAnim->mNumRotationKeys;++qq) for (unsigned int qq = 0; qq < pcNodeAnim->mNumRotationKeys;++qq)
{ {
pcAnim->mDuration = std::max(pcAnim->mDuration, pcAnim->mDuration = std::max(pcAnim->mDuration,
pcNodeAnim->mRotationKeys[qq].mTime); pcNodeAnim->mRotationKeys[qq].mTime);
} }
} }
// there are no scaling keys // copy scaling keys
if ((*i)->mAnim.akeyScaling.size() > 1 )
{
// Allocate the key array and fill it
pcNodeAnim->mNumScalingKeys = (unsigned int) (*i)->mAnim.akeyScaling.size();
pcNodeAnim->mScalingKeys = new aiVectorKey[pcNodeAnim->mNumScalingKeys];
::memcpy(pcNodeAnim->mScalingKeys,&(*i)->mAnim.akeyScaling[0],
pcNodeAnim->mNumScalingKeys * sizeof(aiVectorKey));
// get the longest node anim channel
for (unsigned int qq = 0; qq < pcNodeAnim->mNumScalingKeys;++qq)
{
pcAnim->mDuration = std::max(pcAnim->mDuration,
pcNodeAnim->mScalingKeys[qq].mTime);
}
}
} }
} }
} }
@ -306,6 +378,8 @@ void ASEImporter::BuildCameras()
out->mClipPlaneNear = (in.mNear ? in.mNear : 0.1f); out->mClipPlaneNear = (in.mNear ? in.mNear : 0.1f);
out->mHorizontalFOV = in.mFOV; out->mHorizontalFOV = in.mFOV;
// TODO: Implement proper camera target
out->mName.Set(in.mName); out->mName.Set(in.mName);
} }
} }
@ -324,8 +398,32 @@ void ASEImporter::BuildLights()
aiLight* out = pcScene->mLights[i] = new aiLight(); aiLight* out = pcScene->mLights[i] = new aiLight();
ASE::Light& in = mParser->m_vLights[i]; ASE::Light& in = mParser->m_vLights[i];
// The direction is encoded in the transformation
// matrix of the node. In 3DS MAX the light source
// points in negative Z direction if the node
// transformation is the identity.
out->mDirection = aiVector3D(0.f,0.f,-1.f);
out->mName.Set(in.mName); out->mName.Set(in.mName);
out->mType = aiLightSource_POINT; switch (in.mLightType)
{
case ASE::Light::TARGET:
out->mType = aiLightSource_SPOT;
out->mAngleInnerCone = AI_DEG_TO_RAD(in.mAngle);
out->mAngleOuterCone = (in.mFalloff ? AI_DEG_TO_RAD(in.mFalloff)
: out->mAngleInnerCone);
break;
case ASE::Light::DIRECTIONAL:
out->mType = aiLightSource_DIRECTIONAL;
break;
default:
//case ASE::Light::OMNI:
out->mType = aiLightSource_POINT;
break;
};
out->mColorDiffuse = out->mColorSpecular = in.mColor * in.mIntensity; out->mColorDiffuse = out->mColorSpecular = in.mColor * in.mIntensity;
} }
} }
@ -447,12 +545,12 @@ void ASEImporter::AddNodes (std::vector<BaseNode*>& nodes,
} }
// add sub nodes // add sub nodes
aiMatrix4x4 mNewAbs = mat * node->mTransformation; // aiMatrix4x4 mNewAbs = mat * node->mTransformation;
// prevent stack overflow // prevent stack overflow
if (node->mName != node->mParent->mName) if (node->mName != node->mParent->mName)
{ {
AddNodes(nodes,node,node->mName.data,mNewAbs); AddNodes(nodes,node,node->mName.data,snode->mTransform);
} }
} }
@ -479,22 +577,22 @@ void ASEImporter::BuildNodes()
pcScene->mRootNode->mMeshes = 0; pcScene->mRootNode->mMeshes = 0;
pcScene->mRootNode->mName.Set("<root>"); pcScene->mRootNode->mName.Set("<root>");
// generate a full list of all scenegraph elements we have // Setup the coordinate system transformation
std::vector<BaseNode*> nodes; pcScene->mRootNode->mTransformation.c3 *= -1.f;
nodes.reserve(mParser->m_vMeshes.size() +mParser->m_vLights.size() pcScene->mRootNode->mNumChildren = 1;
+ mParser->m_vCameras.size()); pcScene->mRootNode->mChildren = new aiNode*[1];
pcScene->mRootNode->mChildren[0] = new aiNode();
for (std::vector<ASE::Light>::iterator it = mParser->m_vLights.begin(), // Change the transformation matrix of all nodes
end = mParser->m_vLights.end();it != end; ++it)nodes.push_back(&(*it)); for (std::vector<BaseNode*>::iterator it = nodes.begin(), end = nodes.end();
it != end; ++it)
for (std::vector<ASE::Camera>::iterator it = mParser->m_vCameras.begin(), {
end = mParser->m_vCameras.end();it != end; ++it)nodes.push_back(&(*it)); aiMatrix4x4& m = (*it)->mTransform;
m.Transpose(); // row-order vs column-order
for (std::vector<ASE::Mesh>::iterator it = mParser->m_vMeshes.begin(), }
end = mParser->m_vMeshes.end();it != end; ++it)nodes.push_back(&(*it));
// add all nodes // add all nodes
AddNodes(nodes,pcScene->mRootNode,NULL); AddNodes(nodes,pcScene->mRootNode->mChildren[0],NULL);
// now iterate through al nodes and find those that have not yet // now iterate through al nodes and find those that have not yet
// been added to the nodegraph (= their parent could not be recognized) // been added to the nodegraph (= their parent could not be recognized)
@ -566,11 +664,15 @@ void ASEImporter::BuildNodes()
pcScene->mMeshes[i]->mColors[2] = NULL; pcScene->mMeshes[i]->mColors[2] = NULL;
// if there is only one subnode, set it as root node // if there is only one subnode, set it as root node
if (1 == pcScene->mRootNode->mNumChildren) // FIX: The sub node may not have animations assigned
if (1 == pcScene->mRootNode->mNumChildren && !pcScene->mNumAnimations)
{ {
aiNode* cc = pcScene->mRootNode->mChildren[0];
aiNode* pc = pcScene->mRootNode; aiNode* pc = pcScene->mRootNode;
pcScene->mRootNode = pcScene->mRootNode->mChildren[0];
pcScene->mRootNode = cc;
pcScene->mRootNode->mParent = NULL; pcScene->mRootNode->mParent = NULL;
cc->mTransformation = pc->mTransformation * cc->mTransformation;
// make sure the destructor won't delete us ... // make sure the destructor won't delete us ...
delete[] pc->mChildren; delete[] pc->mChildren;
@ -586,14 +688,6 @@ void ASEImporter::BuildNodes()
return; return;
} }
// ------------------------------------------------------------------------------------------------
void ASEImporter::TransformVertices(ASE::Mesh& mesh)
{
// the matrix data is stored in column-major format,
// but we need row major
mesh.mTransform.Transpose();
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ASEImporter::BuildUniqueRepresentation(ASE::Mesh& mesh) void ASEImporter::BuildUniqueRepresentation(ASE::Mesh& mesh)
{ {
@ -633,16 +727,16 @@ void ASEImporter::BuildUniqueRepresentation(ASE::Mesh& mesh)
} }
// iterate through all faces in the mesh // iterate through all faces in the mesh
unsigned int iCurrent = 0; unsigned int iCurrent = 0, fi = 0;
for (std::vector<ASE::Face>::iterator for (std::vector<ASE::Face>::iterator
i = mesh.mFaces.begin(); i = mesh.mFaces.begin();
i != mesh.mFaces.end();++i) i != mesh.mFaces.end();++i,++fi)
{ {
for (unsigned int n = 0; n < 3;++n,++iCurrent) for (unsigned int n = 0; n < 3;++n,++iCurrent)
{ {
mPositions[iCurrent] = mesh.mPositions[(*i).mIndices[n]]; mPositions[iCurrent] = mesh.mPositions[(*i).mIndices[n]];
//std::swap((float&)mPositions[iCurrent].z,(float&)mPositions[iCurrent].y); // DX-to-OGL //std::swap((float&)mPositions[iCurrent].z,(float&)mPositions[iCurrent].y); // DX-to-OGL
mPositions[iCurrent].y *= -1.f; //mPositions[iCurrent].y *= -1.f;
// add texture coordinates // add texture coordinates
for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
@ -661,11 +755,11 @@ void ASEImporter::BuildUniqueRepresentation(ASE::Mesh& mesh)
// add normal vectors // add normal vectors
if (!mesh.mNormals.empty()) if (!mesh.mNormals.empty())
{ {
mNormals[iCurrent] = mesh.mNormals[(*i).mIndices[n]]; mNormals[iCurrent] = mesh.mNormals[fi*3+n];
mNormals[iCurrent].Normalize(); mNormals[iCurrent].Normalize();
//std::swap((float&)mNormals[iCurrent].z,(float&)mNormals[iCurrent].y); // DX-to-OGL //std::swap((float&)mNormals[iCurrent].z,(float&)mNormals[iCurrent].y); // DX-to-OGL
mNormals[iCurrent].y *= -1.0f; //mNormals[iCurrent].y *= -1.0f;
} }
// handle bone vertices // handle bone vertices
@ -722,11 +816,11 @@ void ASEImporter::ConvertMaterial(ASE::Material& mat)
mat.pcInstance->AddProperty( &mat.mShininessStrength, 1, AI_MATKEY_SHININESS_STRENGTH); mat.pcInstance->AddProperty( &mat.mShininessStrength, 1, AI_MATKEY_SHININESS_STRENGTH);
} }
// if there is no shininess, we can disable phong lighting // if there is no shininess, we can disable phong lighting
else if (Dot3DS::Dot3DSFile::Metal == mat.mShading || else if (D3DS::Discreet3DS::Metal == mat.mShading ||
Dot3DS::Dot3DSFile::Phong == mat.mShading || D3DS::Discreet3DS::Phong == mat.mShading ||
Dot3DS::Dot3DSFile::Blinn == mat.mShading) D3DS::Discreet3DS::Blinn == mat.mShading)
{ {
mat.mShading = Dot3DS::Dot3DSFile::Gouraud; mat.mShading = D3DS::Discreet3DS::Gouraud;
} }
// opacity // opacity
@ -737,24 +831,24 @@ void ASEImporter::ConvertMaterial(ASE::Material& mat)
aiShadingMode eShading = aiShadingMode_NoShading; aiShadingMode eShading = aiShadingMode_NoShading;
switch (mat.mShading) switch (mat.mShading)
{ {
case Dot3DS::Dot3DSFile::Flat: case D3DS::Discreet3DS::Flat:
eShading = aiShadingMode_Flat; break; eShading = aiShadingMode_Flat; break;
case Dot3DS::Dot3DSFile::Phong : case D3DS::Discreet3DS::Phong :
eShading = aiShadingMode_Phong; break; eShading = aiShadingMode_Phong; break;
case Dot3DS::Dot3DSFile::Blinn : case D3DS::Discreet3DS::Blinn :
eShading = aiShadingMode_Blinn; break; eShading = aiShadingMode_Blinn; break;
// I don't know what "Wire" shading should be, // I don't know what "Wire" shading should be,
// assume it is simple lambertian diffuse (L dot N) shading // assume it is simple lambertian diffuse (L dot N) shading
case Dot3DS::Dot3DSFile::Wire: case D3DS::Discreet3DS::Wire:
case Dot3DS::Dot3DSFile::Gouraud: case D3DS::Discreet3DS::Gouraud:
eShading = aiShadingMode_Gouraud; break; eShading = aiShadingMode_Gouraud; break;
case Dot3DS::Dot3DSFile::Metal : case D3DS::Discreet3DS::Metal :
eShading = aiShadingMode_CookTorrance; break; eShading = aiShadingMode_CookTorrance; break;
} }
mat.pcInstance->AddProperty<int>( (int*)&eShading,1,AI_MATKEY_SHADING_MODEL); mat.pcInstance->AddProperty<int>( (int*)&eShading,1,AI_MATKEY_SHADING_MODEL);
if (Dot3DS::Dot3DSFile::Wire == mat.mShading) if (D3DS::Discreet3DS::Wire == mat.mShading)
{ {
// set the wireframe flag // set the wireframe flag
unsigned int iWire = 1; unsigned int iWire = 1;
@ -1190,7 +1284,7 @@ void ASEImporter::BuildMaterialIndices()
// allocate the output material array // allocate the output material array
pcScene->mMaterials = new aiMaterial*[pcScene->mNumMaterials]; pcScene->mMaterials = new aiMaterial*[pcScene->mNumMaterials];
Dot3DS::Material** pcIntMaterials = new Dot3DS::Material*[pcScene->mNumMaterials]; D3DS::Material** pcIntMaterials = new D3DS::Material*[pcScene->mNumMaterials];
unsigned int iNum = 0; unsigned int iNum = 0;
for (unsigned int iMat = 0; iMat < mParser->m_vMaterials.size();++iMat) for (unsigned int iMat = 0; iMat < mParser->m_vMaterials.size();++iMat)

View File

@ -83,7 +83,7 @@ protected:
*/ */
void GetExtensionList(std::string& append) void GetExtensionList(std::string& append)
{ {
append.append("*.ase;*.ask"); append.append("*.ase;*.ask;*.asc");
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -116,12 +116,6 @@ protected:
*/ */
void BuildUniqueRepresentation(ASE::Mesh& mesh); void BuildUniqueRepresentation(ASE::Mesh& mesh);
// -------------------------------------------------------------------
/** Transform all vertices with the inverse transformation
* matrix of the mesh
* \param mesh Mesh to work on
*/
void TransformVertices(ASE::Mesh& mesh);
/** Create one-material-per-mesh meshes ;-) /** Create one-material-per-mesh meshes ;-)
* \param mesh Mesh to work with * \param mesh Mesh to work with
* \param Receives the list of all created meshes * \param Receives the list of all created meshes
@ -192,6 +186,8 @@ protected:
/** Scene to be filled */ /** Scene to be filled */
aiScene* pcScene; aiScene* pcScene;
std::vector<BaseNode*> nodes;
/** Config options: Recompute the normals in every case - WA /** Config options: Recompute the normals in every case - WA
for 3DS Max broken ASE normal export */ for 3DS Max broken ASE normal export */
bool configRecomputeNormals; bool configRecomputeNormals;

View File

@ -135,8 +135,7 @@ void Parser::LogWarning(const char* szWarn)
#if _MSC_VER >= 1400 #if _MSC_VER >= 1400
sprintf_s(szTemp,"Line %i: %s",iLineNumber,szWarn); sprintf_s(szTemp,"Line %i: %s",iLineNumber,szWarn);
#else #else
ai_assert(strlen(szWarn) < 950); snprintf(szTemp,1024,"Line %i: %s",iLineNumber,szWarn);
sprintf(szTemp,"Line %i: %s",iLineNumber,szWarn);
#endif #endif
// output the warning to the logger ... // output the warning to the logger ...
@ -151,8 +150,7 @@ void Parser::LogInfo(const char* szWarn)
#if _MSC_VER >= 1400 #if _MSC_VER >= 1400
sprintf_s(szTemp,"Line %i: %s",iLineNumber,szWarn); sprintf_s(szTemp,"Line %i: %s",iLineNumber,szWarn);
#else #else
ai_assert(strlen(szWarn) < 950); snprintf(szTemp,1024,"Line %i: %s",iLineNumber,szWarn);
sprintf(szTemp,"Line %i: %s",iLineNumber,szWarn);
#endif #endif
// output the information to the logger ... // output the information to the logger ...
@ -167,8 +165,7 @@ void Parser::LogError(const char* szWarn)
#if _MSC_VER >= 1400 #if _MSC_VER >= 1400
sprintf_s(szTemp,"Line %i: %s",iLineNumber,szWarn); sprintf_s(szTemp,"Line %i: %s",iLineNumber,szWarn);
#else #else
ai_assert(strlen(szWarn) < 950); snprintf(szTemp,1024,"Line %i: %s",iLineNumber,szWarn);
sprintf(szTemp,"Line %i: %s",iLineNumber,szWarn);
#endif #endif
// throw an exception // throw an exception
@ -241,10 +238,10 @@ void Parser::Parse()
unsigned int iVersion; unsigned int iVersion;
ParseLV4MeshLong(iVersion); ParseLV4MeshLong(iVersion);
if (200 != iVersion) if (iVersion > 200)
{ {
LogWarning("Unknown file format version: *3DSMAX_ASCIIEXPORT should \ LogWarning("Unknown file format version: *3DSMAX_ASCIIEXPORT should \
be 200. Continuing happily ..."); be <=200. Continuing happily ...");
} }
continue; continue;
} }
@ -254,7 +251,8 @@ void Parser::Parse()
ParseLV1SceneBlock(); ParseLV1SceneBlock();
continue; continue;
} }
// "group" // "group" - no implementation yet, in facte
// we're just ignoring them for the moment
if (TokenMatch(m_szFile,"GROUP",5)) if (TokenMatch(m_szFile,"GROUP",5))
{ {
Parse(); Parse();
@ -271,15 +269,15 @@ void Parser::Parse()
{ {
m_vMeshes.push_back(Mesh()); m_vMeshes.push_back(Mesh());
ParseLV1GeometryObjectBlock(m_vMeshes.back()); ParseLV1ObjectBlock(m_vMeshes.back());
continue; continue;
} }
// helper object = dummy in the hierarchy // helper object = dummy in the hierarchy
if (TokenMatch(m_szFile,"HELPEROBJECT",12)) if (TokenMatch(m_szFile,"HELPEROBJECT",12))
{ {
m_vMeshes.push_back(Mesh()); m_vDummies.push_back(Dummy());
ParseLV1GeometryObjectBlock(m_vMeshes.back()); ParseLV1ObjectBlock(m_vDummies.back());
continue; continue;
} }
// light object // light object
@ -287,14 +285,14 @@ void Parser::Parse()
{ {
m_vLights.push_back(Light()); m_vLights.push_back(Light());
ParseLV1LightObjectBlock(m_vLights.back()); ParseLV1ObjectBlock(m_vLights.back());
continue; continue;
} }
// camera object // camera object
if (TokenMatch(m_szFile,"CAMERAOBJECT",12)) if (TokenMatch(m_szFile,"CAMERAOBJECT",12))
{ {
m_vCameras.push_back(Camera()); m_vCameras.push_back(Camera());
ParseLV1CameraObjectBlock(m_vCameras.back()); ParseLV1ObjectBlock(m_vCameras.back());
continue; continue;
} }
// comment - print it on the console // comment - print it on the console
@ -436,24 +434,24 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
{ {
if (TokenMatch(m_szFile,"Blinn",5)) if (TokenMatch(m_szFile,"Blinn",5))
{ {
mat.mShading = Dot3DSFile::Blinn; mat.mShading = Discreet3DS::Blinn;
} }
else if (TokenMatch(m_szFile,"Phong",5)) else if (TokenMatch(m_szFile,"Phong",5))
{ {
mat.mShading = Dot3DSFile::Phong; mat.mShading = Discreet3DS::Phong;
} }
else if (TokenMatch(m_szFile,"Flat",4)) else if (TokenMatch(m_szFile,"Flat",4))
{ {
mat.mShading = Dot3DSFile::Flat; mat.mShading = Discreet3DS::Flat;
} }
else if (TokenMatch(m_szFile,"Wire",4)) else if (TokenMatch(m_szFile,"Wire",4))
{ {
mat.mShading = Dot3DSFile::Wire; mat.mShading = Discreet3DS::Wire;
} }
else else
{ {
// assume gouraud shading // assume gouraud shading
mat.mShading = Dot3DSFile::Gouraud; mat.mShading = Discreet3DS::Gouraud;
SkipToNextToken(); SkipToNextToken();
} }
continue; continue;
@ -572,13 +570,28 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
void Parser::ParseLV3MapBlock(Texture& map) void Parser::ParseLV3MapBlock(Texture& map)
{ {
int iDepth = 0; int iDepth = 0;
// *BITMAP should not be there if *MAP_CLASS is not BITMAP,
// but we need to expect that case ... if the path is
// empty the texture won't be used later.
bool parsePath = true;
while (true) while (true)
{ {
if ('*' == *m_szFile) if ('*' == *m_szFile)
{ {
++m_szFile; ++m_szFile;
// type of map
if (TokenMatch(m_szFile,"MAP_CLASS" ,9))
{
std::string temp;
if(!ParseString(temp,"*MAP_CLASS"))
SkipToNextToken();
if (temp != "Bitmap")
parsePath = false;
continue;
}
// path to the texture // path to the texture
if (TokenMatch(m_szFile,"BITMAP" ,6)) if (parsePath && TokenMatch(m_szFile,"BITMAP" ,6))
{ {
if(!ParseString(map.mMapName,"*BITMAP")) if(!ParseString(map.mMapName,"*BITMAP"))
SkipToNextToken(); SkipToNextToken();
@ -664,33 +677,7 @@ bool Parser::ParseString(std::string& out,const char* szName)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool Parser::ParseSharedNodeInfo(ASE::BaseNode& mesh) void Parser::ParseLV1ObjectBlock(ASE::BaseNode& node)
{
// name of the mesh/node
if (TokenMatch(m_szFile,"NODE_NAME" ,9))
{
if(!ParseString(mesh.mName,"*NODE_NAME"))
SkipToNextToken();
return true;
}
// name of the parent of the node
if (TokenMatch(m_szFile,"NODE_PARENT" ,11) )
{
if(!ParseString(mesh.mParent,"*NODE_PARENT"))
SkipToNextToken();
return true;
}
// transformation matrix of the node
if (TokenMatch(m_szFile,"NODE_TM" ,7))
{
ParseLV2NodeTransformBlock(mesh);
return true;
}
return false;
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV1LightObjectBlock(ASE::Light& light)
{ {
int iDepth = 0; int iDepth = 0;
while (true) while (true)
@ -698,51 +685,94 @@ void Parser::ParseLV1LightObjectBlock(ASE::Light& light)
if ('*' == *m_szFile) if ('*' == *m_szFile)
{ {
++m_szFile; ++m_szFile;
// first process common tokens such as node name and transform
if (ParseSharedNodeInfo(light))continue;
// light settings
if (TokenMatch(m_szFile,"LIGHT_SETTINGS" ,14))
{
ParseLV2LightSettingsBlock(light);
continue;
}
// type of the light source
if (TokenMatch(m_szFile,"LIGHT_TYPE" ,10))
{
if (!ASSIMP_strincmp("omni",m_szFile,4))
{
light.mLightType = ASE::Light::OMNI;
}
else
{
// TODO: use std::string as parameter for LogWarning
LogWarning("Unknown kind of light source");
}
continue;
}
}
AI_ASE_HANDLE_TOP_LEVEL_SECTION(iDepth);
}
return;
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV1CameraObjectBlock(ASE::Camera& camera)
{
int iDepth = 0;
while (true)
{
if ('*' == *m_szFile)
{
++m_szFile;
// first process common tokens such as node name and transform // first process common tokens such as node name and transform
if (ParseSharedNodeInfo(camera))continue; // name of the mesh/node
// Camera settings if (TokenMatch(m_szFile,"NODE_NAME" ,9))
if (TokenMatch(m_szFile,"CAMERA_SETTINGS" ,15))
{ {
ParseLV2CameraSettingsBlock(camera); if(!ParseString(node.mName,"*NODE_NAME"))
SkipToNextToken();
continue; continue;
} }
// name of the parent of the node
if (TokenMatch(m_szFile,"NODE_PARENT" ,11) )
{
if(!ParseString(node.mParent,"*NODE_PARENT"))
SkipToNextToken();
continue;
}
// transformation matrix of the node
if (TokenMatch(m_szFile,"NODE_TM" ,7))
{
ParseLV2NodeTransformBlock(node);
continue;
}
// animation data of the node
if (TokenMatch(m_szFile,"TM_ANIMATION" ,12))
{
ParseLV2AnimationBlock(node);
continue;
}
if (node.mType == BaseNode::Light)
{
// light settings
if (TokenMatch(m_szFile,"LIGHT_SETTINGS" ,14))
{
ParseLV2LightSettingsBlock((ASE::Light&)node);
continue;
}
// type of the light source
if (TokenMatch(m_szFile,"LIGHT_TYPE" ,10))
{
if (!ASSIMP_strincmp("omni",m_szFile,4))
{
((ASE::Light&)node).mLightType = ASE::Light::OMNI;
}
else if (!ASSIMP_strincmp("target",m_szFile,6))
{
((ASE::Light&)node).mLightType = ASE::Light::TARGET;
}
else if (!ASSIMP_strincmp("free",m_szFile,4))
{
((ASE::Light&)node).mLightType = ASE::Light::FREE;
}
else if (!ASSIMP_strincmp("directional",m_szFile,11))
{
((ASE::Light&)node).mLightType = ASE::Light::DIRECTIONAL;
}
else
{
// TODO: use std::string as parameter for LogWarning
LogWarning("Unknown kind of light source");
}
continue;
}
}
else if (node.mType == BaseNode::Camera)
{
// Camera settings
if (TokenMatch(m_szFile,"CAMERA_SETTINGS" ,15))
{
ParseLV2CameraSettingsBlock((ASE::Camera&)node);
continue;
}
}
else if (node.mType == BaseNode::Mesh)
{
// mesh data
if (TokenMatch(m_szFile,"MESH" ,4))
{
ParseLV2MeshBlock((ASE::Mesh&)node);
continue;
}
// mesh material index
if (TokenMatch(m_szFile,"MATERIAL_REF" ,12))
{
ParseLV4MeshLong(((ASE::Mesh&)node).iMaterialIndex);
continue;
}
}
} }
AI_ASE_HANDLE_TOP_LEVEL_SECTION(iDepth); AI_ASE_HANDLE_TOP_LEVEL_SECTION(iDepth);
} }
@ -798,6 +828,16 @@ void Parser::ParseLV2LightSettingsBlock(ASE::Light& light)
ParseLV4MeshFloat(light.mIntensity); ParseLV4MeshFloat(light.mIntensity);
continue; continue;
} }
if (TokenMatch(m_szFile,"LIGHT_HOTSPOT" ,13))
{
ParseLV4MeshFloat(light.mAngle);
continue;
}
if (TokenMatch(m_szFile,"LIGHT_FALLOFF" ,13))
{
ParseLV4MeshFloat(light.mFalloff);
continue;
}
} }
AI_ASE_HANDLE_SECTION(iDepth,"2","LIGHT_SETTINGS"); AI_ASE_HANDLE_SECTION(iDepth,"2","LIGHT_SETTINGS");
} }
@ -805,79 +845,122 @@ void Parser::ParseLV2LightSettingsBlock(ASE::Light& light)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Parser::ParseLV1GeometryObjectBlock(ASE::Mesh& mesh) void Parser::ParseLV2AnimationBlock(ASE::BaseNode& mesh)
{ {
int iDepth = 0; int iDepth = 0;
ASE::Animation* anim = &mesh.mAnim;
while (true) while (true)
{ {
if ('*' == *m_szFile) if ('*' == *m_szFile)
{ {
++m_szFile; ++m_szFile;
if (TokenMatch(m_szFile,"NODE_NAME" ,9))
{
std::string temp;
if(!ParseString(temp,"*NODE_NAME"))
SkipToNextToken();
if (ParseSharedNodeInfo(mesh))continue; // If the name of the node contains .target it
// represents an animated camera or spot light
// target.
if (std::string::npos != temp.find(".Target"))
{
if (mesh.mType != BaseNode::Camera &&
(mesh.mType != BaseNode::Light ||
((ASE::Light&)mesh).mLightType != ASE::Light::TARGET))
{ /* it is not absolutely sure we know the type of the light source yet */
// mesh data DefaultLogger::get()->error("ASE: Found target animation channel "
if (TokenMatch(m_szFile,"MESH" ,4)) "but the node is neither a camera nor a spot light");
{ anim = NULL;
ParseLV2MeshBlock(mesh); }
else anim = &mesh.mTargetAnim;
}
continue; continue;
} }
// mesh material index
if (TokenMatch(m_szFile,"MATERIAL_REF" ,12))
{
ParseLV4MeshLong(mesh.iMaterialIndex);
continue;
}
// animation data of the node
if (TokenMatch(m_szFile,"TM_ANIMATION" ,12))
{
ParseLV2AnimationBlock(mesh);
continue;
}
}
AI_ASE_HANDLE_TOP_LEVEL_SECTION(iDepth);
}
return;
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV2AnimationBlock(ASE::Mesh& mesh)
{
int iDepth = 0;
while (true)
{
if ('*' == *m_szFile)
{
++m_szFile;
// position keyframes // position keyframes
if (TokenMatch(m_szFile,"CONTROL_POS_TRACK" ,17)) if (TokenMatch(m_szFile,"CONTROL_POS_TRACK" ,17) ||
TokenMatch(m_szFile,"CONTROL_POS_BEZIER" ,18) ||
TokenMatch(m_szFile,"CONTROL_POS_TCB" ,15))
{ {
ParseLV3PosAnimationBlock(mesh);continue; if (!anim)SkipSection();
else ParseLV3PosAnimationBlock(*anim);
continue;
}
// scaling keyframes
if (TokenMatch(m_szFile,"CONTROL_SCALE_TRACK" ,19) ||
TokenMatch(m_szFile,"CONTROL_SCALE_BEZIER" ,20) ||
TokenMatch(m_szFile,"CONTROL_SCALE_TCB" ,17))
{
if (!anim || anim == &mesh.mTargetAnim)
{
// Target animation channels may have no rotation channels
DefaultLogger::get()->error("ASE: Ignoring scaling channel in target animation");
SkipSection();
}
else ParseLV3ScaleAnimationBlock(*anim);
continue;
} }
// rotation keyframes // rotation keyframes
if (TokenMatch(m_szFile,"CONTROL_ROT_TRACK" ,17)) if (TokenMatch(m_szFile,"CONTROL_ROT_TRACK" ,17) ||
TokenMatch(m_szFile,"CONTROL_ROT_BEZIER" ,18) ||
TokenMatch(m_szFile,"CONTROL_ROT_TCB" ,15))
{ {
ParseLV3RotAnimationBlock(mesh);continue; if (!anim || anim == &mesh.mTargetAnim)
{
// Target animation channels may have no rotation channels
DefaultLogger::get()->error("ASE: Ignoring rotation channel in target animation");
SkipSection();
}
else ParseLV3RotAnimationBlock(*anim);
continue;
} }
} }
AI_ASE_HANDLE_SECTION(iDepth,"2","TM_ANIMATION"); AI_ASE_HANDLE_SECTION(iDepth,"2","TM_ANIMATION");
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Parser::ParseLV3PosAnimationBlock(ASE::Mesh& mesh) void Parser::ParseLV3ScaleAnimationBlock(ASE::Animation& anim)
{ {
int iDepth = 0; int iDepth = 0;
unsigned int iIndex;
while (true) while (true)
{ {
if ('*' == *m_szFile) if ('*' == *m_szFile)
{ {
++m_szFile; ++m_szFile;
// position keyframe
if (TokenMatch(m_szFile,"CONTROL_POS_SAMPLE" ,18))
{
unsigned int iIndex;
mesh.mAnim.akeyPositions.push_back(aiVectorKey());
aiVectorKey& key = mesh.mAnim.akeyPositions.back();
bool b = false;
// For the moment we're just reading the three floats -
// we ignore the ádditional information for bezier's and TCBs
// simple scaling keyframe
if (TokenMatch(m_szFile,"CONTROL_SCALE_SAMPLE" ,20))
{
b = true;
anim.mScalingType = ASE::Animation::TRACK;
}
// Bezier scaling keyframe
if (TokenMatch(m_szFile,"CONTROL_BEZIER_SCALE_KEY" ,24))
{
b = true;
anim.mScalingType = ASE::Animation::BEZIER;
}
// TCB scaling keyframe
if (TokenMatch(m_szFile,"CONTROL_TCB_SCALE_KEY" ,21))
{
b = true;
anim.mScalingType = ASE::Animation::TCB;
}
if (b)
{
anim.akeyScaling.push_back(aiVectorKey());
aiVectorKey& key = anim.akeyScaling.back();
ParseLV4MeshFloatTriple(&key.mValue.x,iIndex); ParseLV4MeshFloatTriple(&key.mValue.x,iIndex);
key.mTime = (double)iIndex; key.mTime = (double)iIndex;
} }
@ -886,22 +969,90 @@ void Parser::ParseLV3PosAnimationBlock(ASE::Mesh& mesh)
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Parser::ParseLV3RotAnimationBlock(ASE::Mesh& mesh) void Parser::ParseLV3PosAnimationBlock(ASE::Animation& anim)
{ {
int iDepth = 0; int iDepth = 0;
unsigned int iIndex;
while (true) while (true)
{ {
if ('*' == *m_szFile) if ('*' == *m_szFile)
{ {
++m_szFile; ++m_szFile;
// rotation keyframe
bool b = false;
// For the moment we're just reading the three floats -
// we ignore the ádditional information for bezier's and TCBs
// simple scaling keyframe
if (TokenMatch(m_szFile,"CONTROL_POS_SAMPLE" ,18))
{
b = true;
anim.mPositionType = ASE::Animation::TRACK;
}
// Bezier scaling keyframe
if (TokenMatch(m_szFile,"CONTROL_BEZIER_POS_KEY" ,22))
{
b = true;
anim.mPositionType = ASE::Animation::BEZIER;
}
// TCB scaling keyframe
if (TokenMatch(m_szFile,"CONTROL_TCB_POS_KEY" ,19))
{
b = true;
anim.mPositionType = ASE::Animation::TCB;
}
if (b)
{
anim.akeyPositions.push_back(aiVectorKey());
aiVectorKey& key = anim.akeyPositions.back();
ParseLV4MeshFloatTriple(&key.mValue.x,iIndex);
key.mTime = (double)iIndex;
}
}
AI_ASE_HANDLE_SECTION(iDepth,"3","*CONTROL_POS_TRACK");
}
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV3RotAnimationBlock(ASE::Animation& anim)
{
int iDepth = 0;
unsigned int iIndex;
while (true)
{
if ('*' == *m_szFile)
{
++m_szFile;
bool b = false;
// For the moment we're just reading the floats -
// we ignore the ádditional information for bezier's and TCBs
// simple scaling keyframe
if (TokenMatch(m_szFile,"CONTROL_ROT_SAMPLE" ,18)) if (TokenMatch(m_szFile,"CONTROL_ROT_SAMPLE" ,18))
{ {
unsigned int iIndex; b = true;
mesh.mAnim.akeyRotations.push_back(aiQuatKey()); anim.mRotationType = ASE::Animation::TRACK;
aiQuatKey& key = mesh.mAnim.akeyRotations.back(); }
// first read the axis, then the angle in radians // Bezier scaling keyframe
if (TokenMatch(m_szFile,"CONTROL_BEZIER_ROT_KEY" ,22))
{
b = true;
anim.mRotationType = ASE::Animation::BEZIER;
}
// TCB scaling keyframe
if (TokenMatch(m_szFile,"CONTROL_TCB_ROT_KEY" ,19))
{
b = true;
anim.mRotationType = ASE::Animation::TCB;
}
if (b)
{
anim.akeyRotations.push_back(aiQuatKey());
aiQuatKey& key = anim.akeyRotations.back();
aiVector3D v;float f; aiVector3D v;float f;
ParseLV4MeshFloatTriple(&v.x,iIndex); ParseLV4MeshFloatTriple(&v.x,iIndex);
ParseLV4MeshFloat(f); ParseLV4MeshFloat(f);
@ -916,64 +1067,103 @@ void Parser::ParseLV3RotAnimationBlock(ASE::Mesh& mesh)
void Parser::ParseLV2NodeTransformBlock(ASE::BaseNode& mesh) void Parser::ParseLV2NodeTransformBlock(ASE::BaseNode& mesh)
{ {
int iDepth = 0; int iDepth = 0;
int mode = 0;
while (true) while (true)
{ {
if ('*' == *m_szFile) if ('*' == *m_szFile)
{ {
++m_szFile; ++m_szFile;
// first row of the transformation matrix // name of the node
if (TokenMatch(m_szFile,"TM_ROW0" ,7)) if (TokenMatch(m_szFile,"NODE_NAME" ,9))
{ {
ParseLV4MeshFloatTriple(mesh.mTransform[0]); std::string temp;
continue; if(!ParseString(temp,"*NODE_NAME"))
} SkipToNextToken();
// second row of the transformation matrix
if (TokenMatch(m_szFile,"TM_ROW1" ,7))
{
ParseLV4MeshFloatTriple(mesh.mTransform[1]);
continue;
}
// third row of the transformation matrix
if (TokenMatch(m_szFile,"TM_ROW2" ,7))
{
ParseLV4MeshFloatTriple(mesh.mTransform[2]);
continue;
}
// fourth row of the transformation matrix
if (TokenMatch(m_szFile,"TM_ROW3" ,7))
{
ParseLV4MeshFloatTriple(mesh.mTransform[3]);
continue;
}
// inherited position axes
if (TokenMatch(m_szFile,"INHERIT_POS" ,11))
{
unsigned int aiVal[3];
ParseLV4MeshLongTriple(aiVal);
for (unsigned int i = 0; i < 3;++i) std::string::size_type s;
mesh.inherit.abInheritPosition[i] = aiVal[i] != 0; if (temp == mesh.mName)
{
mode = 1;
}
else if (std::string::npos != (s = temp.find(".Target")) &&
mesh.mName == temp.substr(0,s))
{
// This should be either a target light or a target camera
if ( mesh.mType == BaseNode::Light && ((ASE::Light&)mesh) .mLightType == ASE::Light::TARGET ||
mesh.mType == BaseNode::Camera && ((ASE::Camera&)mesh).mCameraType == ASE::Camera::TARGET)
{
mode = 2;
}
else DefaultLogger::get()->error("ASE: Ignoring target transform, "
"this is no spot light or target camera");
}
else
{
DefaultLogger::get()->error("ASE: Unknown node transformation: " + temp);
// mode = 0
}
continue; continue;
} }
// inherited rotation axes if (mode)
if (TokenMatch(m_szFile,"INHERIT_ROT" ,11))
{ {
unsigned int aiVal[3]; // fourth row of the transformation matrix - and also the
ParseLV4MeshLongTriple(aiVal); // only information here that is interesting for targets
if (TokenMatch(m_szFile,"TM_ROW3" ,7))
{
ParseLV4MeshFloatTriple((mode == 1 ? mesh.mTransform[3] : &mesh.mTargetPosition.x));
continue;
}
if (mode == 1)
{
// first row of the transformation matrix
if (TokenMatch(m_szFile,"TM_ROW0" ,7))
{
ParseLV4MeshFloatTriple(mesh.mTransform[0]);
continue;
}
// second row of the transformation matrix
if (TokenMatch(m_szFile,"TM_ROW1" ,7))
{
ParseLV4MeshFloatTriple(mesh.mTransform[1]);
continue;
}
// third row of the transformation matrix
if (TokenMatch(m_szFile,"TM_ROW2" ,7))
{
ParseLV4MeshFloatTriple(mesh.mTransform[2]);
continue;
}
// inherited position axes
if (TokenMatch(m_szFile,"INHERIT_POS" ,11))
{
unsigned int aiVal[3];
ParseLV4MeshLongTriple(aiVal);
for (unsigned int i = 0; i < 3;++i) for (unsigned int i = 0; i < 3;++i)
mesh.inherit.abInheritRotation[i] = aiVal[i] != 0; mesh.inherit.abInheritPosition[i] = aiVal[i] != 0;
continue; continue;
} }
// inherited scaling axes // inherited rotation axes
if (TokenMatch(m_szFile,"INHERIT_SCL" ,11)) if (TokenMatch(m_szFile,"INHERIT_ROT" ,11))
{ {
unsigned int aiVal[3]; unsigned int aiVal[3];
ParseLV4MeshLongTriple(aiVal); ParseLV4MeshLongTriple(aiVal);
for (unsigned int i = 0; i < 3;++i) for (unsigned int i = 0; i < 3;++i)
mesh.inherit.abInheritScaling[i] = aiVal[i] != 0; mesh.inherit.abInheritRotation[i] = aiVal[i] != 0;
continue; continue;
}
// inherited scaling axes
if (TokenMatch(m_szFile,"INHERIT_SCL" ,11))
{
unsigned int aiVal[3];
ParseLV4MeshLongTriple(aiVal);
for (unsigned int i = 0; i < 3;++i)
mesh.inherit.abInheritScaling[i] = aiVal[i] != 0;
continue;
}
}
} }
} }
AI_ASE_HANDLE_SECTION(iDepth,"2","*NODE_TM"); AI_ASE_HANDLE_SECTION(iDepth,"2","*NODE_TM");
@ -1493,45 +1683,58 @@ void Parser::ParseLV3MeshCFaceListBlock(unsigned int iNumFaces, ASE::Mesh& mesh)
void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh& sMesh) void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh& sMesh)
{ {
// allocate enough storage for the normals // allocate enough storage for the normals
sMesh.mNormals.resize(sMesh.mPositions.size(),aiVector3D( 0.f, 0.f, 0.f )); sMesh.mNormals.resize(sMesh.mFaces.size()*3,aiVector3D( 0.f, 0.f, 0.f ));
int iDepth = 0; int iDepth = 0;
unsigned int iIndex = 0; unsigned int iIndex = 0, faceIdx = 0xffffffff;
// just smooth both vertex and face normals together, so it will still // just smooth both vertex and face normals together, so it will still
// work if one oneof the two is missing ... // work if one one of the two is missing ...
// FIX: ASE normals aren't orhotnormal and not really usable for us
while (true) while (true)
{ {
if ('*' == *m_szFile) if ('*' == *m_szFile)
{ {
++m_szFile; ++m_szFile;
if (TokenMatch(m_szFile,"MESH_VERTEXNORMAL",17)) if (0xffffffff != faceIdx && TokenMatch(m_szFile,"MESH_VERTEXNORMAL",17))
{ {
aiVector3D vNormal; aiVector3D vNormal;
ParseLV4MeshFloatTriple(&vNormal.x,iIndex); ParseLV4MeshFloatTriple(&vNormal.x,iIndex);
if (iIndex >= sMesh.mNormals.size()) if (iIndex == sMesh.mFaces[faceIdx].mIndices[0])
{ {
LogWarning("Normal index is too large"); iIndex = 0;
}
else if (iIndex != sMesh.mFaces[faceIdx].mIndices[1])
{
iIndex = 1;
}
else if (iIndex != sMesh.mFaces[faceIdx].mIndices[2])
{
iIndex = 2;
}
else
{
LogWarning("Normal index doesn't fit to face index");
continue; continue;
} }
sMesh.mNormals[iIndex] += vNormal; // We'll renormalized later
sMesh.mNormals[faceIdx*3 + iIndex] += vNormal;
continue; continue;
} }
if (TokenMatch(m_szFile,"MESH_FACENORMAL",15)) if (TokenMatch(m_szFile,"MESH_FACENORMAL",15))
{ {
aiVector3D vNormal; aiVector3D vNormal;
ParseLV4MeshFloatTriple(&vNormal.x,iIndex); ParseLV4MeshFloatTriple(&vNormal.x,faceIdx);
if (iIndex >= sMesh.mFaces.size()) if (iIndex >= sMesh.mFaces.size())
{ {
LogWarning("Face normal index is too large"); LogWarning("Face normal index is too large");
faceIdx = 0xffffffff;
continue; continue;
} }
for (unsigned int i = 0; i<3; ++i) sMesh.mNormals[faceIdx*3] += vNormal;
{ sMesh.mNormals[faceIdx*3 +1] += vNormal;
sMesh.mNormals[sMesh.mFaces[iIndex].mIndices[i]] += vNormal; sMesh.mNormals[faceIdx*3 +2] += vNormal;
}
continue; continue;
} }
} }

View File

@ -60,17 +60,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ASE is quite similar to 3ds. We can reuse some structures // ASE is quite similar to 3ds. We can reuse some structures
#include "3DSLoader.h" #include "3DSLoader.h"
namespace Assimp namespace Assimp {
{ namespace ASE {
// http://wiki.beyondunreal.com/Legacy:ASE_File_Format using namespace D3DS;
namespace ASE
{
using namespace Dot3DS;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Helper structure representing an ASE material */ /** Helper structure representing an ASE material */
struct Material : public Dot3DS::Material struct Material : public D3DS::Material
{ {
//! Default constructor //! Default constructor
Material() : pcInstance(NULL), bNeed (false) Material() : pcInstance(NULL), bNeed (false)
@ -159,12 +156,34 @@ struct BoneVertex
/** Helper structure to represent an ASE file animation */ /** Helper structure to represent an ASE file animation */
struct Animation struct Animation
{ {
//! List of rotation keyframes enum Type
{
TRACK = 0x0,
BEZIER = 0x1,
TCB = 0x2
} mRotationType, mScalingType, mPositionType;
Animation()
: mRotationType (TRACK)
, mScalingType (TRACK)
, mPositionType (TRACK)
{}
/** ONLY ONE OF THESE SETS IS USED
*
* Bezier and TCB channels are converted to a normal
* trac later.
*/
//! List of track rotation keyframes
std::vector< aiQuatKey > akeyRotations; std::vector< aiQuatKey > akeyRotations;
//! List of position keyframes //! List of track position keyframes
std::vector< aiVectorKey > akeyPositions; std::vector< aiVectorKey > akeyPositions;
//! List of track scaling keyframes
std::vector< aiVectorKey > akeyScaling;
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -217,10 +236,20 @@ struct BaseNode
//! Transformation matrix of the node //! Transformation matrix of the node
aiMatrix4x4 mTransform; aiMatrix4x4 mTransform;
//! Target position (target lights and cameras)
aiVector3D mTargetPosition;
//! Specifies which axes transformations a node inherits //! Specifies which axes transformations a node inherits
//! from its parent ... //! from its parent ...
InheritanceInfo inherit; InheritanceInfo inherit;
//! Animation channels for the node
Animation mAnim;
//! Needed for lights and cameras: target animation channel
//! Should contain position keys only.
Animation mTargetAnim;
bool mProcessed; bool mProcessed;
}; };
@ -253,9 +282,6 @@ struct Mesh : public MeshWithSmoothingGroups<ASE::Face>, public BaseNode
//! List of all bones //! List of all bones
std::vector<Bone> mBones; std::vector<Bone> mBones;
//! Animation channels for the node
Animation mAnim;
//! Material index of the mesh //! Material index of the mesh
unsigned int iMaterialIndex; unsigned int iMaterialIndex;
@ -272,7 +298,10 @@ struct Light : public BaseNode
{ {
enum LightType enum LightType
{ {
OMNI OMNI,
TARGET,
FREE,
DIRECTIONAL
}; };
//! Constructor. //! Constructor.
@ -281,28 +310,51 @@ struct Light : public BaseNode
, mLightType (OMNI) , mLightType (OMNI)
, mColor (1.f,1.f,1.f) , mColor (1.f,1.f,1.f)
, mIntensity (1.f) // light is white by default , mIntensity (1.f) // light is white by default
, mAngle (45.f)
, mFalloff (0.f)
{ {
} }
LightType mLightType; LightType mLightType;
aiColor3D mColor; aiColor3D mColor;
float mIntensity; float mIntensity;
float mAngle; // in degrees
float mFalloff;
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Helper structure to represent an ASE camera */ /** Helper structure to represent an ASE camera */
struct Camera : public BaseNode struct Camera : public BaseNode
{ {
enum CameraType
{
FREE,
TARGET
};
//! Constructor //! Constructor
Camera() Camera()
: BaseNode (BaseNode::Camera) : BaseNode (BaseNode::Camera)
, mFOV (0.75f) // in radians , mFOV (0.75f) // in radians
, mNear (0.1f) , mNear (0.1f)
, mFar (1000.f) // could be zero , mFar (1000.f) // could be zero
, mCameraType (FREE)
{ {
} }
float mFOV, mNear, mFar; float mFOV, mNear, mFar;
CameraType mCameraType;
};
// ---------------------------------------------------------------------------
/** Helper structure to represent an ASE helper object (dummy) */
struct Dummy : public BaseNode
{
//! Constructor
Dummy()
: BaseNode (BaseNode::Dummy)
{
}
}; };
// --------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------
@ -337,26 +389,9 @@ private:
void ParseLV1MaterialListBlock(); void ParseLV1MaterialListBlock();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a *GEOMOBJECT block in a file //! Parse a *<xxx>OBJECT block in a file
//! \param mesh Mesh object to be filled //! \param mesh Node to be filled
void ParseLV1GeometryObjectBlock(Mesh& mesh); void ParseLV1ObjectBlock(BaseNode& mesh);
// -------------------------------------------------------------------
//! Parse a *LIGHTOBJECT block in a file
//! \param light Light object to be filled
void ParseLV1LightObjectBlock(Light& mesh);
// -------------------------------------------------------------------
//! Parse a *CAMERAOBJECT block in a file
//! \param cam Camera object to be filled
void ParseLV1CameraObjectBlock(Camera& cam);
// -------------------------------------------------------------------
//! Parse the shared parts of the *GEOMOBJECT, *LIGHTOBJECT and
//! *CAMERAOBJECT chunks.
//! \param mesh ..
//! \return true = token parsed, get next please
bool ParseSharedNodeInfo(ASE::BaseNode& mesh);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a *MATERIAL blocks in a material list //! Parse a *MATERIAL blocks in a material list
@ -371,9 +406,10 @@ private:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a *TM_ANIMATION block in a file //! Parse a *TM_ANIMATION block in a file
//! \param mesh Mesh object to be filled //! \param mesh Mesh object to be filled
void ParseLV2AnimationBlock(Mesh& mesh); void ParseLV2AnimationBlock(BaseNode& mesh);
void ParseLV3PosAnimationBlock(Mesh& mesh); void ParseLV3PosAnimationBlock(ASE::Animation& anim);
void ParseLV3RotAnimationBlock(Mesh& mesh); void ParseLV3ScaleAnimationBlock(ASE::Animation& anim);
void ParseLV3RotAnimationBlock(ASE::Animation& anim);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a *MESH block in a file //! Parse a *MESH block in a file
@ -573,6 +609,9 @@ public:
//! List of all meshes found in the file //! List of all meshes found in the file
std::vector<Mesh> m_vMeshes; std::vector<Mesh> m_vMeshes;
//! List of all dummies found in the file
std::vector<Dummy> m_vDummies;
//! List of all lights found in the file //! List of all lights found in the file
std::vector<Light> m_vLights; std::vector<Light> m_vLights;

View File

@ -42,6 +42,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_PCH_INCLUDED #ifndef ASSIMP_PCH_INCLUDED
#define ASSIMP_PCH_INCLUDED #define ASSIMP_PCH_INCLUDED
#define ASSIMP_INTERNAL_BUILD
// ******************************************************************* // *******************************************************************
// Print detailled memory allocation statistics? In this case we'll // Print detailled memory allocation statistics? In this case we'll
// need to overload all C++ memory management functions. It is assumed // need to overload all C++ memory management functions. It is assumed
@ -90,7 +92,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../include/aiPostProcess.h" #include "../include/aiPostProcess.h"
#include "../include/assimp.hpp" #include "../include/assimp.hpp"
// ******************************************************************* // *******************************************************************
// internal headers that are nearly always required // internal headers that are nearly always required
// ******************************************************************* // *******************************************************************

View File

@ -140,27 +140,31 @@ bool BaseImporter::SearchFileHeaderForToken(IOSystem* pIOHandler,
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Represents an import request
struct LoadRequest struct LoadRequest
{ {
LoadRequest(const std::string& _file, unsigned int _flags) LoadRequest(const std::string& _file, unsigned int _flags,const BatchLoader::PropertyMap* _map)
: file (_file) : file (_file)
, flags (_flags) , flags (_flags)
, scene (NULL) , scene (NULL)
, refCnt (1) , refCnt (1)
, loaded (false) , loaded (false)
, map (*_map)
{} {}
const std::string file; const std::string file;
unsigned int flags; unsigned int flags;
unsigned int refCnt; unsigned int refCnt;
aiScene* scene; aiScene* scene;
bool loaded; bool loaded;
BatchLoader::PropertyMap map;
bool operator== (const std::string& f) bool operator== (const std::string& f)
{return file == f;} {return file == f;}
}; };
// ------------------------------------------------------------------------------------------------
// BatchLoader::pimpl data structure
struct BatchData struct BatchData
{ {
// IO system to be used for all imports // IO system to be used for all imports
@ -199,7 +203,8 @@ BatchLoader::~BatchLoader()
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BatchLoader::AddLoadRequest (const std::string& file) void BatchLoader::AddLoadRequest (const std::string& file,
unsigned int steps /*= 0*/, const PropertyMap* map /*= NULL*/)
{ {
// no threaded implementation for the moment // no threaded implementation for the moment
BatchData* data = ( BatchData* )pimpl; BatchData* data = ( BatchData* )pimpl;
@ -211,10 +216,9 @@ void BatchLoader::AddLoadRequest (const std::string& file)
(*it).refCnt++; (*it).refCnt++;
return; return;
} }
data->requests.push_back(LoadRequest(file,0)); data->requests.push_back(LoadRequest(file,steps,map));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
aiScene* BatchLoader::GetImport (const std::string& file) aiScene* BatchLoader::GetImport (const std::string& file)
{ {
@ -234,7 +238,6 @@ aiScene* BatchLoader::GetImport (const std::string& file)
return NULL; return NULL;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BatchLoader::LoadAll() void BatchLoader::LoadAll()
{ {
@ -244,12 +247,15 @@ void BatchLoader::LoadAll()
for (std::list<LoadRequest>::iterator it = data->requests.begin(); for (std::list<LoadRequest>::iterator it = data->requests.begin();
it != data->requests.end(); ++it) it != data->requests.end(); ++it)
{ {
// no postprocessing for the moment except validation // force validation in debug builds
// in debug builds unsigned int pp = (*it).flags;
unsigned int pp = 0;
#ifdef _DEBUG #ifdef _DEBUG
pp |= aiProcess_ValidateDataStructure; pp |= aiProcess_ValidateDataStructure;
#endif #endif
// setup config properties if necessary
data->pImporter->mFloatProperties = (*it).map.floats;
data->pImporter->mIntProperties = (*it).map.ints;
data->pImporter->mStringProperties = (*it).map.strings;
data->pImporter->ReadFile((*it).file,pp); data->pImporter->ReadFile((*it).file,pp);
(*it).scene = const_cast<aiScene*>(data->pImporter->GetOrphanedScene()); (*it).scene = const_cast<aiScene*>(data->pImporter->GetOrphanedScene());

View File

@ -247,6 +247,22 @@ protected:
*/ */
class ASSIMP_API BatchLoader class ASSIMP_API BatchLoader
{ {
// friend of Importer
public:
/** Represents a full list of configuration properties
* for the importer.
*
* Properties can be set using SetGenericProperty
*/
struct PropertyMap
{
Importer::IntPropertyMap ints;
Importer::FloatPropertyMap floats;
Importer::StringPropertyMap strings;
};
public: public:
@ -258,10 +274,12 @@ public:
/** Add a new file to the list of files to be loaded. /** Add a new file to the list of files to be loaded.
* *
* No postprocessing steps are executed on the file
* @param file File to be loaded * @param file File to be loaded
* @param steps Steps to be executed on the file
* @param map Optional configuration properties
*/ */
void AddLoadRequest (const std::string& file); void AddLoadRequest (const std::string& file,
unsigned int steps = 0, const PropertyMap* map = NULL);
/** Get an imported scene. /** Get an imported scene.

View File

@ -97,7 +97,7 @@ public:
T data; T data;
}; };
typedef uint32_t KeyType; typedef unsigned int KeyType;
typedef std::map<KeyType, Base*> PropertyMap; typedef std::map<KeyType, Base*> PropertyMap;
public: public:

View File

@ -117,10 +117,18 @@ void ConvertToLHProcess::Execute( aiScene* pScene)
// transform all normals // transform all normals
if (pcMesh->HasNormals()) if (pcMesh->HasNormals())
{ {
mTransform.Inverse().Transpose();
for (unsigned int n = 0; n < pcMesh->mNumVertices;++n) for (unsigned int n = 0; n < pcMesh->mNumVertices;++n)
pcMesh->mNormals[n] = mTransform * pcMesh->mNormals[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 else

View File

@ -118,6 +118,19 @@ bool DXFImporter::GetNextLine()
if(!SkipLine(&buffer)) if(!SkipLine(&buffer))
return false; return false;
if(!SkipSpaces(&buffer))return GetNextLine(); if(!SkipSpaces(&buffer))return GetNextLine();
else if (*buffer == '{')
{
// some strange meta data ...
while (true)
{
if(!SkipLine(&buffer))
return false;
if(SkipSpaces(&buffer) && *buffer == '}')
break;
}
return GetNextLine();
}
return true; return true;
} }
@ -422,7 +435,10 @@ bool DXFImporter::ParsePolyLine()
// flags --- important that we know whether it is a polyface mesh // flags --- important that we know whether it is a polyface mesh
case 70: case 70:
{ {
flags = strtol10(cursor); if (!flags)
{
flags = strtol10(cursor);
}
break; break;
}; };
@ -472,7 +488,7 @@ bool DXFImporter::ParsePolyLine()
it != end; ++it) it != end; ++it)
{ {
unsigned int idx = *it; unsigned int idx = *it;
if (idx > positions.size()) if (idx > positions.size() || !idx)
{ {
DefaultLogger::get()->error("DXF: Polyface mesh index os out of range"); DefaultLogger::get()->error("DXF: Polyface mesh index os out of range");
idx = (unsigned int) positions.size(); idx = (unsigned int) positions.size();
@ -511,7 +527,7 @@ bool DXFImporter::ParsePolyLineVertex(aiVector3D& out,aiColor4D& clr, unsigned i
case 71: outIdx[0] = strtol10(cursor);break; case 71: outIdx[0] = strtol10(cursor);break;
case 72: outIdx[1] = strtol10(cursor);break; case 72: outIdx[1] = strtol10(cursor);break;
case 73: outIdx[2] = strtol10(cursor);break; case 73: outIdx[2] = strtol10(cursor);break;
case 74: outIdx[3] = strtol10(cursor);break; // case 74: outIdx[3] = strtol10(cursor);break;
// color // color
case 62: clr = g_aclrDxfIndexColors[strtol10(cursor) % AI_DXF_NUM_INDEX_COLORS]; break; case 62: clr = g_aclrDxfIndexColors[strtol10(cursor) % AI_DXF_NUM_INDEX_COLORS]; break;

View File

@ -233,6 +233,8 @@ DefaultLogger::DefaultLogger( const std::string &name, LogSeverity severity ) :
if (name.empty()) if (name.empty())
return; return;
m_Streams.push_back( new FileLogStream( name ) ); m_Streams.push_back( new FileLogStream( name ) );
noRepeatMsg = false;
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -262,20 +264,37 @@ void DefaultLogger::writeToStreams(const std::string &message,
{ {
if ( message.empty() ) if ( message.empty() )
return; return;
std::string s;
if (message == lastMsg)
{
if (!noRepeatMsg)
{
noRepeatMsg = true;
s = "Skipping one or more lines with the same contents";
}
else return;
}
else
{
lastMsg = s = message;
noRepeatMsg = false;
}
for ( ConstStreamIt it = m_StreamArray.begin(); for ( ConstStreamIt it = m_StreamArray.begin();
it != m_StreamArray.end(); it != m_StreamArray.end();
++it) ++it)
{ {
if ( ErrorSev & (*it)->m_uiErrorSeverity ) if ( ErrorSev & (*it)->m_uiErrorSeverity )
{ {
(*it)->m_pStream->write( message ); (*it)->m_pStream->write( s);
} }
} }
for (std::vector<LogStream*>::iterator it = m_Streams.begin(); for (std::vector<LogStream*>::iterator it = m_Streams.begin();
it != m_Streams.end(); it != m_Streams.end();
++it) ++it)
{ {
(*it)->write( message + std::string("\n")); (*it)->write( s + std::string("\n"));
} }
} }

View File

@ -109,8 +109,9 @@ void FindInvalidDataProcess::Execute( aiScene* pScene)
bool out = false; bool out = false;
std::vector<unsigned int> meshMapping(pScene->mNumMeshes); std::vector<unsigned int> meshMapping(pScene->mNumMeshes);
unsigned int real = 0; unsigned int real = 0, realAnimations = 0;
// Process meshes
for( unsigned int a = 0; a < pScene->mNumMeshes; a++) for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
{ {
int result; int result;
@ -131,8 +132,32 @@ void FindInvalidDataProcess::Execute( aiScene* pScene)
meshMapping[a] = real++; meshMapping[a] = real++;
} }
// Process animations
for (unsigned int a = 0; a < pScene->mNumAnimations;++a)
{
int result;
if ((result = ProcessAnimation( pScene->mAnimations[a])))
{
out = true;
if (2 == result)
{
// remove this animation
delete pScene->mAnimations[a];
AI_DEBUG_INVALIDATE_PTR(pScene->mAnimations[a]);
continue;
}
}
pScene->mAnimations[realAnimations++] = pScene->mAnimations[a];
}
if (out) if (out)
{ {
if(!(pScene->mNumAnimations = realAnimations))
{
delete[] pScene->mAnimations;
pScene->mAnimations = NULL;
}
if ( real != pScene->mNumMeshes) if ( real != pScene->mNumMeshes)
{ {
if (!real) if (!real)
@ -199,7 +224,69 @@ inline bool ProcessArray(T*& in, unsigned int num,const char* name,
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. template <typename T>
inline bool AllIdentical(T* in, unsigned int num)
{
if (!num)return true;
for (unsigned int i = 0; i < num-1;++i)
{
if (in[i] != in[i+1])return false;
}
return true;
}
// ------------------------------------------------------------------------------------------------
// Search an animation for invalid content
int FindInvalidDataProcess::ProcessAnimation (aiAnimation* anim)
{
bool out = false;
unsigned int real = 0;
// Process all animation channels
for (unsigned int a = 0; a < anim->mNumChannels;++a)
{
int result;
if ((result = ProcessAnimationChannel( anim->mChannels[a])))
{
out = true;
// remove this animation channel
delete anim->mChannels[a];
AI_DEBUG_INVALIDATE_PTR(anim->mChannels[a]);
continue;
}
anim->mChannels[real++] = anim->mChannels[a];
}
if (out)
{
anim->mNumChannels = real;
if (!real)
{
DefaultLogger::get()->error("Deleting anim: it consists of dummy tracks");
return 2;
}
return 1;
}
return 0;
}
// ------------------------------------------------------------------------------------------------
int FindInvalidDataProcess::ProcessAnimationChannel (aiNodeAnim* anim)
{
int i = 0;
// Check whether all values are identical or whether there is just one keyframe
if ((1 >= anim->mNumPositionKeys || AllIdentical(anim->mPositionKeys,anim->mNumPositionKeys)) &&
(1 >= anim->mNumScalingKeys || AllIdentical(anim->mRotationKeys,anim->mNumRotationKeys)) &&
(1 >= anim->mNumRotationKeys || AllIdentical(anim->mScalingKeys,anim->mNumScalingKeys)))
{
DefaultLogger::get()->error("Deleting dummy position animation channel");
return 1;
}
return 0;
}
// ------------------------------------------------------------------------------------------------
// Search a mesh for invalid contents
int FindInvalidDataProcess::ProcessMesh (aiMesh* pMesh) int FindInvalidDataProcess::ProcessMesh (aiMesh* pMesh)
{ {
bool ret = false; bool ret = false;

View File

@ -92,6 +92,21 @@ protected:
* @return 0 - nothing, 1 - removed sth, 2 - please delete me * @return 0 - nothing, 1 - removed sth, 2 - please delete me
*/ */
int ProcessMesh( aiMesh* pMesh); int ProcessMesh( aiMesh* pMesh);
// -------------------------------------------------------------------
/** Executes the postprocessing step on the given animation
* @param anim The animation to process.
* @return 0 - nothing, 1 - removed sth, 2 - please delete me
*/
int ProcessAnimation (aiAnimation* anim);
// -------------------------------------------------------------------
/** Executes the postprocessing step on the given anim channel
* @param anim The animation channel to process.
* @return 0 - nothing, 1 - removed sth, 2 - please delete me
*/
int ProcessAnimationChannel (aiNodeAnim* anim);
}; };
} // end of namespace Assimp } // end of namespace Assimp

View File

@ -46,13 +46,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <class T> template <class T>
inline void SetGenericProperty(std::map< uint32_t, T >& list, inline void SetGenericProperty(std::map< unsigned int, T >& list,
const char* szName, const T& value, bool* bWasExisting = NULL) const char* szName, const T& value, bool* bWasExisting = NULL)
{ {
ai_assert(NULL != szName); ai_assert(NULL != szName);
typedef std::map< uint32_t, T > GenericPropertyMap; typedef std::map< unsigned int, T > GenericPropertyMap;
typedef std::pair< uint32_t, T > GenericPair; typedef std::pair< unsigned int, T > GenericPair;
uint32_t hash = SuperFastHash(szName); uint32_t hash = SuperFastHash(szName);
@ -70,13 +70,13 @@ inline void SetGenericProperty(std::map< uint32_t, T >& list,
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <class T> template <class T>
inline T GetGenericProperty(const std::map< uint32_t, T >& list, inline const T& GetGenericProperty(const std::map< unsigned int, T >& list,
const char* szName, const T& errorReturn) const char* szName, const T& errorReturn)
{ {
ai_assert(NULL != szName); ai_assert(NULL != szName);
typedef std::map< uint32_t, T > GenericPropertyMap; typedef std::map< unsigned int, T > GenericPropertyMap;
typedef std::pair< uint32_t, T > GenericPair; typedef std::pair< unsigned int, T > GenericPair;
uint32_t hash = SuperFastHash(szName); uint32_t hash = SuperFastHash(szName);
@ -90,13 +90,13 @@ inline T GetGenericProperty(const std::map< uint32_t, T >& list,
// Special version for pointer types - they will be deleted when replaced with another value // Special version for pointer types - they will be deleted when replaced with another value
// passing NULL removes the whole property // passing NULL removes the whole property
template <class T> template <class T>
inline void SetGenericPropertyPtr(std::map< uint32_t, T* >& list, inline void SetGenericPropertyPtr(std::map< unsigned int, T* >& list,
const char* szName, T* value, bool* bWasExisting = NULL) const char* szName, T* value, bool* bWasExisting = NULL)
{ {
ai_assert(NULL != szName); ai_assert(NULL != szName);
typedef std::map< uint32_t, T* > GenericPropertyMap; typedef std::map< unsigned int, T* > GenericPropertyMap;
typedef std::pair< uint32_t, T* > GenericPair; typedef std::pair< unsigned int, T* > GenericPair;
uint32_t hash = SuperFastHash(szName); uint32_t hash = SuperFastHash(szName);

View File

@ -58,8 +58,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif #endif
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
inline uint32_t SuperFastHash (const char * data, unsigned int len = 0, uint32_t hash = 0) { inline unsigned int SuperFastHash (const char * data, unsigned int len = 0, unsigned int hash = 0) {
uint32_t tmp; unsigned int tmp;
int rem; int rem;
if (!data) return 0; if (!data) return 0;

View File

@ -122,6 +122,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_BUILD_NO_IRR_IMPORTER #ifndef AI_BUILD_NO_IRR_IMPORTER
# include "IRRLoader.h" # include "IRRLoader.h"
#endif #endif
//#ifndef AI_BUILD_NO_Q3D_IMPORTER
//# include "Q3DLoader.h"
//#endif
// PostProcess-Steps // PostProcess-Steps
@ -213,7 +216,7 @@ Importer::Importer() :
mImporter.push_back( new ObjFileImporter()); mImporter.push_back( new ObjFileImporter());
#endif #endif
#if (!defined AI_BUILD_NO_3DS_IMPORTER) #if (!defined AI_BUILD_NO_3DS_IMPORTER)
mImporter.push_back( new Dot3DSImporter()); mImporter.push_back( new Discreet3DSImporter());
#endif #endif
#if (!defined AI_BUILD_NO_MD3_IMPORTER) #if (!defined AI_BUILD_NO_MD3_IMPORTER)
mImporter.push_back( new MD3Importer()); mImporter.push_back( new MD3Importer());
@ -275,6 +278,9 @@ Importer::Importer() :
#if (!defined AI_BUILD_NO_IRR_IMPORTER) #if (!defined AI_BUILD_NO_IRR_IMPORTER)
mImporter.push_back( new IRRImporter()); mImporter.push_back( new IRRImporter());
#endif #endif
//#if (!defined AI_BUILD_NO_Q3D_IMPORTER)
// mImporter.push_back( new Q3DImporter());
//#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 -
@ -287,6 +293,7 @@ Importer::Importer() :
mPostProcessingSteps.push_back( new DeterminePTypeHelperProcess()); 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());
#endif #endif
@ -705,7 +712,7 @@ float Importer::GetPropertyFloat(const char* szName,
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
std::string Importer::GetPropertyString(const char* szName, const std::string& Importer::GetPropertyString(const char* szName,
const std::string& iErrorReturn /*= ""*/) const const std::string& iErrorReturn /*= ""*/) const
{ {
return GetGenericProperty<std::string>(mStringProperties,szName,iErrorReturn); return GetGenericProperty<std::string>(mStringProperties,szName,iErrorReturn);

View File

@ -69,6 +69,7 @@ inline aiTextureMapMode GetMapMode(LWO::Texture::Wrap in)
return aiTextureMapMode_Mirror; return aiTextureMapMode_Mirror;
case LWO::Texture::RESET: case LWO::Texture::RESET:
DefaultLogger::get()->warn("LWO2: Unsupported texture map mode: RESET"); DefaultLogger::get()->warn("LWO2: Unsupported texture map mode: RESET");
// fall though here
case LWO::Texture::EDGE: case LWO::Texture::EDGE:
return aiTextureMapMode_Clamp; return aiTextureMapMode_Clamp;
} }
@ -258,12 +259,18 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,MaterialHelper* pcMat
if ((*it).functionName == "LW_SuperCelShader" || if ((*it).functionName == "LW_SuperCelShader" ||
(*it).functionName == "AH_CelShader") (*it).functionName == "AH_CelShader")
{ {
DefaultLogger::get()->info("Mapping LW_SuperCelShader/AH_CelShader "
"to aiShadingMode_Toon");
m = aiShadingMode_Toon; m = aiShadingMode_Toon;
break; break;
} }
else if ((*it).functionName == "LW_RealFresnel" || else if ((*it).functionName == "LW_RealFresnel" ||
(*it).functionName == "LW_FastFresnel") (*it).functionName == "LW_FastFresnel")
{ {
DefaultLogger::get()->info("Mapping LW_RealFresnel/LW_FastFresnel "
"to aiShadingMode_Fresnel");
m = aiShadingMode_Fresnel; m = aiShadingMode_Fresnel;
break; break;
} }
@ -554,22 +561,8 @@ void LWOImporter::LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader* head, unsig
{ {
case AI_LWO_ENAB: case AI_LWO_ENAB:
shader.enabled = GetU2() ? true : false; shader.enabled = GetU2() ? true : false;
} break;
mFileBuffer = next;
}
// process other subchunks ...
while (true)
{
if (mFileBuffer + 6 >= end)break;
LE_NCONST IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
if (mFileBuffer + head->length > end)
throw new ImportErrorException("LWO2: Invalid shader data chunk length");
uint8_t* const next = mFileBuffer+head->length;
switch (head->type)
{
case AI_LWO_FUNC: case AI_LWO_FUNC:
GetS0( shader.functionName, head->length ); GetS0( shader.functionName, head->length );
} }

View File

@ -165,6 +165,7 @@ struct Material
//! Constructor //! Constructor
Material() Material()
: diffuse(0.6f,0.6f,0.6f)
{ {
// empty // empty
} }

View File

@ -688,7 +688,7 @@ bool PLY::PropertyInstance::ParseInstance (const char* pCur,const char** pCurOut
unsigned int iNum = PLY::PropertyInstance::ConvertTo<unsigned int>(v,prop->eFirstType); unsigned int iNum = PLY::PropertyInstance::ConvertTo<unsigned int>(v,prop->eFirstType);
// parse all list elements // parse all list elements
p_pcOut->avList.resize(3); p_pcOut->avList.resize(iNum);
for (unsigned int i = 0; i < iNum;++i) for (unsigned int i = 0; i < iNum;++i)
{ {
if (!SkipSpaces(pCur, &pCur))return false; if (!SkipSpaces(pCur, &pCur))return false;

View File

@ -86,7 +86,7 @@ inline VertexWeightTable* ComputeVertexBoneWeightTable(aiMesh* pMesh)
{ {
aiVertexWeight& weight = bone->mWeights[a]; aiVertexWeight& weight = bone->mWeights[a];
avPerVertexWeights[weight.mVertexId].push_back( avPerVertexWeights[weight.mVertexId].push_back(
std::pair<unsigned int,float>(a,weight.mWeight)); std::pair<unsigned int,float>(i,weight.mWeight));
} }
} }
return avPerVertexWeights; return avPerVertexWeights;

View File

@ -298,6 +298,7 @@ bool STLImporter::LoadBinaryFile()
{ {
// read the default vertex color for facets // read the default vertex color for facets
bIsMaterialise = true; bIsMaterialise = true;
DefaultLogger::get()->info("STL: Taking code path for Materialise files");
this->clrColorDefault.r = (*sz2++) / 255.0f; this->clrColorDefault.r = (*sz2++) / 255.0f;
this->clrColorDefault.g = (*sz2++) / 255.0f; this->clrColorDefault.g = (*sz2++) / 255.0f;
this->clrColorDefault.b = (*sz2++) / 255.0f; this->clrColorDefault.b = (*sz2++) / 255.0f;
@ -356,6 +357,8 @@ bool STLImporter::LoadBinaryFile()
for (unsigned int i = 0; i <pMesh->mNumVertices;++i) for (unsigned int i = 0; i <pMesh->mNumVertices;++i)
*pMesh->mColors[0]++ = this->clrColorDefault; *pMesh->mColors[0]++ = this->clrColorDefault;
pMesh->mColors[0] -= pMesh->mNumVertices; pMesh->mColors[0] -= pMesh->mNumVertices;
DefaultLogger::get()->info("STL: Mesh has vertex colors");
} }
aiColor4D* clr = &pMesh->mColors[0][pMesh->mNumFaces*3]; aiColor4D* clr = &pMesh->mColors[0][pMesh->mNumFaces*3];
clr->a = 1.0f; clr->a = 1.0f;
@ -378,7 +381,7 @@ bool STLImporter::LoadBinaryFile()
} }
if (bIsMaterialise && !pMesh->mColors[0]) if (bIsMaterialise && !pMesh->mColors[0])
{ {
// use the color was diffuse material color // use the color as diffuse material color
return true; return true;
} }
return false; return false;

View File

@ -65,6 +65,7 @@ public:
/** Construction from a given stream with a well-defined endianess /** Construction from a given stream with a well-defined endianess
* *
* The stream will be deleted afterwards.
* @param stream Input stream * @param stream Input stream
*/ */
inline StreamReader(IOStream* stream) inline StreamReader(IOStream* stream)
@ -76,10 +77,15 @@ public:
if (!s)throw new ImportErrorException("File is empty"); if (!s)throw new ImportErrorException("File is empty");
current = buffer = new int8_t[s]; current = buffer = new int8_t[s];
end = &buffer[s]; stream->Read(current,s,1);
end = limit = &buffer[s];
} }
inline ~StreamReader() {delete[] buffer;} inline ~StreamReader()
{
delete[] buffer;
delete stream;
}
/** Read a float from the stream /** Read a float from the stream
@ -127,13 +133,90 @@ public:
return Get<int64_t>(); return Get<int64_t>();
} }
/** Get the remaining stream size /** Get the remaining stream size (to the end of the srream)
*/ */
inline unsigned int GetRemainingSize() inline unsigned int GetRemainingSize()
{ {
return (unsigned int)(end - current); return (unsigned int)(end - current);
} }
/** Get the remaining stream size (to the current read limit)
*/
inline unsigned int GetRemainingSizeToLimit()
{
return (unsigned int)(limit - current);
}
/** Increase the file pointer
*/
inline void IncPtr(unsigned int plus)
{
current += plus;
if (current > end)
{
throw new ImportErrorException("End of file was reached");
}
}
/** Get the current file pointer
*/
inline int8_t* GetPtr() const
{
return current;
}
/** Set current file pointer
*/
inline void SetPtr(int8_t* p)
{
current = p;
if (current > end || current < buffer)
{
throw new ImportErrorException("End of file was reached");
}
}
/** Get the current offset from the beginning of the file
*/
inline int GetCurrentPos() const
{
return (unsigned int)(current - buffer);
}
/** Setup a temporary read limit
*
* @param limit Maximum number of bytes to be read from
* the beginning of the file. Passing 0xffffffff
* resets the limit.
*/
inline void SetReadLimit(unsigned int _limit)
{
if (0xffffffff == _limit)
{
limit = end;
return;
}
limit = buffer + _limit;
if (limit > end)
throw new ImportErrorException("StreamReader: Invalid read limit");
}
/** Get the current read limit
*/
inline int GetReadLimit() const
{
return (unsigned int)(limit - buffer);
}
/** Skip to the read limit
*/
inline void SkipToReadLimit()
{
current = limit;
}
// overload operator>> for those who prefer this way ... // overload operator>> for those who prefer this way ...
inline void operator >> (float& f) inline void operator >> (float& f)
{f = GetF4();} {f = GetF4();}
@ -160,8 +243,8 @@ private:
template <typename T> template <typename T>
inline T Get() inline T Get()
{ {
if (current + sizeof(T) > end) if (current + sizeof(T) > limit)
throw new ImportErrorException("End of file was reached"); throw new ImportErrorException("End of file or stream limit was reached");
T f = *((const T*)current); T f = *((const T*)current);
if (SwapEndianess) if (SwapEndianess)
@ -173,7 +256,7 @@ private:
} }
IOStream* stream; IOStream* stream;
int8_t *buffer, *current, *end; int8_t *buffer, *current, *end, *limit;
}; };
#ifdef AI_BUILD_BIG_ENDIAN #ifdef AI_BUILD_BIG_ENDIAN
@ -184,6 +267,6 @@ private:
typedef StreamReader<false> StreamReaderLE; typedef StreamReader<false> StreamReaderLE;
#endif #endif
}; } // end namespace Assimp
#endif // !! AI_STREAMREADER_H_INCLUDED #endif // !! AI_STREAMREADER_H_INCLUDED

View File

@ -49,7 +49,7 @@ namespace Assimp
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void TextureTransform::PreProcessUVTransform( void TextureTransform::PreProcessUVTransform(
Dot3DS::Texture& rcIn) D3DS::Texture& rcIn)
{ {
char szTemp[512]; char szTemp[512];
int iField; int iField;
@ -139,7 +139,7 @@ void TextureTransform::PreProcessUVTransform(
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void TextureTransform::AddToList(std::vector<STransformVecInfo>& rasVec, void TextureTransform::AddToList(std::vector<STransformVecInfo>& rasVec,
Dot3DS::Texture* pcTex) D3DS::Texture* pcTex)
{ {
// check whether the texture is existing // check whether the texture is existing
if (0 == pcTex->mMapName.length())return; if (0 == pcTex->mMapName.length())return;
@ -176,10 +176,10 @@ void TextureTransform::AddToList(std::vector<STransformVecInfo>& rasVec,
rasVec.push_back(sInfo); rasVec.push_back(sInfo);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void TextureTransform::ApplyScaleNOffset(Dot3DS::Material& material) void TextureTransform::ApplyScaleNOffset(D3DS::Material& material)
{ {
unsigned int iCnt = 0; unsigned int iCnt = 0;
Dot3DS::Texture* pcTexture = NULL; D3DS::Texture* pcTexture = NULL;
// diffuse texture // diffuse texture
if (material.sTexDiffuse.mMapName.length()) if (material.sTexDiffuse.mMapName.length())
@ -278,10 +278,10 @@ void TextureTransform::ApplyScaleNOffset(Dot3DS::Material& material)
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void TextureTransform::ApplyScaleNOffset(std::vector<Dot3DS::Material>& materials) void TextureTransform::ApplyScaleNOffset(std::vector<D3DS::Material>& materials)
{ {
unsigned int iNum = 0; unsigned int iNum = 0;
for (std::vector<Dot3DS::Material>::iterator for (std::vector<D3DS::Material>::iterator
i = materials.begin(); i = materials.begin();
i != materials.end();++i,++iNum) i != materials.end();++i,++iNum)
{ {
@ -291,7 +291,7 @@ void TextureTransform::ApplyScaleNOffset(std::vector<Dot3DS::Material>& material
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void TextureTransform::BakeScaleNOffset( void TextureTransform::BakeScaleNOffset(
aiMesh* pcMesh, Dot3DS::Material* pcSrc) aiMesh* pcMesh, D3DS::Material* pcSrc)
{ {
// NOTE: we don't use a texture matrix to do the transformation // NOTE: we don't use a texture matrix to do the transformation
// it is more efficient this way ... // it is more efficient this way ...
@ -538,7 +538,7 @@ void TextureTransform::BakeScaleNOffset(
return; return;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void TextureTransform::SetupMatUVSrc (aiMaterial* pcMat, const Dot3DS::Material* pcMatIn) void TextureTransform::SetupMatUVSrc (aiMaterial* pcMat, const D3DS::Material* pcMatIn)
{ {
ai_assert(NULL != pcMat); ai_assert(NULL != pcMat);
ai_assert(NULL != pcMatIn); ai_assert(NULL != pcMatIn);

View File

@ -54,7 +54,7 @@ struct aiNode;
namespace Assimp namespace Assimp
{ {
using namespace Assimp::Dot3DS; using namespace Assimp::D3DS;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Helper class representing texture coordinate transformations /** Helper class representing texture coordinate transformations
@ -87,7 +87,7 @@ struct STransformVecInfo
//! List of all textures that use this texture //! List of all textures that use this texture
//! coordinate transformations //! coordinate transformations
std::vector<Dot3DS::Texture*> pcTextures; std::vector<D3DS::Texture*> pcTextures;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -148,7 +148,7 @@ public:
* \param rcIn Input texture * \param rcIn Input texture
*/ */
inline static bool HasUVTransform( inline static bool HasUVTransform(
const Dot3DS::Texture& rcIn) const D3DS::Texture& rcIn)
{ {
return (rcIn.mOffsetU || rcIn.mOffsetV || return (rcIn.mOffsetU || rcIn.mOffsetV ||
1.0f != rcIn.mScaleU || 1.0f != rcIn.mScaleV || rcIn.mRotation); 1.0f != rcIn.mScaleU || 1.0f != rcIn.mScaleV || rcIn.mRotation);
@ -159,7 +159,7 @@ public:
* \param rcIn Input texture * \param rcIn Input texture
*/ */
static void PreProcessUVTransform( static void PreProcessUVTransform(
Dot3DS::Texture& rcIn); D3DS::Texture& rcIn);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Check whether the texture coordinate transformation of /** Check whether the texture coordinate transformation of
@ -168,21 +168,21 @@ public:
* \param pcTex Pointer to the texture * \param pcTex Pointer to the texture
*/ */
static void AddToList(std::vector<STransformVecInfo>& rasVec, static void AddToList(std::vector<STransformVecInfo>& rasVec,
Dot3DS::Texture* pcTex); D3DS::Texture* pcTex);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Get a full list of all texture coordinate offsets required /** Get a full list of all texture coordinate offsets required
* for a material * for a material
* \param materials List of materials to be processed * \param materials List of materials to be processed
*/ */
static void ApplyScaleNOffset(std::vector<Dot3DS::Material>& materials); static void ApplyScaleNOffset(std::vector<D3DS::Material>& materials);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Get a full list of all texture coordinate offsets required /** Get a full list of all texture coordinate offsets required
* for a material * for a material
* \param material Material to be processed * \param material Material to be processed
*/ */
static void ApplyScaleNOffset(Dot3DS::Material& material); static void ApplyScaleNOffset(D3DS::Material& material);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Precompute as many texture coordinate transformations as possible /** Precompute as many texture coordinate transformations as possible
@ -190,7 +190,7 @@ public:
* \param pcSrc Input material. Must have been passed to * \param pcSrc Input material. Must have been passed to
* ApplyScaleNOffset * ApplyScaleNOffset
*/ */
static void BakeScaleNOffset(aiMesh* pcMesh, Dot3DS::Material* pcSrc); static void BakeScaleNOffset(aiMesh* pcMesh, D3DS::Material* pcSrc);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -199,7 +199,7 @@ public:
* \param pcMatIn Input material, unconverted * \param pcMatIn Input material, unconverted
*/ */
static void SetupMatUVSrc (aiMaterial* pcMat, static void SetupMatUVSrc (aiMaterial* pcMat,
const Dot3DS::Material* pcMatIn); const D3DS::Material* pcMatIn);
}; };
} }

View File

@ -5,7 +5,7 @@
// Need to include Assimp, too. We're using Assimp's version of fast_atof // Need to include Assimp, too. We're using Assimp's version of fast_atof
// so we need stdint.h // so we need stdint.h
#include "./../../include/aiTypes.h" #include "./../AssimpPCH.h"
#include "irrXML.h" #include "irrXML.h"
#include "irrString.h" #include "irrString.h"

View File

@ -152,6 +152,9 @@ private:
StreamArray m_StreamArray; StreamArray m_StreamArray;
//! Array with default streams //! Array with default streams
std::vector<LogStream*> m_Streams; std::vector<LogStream*> m_Streams;
bool noRepeatMsg;
std::string lastMsg;
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View File

@ -39,7 +39,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
/** @file Defines the data structures in which the imported animations are returned. */ /** @file Defines the data structures in which the imported animations
are returned. */
#ifndef AI_ANIM_H_INC #ifndef AI_ANIM_H_INC
#define AI_ANIM_H_INC #define AI_ANIM_H_INC
@ -55,47 +56,108 @@ struct aiVectorKey
{ {
double mTime; ///< The time of this key double mTime; ///< The time of this key
C_STRUCT aiVector3D mValue; ///< The value of this key C_STRUCT aiVector3D mValue; ///< The value of this key
#ifdef __cplusplus
// time is not compared
bool operator == (const aiVectorKey& o) const
{return o.mValue == this->mValue;}
bool operator != (const aiVectorKey& o) const
{return o.mValue != this->mValue;}
#endif
}; };
/** A time-value pair specifying a rotation for the given time. For joint animations /** A time-value pair specifying a rotation for the given time. For joint
* the rotation is usually expressed using a quaternion. * animations the rotation is usually expressed using a quaternion.
*/ */
struct aiQuatKey struct aiQuatKey
{ {
double mTime; ///< The time of this key double mTime; ///< The time of this key
C_STRUCT aiQuaternion mValue; ///< The value of this key C_STRUCT aiQuaternion mValue; ///< The value of this key
#ifdef __cplusplus
// time is not compared
bool operator == (const aiQuatKey& o) const
{return o.mValue == this->mValue;}
bool operator != (const aiQuatKey& o) const
{return o.mValue != this->mValue;}
#endif
}; };
/** Describes the animation of a single node. The name specifies the bone/node which is affected by this enum aiAnimBehaviour
* animation channel. The keyframes are given in three separate series of values, one each for {
* position, rotation and scaling. // --- Wert aus Node-Transformation wird ĂĽbernommen
aiAnimBehaviour_DEFAULT = 0x0,
// -- Nächster Key wird verwendet
aiAnimBehaviour_CONSTANT = 0x1,
// -- Nächste beiden Keys werden linear extrapoliert
aiAnimBehaviour_LINEAR = 0x2,
// -- Animation wird wiederholt
// Und das solange bis die Animationszeit (aiAnimation::mDuration)
// abgelaufen ist. Ist diese 0 läuft das ganze ewig.
aiAnimBehaviour_REPEAT = 0x3
};
/** Describes the animation of a single node. The name specifies the
* bone/node which is affected by this animation channel. The keyframes
* are given in three separate series of values, one each for position,
* rotation and scaling. The transformation matrix computed from these
* values replaces the node's original transformation matrix at a
* spefific time.
*/ */
struct aiNodeAnim struct aiNodeAnim
{ {
/** The name of the node affected by this animation. */ /** The name of the node affected by this animation. The node
* must exist anf it must be unique.
*/
C_STRUCT aiString mNodeName; C_STRUCT aiString mNodeName;
/** The number of position keys */ /** The number of position keys */
unsigned int mNumPositionKeys; unsigned int mNumPositionKeys;
/** The position keys of this animation channel. Positions are specified as 3D vector.
* The array is mNumPositionKeys in size. /** The position keys of this animation channel. Positions are
*/ * specified as 3D vector. The array is mNumPositionKeys in size.
*
* If there are rotation or scaling keys, but no position keys,
* a constant position of 0|0|0 should be assumed.
*/
C_STRUCT aiVectorKey* mPositionKeys; C_STRUCT aiVectorKey* mPositionKeys;
/** The number of rotation keys */ /** The number of rotation keys */
unsigned int mNumRotationKeys; unsigned int mNumRotationKeys;
/** The rotation keys of this animation channel. Rotations are given as quaternions,
* which are 4D vectors. The array is mNumRotationKeys in size. /** The rotation keys of this animation channel. Rotations are
*/ * given as quaternions, which are 4D vectors. The array is
* mNumRotationKeys in size.
*
* If there are position or scaling keys, but no rotation keys,
* a constant rotation of 0|0|0 should be assumed.
*/
C_STRUCT aiQuatKey* mRotationKeys; C_STRUCT aiQuatKey* mRotationKeys;
/** The number of scaling keys */ /** The number of scaling keys */
unsigned int mNumScalingKeys; unsigned int mNumScalingKeys;
/** The scaling keys of this animation channel. Scalings are specified as 3D vector.
* The array is mNumScalingKeys in size. /** The scaling keys of this animation channel. Scalings are
*/ * specified as 3D vector. The array is mNumScalingKeys in size.
*
* If there are position or rotation keys, but no scaling keys,
* a constant scaling of 1|1|1 should be assumed.
*/
C_STRUCT aiVectorKey* mScalingKeys; C_STRUCT aiVectorKey* mScalingKeys;
aiAnimBehaviour mPrePostState;
#ifdef __cplusplus #ifdef __cplusplus
aiNodeAnim() aiNodeAnim()
{ {
@ -116,26 +178,33 @@ struct aiNodeAnim
#endif // __cplusplus #endif // __cplusplus
}; };
/** An animation consists of keyframe data for a number of nodes. For each node affected by the animation /** An animation consists of keyframe data for a number of nodes. For
* a separate series of data is given. * each node affected by the animation a separate series of data is given.
*/ */
struct aiAnimation struct aiAnimation
{ {
/** The name of the animation. If the modelling package this data was exported from does support /** The name of the animation. If the modelling package this data was
* only a single animation channel, this name is usually empty (length is zero). * exported from does support only a single animation channel, this
*/ * name is usually empty (length is zero).
*/
C_STRUCT aiString mName; C_STRUCT aiString mName;
/** Duration of the animation in ticks. */ /** Duration of the animation in ticks.
*/
double mDuration; double mDuration;
/** Ticks per second. 0 if not specified in the imported file */
/** Ticks per second. 0 if not specified in the imported file
*/
double mTicksPerSecond; double mTicksPerSecond;
/** The number of bone animation channels. Each channel affects a single node. */ /** The number of bone animation channels. Each channel affects
* a single node.
*/
unsigned int mNumChannels; unsigned int mNumChannels;
/** The node animation channels. Each channel affects a single node. The array
* is mNumChannels in size. /** The node animation channels. Each channel affects a single node.
*/ * The array is mNumChannels in size.
*/
C_STRUCT aiNodeAnim** mChannels; C_STRUCT aiNodeAnim** mChannels;
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -90,9 +90,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// compiler specific includes and definitions // compiler specific includes and definitions
#if (defined _MSC_VER) #if (defined _MSC_VER)
// include stdint.h from the C98 standard
# include "Compiler/pstdint.h"
# undef ASSIMP_API # undef ASSIMP_API
@ -155,15 +152,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if (defined(__BORLANDC__) || defined (__BCPLUSPLUS__)) #if (defined(__BORLANDC__) || defined (__BCPLUSPLUS__))
// for borland add the replacement pstdint.h, too
# include "Compiler/pstdint.h"
// "W8059 Packgröße der Struktur geändert" // "W8059 Packgröße der Struktur geändert"
// TODO: find a way to deactivate this warning automatically // TODO: find a way to deactivate this warning automatically
// maybe there is a pragma to do exactly this? // maybe there is a pragma to do exactly this?
#endif #endif
// include our workaround stdint.h from the C98 standard to make
// sure the types it declares are consistently available
#include "./../include/Compiler/pstdint.h"
// ************************************************************ // ************************************************************
// Define ASSIMP_BUILD_BOOST_WORKAROUND to compile assimp // Define ASSIMP_BUILD_BOOST_WORKAROUND to compile assimp

View File

@ -72,6 +72,13 @@ struct aiQuaternion
/** Returns a matrix representation of the quaternion */ /** Returns a matrix representation of the quaternion */
aiMatrix3x3 GetMatrix() const; aiMatrix3x3 GetMatrix() const;
bool operator== (const aiQuaternion& o) const
{return x == o.x && y == o.y && z == o.z && w == o.w;}
bool operator!= (const aiQuaternion& o) const
{return !(*this == o);}
#endif // __cplusplus #endif // __cplusplus
//! w,x,y,z components of the quaternion //! w,x,y,z components of the quaternion

View File

@ -80,7 +80,7 @@ extern "C" {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
struct aiTexel struct aiTexel
{ {
uint8_t b,g,r,a; unsigned char b,g,r,a;
#ifdef __cplusplus #ifdef __cplusplus
//! Comparison operator //! Comparison operator

View File

@ -65,6 +65,7 @@ namespace Assimp
class BaseImporter; class BaseImporter;
class BaseProcess; class BaseProcess;
class SharedPostProcessInfo; class SharedPostProcessInfo;
class BatchLoader;
} }
#define AI_PROPERTY_WAS_NOT_EXISTING 0xffffffff #define AI_PROPERTY_WAS_NOT_EXISTING 0xffffffff
@ -101,11 +102,12 @@ class ASSIMP_API Importer
{ {
// used internally // used internally
friend class BaseProcess; friend class BaseProcess;
friend class BatchLoader;
friend const aiScene* ::aiImportFileEx( const char*, unsigned int, aiFileIO*); friend const aiScene* ::aiImportFileEx( const char*, unsigned int, aiFileIO*);
public: public:
typedef uint32_t KeyType; typedef unsigned int KeyType;
typedef std::map<KeyType, int> IntPropertyMap; typedef std::map<KeyType, int> IntPropertyMap;
typedef std::map<KeyType, float> FloatPropertyMap; typedef std::map<KeyType, float> FloatPropertyMap;
typedef std::map<KeyType, std::string> StringPropertyMap; typedef std::map<KeyType, std::string> StringPropertyMap;
@ -230,9 +232,11 @@ public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Get a string configuration property /** Get a string configuration property
*
* The return value remains valid until the property is modified.
* @see GetPropertyInteger() * @see GetPropertyInteger()
*/ */
std::string GetPropertyString(const char* szName, const std::string& GetPropertyString(const char* szName,
const std::string& sErrorReturn = "") const; const std::string& sErrorReturn = "") const;

View File

@ -0,0 +1,328 @@
*3DSMAX_ASCIIEXPORT 200
*COMMENT "AsciiExport Version 2,00 - Tue Oct 28 18:51:39 2008"
*SCENE {
*SCENE_FILENAME ""
*SCENE_FIRSTFRAME 0
*SCENE_LASTFRAME 100
*SCENE_FRAMESPEED 30
*SCENE_TICKSPERFRAME 160
*SCENE_BACKGROUND_STATIC 0.0000 0.0000 0.0000
*SCENE_AMBIENT_STATIC 0.0000 0.0000 0.0000
}
*MATERIAL_LIST {
*MATERIAL_COUNT 0
}
*GEOMOBJECT {
*NODE_NAME "Box01"
*NODE_TM {
*NODE_NAME "Box01"
*INHERIT_POS 0 0 0
*INHERIT_ROT 0 0 0
*INHERIT_SCL 0 0 0
*TM_ROW0 1.0000 0.0000 0.0000
*TM_ROW1 0.0000 1.0000 0.0000
*TM_ROW2 0.0000 0.0000 1.0000
*TM_ROW3 -1.4245 6.5527 0.0000
*TM_POS -1.4245 6.5527 0.0000
*TM_ROTAXIS 0.0000 0.0000 0.0000
*TM_ROTANGLE 0.0000
*TM_SCALE 1.0000 1.0000 1.0000
*TM_SCALEAXIS 0.0000 0.0000 0.0000
*TM_SCALEAXISANG 0.0000
}
*MESH {
*TIMEVALUE 0
*MESH_NUMVERTEX 8
*MESH_NUMFACES 12
*MESH_VERTEX_LIST {
*MESH_VERTEX 0 -23.0769 -15.0997 0.0000
*MESH_VERTEX 1 20.2279 -15.0997 0.0000
*MESH_VERTEX 2 -23.0769 28.2051 0.0000
*MESH_VERTEX 3 20.2279 28.2051 0.0000
*MESH_VERTEX 4 -23.0769 -15.0997 29.0598
*MESH_VERTEX 5 20.2279 -15.0997 29.0598
*MESH_VERTEX 6 -23.0769 28.2051 29.0598
*MESH_VERTEX 7 20.2279 28.2051 29.0598
}
*MESH_FACE_LIST {
*MESH_FACE 0: A: 0 B: 2 C: 3 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 2 *MESH_MTLID 1
*MESH_FACE 1: A: 3 B: 1 C: 0 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 2 *MESH_MTLID 1
*MESH_FACE 2: A: 4 B: 5 C: 7 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 3 *MESH_MTLID 0
*MESH_FACE 3: A: 7 B: 6 C: 4 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 3 *MESH_MTLID 0
*MESH_FACE 4: A: 0 B: 1 C: 5 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 4 *MESH_MTLID 4
*MESH_FACE 5: A: 5 B: 4 C: 0 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 4 *MESH_MTLID 4
*MESH_FACE 6: A: 1 B: 3 C: 7 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 5 *MESH_MTLID 3
*MESH_FACE 7: A: 7 B: 5 C: 1 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 5 *MESH_MTLID 3
*MESH_FACE 8: A: 3 B: 2 C: 6 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 6 *MESH_MTLID 5
*MESH_FACE 9: A: 6 B: 7 C: 3 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 6 *MESH_MTLID 5
*MESH_FACE 10: A: 2 B: 0 C: 4 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 7 *MESH_MTLID 2
*MESH_FACE 11: A: 4 B: 6 C: 2 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 7 *MESH_MTLID 2
}
*MESH_NUMTVERTEX 12
*MESH_TVERTLIST {
*MESH_TVERT 0 0.0000 0.0000 0.0000
*MESH_TVERT 1 1.0000 0.0000 0.0000
*MESH_TVERT 2 0.0000 1.0000 0.0000
*MESH_TVERT 3 1.0000 1.0000 0.0000
*MESH_TVERT 4 0.0000 0.0000 0.0000
*MESH_TVERT 5 1.0000 0.0000 0.0000
*MESH_TVERT 6 0.0000 1.0000 0.0000
*MESH_TVERT 7 1.0000 1.0000 0.0000
*MESH_TVERT 8 0.0000 0.0000 0.0000
*MESH_TVERT 9 1.0000 0.0000 0.0000
*MESH_TVERT 10 0.0000 1.0000 0.0000
*MESH_TVERT 11 1.0000 1.0000 0.0000
}
*MESH_NUMTVFACES 12
*MESH_TFACELIST {
*MESH_TFACE 0 9 11 10
*MESH_TFACE 1 10 8 9
*MESH_TFACE 2 8 9 11
*MESH_TFACE 3 11 10 8
*MESH_TFACE 4 4 5 7
*MESH_TFACE 5 7 6 4
*MESH_TFACE 6 0 1 3
*MESH_TFACE 7 3 2 0
*MESH_TFACE 8 4 5 7
*MESH_TFACE 9 7 6 4
*MESH_TFACE 10 0 1 3
*MESH_TFACE 11 3 2 0
}
*MESH_NUMCVERTEX 0
*MESH_NORMALS {
*MESH_FACENORMAL 0 0.0000 0.0000 -1.0000
*MESH_VERTEXNORMAL 0 0.0000 0.0000 -1.0000
*MESH_VERTEXNORMAL 2 0.0000 0.0000 -1.0000
*MESH_VERTEXNORMAL 3 0.0000 0.0000 -1.0000
*MESH_FACENORMAL 1 0.0000 0.0000 -1.0000
*MESH_VERTEXNORMAL 3 0.0000 0.0000 -1.0000
*MESH_VERTEXNORMAL 1 0.0000 0.0000 -1.0000
*MESH_VERTEXNORMAL 0 0.0000 0.0000 -1.0000
*MESH_FACENORMAL 2 0.0000 -0.0000 1.0000
*MESH_VERTEXNORMAL 4 0.0000 0.0000 1.0000
*MESH_VERTEXNORMAL 5 0.0000 -0.0000 1.0000
*MESH_VERTEXNORMAL 7 0.0000 0.0000 1.0000
*MESH_FACENORMAL 3 -0.0000 0.0000 1.0000
*MESH_VERTEXNORMAL 7 0.0000 0.0000 1.0000
*MESH_VERTEXNORMAL 6 -0.0000 0.0000 1.0000
*MESH_VERTEXNORMAL 4 0.0000 0.0000 1.0000
*MESH_FACENORMAL 4 0.0000 -1.0000 0.0000
*MESH_VERTEXNORMAL 0 0.0000 -1.0000 0.0000
*MESH_VERTEXNORMAL 1 0.0000 -1.0000 0.0000
*MESH_VERTEXNORMAL 5 0.0000 -1.0000 0.0000
*MESH_FACENORMAL 5 0.0000 -1.0000 0.0000
*MESH_VERTEXNORMAL 5 0.0000 -1.0000 0.0000
*MESH_VERTEXNORMAL 4 0.0000 -1.0000 0.0000
*MESH_VERTEXNORMAL 0 0.0000 -1.0000 0.0000
*MESH_FACENORMAL 6 1.0000 0.0000 -0.0000
*MESH_VERTEXNORMAL 1 1.0000 0.0000 0.0000
*MESH_VERTEXNORMAL 3 1.0000 0.0000 -0.0000
*MESH_VERTEXNORMAL 7 1.0000 0.0000 0.0000
*MESH_FACENORMAL 7 1.0000 -0.0000 0.0000
*MESH_VERTEXNORMAL 7 1.0000 0.0000 0.0000
*MESH_VERTEXNORMAL 5 1.0000 -0.0000 0.0000
*MESH_VERTEXNORMAL 1 1.0000 0.0000 0.0000
*MESH_FACENORMAL 8 0.0000 1.0000 0.0000
*MESH_VERTEXNORMAL 3 0.0000 1.0000 0.0000
*MESH_VERTEXNORMAL 2 0.0000 1.0000 0.0000
*MESH_VERTEXNORMAL 6 0.0000 1.0000 0.0000
*MESH_FACENORMAL 9 0.0000 1.0000 0.0000
*MESH_VERTEXNORMAL 6 0.0000 1.0000 0.0000
*MESH_VERTEXNORMAL 7 0.0000 1.0000 0.0000
*MESH_VERTEXNORMAL 3 0.0000 1.0000 0.0000
*MESH_FACENORMAL 10 -1.0000 0.0000 0.0000
*MESH_VERTEXNORMAL 2 -1.0000 0.0000 0.0000
*MESH_VERTEXNORMAL 0 -1.0000 0.0000 0.0000
*MESH_VERTEXNORMAL 4 -1.0000 0.0000 0.0000
*MESH_FACENORMAL 11 -1.0000 -0.0000 -0.0000
*MESH_VERTEXNORMAL 4 -1.0000 0.0000 0.0000
*MESH_VERTEXNORMAL 6 -1.0000 -0.0000 -0.0000
*MESH_VERTEXNORMAL 2 -1.0000 0.0000 0.0000
}
}
*PROP_MOTIONBLUR 0
*PROP_CASTSHADOW 1
*PROP_RECVSHADOW 1
*WIREFRAME_COLOR 0.7765 0.8824 0.3412
}
*GEOMOBJECT {
*NODE_NAME "Box02"
*NODE_TM {
*NODE_NAME "Box02"
*INHERIT_POS 0 0 0
*INHERIT_ROT 0 0 0
*INHERIT_SCL 0 0 0
*TM_ROW0 0.7750 0.0000 0.0000
*TM_ROW1 0.0000 0.7418 -0.2246
*TM_ROW2 0.0000 0.3655 1.2070
*TM_ROW3 -45.4570 -12.7152 18.9634
*TM_POS -45.4570 -12.7152 18.9634
*TM_ROTAXIS 1.0000 -0.0000 -0.0000
*TM_ROTANGLE 0.2940
*TM_SCALE 0.7750 0.7750 1.2611
*TM_SCALEAXIS 0.0000 0.0000 0.0000
*TM_SCALEAXISANG 0.0000
}
*MESH {
*TIMEVALUE 0
*MESH_NUMVERTEX 8
*MESH_NUMFACES 12
*MESH_VERTEX_LIST {
*MESH_VERTEX 0 -56.7183 -22.4365 21.9073
*MESH_VERTEX 1 -34.1956 -22.4365 21.9073
*MESH_VERTEX 2 -56.7183 -2.9939 16.0196
*MESH_VERTEX 3 -34.1956 -2.9939 16.0196
*MESH_VERTEX 4 -56.7183 -11.8149 56.9822
*MESH_VERTEX 5 -34.1956 -11.8149 56.9822
*MESH_VERTEX 6 -56.7183 7.6277 51.0944
*MESH_VERTEX 7 -34.1956 7.6277 51.0944
}
*MESH_FACE_LIST {
*MESH_FACE 0: A: 0 B: 2 C: 3 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 2 *MESH_MTLID 1
*MESH_FACE 1: A: 3 B: 1 C: 0 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 2 *MESH_MTLID 1
*MESH_FACE 2: A: 4 B: 5 C: 7 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 3 *MESH_MTLID 0
*MESH_FACE 3: A: 7 B: 6 C: 4 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 3 *MESH_MTLID 0
*MESH_FACE 4: A: 0 B: 1 C: 5 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 4 *MESH_MTLID 4
*MESH_FACE 5: A: 5 B: 4 C: 0 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 4 *MESH_MTLID 4
*MESH_FACE 6: A: 1 B: 3 C: 7 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 5 *MESH_MTLID 3
*MESH_FACE 7: A: 7 B: 5 C: 1 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 5 *MESH_MTLID 3
*MESH_FACE 8: A: 3 B: 2 C: 6 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 6 *MESH_MTLID 5
*MESH_FACE 9: A: 6 B: 7 C: 3 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 6 *MESH_MTLID 5
*MESH_FACE 10: A: 2 B: 0 C: 4 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 7 *MESH_MTLID 2
*MESH_FACE 11: A: 4 B: 6 C: 2 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 7 *MESH_MTLID 2
}
*MESH_NUMTVERTEX 12
*MESH_TVERTLIST {
*MESH_TVERT 0 0.0000 0.0000 0.0000
*MESH_TVERT 1 1.0000 0.0000 0.0000
*MESH_TVERT 2 0.0000 1.0000 0.0000
*MESH_TVERT 3 1.0000 1.0000 0.0000
*MESH_TVERT 4 0.0000 0.0000 0.0000
*MESH_TVERT 5 1.0000 0.0000 0.0000
*MESH_TVERT 6 0.0000 1.0000 0.0000
*MESH_TVERT 7 1.0000 1.0000 0.0000
*MESH_TVERT 8 0.0000 0.0000 0.0000
*MESH_TVERT 9 1.0000 0.0000 0.0000
*MESH_TVERT 10 0.0000 1.0000 0.0000
*MESH_TVERT 11 1.0000 1.0000 0.0000
}
*MESH_NUMTVFACES 12
*MESH_TFACELIST {
*MESH_TFACE 0 9 11 10
*MESH_TFACE 1 10 8 9
*MESH_TFACE 2 8 9 11
*MESH_TFACE 3 11 10 8
*MESH_TFACE 4 4 5 7
*MESH_TFACE 5 7 6 4
*MESH_TFACE 6 0 1 3
*MESH_TFACE 7 3 2 0
*MESH_TFACE 8 4 5 7
*MESH_TFACE 9 7 6 4
*MESH_TFACE 10 0 1 3
*MESH_TFACE 11 3 2 0
}
*MESH_NUMCVERTEX 0
*MESH_NORMALS {
*MESH_FACENORMAL 0 0.0000 0.0000 -1.0000
*MESH_VERTEXNORMAL 0 0.0000 0.0000 -1.0000
*MESH_VERTEXNORMAL 2 0.0000 0.0000 -1.0000
*MESH_VERTEXNORMAL 3 0.0000 0.0000 -1.0000
*MESH_FACENORMAL 1 0.0000 0.0000 -1.0000
*MESH_VERTEXNORMAL 3 0.0000 0.0000 -1.0000
*MESH_VERTEXNORMAL 1 0.0000 0.0000 -1.0000
*MESH_VERTEXNORMAL 0 0.0000 0.0000 -1.0000
*MESH_FACENORMAL 2 0.0000 -0.0000 1.0000
*MESH_VERTEXNORMAL 4 0.0000 0.0000 1.0000
*MESH_VERTEXNORMAL 5 0.0000 -0.0000 1.0000
*MESH_VERTEXNORMAL 7 0.0000 0.0000 1.0000
*MESH_FACENORMAL 3 -0.0000 0.0000 1.0000
*MESH_VERTEXNORMAL 7 0.0000 0.0000 1.0000
*MESH_VERTEXNORMAL 6 -0.0000 0.0000 1.0000
*MESH_VERTEXNORMAL 4 0.0000 0.0000 1.0000
*MESH_FACENORMAL 4 0.0000 -1.0000 0.0000
*MESH_VERTEXNORMAL 0 0.0000 -1.0000 0.0000
*MESH_VERTEXNORMAL 1 0.0000 -1.0000 0.0000
*MESH_VERTEXNORMAL 5 0.0000 -1.0000 0.0000
*MESH_FACENORMAL 5 0.0000 -1.0000 0.0000
*MESH_VERTEXNORMAL 5 0.0000 -1.0000 0.0000
*MESH_VERTEXNORMAL 4 0.0000 -1.0000 0.0000
*MESH_VERTEXNORMAL 0 0.0000 -1.0000 0.0000
*MESH_FACENORMAL 6 1.0000 0.0000 -0.0000
*MESH_VERTEXNORMAL 1 1.0000 0.0000 0.0000
*MESH_VERTEXNORMAL 3 1.0000 0.0000 -0.0000
*MESH_VERTEXNORMAL 7 1.0000 0.0000 0.0000
*MESH_FACENORMAL 7 1.0000 -0.0000 0.0000
*MESH_VERTEXNORMAL 7 1.0000 0.0000 0.0000
*MESH_VERTEXNORMAL 5 1.0000 -0.0000 0.0000
*MESH_VERTEXNORMAL 1 1.0000 0.0000 0.0000
*MESH_FACENORMAL 8 0.0000 1.0000 0.0000
*MESH_VERTEXNORMAL 3 0.0000 1.0000 0.0000
*MESH_VERTEXNORMAL 2 0.0000 1.0000 0.0000
*MESH_VERTEXNORMAL 6 0.0000 1.0000 0.0000
*MESH_FACENORMAL 9 0.0000 1.0000 0.0000
*MESH_VERTEXNORMAL 6 0.0000 1.0000 0.0000
*MESH_VERTEXNORMAL 7 0.0000 1.0000 0.0000
*MESH_VERTEXNORMAL 3 0.0000 1.0000 0.0000
*MESH_FACENORMAL 10 -1.0000 0.0000 0.0000
*MESH_VERTEXNORMAL 2 -1.0000 0.0000 0.0000
*MESH_VERTEXNORMAL 0 -1.0000 0.0000 0.0000
*MESH_VERTEXNORMAL 4 -1.0000 0.0000 0.0000
*MESH_FACENORMAL 11 -1.0000 -0.0000 -0.0000
*MESH_VERTEXNORMAL 4 -1.0000 0.0000 0.0000
*MESH_VERTEXNORMAL 6 -1.0000 -0.0000 -0.0000
*MESH_VERTEXNORMAL 2 -1.0000 0.0000 0.0000
}
}
*PROP_MOTIONBLUR 0
*PROP_CASTSHADOW 1
*PROP_RECVSHADOW 1
*TM_ANIMATION {
*NODE_NAME "Box02"
*CONTROL_POS_TRACK {
*CONTROL_POS_SAMPLE 0 -45.4570 -12.7152 18.9634
*CONTROL_POS_SAMPLE 800 -45.1391 -10.6490 18.9634
*CONTROL_POS_SAMPLE 1600 -41.9603 -7.7881 18.9634
*CONTROL_POS_SAMPLE 2400 -37.8278 -5.0861 18.9634
*CONTROL_POS_SAMPLE 3200 -33.2185 -1.9073 18.9634
*CONTROL_POS_SAMPLE 4000 -27.3378 1.2715 18.9634
*CONTROL_POS_SAMPLE 4800 -24.0000 3.4967 18.9634
*CONTROL_POS_SAMPLE 5600 -23.0464 5.4040 18.9634
*CONTROL_POS_SAMPLE 6400 -23.0464 7.4702 18.9634
*CONTROL_POS_SAMPLE 7200 -23.5232 -16.3709 18.9634
*CONTROL_POS_SAMPLE 8000 -24.9536 -15.5762 18.9634
*CONTROL_POS_SAMPLE 8800 -27.6556 -13.0331 18.9634
*CONTROL_POS_SAMPLE 9600 -33.0596 -10.9669 18.9634
*CONTROL_POS_SAMPLE 10400 -40.2119 -9.0596 18.9634
*CONTROL_POS_SAMPLE 11200 -45.7748 -6.6143 18.9634
*CONTROL_POS_SAMPLE 12000 -46.2517 -3.7599 18.9634
*CONTROL_POS_SAMPLE 12800 -45.7748 -1.4305 18.9634
*CONTROL_POS_SAMPLE 13600 -44.1854 0.9536 18.9634
*CONTROL_POS_SAMPLE 14400 -40.8477 1.2715 18.9634
*CONTROL_POS_SAMPLE 15200 -32.7417 1.2715 18.9634
*CONTROL_POS_SAMPLE 16000 -25.1126 1.2715 18.9634
}
*CONTROL_ROT_TRACK {
*CONTROL_ROT_SAMPLE 0 1.0000 -0.0000 0.0000 0.2940
*CONTROL_ROT_SAMPLE 800 -1.0000 0.0000 0.0000 0.0028
*CONTROL_ROT_SAMPLE 1600 -1.0000 0.0000 0.0000 0.0222
*CONTROL_ROT_SAMPLE 2400 -1.0000 0.0000 0.0000 0.0305
*CONTROL_ROT_SAMPLE 3200 -1.0000 0.0000 0.0000 0.0277
*CONTROL_ROT_SAMPLE 4000 -1.0000 0.0000 0.0000 0.0361
*CONTROL_ROT_SAMPLE 4800 -1.0000 0.0000 0.0000 0.0416
*CONTROL_ROT_SAMPLE 5600 -1.0000 0.0000 0.0000 0.0472
*CONTROL_ROT_SAMPLE 6400 -1.0000 0.0000 0.0000 0.0333
*CONTROL_ROT_SAMPLE 7200 -1.0000 0.0000 0.0000 0.0361
*CONTROL_ROT_SAMPLE 8000 -1.0000 0.0000 0.0000 0.0499
*CONTROL_ROT_SAMPLE 8800 -1.0000 0.0000 0.0000 0.0333
*CONTROL_ROT_SAMPLE 9600 -1.0000 0.0000 0.0000 0.0361
*CONTROL_ROT_SAMPLE 10400 -1.0000 0.0000 0.0000 0.0472
*CONTROL_ROT_SAMPLE 11200 -1.0000 0.0000 0.0000 0.0416
*CONTROL_ROT_SAMPLE 12000 -1.0000 0.0000 0.0000 0.0388
*CONTROL_ROT_SAMPLE 12800 -1.0000 0.0000 0.0000 0.0305
*CONTROL_ROT_SAMPLE 13600 -1.0000 0.0000 0.0000 0.0361
*CONTROL_ROT_SAMPLE 15200 1.0000 0.0000 0.0000 0.5853
*CONTROL_ROT_SAMPLE 16000 -1.0000 0.0000 0.0000 0.3024
}
}
*WIREFRAME_COLOR 0.6039 0.8431 0.8980
}

View File

@ -0,0 +1,929 @@
*3DSMAX_ASCIIEXPORT 200
*COMMENT "AsciiExport Version 2,00 - Tue Oct 28 19:00:30 2008"
*SCENE {
*SCENE_FILENAME ""
*SCENE_FIRSTFRAME 0
*SCENE_LASTFRAME 100
*SCENE_FRAMESPEED 30
*SCENE_TICKSPERFRAME 160
*SCENE_BACKGROUND_STATIC 0.0000 0.0000 0.0000
*SCENE_AMBIENT_STATIC 0.0000 0.0000 0.0000
}
*MATERIAL_LIST {
*MATERIAL_COUNT 0
}
*GEOMOBJECT {
*NODE_NAME "Box01"
*NODE_TM {
*NODE_NAME "Box01"
*INHERIT_POS 0 0 0
*INHERIT_ROT 0 0 0
*INHERIT_SCL 0 0 0
*TM_ROW0 1.0000 0.0000 0.0000
*TM_ROW1 0.0000 1.0000 0.0000
*TM_ROW2 0.0000 0.0000 1.0000
*TM_ROW3 -1.4245 6.5527 0.0000
*TM_POS -1.4245 6.5527 0.0000
*TM_ROTAXIS 0.0000 0.0000 0.0000
*TM_ROTANGLE 0.0000
*TM_SCALE 1.0000 1.0000 1.0000
*TM_SCALEAXIS 0.0000 0.0000 0.0000
*TM_SCALEAXISANG 0.0000
}
*MESH {
*TIMEVALUE 0
*MESH_NUMVERTEX 8
*MESH_NUMFACES 12
*MESH_VERTEX_LIST {
*MESH_VERTEX 0 -23.0769 -15.0997 0.0000
*MESH_VERTEX 1 20.2279 -15.0997 0.0000
*MESH_VERTEX 2 -23.0769 28.2051 0.0000
*MESH_VERTEX 3 20.2279 28.2051 0.0000
*MESH_VERTEX 4 -23.0769 -15.0997 29.0598
*MESH_VERTEX 5 20.2279 -15.0997 29.0598
*MESH_VERTEX 6 -23.0769 28.2051 29.0598
*MESH_VERTEX 7 20.2279 28.2051 29.0598
}
*MESH_FACE_LIST {
*MESH_FACE 0: A: 0 B: 2 C: 3 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 2 *MESH_MTLID 1
*MESH_FACE 1: A: 3 B: 1 C: 0 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 2 *MESH_MTLID 1
*MESH_FACE 2: A: 4 B: 5 C: 7 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 3 *MESH_MTLID 0
*MESH_FACE 3: A: 7 B: 6 C: 4 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 3 *MESH_MTLID 0
*MESH_FACE 4: A: 0 B: 1 C: 5 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 4 *MESH_MTLID 4
*MESH_FACE 5: A: 5 B: 4 C: 0 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 4 *MESH_MTLID 4
*MESH_FACE 6: A: 1 B: 3 C: 7 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 5 *MESH_MTLID 3
*MESH_FACE 7: A: 7 B: 5 C: 1 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 5 *MESH_MTLID 3
*MESH_FACE 8: A: 3 B: 2 C: 6 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 6 *MESH_MTLID 5
*MESH_FACE 9: A: 6 B: 7 C: 3 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 6 *MESH_MTLID 5
*MESH_FACE 10: A: 2 B: 0 C: 4 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 7 *MESH_MTLID 2
*MESH_FACE 11: A: 4 B: 6 C: 2 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 7 *MESH_MTLID 2
}
*MESH_NUMTVERTEX 12
*MESH_TVERTLIST {
*MESH_TVERT 0 0.0000 0.0000 0.0000
*MESH_TVERT 1 1.0000 0.0000 0.0000
*MESH_TVERT 2 0.0000 1.0000 0.0000
*MESH_TVERT 3 1.0000 1.0000 0.0000
*MESH_TVERT 4 0.0000 0.0000 0.0000
*MESH_TVERT 5 1.0000 0.0000 0.0000
*MESH_TVERT 6 0.0000 1.0000 0.0000
*MESH_TVERT 7 1.0000 1.0000 0.0000
*MESH_TVERT 8 0.0000 0.0000 0.0000
*MESH_TVERT 9 1.0000 0.0000 0.0000
*MESH_TVERT 10 0.0000 1.0000 0.0000
*MESH_TVERT 11 1.0000 1.0000 0.0000
}
*MESH_NUMTVFACES 12
*MESH_TFACELIST {
*MESH_TFACE 0 9 11 10
*MESH_TFACE 1 10 8 9
*MESH_TFACE 2 8 9 11
*MESH_TFACE 3 11 10 8
*MESH_TFACE 4 4 5 7
*MESH_TFACE 5 7 6 4
*MESH_TFACE 6 0 1 3
*MESH_TFACE 7 3 2 0
*MESH_TFACE 8 4 5 7
*MESH_TFACE 9 7 6 4
*MESH_TFACE 10 0 1 3
*MESH_TFACE 11 3 2 0
}
*MESH_NUMCVERTEX 0
*MESH_NORMALS {
*MESH_FACENORMAL 0 0.0000 0.0000 -1.0000
*MESH_VERTEXNORMAL 0 0.0000 0.0000 -1.0000
*MESH_VERTEXNORMAL 2 0.0000 0.0000 -1.0000
*MESH_VERTEXNORMAL 3 0.0000 0.0000 -1.0000
*MESH_FACENORMAL 1 0.0000 0.0000 -1.0000
*MESH_VERTEXNORMAL 3 0.0000 0.0000 -1.0000
*MESH_VERTEXNORMAL 1 0.0000 0.0000 -1.0000
*MESH_VERTEXNORMAL 0 0.0000 0.0000 -1.0000
*MESH_FACENORMAL 2 0.0000 -0.0000 1.0000
*MESH_VERTEXNORMAL 4 0.0000 0.0000 1.0000
*MESH_VERTEXNORMAL 5 0.0000 -0.0000 1.0000
*MESH_VERTEXNORMAL 7 0.0000 0.0000 1.0000
*MESH_FACENORMAL 3 -0.0000 0.0000 1.0000
*MESH_VERTEXNORMAL 7 0.0000 0.0000 1.0000
*MESH_VERTEXNORMAL 6 -0.0000 0.0000 1.0000
*MESH_VERTEXNORMAL 4 0.0000 0.0000 1.0000
*MESH_FACENORMAL 4 0.0000 -1.0000 0.0000
*MESH_VERTEXNORMAL 0 0.0000 -1.0000 0.0000
*MESH_VERTEXNORMAL 1 0.0000 -1.0000 0.0000
*MESH_VERTEXNORMAL 5 0.0000 -1.0000 0.0000
*MESH_FACENORMAL 5 0.0000 -1.0000 0.0000
*MESH_VERTEXNORMAL 5 0.0000 -1.0000 0.0000
*MESH_VERTEXNORMAL 4 0.0000 -1.0000 0.0000
*MESH_VERTEXNORMAL 0 0.0000 -1.0000 0.0000
*MESH_FACENORMAL 6 1.0000 0.0000 -0.0000
*MESH_VERTEXNORMAL 1 1.0000 0.0000 0.0000
*MESH_VERTEXNORMAL 3 1.0000 0.0000 -0.0000
*MESH_VERTEXNORMAL 7 1.0000 0.0000 0.0000
*MESH_FACENORMAL 7 1.0000 -0.0000 0.0000
*MESH_VERTEXNORMAL 7 1.0000 0.0000 0.0000
*MESH_VERTEXNORMAL 5 1.0000 -0.0000 0.0000
*MESH_VERTEXNORMAL 1 1.0000 0.0000 0.0000
*MESH_FACENORMAL 8 0.0000 1.0000 0.0000
*MESH_VERTEXNORMAL 3 0.0000 1.0000 0.0000
*MESH_VERTEXNORMAL 2 0.0000 1.0000 0.0000
*MESH_VERTEXNORMAL 6 0.0000 1.0000 0.0000
*MESH_FACENORMAL 9 0.0000 1.0000 0.0000
*MESH_VERTEXNORMAL 6 0.0000 1.0000 0.0000
*MESH_VERTEXNORMAL 7 0.0000 1.0000 0.0000
*MESH_VERTEXNORMAL 3 0.0000 1.0000 0.0000
*MESH_FACENORMAL 10 -1.0000 0.0000 0.0000
*MESH_VERTEXNORMAL 2 -1.0000 0.0000 0.0000
*MESH_VERTEXNORMAL 0 -1.0000 0.0000 0.0000
*MESH_VERTEXNORMAL 4 -1.0000 0.0000 0.0000
*MESH_FACENORMAL 11 -1.0000 -0.0000 -0.0000
*MESH_VERTEXNORMAL 4 -1.0000 0.0000 0.0000
*MESH_VERTEXNORMAL 6 -1.0000 -0.0000 -0.0000
*MESH_VERTEXNORMAL 2 -1.0000 0.0000 0.0000
}
}
*PROP_MOTIONBLUR 0
*PROP_CASTSHADOW 1
*PROP_RECVSHADOW 1
*WIREFRAME_COLOR 0.7765 0.8824 0.3412
}
*GEOMOBJECT {
*NODE_NAME "Box02"
*NODE_TM {
*NODE_NAME "Box02"
*INHERIT_POS 0 0 0
*INHERIT_ROT 0 0 0
*INHERIT_SCL 0 0 0
*TM_ROW0 0.7748 0.0000 -0.0193
*TM_ROW1 -0.0056 0.7418 -0.2246
*TM_ROW2 0.0301 0.3655 1.2066
*TM_ROW3 -45.4570 -12.7152 18.9634
*TM_POS -45.4570 -12.7152 18.9634
*TM_ROTAXIS 0.9964 -0.0840 -0.0124
*TM_ROTANGLE 0.2951
*TM_SCALE 0.7750 0.7750 1.2611
*TM_SCALEAXIS -0.0000 0.0000 -1.0000
*TM_SCALEAXISANG 0.0039
}
*MESH {
*TIMEVALUE 0
*MESH_NUMVERTEX 8
*MESH_NUMFACES 12
*MESH_VERTEX_LIST {
*MESH_VERTEX 0 -56.6413 -22.4365 22.1875
*MESH_VERTEX 1 -34.1257 -22.4365 21.6253
*MESH_VERTEX 2 -56.7883 -2.9939 16.3016
*MESH_VERTEX 3 -34.2726 -2.9939 15.7394
*MESH_VERTEX 4 -55.7657 -11.8149 57.2514
*MESH_VERTEX 5 -33.2501 -11.8149 56.6892
*MESH_VERTEX 6 -55.9127 7.6277 51.3655
*MESH_VERTEX 7 -33.3970 7.6277 50.8033
}
*MESH_FACE_LIST {
*MESH_FACE 0: A: 0 B: 2 C: 3 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 2 *MESH_MTLID 1
*MESH_FACE 1: A: 3 B: 1 C: 0 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 2 *MESH_MTLID 1
*MESH_FACE 2: A: 4 B: 5 C: 7 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 3 *MESH_MTLID 0
*MESH_FACE 3: A: 7 B: 6 C: 4 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 3 *MESH_MTLID 0
*MESH_FACE 4: A: 0 B: 1 C: 5 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 4 *MESH_MTLID 4
*MESH_FACE 5: A: 5 B: 4 C: 0 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 4 *MESH_MTLID 4
*MESH_FACE 6: A: 1 B: 3 C: 7 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 5 *MESH_MTLID 3
*MESH_FACE 7: A: 7 B: 5 C: 1 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 5 *MESH_MTLID 3
*MESH_FACE 8: A: 3 B: 2 C: 6 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 6 *MESH_MTLID 5
*MESH_FACE 9: A: 6 B: 7 C: 3 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 6 *MESH_MTLID 5
*MESH_FACE 10: A: 2 B: 0 C: 4 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 7 *MESH_MTLID 2
*MESH_FACE 11: A: 4 B: 6 C: 2 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 7 *MESH_MTLID 2
}
*MESH_NUMTVERTEX 12
*MESH_TVERTLIST {
*MESH_TVERT 0 0.0000 0.0000 0.0000
*MESH_TVERT 1 1.0000 0.0000 0.0000
*MESH_TVERT 2 0.0000 1.0000 0.0000
*MESH_TVERT 3 1.0000 1.0000 0.0000
*MESH_TVERT 4 0.0000 0.0000 0.0000
*MESH_TVERT 5 1.0000 0.0000 0.0000
*MESH_TVERT 6 0.0000 1.0000 0.0000
*MESH_TVERT 7 1.0000 1.0000 0.0000
*MESH_TVERT 8 0.0000 0.0000 0.0000
*MESH_TVERT 9 1.0000 0.0000 0.0000
*MESH_TVERT 10 0.0000 1.0000 0.0000
*MESH_TVERT 11 1.0000 1.0000 0.0000
}
*MESH_NUMTVFACES 12
*MESH_TFACELIST {
*MESH_TFACE 0 9 11 10
*MESH_TFACE 1 10 8 9
*MESH_TFACE 2 8 9 11
*MESH_TFACE 3 11 10 8
*MESH_TFACE 4 4 5 7
*MESH_TFACE 5 7 6 4
*MESH_TFACE 6 0 1 3
*MESH_TFACE 7 3 2 0
*MESH_TFACE 8 4 5 7
*MESH_TFACE 9 7 6 4
*MESH_TFACE 10 0 1 3
*MESH_TFACE 11 3 2 0
}
*MESH_NUMCVERTEX 0
*MESH_NORMALS {
*MESH_FACENORMAL 0 0.0000 0.0000 -1.0000
*MESH_VERTEXNORMAL 0 0.0000 0.0000 -1.0000
*MESH_VERTEXNORMAL 2 0.0000 0.0000 -1.0000
*MESH_VERTEXNORMAL 3 0.0000 0.0000 -1.0000
*MESH_FACENORMAL 1 0.0000 0.0000 -1.0000
*MESH_VERTEXNORMAL 3 0.0000 0.0000 -1.0000
*MESH_VERTEXNORMAL 1 0.0000 0.0000 -1.0000
*MESH_VERTEXNORMAL 0 0.0000 0.0000 -1.0000
*MESH_FACENORMAL 2 0.0000 -0.0000 1.0000
*MESH_VERTEXNORMAL 4 0.0000 0.0000 1.0000
*MESH_VERTEXNORMAL 5 0.0000 -0.0000 1.0000
*MESH_VERTEXNORMAL 7 0.0000 0.0000 1.0000
*MESH_FACENORMAL 3 -0.0000 0.0000 1.0000
*MESH_VERTEXNORMAL 7 0.0000 0.0000 1.0000
*MESH_VERTEXNORMAL 6 -0.0000 0.0000 1.0000
*MESH_VERTEXNORMAL 4 0.0000 0.0000 1.0000
*MESH_FACENORMAL 4 0.0000 -1.0000 0.0000
*MESH_VERTEXNORMAL 0 0.0000 -1.0000 0.0000
*MESH_VERTEXNORMAL 1 0.0000 -1.0000 0.0000
*MESH_VERTEXNORMAL 5 0.0000 -1.0000 0.0000
*MESH_FACENORMAL 5 0.0000 -1.0000 0.0000
*MESH_VERTEXNORMAL 5 0.0000 -1.0000 0.0000
*MESH_VERTEXNORMAL 4 0.0000 -1.0000 0.0000
*MESH_VERTEXNORMAL 0 0.0000 -1.0000 0.0000
*MESH_FACENORMAL 6 1.0000 0.0000 -0.0000
*MESH_VERTEXNORMAL 1 1.0000 0.0000 0.0000
*MESH_VERTEXNORMAL 3 1.0000 0.0000 -0.0000
*MESH_VERTEXNORMAL 7 1.0000 0.0000 0.0000
*MESH_FACENORMAL 7 1.0000 -0.0000 0.0000
*MESH_VERTEXNORMAL 7 1.0000 0.0000 0.0000
*MESH_VERTEXNORMAL 5 1.0000 -0.0000 0.0000
*MESH_VERTEXNORMAL 1 1.0000 0.0000 0.0000
*MESH_FACENORMAL 8 0.0000 1.0000 0.0000
*MESH_VERTEXNORMAL 3 0.0000 1.0000 0.0000
*MESH_VERTEXNORMAL 2 0.0000 1.0000 0.0000
*MESH_VERTEXNORMAL 6 0.0000 1.0000 0.0000
*MESH_FACENORMAL 9 0.0000 1.0000 0.0000
*MESH_VERTEXNORMAL 6 0.0000 1.0000 0.0000
*MESH_VERTEXNORMAL 7 0.0000 1.0000 0.0000
*MESH_VERTEXNORMAL 3 0.0000 1.0000 0.0000
*MESH_FACENORMAL 10 -1.0000 0.0000 0.0000
*MESH_VERTEXNORMAL 2 -1.0000 0.0000 0.0000
*MESH_VERTEXNORMAL 0 -1.0000 0.0000 0.0000
*MESH_VERTEXNORMAL 4 -1.0000 0.0000 0.0000
*MESH_FACENORMAL 11 -1.0000 -0.0000 -0.0000
*MESH_VERTEXNORMAL 4 -1.0000 0.0000 0.0000
*MESH_VERTEXNORMAL 6 -1.0000 -0.0000 -0.0000
*MESH_VERTEXNORMAL 2 -1.0000 0.0000 0.0000
}
}
*PROP_MOTIONBLUR 0
*PROP_CASTSHADOW 1
*PROP_RECVSHADOW 1
*TM_ANIMATION {
*NODE_NAME "Box02"
*CONTROL_POS_TRACK {
*CONTROL_POS_SAMPLE 0 -45.4570 -12.7152 18.9634
*CONTROL_POS_SAMPLE 160 -45.4570 -12.3974 18.9634
*CONTROL_POS_SAMPLE 320 -45.4570 -12.0795 18.9634
*CONTROL_POS_SAMPLE 480 -45.4570 -11.7616 18.9634
*CONTROL_POS_SAMPLE 640 -45.2980 -11.2848 18.9634
*CONTROL_POS_SAMPLE 800 -45.1391 -10.6490 18.9634
*CONTROL_POS_SAMPLE 960 -44.8212 -10.1722 18.9634
*CONTROL_POS_SAMPLE 1120 -44.3444 -9.6954 18.9634
*CONTROL_POS_SAMPLE 1280 -43.5497 -8.9007 18.9634
*CONTROL_POS_SAMPLE 1440 -42.7550 -8.2649 18.9634
*CONTROL_POS_SAMPLE 1600 -41.9603 -7.7881 18.9634
*CONTROL_POS_SAMPLE 1760 -41.3245 -7.1523 18.9634
*CONTROL_POS_SAMPLE 1920 -40.3709 -6.5166 18.9634
*CONTROL_POS_SAMPLE 2080 -39.7351 -6.0397 18.9634
*CONTROL_POS_SAMPLE 2240 -38.9404 -5.4040 18.9634
*CONTROL_POS_SAMPLE 2400 -37.8278 -5.0861 18.9634
*CONTROL_POS_SAMPLE 2560 -37.1921 -4.4503 18.9634
*CONTROL_POS_SAMPLE 2720 -36.2384 -3.6556 18.9634
*CONTROL_POS_SAMPLE 2880 -35.1258 -3.3377 18.9634
*CONTROL_POS_SAMPLE 3040 -34.1722 -2.7020 18.9634
*CONTROL_POS_SAMPLE 3200 -33.2185 -1.9073 18.9634
*CONTROL_POS_SAMPLE 3360 -32.1060 -1.5894 18.9634
*CONTROL_POS_SAMPLE 3520 -30.9934 -1.1126 18.9634
*CONTROL_POS_SAMPLE 3680 -29.7219 -0.6358 18.9634
*CONTROL_POS_SAMPLE 3840 -28.4503 0.6358 18.9634
*CONTROL_POS_SAMPLE 4000 -27.3378 1.2715 18.9634
*CONTROL_POS_SAMPLE 4160 -26.3841 1.5894 18.9634
*CONTROL_POS_SAMPLE 4320 -25.4305 2.3841 18.9634
*CONTROL_POS_SAMPLE 4480 -24.7947 2.7020 18.9634
*CONTROL_POS_SAMPLE 4640 -24.3179 3.0199 18.9634
*CONTROL_POS_SAMPLE 4800 -24.0000 3.4967 18.9634
*CONTROL_POS_SAMPLE 4960 -23.6821 3.8146 18.9634
*CONTROL_POS_SAMPLE 5120 -23.5232 4.2914 18.9634
*CONTROL_POS_SAMPLE 5280 -23.2053 4.6093 18.9634
*CONTROL_POS_SAMPLE 5440 -23.0464 4.9272 18.9634
*CONTROL_POS_SAMPLE 5600 -23.0464 5.4040 18.9634
*CONTROL_POS_SAMPLE 5760 -23.0464 5.8808 18.9634
*CONTROL_POS_SAMPLE 5920 -23.0464 6.1987 18.9634
*CONTROL_POS_SAMPLE 6080 -23.0464 6.6755 18.9634
*CONTROL_POS_SAMPLE 6240 -23.0464 7.1523 18.9634
*CONTROL_POS_SAMPLE 6400 -23.0464 7.4702 18.9634
*CONTROL_POS_SAMPLE 6560 -23.2053 7.7881 18.9634
*CONTROL_POS_SAMPLE 6720 -23.0464 6.0397 18.9634
*CONTROL_POS_SAMPLE 6880 -23.0464 0.6358 18.9634
*CONTROL_POS_SAMPLE 7040 -23.3642 -5.8808 18.9634
*CONTROL_POS_SAMPLE 7200 -23.5232 -16.3709 18.9634
*CONTROL_POS_SAMPLE 7360 -23.8411 -17.4834 18.9634
*CONTROL_POS_SAMPLE 7520 -24.0000 -17.0066 18.9634
*CONTROL_POS_SAMPLE 7680 -24.3179 -16.5298 18.9634
*CONTROL_POS_SAMPLE 7840 -24.4768 -16.0530 18.9634
*CONTROL_POS_SAMPLE 8000 -24.9536 -15.5762 18.9634
*CONTROL_POS_SAMPLE 8160 -25.2715 -14.9404 18.9634
*CONTROL_POS_SAMPLE 8320 -25.7483 -14.3046 18.9634
*CONTROL_POS_SAMPLE 8480 -26.3841 -13.9868 18.9634
*CONTROL_POS_SAMPLE 8640 -26.8609 -13.6689 18.9634
*CONTROL_POS_SAMPLE 8800 -27.6556 -13.0331 18.9634
*CONTROL_POS_SAMPLE 8960 -28.4503 -12.5563 18.9634
*CONTROL_POS_SAMPLE 9120 -29.7219 -12.0795 18.9634
*CONTROL_POS_SAMPLE 9280 -30.8344 -11.8543 18.9634
*CONTROL_POS_SAMPLE 9440 -31.7881 -11.6026 18.9634
*CONTROL_POS_SAMPLE 9600 -33.0596 -10.9669 18.9634
*CONTROL_POS_SAMPLE 9760 -33.5364 -10.6490 18.9634
*CONTROL_POS_SAMPLE 9920 -34.9669 -10.1656 18.9634
*CONTROL_POS_SAMPLE 10080 -37.0331 -9.6954 18.9634
*CONTROL_POS_SAMPLE 10240 -38.3046 -9.3974 18.9634
*CONTROL_POS_SAMPLE 10400 -40.2119 -9.0596 18.9634
*CONTROL_POS_SAMPLE 10560 -41.8013 -8.2649 18.9634
*CONTROL_POS_SAMPLE 10720 -43.0728 -7.8705 18.9634
*CONTROL_POS_SAMPLE 10880 -44.5033 -7.5467 18.9634
*CONTROL_POS_SAMPLE 11040 -45.2980 -7.1523 18.9634
*CONTROL_POS_SAMPLE 11200 -45.7748 -6.6143 18.9634
*CONTROL_POS_SAMPLE 11360 -46.0927 -6.0056 18.9634
*CONTROL_POS_SAMPLE 11520 -46.2517 -5.4040 18.9634
*CONTROL_POS_SAMPLE 11680 -46.4106 -4.8371 18.9634
*CONTROL_POS_SAMPLE 11840 -46.4106 -4.2914 18.9634
*CONTROL_POS_SAMPLE 12000 -46.2517 -3.7599 18.9634
*CONTROL_POS_SAMPLE 12160 -46.2517 -3.2318 18.9634
*CONTROL_POS_SAMPLE 12320 -46.0927 -2.7169 18.9634
*CONTROL_POS_SAMPLE 12480 -46.0927 -2.2252 18.9634
*CONTROL_POS_SAMPLE 12640 -45.9338 -1.8013 18.9634
*CONTROL_POS_SAMPLE 12800 -45.7748 -1.4305 18.9634
*CONTROL_POS_SAMPLE 12960 -45.4570 -1.1126 18.9634
*CONTROL_POS_SAMPLE 13120 -44.9801 -0.5563 18.9634
*CONTROL_POS_SAMPLE 13280 -44.8212 0.0000 18.9634
*CONTROL_POS_SAMPLE 13440 -44.5033 0.3179 18.9634
*CONTROL_POS_SAMPLE 13600 -44.1854 0.9536 18.9634
*CONTROL_POS_SAMPLE 13760 -43.7219 1.1126 18.9634
*CONTROL_POS_SAMPLE 13920 -43.2318 1.2715 18.9634
*CONTROL_POS_SAMPLE 14080 -42.7550 1.2715 18.9634
*CONTROL_POS_SAMPLE 14240 -41.9603 1.2715 18.9634
*CONTROL_POS_SAMPLE 14400 -40.8477 1.2715 18.9634
*CONTROL_POS_SAMPLE 14560 -38.9404 1.2715 18.9634
*CONTROL_POS_SAMPLE 14720 -37.5099 1.2715 18.9634
*CONTROL_POS_SAMPLE 14880 -36.2384 1.2715 18.9634
*CONTROL_POS_SAMPLE 15040 -34.4901 1.2715 18.9634
*CONTROL_POS_SAMPLE 15200 -32.7417 1.2715 18.9634
*CONTROL_POS_SAMPLE 15360 -30.8344 1.2715 18.9634
*CONTROL_POS_SAMPLE 15520 -28.6093 1.2715 18.9634
*CONTROL_POS_SAMPLE 15680 -26.5431 1.2715 18.9634
*CONTROL_POS_SAMPLE 15840 -25.5894 1.2715 18.9634
*CONTROL_POS_SAMPLE 16000 -25.1126 1.2715 18.9634
}
*CONTROL_ROT_TRACK {
*CONTROL_ROT_SAMPLE 0 0.9964 -0.0840 -0.0124 0.2951
*CONTROL_ROT_SAMPLE 800 -0.9997 -0.0000 0.0250 0.0028
*CONTROL_ROT_SAMPLE 960 -0.6973 -0.7166 0.0184 0.0040
*CONTROL_ROT_SAMPLE 1120 -0.5656 -0.8245 0.0180 0.0098
*CONTROL_ROT_SAMPLE 1280 -0.4021 -0.9154 0.0170 0.0138
*CONTROL_ROT_SAMPLE 1440 -0.1659 -0.9861 0.0094 0.0167
*CONTROL_ROT_SAMPLE 1600 -0.2716 -0.9622 0.0203 0.0204
*CONTROL_ROT_SAMPLE 1760 -0.2430 -0.9698 0.0233 0.0227
*CONTROL_ROT_SAMPLE 1920 -0.3279 -0.9439 0.0390 0.0252
*CONTROL_ROT_SAMPLE 2080 -0.1099 -0.9938 0.0158 0.0250
*CONTROL_ROT_SAMPLE 2240 -0.2121 -0.9766 0.0359 0.0258
*CONTROL_ROT_SAMPLE 2400 -0.3119 -0.9482 0.0609 0.0262
*CONTROL_ROT_SAMPLE 2560 -0.1131 -0.9933 0.0250 0.0239
*CONTROL_ROT_SAMPLE 2720 -0.2371 -0.9697 0.0580 0.0227
*CONTROL_ROT_SAMPLE 2880 -0.3776 -0.9205 0.1008 0.0213
*CONTROL_ROT_SAMPLE 3040 -0.3071 -0.9476 0.0879 0.0174
*CONTROL_ROT_SAMPLE 3200 -0.3853 -0.9154 0.1164 0.0138
*CONTROL_ROT_SAMPLE 3360 -0.3097 -0.9459 0.0971 0.0085
*CONTROL_ROT_SAMPLE 3520 -0.9012 -0.3240 0.2879 0.0088
*CONTROL_ROT_SAMPLE 3680 -0.7198 0.6552 0.2292 0.0073
*CONTROL_ROT_SAMPLE 3840 -0.5043 0.8494 0.1555 0.0158
*CONTROL_ROT_SAMPLE 4000 -0.4586 0.8786 0.1330 0.0232
*CONTROL_ROT_SAMPLE 4160 -0.2026 0.9778 0.0537 0.0265
*CONTROL_ROT_SAMPLE 4320 -0.3398 0.9371 0.0800 0.0318
*CONTROL_ROT_SAMPLE 4480 -0.2458 0.9680 0.0499 0.0332
*CONTROL_ROT_SAMPLE 4640 -0.2418 0.9695 0.0410 0.0339
*CONTROL_ROT_SAMPLE 4800 -0.2485 0.9680 0.0338 0.0332
*CONTROL_ROT_SAMPLE 4960 -0.2677 0.9631 0.0280 0.0309
*CONTROL_ROT_SAMPLE 5120 -0.4710 0.8814 0.0361 0.0294
*CONTROL_ROT_SAMPLE 5280 -0.2618 0.9650 0.0140 0.0212
*CONTROL_ROT_SAMPLE 5440 -0.3824 0.9239 0.0140 0.0145
*CONTROL_ROT_SAMPLE 5600 -0.9444 0.3278 0.0259 0.0147
*CONTROL_ROT_SAMPLE 5760 -0.9997 -0.0000 0.0250 0.0028
*CONTROL_ROT_SAMPLE 5920 -0.9997 -0.0000 0.0250 0.0111
*CONTROL_ROT_SAMPLE 6080 -0.9997 0.0000 0.0250 0.0055
*CONTROL_ROT_SAMPLE 6240 -0.9997 -0.0000 0.0250 0.0083
*CONTROL_ROT_SAMPLE 6400 -0.9997 0.0000 0.0250 0.0055
*CONTROL_ROT_SAMPLE 6560 -0.9997 -0.0000 0.0250 0.0055
*CONTROL_ROT_SAMPLE 6720 -0.9997 0.0000 0.0250 0.0111
*CONTROL_ROT_SAMPLE 6880 -0.9997 -0.0000 0.0250 0.0055
*CONTROL_ROT_SAMPLE 7040 -0.9997 0.0000 0.0250 0.0083
*CONTROL_ROT_SAMPLE 7200 -0.9997 0.0000 0.0250 0.0055
*CONTROL_ROT_SAMPLE 7360 -0.9997 -0.0000 0.0250 0.0111
*CONTROL_ROT_SAMPLE 7520 -0.9997 0.0000 0.0250 0.0083
*CONTROL_ROT_SAMPLE 7680 -0.9997 -0.0000 0.0250 0.0083
*CONTROL_ROT_SAMPLE 7840 -0.9997 0.0000 0.0250 0.0111
*CONTROL_ROT_SAMPLE 8000 -0.9997 -0.0000 0.0250 0.0111
*CONTROL_ROT_SAMPLE 8160 -0.9997 -0.0000 0.0250 0.0055
*CONTROL_ROT_SAMPLE 8320 -0.9997 -0.0000 0.0250 0.0055
*CONTROL_ROT_SAMPLE 8480 -0.9997 0.0000 0.0250 0.0083
*CONTROL_ROT_SAMPLE 8640 -0.9997 -0.0000 0.0250 0.0055
*CONTROL_ROT_SAMPLE 8800 -0.9997 0.0000 0.0250 0.0083
*CONTROL_ROT_SAMPLE 8960 -0.9997 -0.0000 0.0250 0.0055
*CONTROL_ROT_SAMPLE 9120 -0.9997 0.0000 0.0250 0.0111
*CONTROL_ROT_SAMPLE 9280 -0.9997 0.0000 0.0250 0.0055
*CONTROL_ROT_SAMPLE 9440 -0.9997 0.0000 0.0250 0.0083
*CONTROL_ROT_SAMPLE 9600 -0.9997 0.0000 0.0250 0.0055
*CONTROL_ROT_SAMPLE 9760 -0.9997 -0.0000 0.0250 0.0083
*CONTROL_ROT_SAMPLE 9920 -0.9997 -0.0000 0.0250 0.0083
*CONTROL_ROT_SAMPLE 10080 -0.9997 0.0000 0.0250 0.0055
*CONTROL_ROT_SAMPLE 10240 -0.9997 -0.0000 0.0250 0.0083
*CONTROL_ROT_SAMPLE 10400 -0.9997 -0.0000 0.0250 0.0166
*CONTROL_ROT_SAMPLE 10560 -0.9997 0.0000 0.0250 0.0083
*CONTROL_ROT_SAMPLE 10720 -0.9997 0.0000 0.0250 0.0055
*CONTROL_ROT_SAMPLE 10880 -0.9997 -0.0000 0.0250 0.0139
*CONTROL_ROT_SAMPLE 11040 -0.9997 -0.0000 0.0250 0.0055
*CONTROL_ROT_SAMPLE 11200 -0.9997 0.0000 0.0250 0.0083
*CONTROL_ROT_SAMPLE 11360 -0.9997 0.0000 0.0250 0.0111
*CONTROL_ROT_SAMPLE 11520 -0.9997 0.0000 0.0250 0.0083
*CONTROL_ROT_SAMPLE 11680 -0.9997 -0.0000 0.0250 0.0083
*CONTROL_ROT_SAMPLE 11840 -0.9997 0.0000 0.0250 0.0083
*CONTROL_ROT_SAMPLE 12000 -0.9997 0.0000 0.0250 0.0028
*CONTROL_ROT_SAMPLE 12160 -0.9997 -0.0000 0.0250 0.0055
*CONTROL_ROT_SAMPLE 12320 -0.9997 0.0000 0.0250 0.0083
*CONTROL_ROT_SAMPLE 12480 -0.9997 -0.0000 0.0250 0.0055
*CONTROL_ROT_SAMPLE 12640 -0.9997 -0.0000 0.0250 0.0055
*CONTROL_ROT_SAMPLE 12800 -0.9997 0.0000 0.0250 0.0055
*CONTROL_ROT_SAMPLE 12960 -0.9997 0.0000 0.0250 0.0083
*CONTROL_ROT_SAMPLE 13120 -0.9997 -0.0000 0.0250 0.0083
*CONTROL_ROT_SAMPLE 13280 -0.9997 0.0000 0.0250 0.0055
*CONTROL_ROT_SAMPLE 13440 -0.9997 -0.0000 0.0250 0.0083
*CONTROL_ROT_SAMPLE 13600 -0.9997 0.0000 0.0250 0.0055
*CONTROL_ROT_SAMPLE 13760 -0.9997 -0.0000 0.0250 0.0055
*CONTROL_ROT_SAMPLE 13920 -0.9997 0.0000 0.0250 0.0028
*CONTROL_ROT_SAMPLE 14080 -0.9997 -0.0000 0.0250 0.0028
*CONTROL_ROT_SAMPLE 14240 0.9997 0.0000 -0.0250 0.0028
*CONTROL_ROT_SAMPLE 14400 0.9997 -0.0000 -0.0250 0.0083
*CONTROL_ROT_SAMPLE 14560 0.9997 -0.0000 -0.0250 0.0055
*CONTROL_ROT_SAMPLE 14720 0.9997 0.0000 -0.0250 0.5243
*CONTROL_ROT_SAMPLE 14880 0.9997 0.0000 -0.0250 0.0250
*CONTROL_ROT_SAMPLE 15040 0.9997 0.0000 -0.0250 0.0111
*CONTROL_ROT_SAMPLE 15200 0.9997 -0.0000 -0.0250 0.0194
*CONTROL_ROT_SAMPLE 15360 0.9997 0.0000 -0.0250 0.0166
*CONTROL_ROT_SAMPLE 15520 0.9997 0.0000 -0.0250 0.0055
*CONTROL_ROT_SAMPLE 15680 -0.9997 -0.0000 0.0250 0.3246
}
*CONTROL_SCALE_TRACK {
*CONTROL_SCALE_SAMPLE 0 0.7750 0.7750 1.2611 -0.0000 0.0000 -1.0000 0.0039
*CONTROL_SCALE_SAMPLE 1600 0.7766 0.7766 1.2627 0.0000 0.0000 0.0000 0.0000
*CONTROL_SCALE_SAMPLE 1760 0.7812 0.7812 1.2672 -0.0000 0.0000 -1.0000 0.0156
*CONTROL_SCALE_SAMPLE 1920 0.7885 0.7885 1.2746 0.0000 -0.0000 1.0000 0.0312
*CONTROL_SCALE_SAMPLE 2080 0.7984 0.7984 1.2844 0.0000 0.0000 0.0000 0.0000
*CONTROL_SCALE_SAMPLE 2240 0.8106 0.8106 1.2966 0.0000 0.0000 0.0000 0.0000
*CONTROL_SCALE_SAMPLE 2400 0.8249 0.8249 1.3109 0.0000 0.0000 0.0000 0.0000
*CONTROL_SCALE_SAMPLE 2560 0.8410 0.8410 1.3271 0.0000 -0.0000 1.0000 0.0312
*CONTROL_SCALE_SAMPLE 2720 0.8589 0.8589 1.3450 0.0000 0.0000 1.0000 0.0312
*CONTROL_SCALE_SAMPLE 2880 0.8782 0.8782 1.3642 -0.0000 0.0000 -1.0000 0.0622
*CONTROL_SCALE_SAMPLE 3040 0.8987 0.8987 1.3847 0.0000 0.0000 0.0000 0.0000
*CONTROL_SCALE_SAMPLE 3200 0.9202 0.9202 1.4062 0.0000 0.0000 0.0000 0.0000
*CONTROL_SCALE_SAMPLE 3360 0.9424 0.9424 1.4285 0.0000 -0.0000 -1.0000 0.0927
*CONTROL_SCALE_SAMPLE 3520 0.9653 0.9653 1.4513 0.0000 0.0000 0.0000 0.0000
*CONTROL_SCALE_SAMPLE 3680 0.9884 0.9884 1.4745 -0.0000 0.0000 -1.0000 0.0622
*CONTROL_SCALE_SAMPLE 3840 1.0117 1.0117 1.4978 0.0000 0.0000 0.0000 0.0000
*CONTROL_SCALE_SAMPLE 4000 1.0348 1.0348 1.5209 0.0000 0.0000 0.0000 0.0000
*CONTROL_SCALE_SAMPLE 4160 1.0577 1.0577 1.5437 -0.0000 -0.0000 -1.0000 0.0156
*CONTROL_SCALE_SAMPLE 4320 1.0799 1.0799 1.5660 0.0000 0.0000 0.0000 0.0000
*CONTROL_SCALE_SAMPLE 4480 1.1014 1.1014 1.5875 0.0000 0.0000 0.0000 0.0000
*CONTROL_SCALE_SAMPLE 4640 1.1219 1.1219 1.6080 0.0000 0.0000 0.0000 0.0000
*CONTROL_SCALE_SAMPLE 4800 1.1412 1.1412 1.6273 -0.0000 0.0000 1.0000 0.0078
*CONTROL_SCALE_SAMPLE 4960 1.1591 1.1591 1.6451 0.0000 0.0000 0.0000 0.0000
*CONTROL_SCALE_SAMPLE 5120 1.1752 1.1752 1.6613 0.0000 0.0000 1.0000 0.0039
*CONTROL_SCALE_SAMPLE 5280 1.1895 1.1895 1.6756 0.0000 0.0000 -1.0000 0.0020
*CONTROL_SCALE_SAMPLE 5440 1.2017 1.2017 1.6878 0.0000 0.0000 0.0000 0.0000
*CONTROL_SCALE_SAMPLE 5600 1.2116 1.2116 1.6977 -0.0000 0.0000 -1.0000 0.0010
*CONTROL_SCALE_SAMPLE 5760 1.2189 1.2189 1.7050 0.0000 -0.0000 1.0000 0.0020
*CONTROL_SCALE_SAMPLE 5920 1.2235 1.2235 1.7096 0.0000 0.0000 0.0000 0.0000
*CONTROL_SCALE_SAMPLE 6080 1.2251 1.2251 1.7111 0.0000 0.0000 0.0000 0.0000
*CONTROL_SCALE_SAMPLE 6240 1.2193 1.2193 1.7054 0.0000 0.0000 1.0000 0.0015
*CONTROL_SCALE_SAMPLE 6400 1.2032 1.2032 1.6893 0.0000 0.0000 -1.0000 0.0002
*CONTROL_SCALE_SAMPLE 6560 1.1783 1.1783 1.6643 0.0000 0.0000 0.0000 0.0000
*CONTROL_SCALE_SAMPLE 6720 1.1461 1.1461 1.6322 0.0000 0.0000 0.0000 0.0000
*CONTROL_SCALE_SAMPLE 6880 1.1084 1.1084 1.5945 0.0000 -0.0000 -1.0000 0.0002
*CONTROL_SCALE_SAMPLE 7040 1.0667 1.0667 1.5527 0.0000 0.0000 0.0000 0.0000
*CONTROL_SCALE_SAMPLE 7200 1.0225 1.0225 1.5086 0.0000 0.0000 0.0000 0.0000
*CONTROL_SCALE_SAMPLE 7360 0.9776 0.9776 1.4637 -0.0000 0.0000 -1.0000 0.0001
*CONTROL_SCALE_SAMPLE 7520 0.9335 0.9335 1.4195 -0.0000 -0.0002 -1.0000 0.0000
*CONTROL_SCALE_SAMPLE 7680 0.8917 0.8917 1.3778 0.0000 0.0000 0.0000 0.0000
*CONTROL_SCALE_SAMPLE 7840 0.8540 0.8540 1.3401 -0.0000 -0.0000 1.0000 0.0002
*CONTROL_SCALE_SAMPLE 8000 0.8218 0.8218 1.3079 0.0000 0.0000 0.0000 0.0000
*CONTROL_SCALE_SAMPLE 8160 0.7969 0.7969 1.2830 0.0000 0.0000 0.0000 0.0000
*CONTROL_SCALE_SAMPLE 8320 0.7808 0.7808 1.2669 0.0000 0.0000 0.0000 0.0000
*CONTROL_SCALE_SAMPLE 8480 0.7750 0.7750 1.2611 -0.0000 -0.0000 -1.0000 0.0010
}
}
*WIREFRAME_COLOR 0.6039 0.8431 0.8980
}
*CAMERAOBJECT {
*NODE_NAME "Camera01"
*CAMERA_TYPE Target
*NODE_TM {
*NODE_NAME "Camera01"
*INHERIT_POS 0 0 0
*INHERIT_ROT 0 0 0
*INHERIT_SCL 1 1 1
*TM_ROW0 0.4542 -0.8829 -0.1190
*TM_ROW1 0.0544 -0.1058 0.9929
*TM_ROW2 -0.8892 -0.4575 0.0000
*TM_ROW3 -84.7152 -0.4114 0.0000
*TM_POS -84.7152 -0.4114 0.0000
*TM_ROTAXIS -0.7670 0.4073 0.4957
*TM_ROTANGLE 1.9026
*TM_SCALE 1.0000 1.0000 1.0000
*TM_SCALEAXIS 0.0000 0.0000 0.0000
*TM_SCALEAXISANG 0.0000
}
*NODE_TM {
*NODE_NAME "Camera01.Target"
*INHERIT_POS 0 0 0
*INHERIT_ROT 0 0 0
*INHERIT_SCL 0 0 0
*TM_ROW0 1.0000 0.0000 0.0000
*TM_ROW1 0.0000 1.0000 0.0000
*TM_ROW2 0.0000 0.0000 1.0000
*TM_ROW3 46.1410 66.9139 0.0000
*TM_POS 46.1410 66.9139 0.0000
*TM_ROTAXIS 0.0000 0.0000 0.0000
*TM_ROTANGLE 0.0000
*TM_SCALE 1.0000 1.0000 1.0000
*TM_SCALEAXIS 0.0000 0.0000 0.0000
*TM_SCALEAXISANG 0.0000
}
*CAMERA_SETTINGS {
*TIMEVALUE 0
*CAMERA_NEAR 0.0000
*CAMERA_FAR 1000.0000
*CAMERA_FOV 0.7854
*CAMERA_TDIST 147.1600
}
*TM_ANIMATION {
*NODE_NAME "Camera01"
*CONTROL_POS_TRACK {
*CONTROL_POS_SAMPLE 0 -84.7152 -0.4114 0.0000
*CONTROL_POS_SAMPLE 1280 -83.9205 -0.4114 0.0000
*CONTROL_POS_SAMPLE 1440 -82.8080 -0.4114 0.0000
*CONTROL_POS_SAMPLE 1600 -81.0596 -0.4114 0.0000
*CONTROL_POS_SAMPLE 1760 -79.9470 -0.4114 0.0000
*CONTROL_POS_SAMPLE 1920 -78.8344 -0.4114 0.0000
*CONTROL_POS_SAMPLE 2080 -78.0397 -0.4114 0.0000
*CONTROL_POS_SAMPLE 2240 -76.9272 -0.4114 0.0000
*CONTROL_POS_SAMPLE 2400 -75.6556 -0.4114 0.0000
*CONTROL_POS_SAMPLE 2560 -74.7020 -0.4114 0.0000
*CONTROL_POS_SAMPLE 2720 -73.5894 -0.4114 0.0000
*CONTROL_POS_SAMPLE 2880 -72.7947 -0.4114 0.0000
*CONTROL_POS_SAMPLE 3040 -74.2252 -0.4114 0.0000
*CONTROL_POS_SAMPLE 3200 -75.8146 -0.4114 0.0000
*CONTROL_POS_SAMPLE 3360 -77.2450 -0.4114 0.0000
*CONTROL_POS_SAMPLE 3520 -78.8344 -0.4114 0.0000
*CONTROL_POS_SAMPLE 3680 -80.2649 -0.4114 0.0000
*CONTROL_POS_SAMPLE 3840 -81.6954 -0.4114 0.0000
*CONTROL_POS_SAMPLE 4000 -83.2848 -0.4114 0.0000
*CONTROL_POS_SAMPLE 4160 -85.0331 -0.4114 0.0000
*CONTROL_POS_SAMPLE 4320 -86.4636 -0.4114 0.0000
*CONTROL_POS_SAMPLE 4480 -86.1457 -0.4114 0.0000
*CONTROL_POS_SAMPLE 4640 -84.7152 -0.4114 0.0000
*CONTROL_POS_SAMPLE 4800 -83.2848 -0.4114 0.0000
*CONTROL_POS_SAMPLE 4960 -81.5364 -0.4114 0.0000
*CONTROL_POS_SAMPLE 5120 -80.1060 -0.4114 0.0000
*CONTROL_POS_SAMPLE 5280 -77.8808 -0.4114 0.0000
*CONTROL_POS_SAMPLE 5440 -76.2914 -0.4114 0.0000
*CONTROL_POS_SAMPLE 5600 -74.8609 -0.4114 0.0000
*CONTROL_POS_SAMPLE 5760 -73.2715 -0.4114 0.0000
*CONTROL_POS_SAMPLE 5920 -71.8411 -0.4114 0.0000
*CONTROL_POS_SAMPLE 6080 -74.0662 -0.4114 0.0000
*CONTROL_POS_SAMPLE 6240 -75.9735 -0.4114 0.0000
*CONTROL_POS_SAMPLE 6400 -78.0397 -0.4114 0.0000
*CONTROL_POS_SAMPLE 6560 -79.9470 -0.4114 0.0000
*CONTROL_POS_SAMPLE 6720 -81.2186 -0.4114 0.0000
*CONTROL_POS_SAMPLE 6880 -82.4901 -0.4114 0.0000
*CONTROL_POS_SAMPLE 7040 -83.6027 -0.4114 0.0000
*CONTROL_POS_SAMPLE 7200 -84.5563 -0.4114 0.0000
*CONTROL_POS_SAMPLE 7360 -85.6689 -0.4114 0.0000
*CONTROL_POS_SAMPLE 7520 -86.1457 -0.4114 0.0000
*CONTROL_POS_SAMPLE 7680 -84.2384 -0.4114 0.0000
*CONTROL_POS_SAMPLE 7840 -82.6490 -0.4114 0.0000
*CONTROL_POS_SAMPLE 8000 -81.5364 -0.4114 0.0000
*CONTROL_POS_SAMPLE 8160 -79.6291 -0.4114 0.0000
*CONTROL_POS_SAMPLE 8320 -77.7219 -0.4114 0.0000
*CONTROL_POS_SAMPLE 8480 -76.6093 -0.4114 0.0000
*CONTROL_POS_SAMPLE 8640 -75.1788 -0.4114 0.0000
*CONTROL_POS_SAMPLE 8800 -73.7484 -0.4114 0.0000
*CONTROL_POS_SAMPLE 8960 -72.1589 -0.4114 0.0000
*CONTROL_POS_SAMPLE 9120 -71.0464 -0.4114 0.0000
*CONTROL_POS_SAMPLE 9280 -71.6821 -0.4114 0.0000
*CONTROL_POS_SAMPLE 9440 -74.2252 -0.4114 0.0000
*CONTROL_POS_SAMPLE 9600 -75.3378 -0.4114 0.0000
*CONTROL_POS_SAMPLE 9760 -77.4040 -0.4114 0.0000
*CONTROL_POS_SAMPLE 9920 -78.8344 -0.4114 0.0000
*CONTROL_POS_SAMPLE 10080 -81.6954 -0.4114 0.0000
*CONTROL_POS_SAMPLE 10240 -82.6490 -0.4114 0.0000
*CONTROL_POS_SAMPLE 10400 -83.4437 -0.4114 0.0000
*CONTROL_POS_SAMPLE 10560 -85.3510 -0.4114 0.0000
*CONTROL_POS_SAMPLE 10720 -86.9404 -0.4114 0.0000
*CONTROL_POS_SAMPLE 10880 -87.7351 -0.4114 0.0000
}
*CONTROL_ROT_TRACK {
*CONTROL_ROT_SAMPLE 0 -0.7670 0.4073 0.4957 1.9026
*CONTROL_ROT_SAMPLE 480 0.8892 0.4575 0.0000 0.0083
*CONTROL_ROT_SAMPLE 640 0.8892 0.4575 0.0000 0.0028
*CONTROL_ROT_SAMPLE 800 0.8892 0.4575 -0.0000 0.0083
*CONTROL_ROT_SAMPLE 960 0.8892 0.4575 0.0000 0.0055
*CONTROL_ROT_SAMPLE 1120 0.7310 0.3769 -0.5689 0.0034
*CONTROL_ROT_SAMPLE 1280 0.7454 0.3879 -0.5422 0.0099
*CONTROL_ROT_SAMPLE 1440 0.3109 0.1643 -0.9362 0.0079
*CONTROL_ROT_SAMPLE 1600 0.6127 0.3301 -0.7180 0.0120
*CONTROL_ROT_SAMPLE 1760 0.4012 0.2206 -0.8890 0.0096
*CONTROL_ROT_SAMPLE 1920 0.4952 0.2769 -0.8235 0.0069
*CONTROL_ROT_SAMPLE 2080 0.4387 0.2497 -0.8632 0.0110
*CONTROL_ROT_SAMPLE 2240 0.5032 0.2922 -0.8133 0.0095
*CONTROL_ROT_SAMPLE 2400 0.4561 0.2699 -0.8480 0.0105
*CONTROL_ROT_SAMPLE 2560 0.4964 0.2994 -0.8149 0.0096
*CONTROL_ROT_SAMPLE 2720 0.4872 0.2991 -0.8205 0.0097
*CONTROL_ROT_SAMPLE 2880 0.4210 0.2636 -0.8679 0.0112
*CONTROL_ROT_SAMPLE 3040 0.8123 0.5132 0.2772 0.0058
*CONTROL_ROT_SAMPLE 3200 0.8132 0.5137 -0.2735 0.0058
*CONTROL_ROT_SAMPLE 3360 0.8331 0.5279 -0.1650 0.0073
*CONTROL_ROT_SAMPLE 3520 0.6275 0.4008 -0.6676 0.0090
*CONTROL_ROT_SAMPLE 3680 0.2462 0.1599 -0.9559 0.0094
*CONTROL_ROT_SAMPLE 3840 0.7048 0.4649 -0.5359 0.0099
*CONTROL_ROT_SAMPLE 4000 0.7179 0.4720 0.5117 0.0161
*CONTROL_ROT_SAMPLE 4160 0.4219 0.2721 0.8648 0.0111
*CONTROL_ROT_SAMPLE 4320 0.7437 0.4706 0.4748 0.0158
*CONTROL_ROT_SAMPLE 4480 0.8355 0.5230 0.1684 0.0141
*CONTROL_ROT_SAMPLE 4640 0.8302 0.5196 -0.2017 0.0113
*CONTROL_ROT_SAMPLE 4800 0.8471 0.5313 0.0140 0.0222
*CONTROL_ROT_SAMPLE 4960 0.8448 0.5307 -0.0677 0.0250
*CONTROL_ROT_SAMPLE 5120 0.8445 0.5329 -0.0540 0.0444
*CONTROL_ROT_SAMPLE 5280 0.8424 0.5351 -0.0634 0.0556
*CONTROL_ROT_SAMPLE 5440 0.8369 0.5360 -0.1110 0.0363
*CONTROL_ROT_SAMPLE 5600 0.8387 0.5406 -0.0664 0.0250
*CONTROL_ROT_SAMPLE 5760 0.8304 0.5381 -0.1445 0.0224
*CONTROL_ROT_SAMPLE 5920 0.8383 0.5451 0.0084 0.0166
*CONTROL_ROT_SAMPLE 6080 0.4433 0.2825 0.8507 0.0211
*CONTROL_ROT_SAMPLE 6240 0.3102 0.1893 0.9316 0.0229
*CONTROL_ROT_SAMPLE 6400 0.2051 0.1190 0.9715 0.0234
*CONTROL_ROT_SAMPLE 6560 0.2589 0.1418 0.9554 0.0282
*CONTROL_ROT_SAMPLE 6720 0.0000 0.0000 1.0000 0.0160
*CONTROL_ROT_SAMPLE 6880 0.2645 0.1334 0.9551 0.0094
*CONTROL_ROT_SAMPLE 7040 -0.0000 -0.0000 1.0000 0.0034
*CONTROL_ROT_SAMPLE 7200 -0.0009 0.0018 -1.0000 0.0000
*CONTROL_ROT_SAMPLE 7360 -0.8936 -0.4416 0.0803 0.0056
*CONTROL_ROT_SAMPLE 7520 -0.8823 -0.4360 -0.1776 0.0028
*CONTROL_ROT_SAMPLE 7680 -0.6777 -0.3382 -0.6530 0.0110
*CONTROL_ROT_SAMPLE 7840 -0.3503 -0.1778 -0.9196 0.0071
*CONTROL_ROT_SAMPLE 8000 -0.7016 -0.3618 -0.6139 0.0105
*CONTROL_ROT_SAMPLE 8160 -0.8184 -0.4302 -0.3811 0.0240
*CONTROL_ROT_SAMPLE 8320 -0.5861 -0.3150 -0.7465 0.0125
*CONTROL_ROT_SAMPLE 8480 -0.8475 -0.4635 -0.2589 0.0201
*CONTROL_ROT_SAMPLE 8640 -0.8388 -0.4652 -0.2830 0.0231
*CONTROL_ROT_SAMPLE 8800 -0.8275 -0.4674 -0.3109 0.0292
*CONTROL_ROT_SAMPLE 8960 -0.6793 -0.3918 -0.6205 0.0141
*CONTROL_ROT_SAMPLE 9120 -0.8499 -0.4992 -0.1690 0.0422
*CONTROL_ROT_SAMPLE 9280 -0.8602 -0.5097 -0.0151 0.0416
*CONTROL_ROT_SAMPLE 9440 -0.8587 -0.5061 0.0805 0.0668
*CONTROL_ROT_SAMPLE 9600 -0.8631 -0.5044 0.0246 0.0832
*CONTROL_ROT_SAMPLE 9760 -0.8612 -0.4990 0.0964 0.0557
*CONTROL_ROT_SAMPLE 9920 -0.8666 -0.4978 0.0358 0.0583
*CONTROL_ROT_SAMPLE 10080 -0.8438 -0.4797 0.2405 0.0286
*CONTROL_ROT_SAMPLE 10240 -0.8649 -0.4897 -0.1101 0.0307
*CONTROL_ROT_SAMPLE 10400 -0.8643 -0.4924 -0.1024 0.0195
*CONTROL_ROT_SAMPLE 10560 -0.8594 -0.4919 -0.1396 0.0140
*CONTROL_ROT_SAMPLE 10720 -0.5620 -0.3248 -0.7607 0.0085
*CONTROL_ROT_SAMPLE 10880 -0.3954 -0.2317 -0.8888 0.0061
*CONTROL_ROT_SAMPLE 11040 0.3160 0.1878 -0.9300 0.0075
*CONTROL_ROT_SAMPLE 11200 0.5765 0.3477 -0.7394 0.0082
*CONTROL_ROT_SAMPLE 11360 0.7243 0.4417 -0.5294 0.0065
*CONTROL_ROT_SAMPLE 11520 0.7237 0.4447 -0.5278 0.0065
*CONTROL_ROT_SAMPLE 11680 0.8331 0.5149 -0.2022 0.0085
*CONTROL_ROT_SAMPLE 11840 0.8323 0.5164 -0.2018 0.0085
*CONTROL_ROT_SAMPLE 12000 0.8493 0.5279 0.0000 0.0111
*CONTROL_ROT_SAMPLE 12160 0.8280 0.5132 0.2259 0.0114
*CONTROL_ROT_SAMPLE 12320 0.8246 0.5072 0.2505 0.0172
*CONTROL_ROT_SAMPLE 12480 0.7576 0.4615 0.4615 0.0094
*CONTROL_ROT_SAMPLE 12640 0.8170 0.4928 0.2994 0.0145
*CONTROL_ROT_SAMPLE 12800 0.7766 0.4620 0.4284 0.0184
*CONTROL_ROT_SAMPLE 12960 0.7014 0.4098 0.5832 0.0137
*CONTROL_ROT_SAMPLE 13120 0.8156 0.4678 0.3406 0.0236
*CONTROL_ROT_SAMPLE 13280 0.8695 0.4940 0.0000 0.0222
*CONTROL_ROT_SAMPLE 13440 0.8695 0.4940 0.0000 0.0277
*CONTROL_ROT_SAMPLE 13600 0.8695 0.4940 -0.0000 0.0416
*CONTROL_ROT_SAMPLE 13760 0.8695 0.4940 0.0000 0.0583
*CONTROL_ROT_SAMPLE 13920 0.8695 0.4940 0.0000 0.0361
*CONTROL_ROT_SAMPLE 14080 0.8695 0.4940 0.0000 0.0527
*CONTROL_ROT_SAMPLE 14240 0.8695 0.4940 -0.0000 0.0361
*CONTROL_ROT_SAMPLE 14400 0.8695 0.4940 0.0000 0.0444
*CONTROL_ROT_SAMPLE 14560 0.8695 0.4940 -0.0000 0.0333
}
}
*TM_ANIMATION {
*NODE_NAME "Camera01.Target"
*CONTROL_POS_TRACK {
*CONTROL_POS_SAMPLE 0 46.1410 66.9139 0.0000
*CONTROL_POS_SAMPLE 1120 46.1410 67.2318 0.0000
*CONTROL_POS_SAMPLE 1280 46.1410 67.7086 0.0000
*CONTROL_POS_SAMPLE 1440 46.1410 68.3444 0.0000
*CONTROL_POS_SAMPLE 1600 46.1410 68.8212 0.0000
*CONTROL_POS_SAMPLE 1760 46.1410 69.6159 0.0000
*CONTROL_POS_SAMPLE 1920 46.1410 69.9338 0.0000
*CONTROL_POS_SAMPLE 2080 46.1410 71.0464 0.0000
*CONTROL_POS_SAMPLE 2240 46.1410 71.6821 0.0000
*CONTROL_POS_SAMPLE 2400 46.1410 72.3974 0.0000
*CONTROL_POS_SAMPLE 2560 46.1410 73.1126 0.0000
*CONTROL_POS_SAMPLE 2720 46.1410 73.7484 0.0000
*CONTROL_POS_SAMPLE 2880 46.1410 74.8609 0.0000
*CONTROL_POS_SAMPLE 3040 46.1410 75.4967 0.0000
*CONTROL_POS_SAMPLE 3200 46.1410 76.7682 0.0000
*CONTROL_POS_SAMPLE 3360 46.1410 77.8808 0.0000
*CONTROL_POS_SAMPLE 3520 46.1410 79.9470 0.0000
*CONTROL_POS_SAMPLE 3680 46.1410 82.4901 0.0000
*CONTROL_POS_SAMPLE 3840 46.1410 84.3974 0.0000
*CONTROL_POS_SAMPLE 4000 46.1410 83.9205 0.0000
*CONTROL_POS_SAMPLE 4160 46.1410 83.2848 0.0000
*CONTROL_POS_SAMPLE 4320 46.1410 82.8080 0.0000
*CONTROL_POS_SAMPLE 4480 46.1410 82.1722 0.0000
*CONTROL_POS_SAMPLE 4640 46.1410 81.6954 0.0000
*CONTROL_POS_SAMPLE 4800 46.1410 80.7417 0.0000
*CONTROL_POS_SAMPLE 4960 46.1410 79.9470 0.0000
*CONTROL_POS_SAMPLE 5120 46.1410 79.4702 0.0000
*CONTROL_POS_SAMPLE 5280 46.1410 78.6755 0.0000
*CONTROL_POS_SAMPLE 5440 46.1410 78.3576 0.0000
*CONTROL_POS_SAMPLE 5600 46.1410 77.7219 0.0000
*CONTROL_POS_SAMPLE 5760 46.1410 77.2450 0.0000
*CONTROL_POS_SAMPLE 5920 46.1410 76.2914 0.0000
*CONTROL_POS_SAMPLE 6080 46.1410 74.7020 0.0000
*CONTROL_POS_SAMPLE 6240 46.1410 72.3179 0.0000
*CONTROL_POS_SAMPLE 6400 46.1410 69.7748 0.0000
*CONTROL_POS_SAMPLE 6560 46.1410 66.4371 0.0000
*CONTROL_POS_SAMPLE 6720 46.1410 64.5298 0.0000
*CONTROL_POS_SAMPLE 6880 46.1410 63.7351 0.0000
*CONTROL_POS_SAMPLE 7200 46.1410 64.2119 0.0000
*CONTROL_POS_SAMPLE 7360 46.1410 64.6887 0.0000
*CONTROL_POS_SAMPLE 7520 46.1410 65.0066 0.0000
*CONTROL_POS_SAMPLE 7680 46.1410 65.2318 0.0000
*CONTROL_POS_SAMPLE 7840 46.1410 65.4834 0.0000
*CONTROL_POS_SAMPLE 8000 46.1410 65.9603 0.0000
*CONTROL_POS_SAMPLE 8160 46.1410 66.4371 0.0000
*CONTROL_POS_SAMPLE 8320 46.1410 66.9139 0.0000
*CONTROL_POS_SAMPLE 8480 46.1410 67.1391 0.0000
*CONTROL_POS_SAMPLE 8640 46.1410 67.3907 0.0000
*CONTROL_POS_SAMPLE 8800 46.1410 68.0265 0.0000
*CONTROL_POS_SAMPLE 8960 46.1410 68.5033 0.0000
*CONTROL_POS_SAMPLE 9120 46.1410 68.9801 0.0000
*CONTROL_POS_SAMPLE 9280 46.1410 69.4570 0.0000
*CONTROL_POS_SAMPLE 9440 46.1410 70.0927 0.0000
*CONTROL_POS_SAMPLE 9600 46.1410 70.4106 0.0000
*CONTROL_POS_SAMPLE 9760 46.1410 70.7285 0.0000
*CONTROL_POS_SAMPLE 9920 46.1410 71.2053 0.0000
*CONTROL_POS_SAMPLE 10080 46.1410 71.6821 0.0000
*CONTROL_POS_SAMPLE 10240 46.1410 72.7947 0.0000
*CONTROL_POS_SAMPLE 10400 46.1410 73.5894 0.0000
*CONTROL_POS_SAMPLE 10560 46.1410 75.0199 0.0000
*CONTROL_POS_SAMPLE 10720 46.1410 77.0861 0.0000
*CONTROL_POS_SAMPLE 10880 46.1410 78.5166 0.0000
*CONTROL_POS_SAMPLE 11040 46.1410 79.7881 0.0000
*CONTROL_POS_SAMPLE 11200 46.1410 80.9007 0.0000
*CONTROL_POS_SAMPLE 11360 46.1410 81.5364 0.0000
*CONTROL_POS_SAMPLE 11520 46.1410 82.1722 0.0000
*CONTROL_POS_SAMPLE 11680 46.1410 82.4901 0.0000
*CONTROL_POS_SAMPLE 11840 46.1410 82.8080 0.0000
*CONTROL_POS_SAMPLE 12160 46.1410 82.3311 0.0000
*CONTROL_POS_SAMPLE 12320 46.1410 81.5364 0.0000
*CONTROL_POS_SAMPLE 12480 46.1410 80.7417 0.0000
*CONTROL_POS_SAMPLE 12640 46.1410 79.9470 0.0000
*CONTROL_POS_SAMPLE 12800 46.1410 78.5166 0.0000
*CONTROL_POS_SAMPLE 12960 46.1410 77.0861 0.0000
*CONTROL_POS_SAMPLE 13120 46.1410 75.6556 0.0000
}
}
}
*LIGHTOBJECT {
*NODE_NAME "FDirect01"
*LIGHT_TYPE Directional
*NODE_TM {
*NODE_NAME "FDirect01"
*INHERIT_POS 0 0 0
*INHERIT_ROT 0 0 0
*INHERIT_SCL 0 0 0
*TM_ROW0 1.0000 0.0000 0.0000
*TM_ROW1 0.0000 0.5278 0.8493
*TM_ROW2 0.0000 -0.8493 0.5278
*TM_ROW3 83.8439 1.3881 51.1261
*TM_POS 83.8439 1.3881 51.1261
*TM_ROTAXIS -1.0000 -0.0000 -0.0000
*TM_ROTANGLE 1.0147
*TM_SCALE 1.0000 1.0000 1.0000
*TM_SCALEAXIS 0.0000 0.0000 0.0000
*TM_SCALEAXISANG 0.0000
}
*LIGHT_SHADOWS Off
*LIGHT_USELIGHT 1
*LIGHT_SPOTSHAPE Circle
*LIGHT_USEGLOBAL 0
*LIGHT_ABSMAPBIAS 0
*LIGHT_OVERSHOOT 0
*LIGHT_SETTINGS {
*TIMEVALUE 0
*LIGHT_COLOR 1.0000 1.0000 1.0000
*LIGHT_INTENS 1.0000
*LIGHT_ASPECT 1.0000
*LIGHT_HOTSPOT 43.0000
*LIGHT_FALLOFF 45.0000
*LIGHT_TDIST 240.0000
*LIGHT_MAPBIAS 1.0000
*LIGHT_MAPRANGE 4.0000
*LIGHT_MAPSIZE 512
*LIGHT_RAYBIAS 0.0000
}
}
*LIGHTOBJECT {
*NODE_NAME "FDirect02"
*LIGHT_TYPE Directional
*NODE_TM {
*NODE_NAME "FDirect02"
*INHERIT_POS 0 0 0
*INHERIT_ROT 0 0 0
*INHERIT_SCL 0 0 0
*TM_ROW0 1.0000 0.0000 0.0000
*TM_ROW1 0.0000 -0.1220 0.9925
*TM_ROW2 0.0000 -0.9925 -0.1220
*TM_ROW3 -20.7843 -45.6140 0.0000
*TM_POS -20.7843 -45.6140 0.0000
*TM_ROTAXIS -1.0000 -0.0000 -0.0000
*TM_ROTANGLE 1.6931
*TM_SCALE 1.0000 1.0000 1.0000
*TM_SCALEAXIS 0.0000 0.0000 0.0000
*TM_SCALEAXISANG 0.0000
}
*LIGHT_SHADOWS Off
*LIGHT_USELIGHT 1
*LIGHT_SPOTSHAPE Circle
*LIGHT_USEGLOBAL 0
*LIGHT_ABSMAPBIAS 0
*LIGHT_OVERSHOOT 0
*LIGHT_SETTINGS {
*TIMEVALUE 0
*LIGHT_COLOR 1.0000 1.0000 1.0000
*LIGHT_INTENS 1.0000
*LIGHT_ASPECT 1.0000
*LIGHT_HOTSPOT 43.0000
*LIGHT_FALLOFF 45.0000
*LIGHT_TDIST 240.0000
*LIGHT_MAPBIAS 1.0000
*LIGHT_MAPRANGE 4.0000
*LIGHT_MAPSIZE 512
*LIGHT_RAYBIAS 0.0000
}
}
*LIGHTOBJECT {
*NODE_NAME "Sky01"
*LIGHT_TYPE Free
*NODE_TM {
*NODE_NAME "Sky01"
*INHERIT_POS 0 0 0
*INHERIT_ROT 0 0 0
*INHERIT_SCL 0 0 0
*TM_ROW0 1.0000 0.0000 0.0000
*TM_ROW1 0.0000 1.0000 0.0000
*TM_ROW2 0.0000 0.0000 1.0000
*TM_ROW3 -38.5409 -85.6864 74.8710
*TM_POS -38.5409 -85.6864 74.8710
*TM_ROTAXIS 0.0000 0.0000 0.0000
*TM_ROTANGLE 0.0000
*TM_SCALE 1.0000 1.0000 1.0000
*TM_SCALEAXIS 0.0000 0.0000 0.0000
*TM_SCALEAXISANG 0.0000
}
*LIGHT_SHADOWS Raytraced
*LIGHT_USELIGHT 1
*LIGHT_SPOTSHAPE Circle
*LIGHT_USEGLOBAL 0
*LIGHT_ABSMAPBIAS 0
*LIGHT_OVERSHOOT 0
*LIGHT_SETTINGS {
*TIMEVALUE 0
*LIGHT_COLOR 0.9500 0.9500 1.0000
*LIGHT_INTENS 1.0000
*LIGHT_ASPECT 1.0000
*LIGHT_HOTSPOT 0.0000
*LIGHT_FALLOFF 0.0000
*LIGHT_TDIST 0.0000
*LIGHT_MAPBIAS 0.0000
*LIGHT_MAPRANGE 0.0000
*LIGHT_MAPSIZE 0
*LIGHT_RAYBIAS 0.0000
}
}

View File

@ -0,0 +1,23 @@
ply
format ascii 1.0
element vertex 8
property float32 x
property float32 y
property float32 z
element face 6
property list uint8 int32 vertex_index
end_header
0 0 0
0 0 1
0 1 1
0 1 0
1 0 0
1 0 1
1 1 1
1 1 0
4 0 1 2 3
4 7 6 5 4
4 0 4 5 1
4 1 5 6 2
4 2 6 7 3
4 3 7 4 0

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1989,8 +1989,9 @@ int CDisplay::RenderNode (aiNode* piNode,const aiMatrix4x4& piMatrix,
*tempmat++ = mat.b1; *tempmat++ = mat.b2; *tempmat++ = mat.b3; *tempmat++ = mat.b4; *tempmat++ = mat.b1; *tempmat++ = mat.b2; *tempmat++ = mat.b3; *tempmat++ = mat.b4;
*tempmat++ = mat.c1; *tempmat++ = mat.c2; *tempmat++ = mat.c3; *tempmat++ = mat.c4; *tempmat++ = mat.c1; *tempmat++ = mat.c2; *tempmat++ = mat.c3; *tempmat++ = mat.c4;
*tempmat++ = mat.d1; *tempmat++ = mat.d2; *tempmat++ = mat.d3; *tempmat++ = mat.d4; *tempmat++ = mat.d1; *tempmat++ = mat.d2; *tempmat++ = mat.d3; *tempmat++ = mat.d4;
//tempmat += 4;
} }
helper->piEffect->SetMatrixArray( "gBoneMatrix", (D3DXMATRIX*)matrices, 60); helper->piEffect->SetMatrixTransposeArray( "gBoneMatrix", (D3DXMATRIX*)matrices, 60);
} }
// now setup the material // now setup the material

View File

@ -224,7 +224,7 @@ void SceneAnimator::CalculateGlobalTransform( SceneAnimNode* pInternalNode)
SceneAnimNode* node = pInternalNode->mParent; SceneAnimNode* node = pInternalNode->mParent;
while( node) while( node)
{ {
pInternalNode->mGlobalTransform *= node->mLocalTransform; pInternalNode->mGlobalTransform = pInternalNode->mGlobalTransform * node->mLocalTransform;
node = node->mParent; node = node->mParent;
} }
} }

View File

@ -608,13 +608,14 @@ std::string g_szMaterialShader = std::string(
"{\n" "{\n"
"float3 Position : POSITION;\n" "float3 Position : POSITION;\n"
"float3 Normal : NORMAL;\n" "float3 Normal : NORMAL;\n"
"float3 Tangent : TEXCOORD0;\n" "float4 Color : COLOR0;\n"
"float3 Bitangent : TEXCOORD1;\n" "float3 Tangent : TANGENT;\n"
"float2 TexCoord0 : TEXCOORD2;\n" "float3 Bitangent : BINORMAL;\n"
// "#ifdef AV_SKINNING \n" "float2 TexCoord0 : TEXCOORD0;\n"
"#ifdef AV_SKINNING \n"
"float4 BlendIndices : BLENDINDICES;\n" "float4 BlendIndices : BLENDINDICES;\n"
"float4 BlendWeights : BLENDWEIGHT;\n" "float4 BlendWeights : BLENDWEIGHT;\n"
// "#endif // AV_SKINNING \n" "#endif // AV_SKINNING \n"
"};\n" "};\n"
// Vertex shader output structure for pixel shader usage // Vertex shader output structure for pixel shader usage
@ -623,6 +624,8 @@ std::string g_szMaterialShader = std::string(
"float4 Position : POSITION;\n" "float4 Position : POSITION;\n"
"float3 ViewDir : TEXCOORD0;\n" "float3 ViewDir : TEXCOORD0;\n"
"float4 Color : COLOR0;\n"
"#ifndef AV_NORMAL_TEXTURE\n" "#ifndef AV_NORMAL_TEXTURE\n"
"float3 Normal : TEXCOORD1;\n" "float3 Normal : TEXCOORD1;\n"
"#endif\n" "#endif\n"
@ -706,6 +709,7 @@ std::string g_szMaterialShader = std::string(
"Out.Position = mul( float4( objPos, 1.0f), WorldViewProjection);\n" "Out.Position = mul( float4( objPos, 1.0f), WorldViewProjection);\n"
"float3 WorldPos = mul( float4( objPos, 1.0f), World);\n" "float3 WorldPos = mul( float4( objPos, 1.0f), World);\n"
"Out.TexCoord0 = IN.TexCoord0;\n" "Out.TexCoord0 = IN.TexCoord0;\n"
"Out.Color = IN.Color;\n"
"#ifndef AV_NORMAL_TEXTURE\n" "#ifndef AV_NORMAL_TEXTURE\n"
"Out.ViewDir = vCameraPos - WorldPos;\n" "Out.ViewDir = vCameraPos - WorldPos;\n"
@ -741,6 +745,7 @@ std::string g_szMaterialShader = std::string(
"Out.Position = mul( float4( objPos, 1.0f), WorldViewProjection);\n" "Out.Position = mul( float4( objPos, 1.0f), WorldViewProjection);\n"
"float3 WorldPos = mul( float4( objPos, 1.0f), World);\n" "float3 WorldPos = mul( float4( objPos, 1.0f), World);\n"
"Out.TexCoord0 = IN.TexCoord0;\n" "Out.TexCoord0 = IN.TexCoord0;\n"
"Out.Color = IN.Color;\n"
"#ifndef AV_NORMAL_TEXTURE\n" "#ifndef AV_NORMAL_TEXTURE\n"
"Out.ViewDir = vCameraPos - WorldPos;\n" "Out.ViewDir = vCameraPos - WorldPos;\n"
@ -832,9 +837,9 @@ std::string g_szMaterialShader = std::string(
"#endif\n" "#endif\n"
"float fHalfLambert = L1*L1;\n" "float fHalfLambert = L1*L1;\n"
"#ifdef AV_DIFFUSE_TEXTURE\n" "#ifdef AV_DIFFUSE_TEXTURE\n"
"OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * tex2D(DIFFUSE_SAMPLER,IN.TexCoord0).rgb * fHalfLambert +\n" "OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * tex2D(DIFFUSE_SAMPLER,IN.TexCoord0).rgb * fHalfLambert * IN.Color.rgb +\n"
"#else\n" "#else\n"
"OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * fHalfLambert +\n" "OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * fHalfLambert * IN.Color.rgb +\n"
"#endif // !AV_DIFFUSE_TEXTURE\n" "#endif // !AV_DIFFUSE_TEXTURE\n"
"#ifdef AV_SPECULAR_COMPONENT\n" "#ifdef AV_SPECULAR_COMPONENT\n"
@ -904,9 +909,9 @@ std::string g_szMaterialShader = std::string(
"float fHalfLambert = L1*L1;\n" "float fHalfLambert = L1*L1;\n"
"#ifdef AV_DIFFUSE_TEXTURE\n" "#ifdef AV_DIFFUSE_TEXTURE\n"
"OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * tex2D(DIFFUSE_SAMPLER,IN.TexCoord0).rgb * fHalfLambert +\n" "OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * tex2D(DIFFUSE_SAMPLER,IN.TexCoord0).rgb * fHalfLambert * IN.Color.rgb +\n"
"#else\n" "#else\n"
"OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * fHalfLambert +\n" "OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * fHalfLambert * IN.Color.rgb +\n"
"#endif // !AV_DIFFUSE_TEXTURE\n" "#endif // !AV_DIFFUSE_TEXTURE\n"
"#ifdef AV_SPECULAR_COMPONENT\n" "#ifdef AV_SPECULAR_COMPONENT\n"
@ -945,9 +950,9 @@ std::string g_szMaterialShader = std::string(
"#endif\n" "#endif\n"
"float fHalfLambert = L1*L1;\n" "float fHalfLambert = L1*L1;\n"
"#ifdef AV_DIFFUSE_TEXTURE\n" "#ifdef AV_DIFFUSE_TEXTURE\n"
"OUT.rgb += afLightColor[1].rgb * DIFFUSE_COLOR.rgb * tex2D(DIFFUSE_SAMPLER,IN.TexCoord0).rgb * fHalfLambert +\n" "OUT.rgb += afLightColor[1].rgb * DIFFUSE_COLOR.rgb * tex2D(DIFFUSE_SAMPLER,IN.TexCoord0).rgb * fHalfLambert * IN.Color.rgb +\n"
"#else\n" "#else\n"
"OUT.rgb += afLightColor[1].rgb * DIFFUSE_COLOR.rgb * fHalfLambert +\n" "OUT.rgb += afLightColor[1].rgb * DIFFUSE_COLOR.rgb * fHalfLambert * IN.Color.rgb +\n"
"#endif // !AV_DIFFUSE_TEXTURE\n" "#endif // !AV_DIFFUSE_TEXTURE\n"
"#ifdef AV_SPECULAR_COMPONENT\n" "#ifdef AV_SPECULAR_COMPONENT\n"

View File

@ -561,7 +561,7 @@ int CreateAssetData()
((unsigned char)std::max( std::min( mesh->mColors[0][x].g * 255.0f, 255.0f),0.0f)), ((unsigned char)std::max( std::min( mesh->mColors[0][x].g * 255.0f, 255.0f),0.0f)),
((unsigned char)std::max( std::min( mesh->mColors[0][x].b * 255.0f, 255.0f),0.0f))); ((unsigned char)std::max( std::min( mesh->mColors[0][x].b * 255.0f, 255.0f),0.0f)));
} }
else pbData2->dColorDiffuse = D3DCOLOR_ARGB(0xFF,0,0,0); else pbData2->dColorDiffuse = D3DCOLOR_ARGB(0xFF,0xff,0xff,0xff);
// ignore a third texture coordinate component // ignore a third texture coordinate component
if (mesh->HasTextureCoords( 0)) if (mesh->HasTextureCoords( 0))
@ -570,7 +570,7 @@ int CreateAssetData()
mesh->mTextureCoords[0][x].x, mesh->mTextureCoords[0][x].x,
mesh->mTextureCoords[0][x].y); mesh->mTextureCoords[0][x].y);
} }
else pbData2->vTextureUV = aiVector2D(0.0f,0.0f); else pbData2->vTextureUV = aiVector2D(0.5f,0.5f);
// Bone indices and weights // Bone indices and weights
if( mesh->HasBones()) if( mesh->HasBones())

View File

@ -847,6 +847,14 @@
RelativePath="..\..\code\SGSpatialSort.h" RelativePath="..\..\code\SGSpatialSort.h"
> >
</File> </File>
<File
RelativePath="..\..\code\SkeletonMeshBuilder.cpp"
>
</File>
<File
RelativePath="..\..\code\SkeletonMeshBuilder.h"
>
</File>
<File <File
RelativePath="..\..\code\SmoothingGroups.h" RelativePath="..\..\code\SmoothingGroups.h"
> >
@ -1374,6 +1382,10 @@
> >
</File> </File>
</Filter> </Filter>
<Filter
Name="Q3D"
>
</Filter>
</Filter> </Filter>
<Filter <Filter
Name="PostProcess" Name="PostProcess"
@ -1594,10 +1606,6 @@
RelativePath="..\..\code\irrXML\CXMLReaderImpl.h" RelativePath="..\..\code\irrXML\CXMLReaderImpl.h"
> >
</File> </File>
<File
RelativePath="..\..\code\irrXML\fast_atof.h"
>
</File>
<File <File
RelativePath="..\..\code\irrXML\heapsort.h" RelativePath="..\..\code\irrXML\heapsort.h"
> >
@ -1732,14 +1740,6 @@
> >
</File> </File>
</Filter> </Filter>
<File
RelativePath="..\..\code\SkeletonMeshBuilder.cpp"
>
</File>
<File
RelativePath="..\..\code\SkeletonMeshBuilder.h"
>
</File>
</Files> </Files>
<Globals> <Globals>
</Globals> </Globals>