- Fixed a bug in FindInvalidData causing some animation channels to be lost

- Added Q3D loader. Seems to work quite well with Quick 3D 4.0
- Updated makefile, fixed GCC compilation error cause of packed matrix fields

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@214 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
pull/1/head
aramis_acg 2008-11-01 15:14:00 +00:00
parent c7e6fe3d73
commit daae32d62f
13 changed files with 760 additions and 26 deletions

View File

@ -666,7 +666,14 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut)
pcNode->mName = mScene->mLights[i]->mName;
}
}
else AddNodeToGraph(pcOut, pcOut->mRootNode, mRootNode);
else
{
// First of all: find out how many scaling, rotation and translation
// animation tracks we'll have afterwards
//unsigned int numRot = 0, numScale = 0, numTranslate = 0;
//CountTracks(mRootNode,numRot,numScale,numTranslate);
AddNodeToGraph(pcOut, pcOut->mRootNode, mRootNode);
}
// We used the first vertex color set to store some
// temporary values, so we need to cleanup here

View File

@ -273,14 +273,14 @@ int FindInvalidDataProcess::ProcessAnimation (aiAnimation* anim)
int FindInvalidDataProcess::ProcessAnimationChannel (aiNodeAnim* anim)
{
// TODO: (thom) For some reason, even proper channels are deleted as well. Therefore deactivated it for the moment.
return 0;
//return 0;
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)))
if ((anim->mNumPositionKeys < 1 || AllIdentical(anim->mPositionKeys,anim->mNumPositionKeys)) &&
(anim->mNumScalingKeys < 1 || AllIdentical(anim->mRotationKeys,anim->mNumRotationKeys)) &&
(anim->mNumRotationKeys < 1 || AllIdentical(anim->mScalingKeys,anim->mNumScalingKeys)))
{
DefaultLogger::get()->error("Deleting dummy position animation channel");
return 1;

View File

@ -122,9 +122,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_BUILD_NO_IRR_IMPORTER
# include "IRRLoader.h"
#endif
//#ifndef AI_BUILD_NO_Q3D_IMPORTER
//# include "Q3DLoader.h"
//#endif
#ifndef AI_BUILD_NO_Q3D_IMPORTER
# include "Q3DLoader.h"
#endif
// PostProcess-Steps
@ -278,9 +278,9 @@ Importer::Importer() :
#if (!defined AI_BUILD_NO_IRR_IMPORTER)
mImporter.push_back( new IRRImporter());
#endif
//#if (!defined AI_BUILD_NO_Q3D_IMPORTER)
// mImporter.push_back( new Q3DImporter());
//#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
// of sequence it is executed. steps that are added here are not validated -

View File

@ -144,8 +144,8 @@ struct Frame
*/
struct TexCoord
{
int16_t s;
int16_t t;
uint16_t s;
uint16_t t;
} PACK_STRUCT;
// ---------------------------------------------------------------------------

View File

@ -414,7 +414,7 @@ void MD2Importer::InternReadFile( const std::string& pFile,
// the texture coordinates are absolute values but we
// need relative values between 0 and 1
pcOut.x = pcTexCoords[iIndex].s / fDivisorU;
pcOut.y = 1.f- pcTexCoords[iIndex].t / fDivisorV;
pcOut.y = 1.f - pcTexCoords[iIndex].t / fDivisorV;
}
}
// FIX: flip the face order for use with OpenGL

577
code/Q3DLoader.cpp 100644
View File

