- 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-9d2fd5bffc1fpull/1/head
parent
c7e6fe3d73
commit
daae32d62f
|
@ -666,7 +666,14 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut)
|
||||||
pcNode->mName = mScene->mLights[i]->mName;
|
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
|
// We used the first vertex color set to store some
|
||||||
// temporary values, so we need to cleanup here
|
// temporary values, so we need to cleanup here
|
||||||
|
|
|
@ -273,14 +273,14 @@ int FindInvalidDataProcess::ProcessAnimation (aiAnimation* anim)
|
||||||
int FindInvalidDataProcess::ProcessAnimationChannel (aiNodeAnim* anim)
|
int FindInvalidDataProcess::ProcessAnimationChannel (aiNodeAnim* anim)
|
||||||
{
|
{
|
||||||
// TODO: (thom) For some reason, even proper channels are deleted as well. Therefore deactivated it for the moment.
|
// 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;
|
int i = 0;
|
||||||
|
|
||||||
// Check whether all values are identical or whether there is just one keyframe
|
// Check whether all values are identical or whether there is just one keyframe
|
||||||
if ((1 >= anim->mNumPositionKeys || AllIdentical(anim->mPositionKeys,anim->mNumPositionKeys)) &&
|
if ((anim->mNumPositionKeys < 1 || AllIdentical(anim->mPositionKeys,anim->mNumPositionKeys)) &&
|
||||||
(1 >= anim->mNumScalingKeys || AllIdentical(anim->mRotationKeys,anim->mNumRotationKeys)) &&
|
(anim->mNumScalingKeys < 1 || AllIdentical(anim->mRotationKeys,anim->mNumRotationKeys)) &&
|
||||||
(1 >= anim->mNumRotationKeys || AllIdentical(anim->mScalingKeys,anim->mNumScalingKeys)))
|
(anim->mNumRotationKeys < 1 || AllIdentical(anim->mScalingKeys,anim->mNumScalingKeys)))
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->error("Deleting dummy position animation channel");
|
DefaultLogger::get()->error("Deleting dummy position animation channel");
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -122,9 +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
|
#ifndef AI_BUILD_NO_Q3D_IMPORTER
|
||||||
//# include "Q3DLoader.h"
|
# include "Q3DLoader.h"
|
||||||
//#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// PostProcess-Steps
|
// PostProcess-Steps
|
||||||
|
@ -278,9 +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)
|
#if (!defined AI_BUILD_NO_Q3D_IMPORTER)
|
||||||
// mImporter.push_back( new Q3DImporter());
|
mImporter.push_back( new Q3DImporter());
|
||||||
//#endif
|
#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 -
|
||||||
|
|
|
@ -144,8 +144,8 @@ struct Frame
|
||||||
*/
|
*/
|
||||||
struct TexCoord
|
struct TexCoord
|
||||||
{
|
{
|
||||||
int16_t s;
|
uint16_t s;
|
||||||
int16_t t;
|
uint16_t t;
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
|
@ -414,7 +414,7 @@ void MD2Importer::InternReadFile( const std::string& pFile,
|
||||||
// the texture coordinates are absolute values but we
|
// the texture coordinates are absolute values but we
|
||||||
// need relative values between 0 and 1
|
// need relative values between 0 and 1
|
||||||
pcOut.x = pcTexCoords[iIndex].s / fDivisorU;
|
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
|
// FIX: flip the face order for use with OpenGL
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
|
@ -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
|
// check whether there are invalid texture keys
|
||||||
SearchForInvalidTextures(pMaterial,"diffuse");
|
SearchForInvalidTextures(pMaterial,"diffuse");
|
||||||
SearchForInvalidTextures(pMaterial,"specular");
|
SearchForInvalidTextures(pMaterial,"specular");
|
||||||
|
|
|
@ -70,7 +70,8 @@ SOURCES = AssimpPCH.cpp \
|
||||||
XFileParser.cpp \
|
XFileParser.cpp \
|
||||||
./irrXML/irrXML.cpp \
|
./irrXML/irrXML.cpp \
|
||||||
IRRMeshLoader.cpp \
|
IRRMeshLoader.cpp \
|
||||||
IRRLoader.cpp
|
IRRLoader.cpp \
|
||||||
|
Q3DLoader.cpp
|
||||||
|
|
||||||
OBJECTS = $(SOURCES:.cpp=.o)
|
OBJECTS = $(SOURCES:.cpp=.o)
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,8 @@ SOURCES = AssimpPCH.cpp \
|
||||||
BVHLoader.cpp \
|
BVHLoader.cpp \
|
||||||
./irrXML/irrXML.cpp \
|
./irrXML/irrXML.cpp \
|
||||||
IRRMeshLoader.cpp \
|
IRRMeshLoader.cpp \
|
||||||
IRRLoader.cpp
|
IRRLoader.cpp \
|
||||||
|
Q3DLoader.cpp
|
||||||
|
|
||||||
OBJECTS = $(SOURCES:.cpp=.o)
|
OBJECTS = $(SOURCES:.cpp=.o)
|
||||||
|
|
||||||
|
|
|
@ -44,9 +44,10 @@ inline aiMatrix3x3 aiMatrix3x3::operator* (const aiMatrix3x3& m) const
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
inline aiMatrix3x3& aiMatrix3x3::Transpose()
|
inline aiMatrix3x3& aiMatrix3x3::Transpose()
|
||||||
{
|
{
|
||||||
std::swap( a2, b1);
|
// (float&) don't remove, GCC complains cause of packed fields
|
||||||
std::swap( a3, c1);
|
std::swap( (float&)a2, (float&)b1);
|
||||||
std::swap( b3, c2);
|
std::swap( (float&)a3, (float&)c1);
|
||||||
|
std::swap( (float&)b3, (float&)c2);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,12 +58,13 @@ inline aiMatrix4x4 aiMatrix4x4::operator* (const aiMatrix4x4& m) const
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
inline aiMatrix4x4& aiMatrix4x4::Transpose()
|
inline aiMatrix4x4& aiMatrix4x4::Transpose()
|
||||||
{
|
{
|
||||||
std::swap( b1, a2);
|
// (float&) don't remove, GCC complains cause of packed fields
|
||||||
std::swap( c1, a3);
|
std::swap( (float&)b1, (float&)a2);
|
||||||
std::swap( c2, b3);
|
std::swap( (float&)c1, (float&)a3);
|
||||||
std::swap( d1, a4);
|
std::swap( (float&)c2, (float&)b3);
|
||||||
std::swap( d2, b4);
|
std::swap( (float&)d1, (float&)a4);
|
||||||
std::swap( d3, c4);
|
std::swap( (float&)d2, (float&)b4);
|
||||||
|
std::swap( (float&)d3, (float&)c4);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1385,6 +1385,14 @@
|
||||||
<Filter
|
<Filter
|
||||||
Name="Q3D"
|
Name="Q3D"
|
||||||
>
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\code\Q3DLoader.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\code\Q3DLoader.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
|
@ -1631,7 +1639,7 @@
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
BasicRuntimeChecks="0"
|
BasicRuntimeChecks="0"
|
||||||
SmallerTypeCheck="false"
|
SmallerTypeCheck="true"
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
/>
|
/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
|
|
Loading…
Reference in New Issue