@ -0,0 +1,577 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (ASSIMP)
---------------------------------------------------------------------------
Copyright (c) 2006-2008, ASSIMP Development Team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the ASSIMP team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the ASSIMP Development Team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
/** @file Implementation of the Q3D importer class */
#include "AssimpPCH.h"
// internal headers
#include "Q3DLoader.h"
#include "StreamReader.h"
#include "fast_atof.h"
using namespace Assimp;
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
Q3DImporter::Q3DImporter()
{
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
Q3DImporter::~Q3DImporter()
{
}
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool Q3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler) const
{
// simple check of file extension is enough for the moment
std::string::size_type pos = pFile.find_last_of('.');
// no file extension - can't read
if( pos == std::string::npos)return false;
std::string extension = pFile.substr( pos);
for (std::string::iterator it = extension.begin();
it != extension.end(); ++it)
*it = ::tolower(*it);
return (extension == ".q3o" || extension == ".q3s");
}
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void Q3DImporter::InternReadFile( const std::string& pFile,
aiScene* pScene, IOSystem* pIOHandler)
{
StreamReaderLE stream(pIOHandler->Open(pFile,"rb"));
// The header is 22 bytes large
if (stream.GetRemainingSize() < 22)
throw new ImportErrorException("File is either empty or corrupt: " + pFile);
// Check the file signature
if (ASSIMP_strincmp( (const char*)stream.GetPtr(), "quick3Do", 8 ) &&
ASSIMP_strincmp( (const char*)stream.GetPtr(), "quick3Ds", 8 ))
{
throw new ImportErrorException("No Quick3D file. Signature is: " +
std::string((const char*)stream.GetPtr(),8));
}
// Print the file format version
DefaultLogger::get()->info("Quick3D File format version: " +
std::string(&((const char*)stream.GetPtr())[8],2));
// ... an store it
unsigned int ff = strtol10(&((const char*)stream.GetPtr())[8]);
stream.IncPtr(10);
unsigned int numMeshes = (unsigned int)stream.GetI4();
unsigned int numMats = (unsigned int)stream.GetI4();
unsigned int numTextures = (unsigned int)stream.GetI4();
std::vector<Material> materials;
materials.reserve(numMats);
std::vector<Mesh> meshes;
meshes.reserve(numMeshes);
// Allocate the scene root node
pScene->mRootNode = new aiNode();
aiColor3D fgColor (0.6f,0.6f,0.6f);
// Now read all file chunks
while (true)
{
if (stream.GetRemainingSize() < 1)break;
char c = stream.GetI1();
switch (c)
{
// Meshes chunk
case 'm':
{
for (unsigned int quak = 0; quak < numMeshes; ++quak)
{
meshes.push_back(Mesh());
Mesh& mesh = meshes.back();
// read all vertices
unsigned int numVerts = (unsigned int)stream.GetI4();
if (!numVerts)
throw new ImportErrorException("Quick3D: Found mesh with zero vertices");
std::vector<aiVector3D>& verts = mesh.verts;
verts.resize(numVerts);
for (unsigned int i = 0; i < numVerts;++i)
{
verts[i].x = stream.GetF4();
verts[i].y = stream.GetF4();
verts[i].z = stream.GetF4();
}
// read all faces
numVerts = (unsigned int)stream.GetI4();
if (!numVerts)
throw new ImportErrorException("Quick3D: Found mesh with zero faces");
std::vector<Face >& faces = mesh.faces;
faces.reserve(numVerts);
// number of indices
for (unsigned int i = 0; i < numVerts;++i)
{
faces.push_back(Face(stream.GetI2()) );
if (faces.back().indices.empty())
throw new ImportErrorException("Quick3D: Found face with zero indices");
}
// indices
for (unsigned int i = 0; i < numVerts;++i)
{
Face& vec = faces[i];
for (unsigned int a = 0; a < (unsigned int)vec.indices.size();++a)
vec.indices[a] = stream.GetI4();
}
// material indices
for (unsigned int i = 0; i < numVerts;++i)
{
faces[i].mat = (unsigned int)stream.GetI4();
}
// read all normals
numVerts = (unsigned int)stream.GetI4();
std::vector<aiVector3D>& normals = mesh.normals;
normals.resize(numVerts);
for (unsigned int i = 0; i < numVerts;++i)
{
normals[i].x = stream.GetF4();
normals[i].y = stream.GetF4();
normals[i].z = stream.GetF4();
}
if (numTextures)
{
// read all texture coordinates
numVerts = (unsigned int)stream.GetI4();
std::vector<aiVector3D>& uv = mesh.uv;
uv.resize(numVerts);
for (unsigned int i = 0; i < numVerts;++i)
{
uv[i].x = stream.GetF4();
uv[i].y = stream.GetF4();
}
// UV indices
for (unsigned int i = 0; i < (unsigned int)faces.size();++i)
{
Face& vec = faces[i];
for (unsigned int a = 0; a < (unsigned int)vec.indices.size();++a)
{
vec.indices[a] = stream.GetI4();
if (!i && !a)
mesh.prevUVIdx = vec.indices[a];
else if (vec.indices[a] != mesh.prevUVIdx)
mesh.prevUVIdx = 0xffffffff;
}
}
}
// we don't need the rest, but we need to get to the next chunk
stream.IncPtr(36 + ((ff > 30 ? 12 : 0 )));
}
stream.IncPtr(4 + (ff > 30 ? 24 : 0 )); // unknown value here
}
break;
// materials chunk
case 'c':
for (unsigned int i = 0; i < numMats; ++i)
{
materials.push_back(Material());
Material& mat = materials.back();
// read the material name
while (( c = stream.GetI1()))
mat.name.data[mat.name.length++] = c;
// add the terminal character
mat.name.data[mat.name.length] = '\0';
// read the ambient color
mat.ambient.r = stream.GetF4();
mat.ambient.g = stream.GetF4();
mat.ambient.b = stream.GetF4();
// read the diffuse color
mat.diffuse.r = stream.GetF4();
mat.diffuse.g = stream.GetF4();
mat.diffuse.b = stream.GetF4();
// read the ambient color
mat.specular.r = stream.GetF4();
mat.specular.g = stream.GetF4();
mat.specular.b = stream.GetF4();
// read the transparency
mat.transparency = stream.GetF4();
// unknown value here
stream.IncPtr(4);
}
break;
// texture chunk
case 't':
pScene->mNumTextures = numTextures;
if (!numTextures)break;
pScene->mTextures = new aiTexture*[pScene->mNumTextures];
// to make sure we won't crash if we leave through an exception
::memset(pScene->mTextures,0,sizeof(void*)*pScene->mNumTextures);
for (unsigned int i = 0; i < pScene->mNumTextures; ++i)
{
aiTexture* tex = pScene->mTextures[i] = new aiTexture();
// skip the texture name
while (stream.GetI1());
// read texture width and height
tex->mWidth = (unsigned int)stream.GetI4();
tex->mHeight = (unsigned int)stream.GetI4();
if (!tex->mWidth || !tex->mHeight)
throw new ImportErrorException("Quick3D: Invalid texture. Width or height is zero");
register unsigned int mul = tex->mWidth * tex->mHeight;
aiTexel* begin = tex->pcData = new aiTexel[mul];
aiTexel* const end = & begin [mul];
for (;begin != end; ++begin)
{
begin->r = stream.GetI1();
begin->g = stream.GetI1();
begin->b = stream.GetI1();
begin->a = 0xff;
}
}
break;
// scene chunk
case 's':
{
// skip position and rotation
stream.IncPtr(12);
for (unsigned int i = 0; i < 4;++i)
for (unsigned int a = 0; a < 4;++a)
pScene->mRootNode->mTransformation[i][a] = stream.GetF4();
stream.IncPtr(16);
// now setup a single camera
pScene->mNumCameras = 1;
pScene->mCameras = new aiCamera*[1];
aiCamera* cam = pScene->mCameras[0] = new aiCamera();
cam->mPosition.x = stream.GetF4();
cam->mPosition.y = stream.GetF4();
cam->mPosition.z = stream.GetF4();
cam->mName.Set("Q3DCamera");
// skip eye rotation for the moment
stream.IncPtr(12);
// read the default material color
fgColor .r = stream.GetF4();
fgColor .g = stream.GetF4();
fgColor .b = stream.GetF4();
// skip some unimportant properties
stream.IncPtr(29);
// setup a single point light with no attenuation
pScene->mNumLights = 1;
pScene->mLights = new aiLight*[1];
aiLight* light = pScene->mLights[0] = new aiLight();
light->mName.Set("Q3DLight");
light->mType = aiLightSource_POINT;
light->mAttenuationConstant = 1;
light->mAttenuationLinear = 0;
light->mAttenuationQuadratic = 0;
light->mColorDiffuse.r = stream.GetF4();
light->mColorDiffuse.g = stream.GetF4();
light->mColorDiffuse.b = stream.GetF4();
light->mColorSpecular = light->mColorDiffuse;
// We don't need the rest, but we need to know where
// this fucking chunk ends.
unsigned int temp = (unsigned int)(stream.GetI4() * stream.GetI4());
// skip the background file name
while (stream.GetI1());
// skip background texture data + the remaining fields
stream.IncPtr(temp*3 + 20); // 4 bytes of unknown data here
// TODO
goto outer;
}
break;
default:
throw new ImportErrorException("Quick3D: Unknown chunk");
break;
};
}
outer:
// If we have no mesh loaded - break here
if (meshes.empty())
throw new ImportErrorException("Quick3D: No meshes loaded");
// If we have no materials loaded - generate a default mat
if (materials.empty())
{
DefaultLogger::get()->info("Quick3D: No material found, generating one");
materials.push_back(Material());
materials.back().diffuse = fgColor ;
}
// find out which materials we'll need
typedef std::pair<unsigned int, unsigned int> FaceIdx;
typedef std::vector< FaceIdx > FaceIdxArray;
FaceIdxArray* fidx = new FaceIdxArray[materials.size()];
unsigned int p = 0;
for (std::vector<Mesh>::iterator it = meshes.begin(), end = meshes.end();
it != end; ++it,++p)
{
unsigned int q = 0;
for (std::vector<Face>::iterator fit = (*it).faces.begin(), fend = (*it).faces.end();
fit != fend; ++fit,++q)
{
if ((*fit).mat >= materials.size())
{
DefaultLogger::get()->warn("Quick3D: Material index overflow");
(*fit).mat = 0;
}
if (fidx[(*fit).mat].empty())++pScene->mNumMeshes;
fidx[(*fit).mat].push_back( FaceIdx(p,q) );
}
}
pScene->mNumMaterials = pScene->mNumMeshes;
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
pScene->mMeshes = new aiMesh*[pScene->mNumMaterials];
for (unsigned int i = 0, real = 0; i < (unsigned int)materials.size(); ++i)
{
if (fidx[i].empty())continue;
// Allocate a mesh and a material
aiMesh* mesh = pScene->mMeshes[real] = new aiMesh();
MaterialHelper* mat = new MaterialHelper();
pScene->mMaterials[real] = mat;
mesh->mMaterialIndex = real;
// Build the output material
Material& srcMat = materials[i];
mat->AddProperty(&srcMat.diffuse, 1,AI_MATKEY_COLOR_DIFFUSE);
mat->AddProperty(&srcMat.specular, 1,AI_MATKEY_COLOR_SPECULAR);
mat->AddProperty(&srcMat.ambient, 1,AI_MATKEY_COLOR_AMBIENT);
//srcMat.transparency = 1.0f - srcMat.transparency;
mat->AddProperty(&srcMat.transparency, 1, AI_MATKEY_OPACITY);
// add shininess - Quick3D seems to use it ins its viewer
srcMat.transparency = 16.f;
mat->AddProperty(&srcMat.transparency, 1, AI_MATKEY_SHININESS);
int m = (int)aiShadingMode_Phong;
mat->AddProperty(&m, 1, AI_MATKEY_SHADING_MODEL);
if (srcMat.name.length)
mat->AddProperty(&srcMat.name,AI_MATKEY_NAME);
// Add a texture
if (real < pScene->mNumTextures)
{
srcMat.name.data[0] = '*';
srcMat.name.length = itoa10(&srcMat.name.data[1],1000,real);
mat->AddProperty(&srcMat.name,AI_MATKEY_TEXTURE_DIFFUSE(0));
}
mesh->mNumFaces = (unsigned int)fidx[i].size();
aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces];
// Now build the output mesh. First find out how many
// vertices we'll need
for (FaceIdxArray::const_iterator it = fidx[i].begin(),end = fidx[i].end();
it != end; ++it)
{
mesh->mNumVertices += (unsigned int)meshes[(*it).first].faces[
(*it).second].indices.size();
}
aiVector3D* verts = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
aiVector3D* norms = mesh->mNormals = new aiVector3D[mesh->mNumVertices];
aiVector3D* uv;
if (real < pScene->mNumTextures)
{
uv = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
mesh->mNumUVComponents[0] = 2;
}
else uv = NULL;
// Build the final array
unsigned int cnt = 0;
for (FaceIdxArray::const_iterator it = fidx[i].begin(),end = fidx[i].end();
it != end; ++it, ++faces)
{
Mesh& m = meshes[(*it).first];
Face& face = m.faces[(*it).second];
faces->mNumIndices = (unsigned int)face.indices.size();
faces->mIndices = new unsigned int [faces->mNumIndices];
aiVector3D faceNormal;
bool fnOK = false;
for (unsigned int n = 0; n < faces->mNumIndices;++n, ++cnt, ++norms, ++verts)
{
if (face.indices[n] >= m.verts.size())
{
DefaultLogger::get()->warn("Quick3D: Vertex index overflow");
face.indices[n] = 0;
}
// copy vertices
*verts = m.verts[ face.indices[n] ];
if (face.indices[n] >= m.normals.size() && faces->mNumIndices >= 3)
{
// we have no normal here - assign the face normal
if (!fnOK)
{
const aiVector3D& pV1 = m.verts[ face.indices[0] ];
const aiVector3D& pV2 = m.verts[ face.indices[1] ];
const aiVector3D& pV3 = m.verts[ face.indices.size() - 1 ];
faceNormal = (pV2 - pV1) ^ (pV3 - pV1).Normalize();
fnOK = true;
}
*norms = faceNormal;
}
else *norms = m.normals[ face.indices[n] ];
// copy texture coordinates
if (uv)
{
if (m.prevUVIdx != 0xffffffff && m.uv.size() >= m.verts.size()) // workaround
{
*uv++ = m.uv[face.indices[n]];
}
else
{
if (face.uvindices[n] >= m.uv.size())
{
DefaultLogger::get()->warn("Quick3D: Texture coordinate index overflow");
face.uvindices[n] = 0;
}
*uv++ = m.uv[face.uvindices[n]];
}
}
// setup the new vertex index
faces->mIndices[n] = cnt;
}
}
++real;
}
// Delete our nice helper array
delete[] fidx;
// Now we need to attach the meshes to the root node of the scene
pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
pScene->mRootNode->mMeshes = new unsigned int [pScene->mNumMeshes];
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
pScene->mRootNode->mMeshes[i] = i;
pScene->mRootNode->mTransformation *= aiMatrix4x4(
1.f, 0.f, 0.f, 0.f,
0.f, -1.f,0.f, 0.f,
0.f, 0.f, 1.f, 0.f,
0.f, 0.f, 0.f, 1.f);
// Add cameras and light sources to the scene root node
pScene->mRootNode->mNumChildren = pScene->mNumLights+pScene->mNumCameras;
if (pScene->mRootNode->mNumChildren)
{
pScene->mRootNode->mChildren = new aiNode* [ pScene->mRootNode->mNumChildren ];
// the light source
aiNode* nd = pScene->mRootNode->mChildren[0] = new aiNode();
nd->mParent = pScene->mRootNode;
nd->mName.Set("Q3DLight");
nd->mTransformation = pScene->mRootNode->mTransformation;
nd->mTransformation.Inverse();
// camera
nd = pScene->mRootNode->mChildren[1] = new aiNode();
nd->mParent = pScene->mRootNode;
nd->mName.Set("Q3DCamera");
nd->mTransformation = pScene->mRootNode->mChildren[0]->mTransformation;
}
}

132
code/Q3DLoader.h 100644
View File

@ -0,0 +1,132 @@
/*
Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------
Copyright (c) 2006-2008, ASSIMP Development Team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the
following conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the ASSIMP team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the ASSIMP Development Team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/** @file Declaration of the Q3D importer class. */
#ifndef AI_Q3DLOADER_H_INCLUDED
#define AI_Q3DLOADER_H_INCLUDED
#include "BaseImporter.h"
#include "../include/aiTypes.h"
#include <vector>
namespace Assimp {
// ---------------------------------------------------------------------------
/** Importer class for the Quick3D Object and Scene formats.
*/
class Q3DImporter : public BaseImporter
{
friend class Importer;
protected:
/** Constructor to be privately used by Importer */
Q3DImporter();
/** Destructor, private as well */
~Q3DImporter();
public:
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. */
bool CanRead( const std::string& pFile, IOSystem* pIOHandler) const;
protected:
// -------------------------------------------------------------------
/** Called by Importer::GetExtensionList() for each loaded importer.
* See BaseImporter::GetExtensionList() for details
*/
void GetExtensionList(std::string& append)
{
append.append("*.q3o;*.q3s");
}
// -------------------------------------------------------------------
/** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details
*/
void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler);
private:
struct Material
{
Material()
: diffuse (0.6f,0.6f,0.6f)
, transparency (0.f)
{}
aiString name;
aiColor3D ambient, diffuse, specular;
float transparency;
};
struct Face
{
Face(unsigned int s)
: indices (s)
, uvindices (s)
, mat (0)
{
}
std::vector<unsigned int> indices;
std::vector<unsigned int> uvindices;
unsigned int mat;
};
struct Mesh
{
std::vector<aiVector3D> verts;
std::vector<aiVector3D> normals;
std::vector<aiVector3D> uv;
std::vector<Face> faces;
uint32_t prevUVIdx;
};
};
} // end of namespace Assimp
#endif // AI_Q3DIMPORTER_H_IN

View File

@ -735,6 +735,12 @@ void ValidateDSProcess::Validate( const aiMaterial* pMaterial)
};
}
if (AI_SUCCESS == aiGetMaterialFloat( pMaterial,AI_MATKEY_OPACITY,&fTemp))
{
if (!fTemp)
ReportWarning("Material is fully transparent ... are you sure you REALLY want this?");
}
// check whether there are invalid texture keys
SearchForInvalidTextures(pMaterial,"diffuse");
SearchForInvalidTextures(pMaterial,"specular");

View File

@ -70,7 +70,8 @@ SOURCES = AssimpPCH.cpp \
XFileParser.cpp \
./irrXML/irrXML.cpp \
IRRMeshLoader.cpp \
IRRLoader.cpp
IRRLoader.cpp \
Q3DLoader.cpp
OBJECTS = $(SOURCES:.cpp=.o)

View File

@ -70,7 +70,8 @@ SOURCES = AssimpPCH.cpp \
BVHLoader.cpp \
./irrXML/irrXML.cpp \
IRRMeshLoader.cpp \
IRRLoader.cpp
IRRLoader.cpp \
Q3DLoader.cpp
OBJECTS = $(SOURCES:.cpp=.o)

View File

@ -44,9 +44,10 @@ inline aiMatrix3x3 aiMatrix3x3::operator* (const aiMatrix3x3& m) const
// ------------------------------------------------------------------------------------------------
inline aiMatrix3x3& aiMatrix3x3::Transpose()
{
std::swap( a2, b1);
std::swap( a3, c1);
std::swap( b3, c2);
// (float&) don't remove, GCC complains cause of packed fields
std::swap( (float&)a2, (float&)b1);
std::swap( (float&)a3, (float&)c1);
std::swap( (float&)b3, (float&)c2);
return *this;
}

View File

@ -58,12 +58,13 @@ inline aiMatrix4x4 aiMatrix4x4::operator* (const aiMatrix4x4& m) const
// ---------------------------------------------------------------------------
inline aiMatrix4x4& aiMatrix4x4::Transpose()
{
std::swap( b1, a2);
std::swap( c1, a3);
std::swap( c2, b3);
std::swap( d1, a4);
std::swap( d2, b4);
std::swap( d3, c4);
// (float&) don't remove, GCC complains cause of packed fields
std::swap( (float&)b1, (float&)a2);
std::swap( (float&)c1, (float&)a3);
std::swap( (float&)c2, (float&)b3);
std::swap( (float&)d1, (float&)a4);
std::swap( (float&)d2, (float&)b4);
std::swap( (float&)d3, (float&)c4);
return *this;
}

View File

@ -1385,6 +1385,14 @@
<Filter
Name="Q3D"
>
<File
RelativePath="..\..\code\Q3DLoader.cpp"
>
</File>
<File
RelativePath="..\..\code\Q3DLoader.h"
>
</File>
</Filter>
</Filter>
<Filter
@ -1631,7 +1639,7 @@
<Tool
Name="VCCLCompilerTool"
BasicRuntimeChecks="0"
SmallerTypeCheck="false"
SmallerTypeCheck="true"
UsePrecompiledHeader="0"
/>
</FileConfiguration>