Fixed third-person camera movement bug in the viewer.
Fixed a bug that caused the viewer to render "random" polygons in some special cases. ASE: Added parsing support for *GROUP nodes. Improved light & camera handling (still WIP). Fixed a bug that was caused by a recent change. Improved logging. Updated PretransformVertices. The step works now (and supports line and point meshes). Important: The position of the step in the pipeline has changed. No unit test yet. Minor fixes to SortByPType. Added a config option that allows users to specify which primitive types they don't need. Added WIP version of an Irrlicht Scene Loader (.irr). Added a small helper class ("BatchLoader") to make it easy for loaders to load subsequent meshes from external files (needed for irr and lws). Added test models for IRR. Added dwarf.x from the Irrlicht repository (readme included) to the test X files. [Current TODO: Fix bugs in: AC, 3DS, LWO. Finish MDR and OG. Implement: IRR, LWS. Write some more ut's ... ] git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@197 67173fc5-114c-0410-ac8e-9d2fd5bffc1fpull/1/head
parent
a62b94079f
commit
3d3b9719f8
|
@ -78,20 +78,22 @@ 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);
|
||||||
|
|
||||||
if (extension.length() < 4)return false;
|
// Either ASE or ASK
|
||||||
if (extension[0] != '.')return false;
|
return !(extension.length() < 4 || extension[0] != '.' ||
|
||||||
|
extension[1] != 'a' && extension[1] != 'A' ||
|
||||||
if (extension[1] != 'a' && extension[1] != 'A')return false;
|
extension[2] != 's' && extension[2] != 'S' ||
|
||||||
if (extension[2] != 's' && extension[2] != 'S')return false;
|
extension[3] != 'e' && extension[3] != 'E' &&
|
||||||
|
extension[3] != 'k' && extension[3] != 'K');
|
||||||
// NOTE: Sometimes the extension .ASK is also used
|
|
||||||
// however, it often contains static animation skeletons
|
|
||||||
// only (without real animations).
|
|
||||||
if (extension[3] != 'e' && extension[3] != 'E' &&
|
|
||||||
extension[3] != 'k' && extension[3] != 'K')return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Setup configuration options
|
||||||
|
void ASEImporter::SetupProperties(const Importer* pImp)
|
||||||
|
{
|
||||||
|
configRecomputeNormals = (pImp->GetPropertyInteger(
|
||||||
|
AI_CONFIG_IMPORT_ASE_RECONSTRUCT_NORMALS,0) ? true : false);
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Imports the given file into the given scene structure.
|
// Imports the given file into the given scene structure.
|
||||||
void ASEImporter::InternReadFile(
|
void ASEImporter::InternReadFile(
|
||||||
|
@ -125,6 +127,7 @@ void ASEImporter::InternReadFile(
|
||||||
GenerateDefaultMaterial();
|
GenerateDefaultMaterial();
|
||||||
|
|
||||||
// process all meshes
|
// process all meshes
|
||||||
|
bool tookNormals = false;
|
||||||
std::vector<aiMesh*> avOutMeshes;
|
std::vector<aiMesh*> avOutMeshes;
|
||||||
avOutMeshes.reserve(mParser->m_vMeshes.size()*2);
|
avOutMeshes.reserve(mParser->m_vMeshes.size()*2);
|
||||||
for (std::vector<ASE::Mesh>::iterator
|
for (std::vector<ASE::Mesh>::iterator
|
||||||
|
@ -140,11 +143,17 @@ void ASEImporter::InternReadFile(
|
||||||
BuildUniqueRepresentation(*i);
|
BuildUniqueRepresentation(*i);
|
||||||
|
|
||||||
// need to generate proper vertex normals if necessary
|
// need to generate proper vertex normals if necessary
|
||||||
GenerateNormals(*i);
|
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)
|
||||||
|
{
|
||||||
|
DefaultLogger::get()->debug("ASE: Taking normals from the file. Use "
|
||||||
|
"the AI_CONFIG_IMPORT_ASE_RECONSTRUCT_NORMALS option if you "
|
||||||
|
"experience problems");
|
||||||
|
}
|
||||||
|
|
||||||
// now build the output mesh list. remove dummies
|
// now build the output mesh list. remove dummies
|
||||||
pScene->mNumMeshes = (unsigned int)avOutMeshes.size();
|
pScene->mNumMeshes = (unsigned int)avOutMeshes.size();
|
||||||
|
@ -192,15 +201,15 @@ void ASEImporter::GenerateDefaultMaterial()
|
||||||
}
|
}
|
||||||
if (bHas || mParser->m_vMaterials.empty())
|
if (bHas || mParser->m_vMaterials.empty())
|
||||||
{
|
{
|
||||||
// add a simple material without sub materials to the parser's list
|
// add a simple material without submaterials to the parser's list
|
||||||
mParser->m_vMaterials.push_back ( ASE::Material() );
|
mParser->m_vMaterials.push_back ( ASE::Material() );
|
||||||
ASE::Material& mat = mParser->m_vMaterials.back();
|
ASE::Material& mat = mParser->m_vMaterials.back();
|
||||||
|
|
||||||
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 = Dot3DSFile::Gouraud;
|
||||||
mat.mName = AI_DEFAULT_MATERIAL_NAME;
|
mat.mName = AI_DEFAULT_MATERIAL_NAME;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,7 +304,7 @@ void ASEImporter::BuildCameras()
|
||||||
// copy members
|
// copy members
|
||||||
out->mClipPlaneFar = in.mFar;
|
out->mClipPlaneFar = in.mFar;
|
||||||
out->mClipPlaneNear = (in.mNear ? in.mNear : 0.1f);
|
out->mClipPlaneNear = (in.mNear ? in.mNear : 0.1f);
|
||||||
out->mHorizontalFOV = AI_RAD_TO_DEG( in.mFOV );
|
out->mHorizontalFOV = in.mFOV;
|
||||||
|
|
||||||
out->mName.Set(in.mName);
|
out->mName.Set(in.mName);
|
||||||
}
|
}
|
||||||
|
@ -317,6 +326,7 @@ void ASEImporter::BuildLights()
|
||||||
|
|
||||||
out->mName.Set(in.mName);
|
out->mName.Set(in.mName);
|
||||||
out->mType = aiLightSource_POINT;
|
out->mType = aiLightSource_POINT;
|
||||||
|
out->mColorDiffuse = out->mColorSpecular = in.mColor * in.mIntensity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -329,6 +339,64 @@ void ASEImporter::AddNodes(std::vector<BaseNode*>& nodes,
|
||||||
this->AddNodes(nodes,pcParent,szName,m);
|
this->AddNodes(nodes,pcParent,szName,m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void ASEImporter::AddMeshes(const ASE::BaseNode* snode,aiNode* node)
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < pcScene->mNumMeshes;++i)
|
||||||
|
{
|
||||||
|
// Get the name of the mesh (the mesh instance has been temporarily
|
||||||
|
// stored in the third vertex color)
|
||||||
|
const aiMesh* pcMesh = pcScene->mMeshes[i];
|
||||||
|
const ASE::Mesh* mesh = (const ASE::Mesh*)pcMesh->mColors[2];
|
||||||
|
|
||||||
|
if (mesh == snode)++node->mNumMeshes;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(node->mNumMeshes)
|
||||||
|
{
|
||||||
|
node->mMeshes = new unsigned int[node->mNumMeshes];
|
||||||
|
for (unsigned int i = 0, p = 0; i < pcScene->mNumMeshes;++i)
|
||||||
|
{
|
||||||
|
const aiMesh* pcMesh = pcScene->mMeshes[i];
|
||||||
|
const ASE::Mesh* mesh = (const ASE::Mesh*)pcMesh->mColors[2];
|
||||||
|
if (mesh == snode)
|
||||||
|
{
|
||||||
|
node->mMeshes[p++] = i;
|
||||||
|
|
||||||
|
// Transform all vertices of the mesh back into their local space ->
|
||||||
|
// at the moment they are pretransformed
|
||||||
|
aiMatrix4x4 m = mesh->mTransform;
|
||||||
|
m.Inverse();
|
||||||
|
|
||||||
|
aiVector3D* pvCurPtr = pcMesh->mVertices;
|
||||||
|
const aiVector3D* pvEndPtr = pvCurPtr + pcMesh->mNumVertices;
|
||||||
|
while (pvCurPtr != pvEndPtr)
|
||||||
|
{
|
||||||
|
*pvCurPtr = m * (*pvCurPtr);
|
||||||
|
pvCurPtr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do the same for the normal vectors if we have them
|
||||||
|
// Here we need to use the (Inverse)Transpose of a 3x3
|
||||||
|
// matrix without the translational component.
|
||||||
|
if (pcMesh->mNormals)
|
||||||
|
{
|
||||||
|
aiMatrix3x3 m3 = aiMatrix3x3( mesh->mTransform );
|
||||||
|
m3.Transpose();
|
||||||
|
|
||||||
|
pvCurPtr = pcMesh->mNormals;
|
||||||
|
pvEndPtr = pvCurPtr + pcMesh->mNumVertices;
|
||||||
|
while (pvCurPtr != pvEndPtr)
|
||||||
|
{
|
||||||
|
*pvCurPtr = m3 * (*pvCurPtr);
|
||||||
|
pvCurPtr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ASEImporter::AddNodes (std::vector<BaseNode*>& nodes,
|
void ASEImporter::AddNodes (std::vector<BaseNode*>& nodes,
|
||||||
aiNode* pcParent, const char* szName,
|
aiNode* pcParent, const char* szName,
|
||||||
|
@ -375,64 +443,17 @@ void ASEImporter::AddNodes (std::vector<BaseNode*>& nodes,
|
||||||
// be used when this code is refactored next.
|
// be used when this code is refactored next.
|
||||||
if (snode->mType == BaseNode::Mesh)
|
if (snode->mType == BaseNode::Mesh)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < pcScene->mNumMeshes;++i)
|
AddMeshes(snode,node);
|
||||||
{
|
|
||||||
// Get the name of the mesh (the mesh instance has been temporarily
|
|
||||||
// stored in the third vertex color)
|
|
||||||
const aiMesh* pcMesh = pcScene->mMeshes[i];
|
|
||||||
const ASE::Mesh* mesh = (const ASE::Mesh*)pcMesh->mColors[2];
|
|
||||||
|
|
||||||
if (mesh == snode)++node->mNumMeshes;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(node->mNumMeshes)
|
|
||||||
{
|
|
||||||
node->mMeshes = new unsigned int[node->mNumMeshes];
|
|
||||||
for (unsigned int i = 0, p = 0; i < pcScene->mNumMeshes;++i)
|
|
||||||
{
|
|
||||||
const aiMesh* pcMesh = pcScene->mMeshes[i];
|
|
||||||
const ASE::Mesh* mesh = (const ASE::Mesh*)pcMesh->mColors[2];
|
|
||||||
if (mesh == snode)
|
|
||||||
{
|
|
||||||
node->mMeshes[p++] = i;
|
|
||||||
|
|
||||||
// Transform all vertices of the mesh back into their local space ->
|
|
||||||
// at the moment they are pretransformed
|
|
||||||
mParentAdjust = mesh->mTransform;
|
|
||||||
mParentAdjust.Inverse();
|
|
||||||
|
|
||||||
aiVector3D* pvCurPtr = pcMesh->mVertices;
|
|
||||||
const aiVector3D* pvEndPtr = pvCurPtr + pcMesh->mNumVertices;
|
|
||||||
while (pvCurPtr != pvEndPtr)
|
|
||||||
{
|
|
||||||
*pvCurPtr = mParentAdjust * (*pvCurPtr);
|
|
||||||
pvCurPtr++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do the same for the normal vectors if we have them
|
|
||||||
// Here we need to use the (Inverse)Transpose of a 3x3
|
|
||||||
// matrix without the translational component.
|
|
||||||
if (pcMesh->mNormals)
|
|
||||||
{
|
|
||||||
aiMatrix3x3 m3 = aiMatrix3x3( mesh->mTransform );
|
|
||||||
m3.Transpose();
|
|
||||||
|
|
||||||
pvCurPtr = pcMesh->mNormals;
|
|
||||||
pvEndPtr = pvCurPtr + pcMesh->mNumVertices;
|
|
||||||
while (pvCurPtr != pvEndPtr)
|
|
||||||
{
|
|
||||||
*pvCurPtr = m3 * (*pvCurPtr);
|
|
||||||
pvCurPtr++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add sub nodes
|
// add sub nodes
|
||||||
aiMatrix4x4 mNewAbs = mat * node->mTransformation;
|
aiMatrix4x4 mNewAbs = mat * node->mTransformation;
|
||||||
AddNodes(nodes,node,node->mName.data,mNewAbs);
|
|
||||||
|
// prevent stack overflow
|
||||||
|
if (node->mName != node->mParent->mName)
|
||||||
|
{
|
||||||
|
AddNodes(nodes,node,node->mName.data,mNewAbs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate enough space for the child nodes
|
// allocate enough space for the child nodes
|
||||||
|
@ -493,7 +514,7 @@ void ASEImporter::BuildNodes()
|
||||||
{
|
{
|
||||||
if (it2 == it)continue;
|
if (it2 == it)continue;
|
||||||
|
|
||||||
if ((*it2)->mParent == (*it)->mName)
|
if ((*it2)->mName == (*it)->mParent)
|
||||||
{
|
{
|
||||||
bKnowParent = true;
|
bKnowParent = true;
|
||||||
break;
|
break;
|
||||||
|
@ -521,17 +542,12 @@ void ASEImporter::BuildNodes()
|
||||||
{
|
{
|
||||||
const ASE::BaseNode* src = *i;
|
const ASE::BaseNode* src = *i;
|
||||||
|
|
||||||
/*
|
|
||||||
DefaultLogger::get()->info("Generating dummy node: " + src->mName + ". "
|
|
||||||
"This node is not defined in the ASE file, but referenced as "
|
|
||||||
"parent node");
|
|
||||||
*/
|
|
||||||
|
|
||||||
// the parent is not known, so we can assume that we must add
|
// the parent is not known, so we can assume that we must add
|
||||||
// this node to the root node of the whole scene
|
// this node to the root node of the whole scene
|
||||||
aiNode* pcNode = new aiNode();
|
aiNode* pcNode = new aiNode();
|
||||||
pcNode->mParent = pcScene->mRootNode;
|
pcNode->mParent = pcScene->mRootNode;
|
||||||
pcNode->mName.Set(src->mName);
|
pcNode->mName.Set(src->mName);
|
||||||
|
AddMeshes(src,pcNode);
|
||||||
AddNodes(nodes,pcNode,pcNode->mName.data);
|
AddNodes(nodes,pcNode,pcNode->mName.data);
|
||||||
apcNodes.push_back(pcNode);
|
apcNodes.push_back(pcNode);
|
||||||
}
|
}
|
||||||
|
@ -1252,9 +1268,9 @@ void ASEImporter::BuildMaterialIndices()
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Generate normal vectors basing on smoothing groups
|
// Generate normal vectors basing on smoothing groups
|
||||||
void ASEImporter::GenerateNormals(ASE::Mesh& mesh)
|
bool ASEImporter::GenerateNormals(ASE::Mesh& mesh)
|
||||||
{
|
{
|
||||||
if (!mesh.mNormals.empty())
|
if (!mesh.mNormals.empty() && !configRecomputeNormals)
|
||||||
{
|
{
|
||||||
// check whether there are only uninitialized normals. If there are
|
// check whether there are only uninitialized normals. If there are
|
||||||
// some, skip all normals from the file and compute them on our own
|
// some, skip all normals from the file and compute them on our own
|
||||||
|
@ -1264,14 +1280,11 @@ void ASEImporter::GenerateNormals(ASE::Mesh& mesh)
|
||||||
{
|
{
|
||||||
if ((*qq).x || (*qq).y || (*qq).z)
|
if ((*qq).x || (*qq).y || (*qq).z)
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->debug("Using normal vectors from the ASE file. They are sometimes crappy");
|
return true;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mesh.mNormals.clear();
|
|
||||||
}
|
|
||||||
if (mesh.mNormals.empty())
|
|
||||||
{
|
|
||||||
ComputeNormalsWithSmoothingsGroups<ASE::Face>(mesh);
|
|
||||||
}
|
}
|
||||||
|
// The array will be reused
|
||||||
|
ComputeNormalsWithSmoothingsGroups<ASE::Face>(mesh);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,12 +93,20 @@ protected:
|
||||||
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
||||||
IOSystem* pIOHandler);
|
IOSystem* pIOHandler);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Called prior to ReadFile().
|
||||||
|
* The function is a request to the importer to update its configuration
|
||||||
|
* basing on the Importer's configuration property list.
|
||||||
|
*/
|
||||||
|
void SetupProperties(const Importer* pImp);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Generate normal vectors basing on smoothing groups
|
/** Generate normal vectors basing on smoothing groups
|
||||||
* (in some cases the normal are already contained in the file)
|
* (in some cases the normal are already contained in the file)
|
||||||
* \param mesh Mesh to work on
|
* \param mesh Mesh to work on
|
||||||
|
* \return false if the normals have been recomputed
|
||||||
*/
|
*/
|
||||||
void GenerateNormals(ASE::Mesh& mesh);
|
bool GenerateNormals(ASE::Mesh& mesh);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Create valid vertex/normal/UV/color/face lists.
|
/** Create valid vertex/normal/UV/color/face lists.
|
||||||
|
@ -164,6 +172,8 @@ protected:
|
||||||
aiNode* pcParent,const char* szName,
|
aiNode* pcParent,const char* szName,
|
||||||
const aiMatrix4x4& matrix);
|
const aiMatrix4x4& matrix);
|
||||||
|
|
||||||
|
void AddMeshes(const ASE::BaseNode* snode,aiNode* node);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Generate a default material and add it to the parser's list
|
/** Generate a default material and add it to the parser's list
|
||||||
* Called if no material has been found in the file (rare for ASE,
|
* Called if no material has been found in the file (rare for ASE,
|
||||||
|
@ -181,6 +191,10 @@ protected:
|
||||||
|
|
||||||
/** Scene to be filled */
|
/** Scene to be filled */
|
||||||
aiScene* pcScene;
|
aiScene* pcScene;
|
||||||
|
|
||||||
|
/** Config options: Recompute the normals in every case - WA
|
||||||
|
for 3DS Max broken ASE normal export */
|
||||||
|
bool configRecomputeNormals;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
|
@ -254,6 +254,12 @@ void Parser::Parse()
|
||||||
ParseLV1SceneBlock();
|
ParseLV1SceneBlock();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// "group"
|
||||||
|
if (TokenMatch(m_szFile,"GROUP",5))
|
||||||
|
{
|
||||||
|
Parse();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// material list
|
// material list
|
||||||
if (TokenMatch(m_szFile,"MATERIAL_LIST",13))
|
if (TokenMatch(m_szFile,"MATERIAL_LIST",13))
|
||||||
{
|
{
|
||||||
|
|
|
@ -139,4 +139,124 @@ bool BaseImporter::SearchFileHeaderForToken(IOSystem* pIOHandler,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
struct LoadRequest
|
||||||
|
{
|
||||||
|
LoadRequest(const std::string& _file, unsigned int _flags)
|
||||||
|
: file (_file)
|
||||||
|
, flags (_flags)
|
||||||
|
, scene (NULL)
|
||||||
|
, refCnt (1)
|
||||||
|
, loaded (false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
const std::string file;
|
||||||
|
unsigned int flags;
|
||||||
|
unsigned int refCnt;
|
||||||
|
|
||||||
|
aiScene* scene;
|
||||||
|
bool loaded;
|
||||||
|
|
||||||
|
bool operator== (const std::string& f)
|
||||||
|
{return file == f;}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BatchData
|
||||||
|
{
|
||||||
|
// IO system to be used for all imports
|
||||||
|
IOSystem* pIOSystem;
|
||||||
|
|
||||||
|
// Importer used to load all meshes
|
||||||
|
Importer* pImporter;
|
||||||
|
|
||||||
|
// List of all imports
|
||||||
|
std::list<LoadRequest> requests;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
BatchLoader::BatchLoader(IOSystem* pIO)
|
||||||
|
{
|
||||||
|
ai_assert(NULL != pIO);
|
||||||
|
|
||||||
|
pimpl = new BatchData();
|
||||||
|
BatchData* data = ( BatchData* )pimpl;
|
||||||
|
data->pIOSystem = pIO;
|
||||||
|
data->pImporter = new Importer();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
BatchLoader::~BatchLoader()
|
||||||
|
{
|
||||||
|
// delete all scenes wthat have not been polled by the user
|
||||||
|
BatchData* data = ( BatchData* )pimpl;
|
||||||
|
for (std::list<LoadRequest>::iterator it = data->requests.begin();
|
||||||
|
it != data->requests.end(); ++it)
|
||||||
|
{
|
||||||
|
delete (*it).scene;
|
||||||
|
}
|
||||||
|
delete data->pImporter;
|
||||||
|
delete data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BatchLoader::AddLoadRequest (const std::string& file)
|
||||||
|
{
|
||||||
|
// no threaded implementation for the moment
|
||||||
|
BatchData* data = ( BatchData* )pimpl;
|
||||||
|
std::list<LoadRequest>::iterator it = std::find(data->requests.begin(),
|
||||||
|
data->requests.end(), file);
|
||||||
|
|
||||||
|
if (it != data->requests.end())
|
||||||
|
{
|
||||||
|
(*it).refCnt++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
data->requests.push_back(LoadRequest(file,0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
aiScene* BatchLoader::GetImport (const std::string& file)
|
||||||
|
{
|
||||||
|
// no threaded implementation for the moment
|
||||||
|
BatchData* data = ( BatchData* )pimpl;
|
||||||
|
std::list<LoadRequest>::iterator it = std::find(data->requests.begin(),
|
||||||
|
data->requests.end(), file);
|
||||||
|
if (it != data->requests.end() && (*it).loaded)
|
||||||
|
{
|
||||||
|
aiScene* sc = (*it).scene;
|
||||||
|
if (!(--(*it).refCnt))
|
||||||
|
{
|
||||||
|
data->requests.erase(it);
|
||||||
|
}
|
||||||
|
return sc;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BatchLoader::LoadAll()
|
||||||
|
{
|
||||||
|
BatchData* data = ( BatchData* )pimpl;
|
||||||
|
|
||||||
|
// no threaded implementation for the moment
|
||||||
|
for (std::list<LoadRequest>::iterator it = data->requests.begin();
|
||||||
|
it != data->requests.end(); ++it)
|
||||||
|
{
|
||||||
|
// no postprocessing for the moment except validation
|
||||||
|
// in debug builds
|
||||||
|
unsigned int pp = 0;
|
||||||
|
#ifdef _DEBUG
|
||||||
|
pp |= aiProcess_ValidateDataStructure;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
data->pImporter->ReadFile((*it).file,pp);
|
||||||
|
(*it).scene = const_cast<aiScene*>(data->pImporter->GetOrphanedScene());
|
||||||
|
(*it).loaded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -215,12 +215,77 @@ protected:
|
||||||
unsigned int numTokens,
|
unsigned int numTokens,
|
||||||
unsigned int searchBytes = 200);
|
unsigned int searchBytes = 200);
|
||||||
|
|
||||||
|
#if 0 /** TODO **/
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** An utility for all text file loaders. It converts a file to our
|
||||||
|
* ASCII/UTF8 character set. Special unicode characters are lost.
|
||||||
|
*
|
||||||
|
* @param buffer Input buffer. Needn't be terminated with zero.
|
||||||
|
* @param length Length of the input buffer, in bytes. Receives the
|
||||||
|
* number of output characters, excluding the terminal char.
|
||||||
|
* @return true if the source format did not match our internal
|
||||||
|
* format so it was converted.
|
||||||
|
*/
|
||||||
|
static bool ConvertToUTF8(const char* buffer,
|
||||||
|
unsigned int& length);
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/** Error description in case there was one. */
|
/** Error description in case there was one. */
|
||||||
std::string mErrorText;
|
std::string mErrorText;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/** A helper class that can be used by importers which need to load many
|
||||||
|
* extern meshes recursively.
|
||||||
|
*
|
||||||
|
* The class uses several threads to load these meshes (or at least it
|
||||||
|
* could, this has not yet been implemented at the moment).
|
||||||
|
*
|
||||||
|
* @note The class may not be used by more than one thread
|
||||||
|
*/
|
||||||
|
class ASSIMP_API BatchLoader
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** Construct a batch loader from a given IO system
|
||||||
|
*/
|
||||||
|
BatchLoader(IOSystem* pIO);
|
||||||
|
~BatchLoader();
|
||||||
|
|
||||||
|
|
||||||
|
/** 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
|
||||||
|
*/
|
||||||
|
void AddLoadRequest (const std::string& file);
|
||||||
|
|
||||||
|
|
||||||
|
/** Get an imported scene.
|
||||||
|
*
|
||||||
|
* This polls the import from the internal request list.
|
||||||
|
* If an import is requested several times, this function
|
||||||
|
* can be called several times, too.
|
||||||
|
*
|
||||||
|
* @param file File name of the scene
|
||||||
|
* @return NULL if there is no scene with this file name
|
||||||
|
* in the queue of the scene hasn't been loaded yet.
|
||||||
|
*/
|
||||||
|
aiScene* GetImport (const std::string& file);
|
||||||
|
|
||||||
|
|
||||||
|
/** Waits until all scenes have been loaded.
|
||||||
|
*/
|
||||||
|
void LoadAll();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// No need to have that in the public API ...
|
||||||
|
void* pimpl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
|
@ -78,8 +78,7 @@ bool ConvertToLHProcess::IsActive( unsigned int pFlags) const
|
||||||
{
|
{
|
||||||
if (pFlags & aiProcess_ConvertToLeftHanded)
|
if (pFlags & aiProcess_ConvertToLeftHanded)
|
||||||
{
|
{
|
||||||
if (pFlags & aiProcess_PreTransformVertices)
|
bTransformVertices = (0 != (pFlags & aiProcess_PreTransformVertices) ? true : false);
|
||||||
this->bTransformVertices = true;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -99,25 +98,28 @@ void ConvertToLHProcess::Execute( aiScene* pScene)
|
||||||
DefaultLogger::get()->debug("ConvertToLHProcess begin");
|
DefaultLogger::get()->debug("ConvertToLHProcess begin");
|
||||||
|
|
||||||
// transform vertex by vertex or change the root transform?
|
// transform vertex by vertex or change the root transform?
|
||||||
if (this->bTransformVertices)
|
// We can't do the coordinate system transformation earlier
|
||||||
|
// in the pipeline - most steps assume that we're in OGL
|
||||||
|
// space. So we need to transform all vertices a second time
|
||||||
|
// here.
|
||||||
|
if (bTransformVertices)
|
||||||
{
|
{
|
||||||
this->bTransformVertices = false;
|
|
||||||
aiMatrix4x4 mTransform;
|
aiMatrix4x4 mTransform;
|
||||||
this->ConvertToDX(mTransform);
|
ConvertToDX(mTransform);
|
||||||
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
|
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
|
||||||
{
|
{
|
||||||
aiMesh* pcMesh = pScene->mMeshes[i];
|
aiMesh* pcMesh = pScene->mMeshes[i];
|
||||||
|
|
||||||
|
// transform all vertices
|
||||||
for (unsigned int n = 0; n < pcMesh->mNumVertices;++n)
|
for (unsigned int n = 0; n < pcMesh->mNumVertices;++n)
|
||||||
{
|
pcMesh->mVertices[n] = mTransform * pcMesh->mVertices[n];
|
||||||
pcMesh->mVertices[n] = mTransform * pcMesh->mVertices[n];
|
|
||||||
}
|
// transform all normals
|
||||||
if (pcMesh->HasNormals())
|
if (pcMesh->HasNormals())
|
||||||
{
|
{
|
||||||
mTransform.Inverse().Transpose();
|
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];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,7 +141,7 @@ void FindDegeneratesProcess::Execute( aiScene* pScene)
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (deg)
|
if (deg && !DefaultLogger::isNullLogger())
|
||||||
{
|
{
|
||||||
char s[64];
|
char s[64];
|
||||||
itoa10(s,deg);
|
itoa10(s,deg);
|
||||||
|
|
|
@ -0,0 +1,424 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
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 Irr importer class */
|
||||||
|
|
||||||
|
#include "AssimpPCH.h"
|
||||||
|
|
||||||
|
#include "IRRLoader.h"
|
||||||
|
#include "ParsingUtils.h"
|
||||||
|
#include "fast_atof.h"
|
||||||
|
|
||||||
|
#include "StandardShapes.h"
|
||||||
|
|
||||||
|
using namespace Assimp;
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Constructor to be privately used by Importer
|
||||||
|
IRRImporter::IRRImporter()
|
||||||
|
{
|
||||||
|
// nothing to do here
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Destructor, private as well
|
||||||
|
IRRImporter::~IRRImporter()
|
||||||
|
{
|
||||||
|
// nothing to do here
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Returns whether the class can handle the format of the given file.
|
||||||
|
bool IRRImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler) const
|
||||||
|
{
|
||||||
|
/* NOTE: A simple check for the file extension is not enough
|
||||||
|
* here. Irrmesh and irr are easy, but xml is too generic
|
||||||
|
* and could be collada, too. So we need to open the file and
|
||||||
|
* search for typical tokens.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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 i = extension.begin(); i != extension.end();++i)
|
||||||
|
*i = ::tolower(*i);
|
||||||
|
|
||||||
|
if (extension == ".irr")return true;
|
||||||
|
else if (extension == ".xml")
|
||||||
|
{
|
||||||
|
/* If CanRead() is called to check whether the loader
|
||||||
|
* supports a specific file extension in general we
|
||||||
|
* must return true here.
|
||||||
|
*/
|
||||||
|
if (!pIOHandler)return true;
|
||||||
|
const char* tokens[] = {"irr_scene"};
|
||||||
|
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Imports the given file into the given scene structure.
|
||||||
|
void IRRImporter::InternReadFile( const std::string& pFile,
|
||||||
|
aiScene* pScene, IOSystem* pIOHandler)
|
||||||
|
{
|
||||||
|
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
|
||||||
|
|
||||||
|
// Check whether we can read from the file
|
||||||
|
if( file.get() == NULL)
|
||||||
|
throw new ImportErrorException( "Failed to open IRR file " + pFile + "");
|
||||||
|
|
||||||
|
// Construct the irrXML parser
|
||||||
|
CIrrXML_IOStreamReader st(file.get());
|
||||||
|
reader = createIrrXMLReader((IFileReadCallBack*) &st);
|
||||||
|
|
||||||
|
// The root node of the scene
|
||||||
|
Node* root = new Node(Node::DUMMY);
|
||||||
|
root->parent = NULL;
|
||||||
|
|
||||||
|
// Current node parent
|
||||||
|
Node* curParent = root;
|
||||||
|
|
||||||
|
// Scenegraph node we're currently working on
|
||||||
|
Node* curNode = NULL;
|
||||||
|
|
||||||
|
// List of output cameras
|
||||||
|
std::vector<aiCamera*> cameras;
|
||||||
|
|
||||||
|
// List of output lights
|
||||||
|
std::vector<aiLight*> lights;
|
||||||
|
|
||||||
|
// List of output meshes
|
||||||
|
std::vector<aiMesh*> meshes;
|
||||||
|
|
||||||
|
// List of output animation channels
|
||||||
|
std::vector<aiNodeAnim*> animations;
|
||||||
|
|
||||||
|
BatchLoader batch(pIOHandler);
|
||||||
|
|
||||||
|
cameras.reserve(5);
|
||||||
|
lights.reserve(5);
|
||||||
|
animations.reserve(5);
|
||||||
|
meshes.reserve(5);
|
||||||
|
|
||||||
|
bool inMaterials = false;
|
||||||
|
|
||||||
|
// Parse the XML file
|
||||||
|
while (reader->read())
|
||||||
|
{
|
||||||
|
switch (reader->getNodeType())
|
||||||
|
{
|
||||||
|
case EXN_ELEMENT:
|
||||||
|
|
||||||
|
if (!ASSIMP_stricmp(reader->getNodeName(),"node"))
|
||||||
|
{
|
||||||
|
/* What we're going to do with the node depends
|
||||||
|
* on its type:
|
||||||
|
*
|
||||||
|
* "mesh" - Load a mesh from an external file
|
||||||
|
* "cube" - Generate a cube
|
||||||
|
* "skybox" - Generate a skybox
|
||||||
|
* "light" - A light source
|
||||||
|
* "sphere" - Generate a sphere mesh
|
||||||
|
* "animatedMesh" - Load an animated mesh from an external file
|
||||||
|
* and join its animation channels with ours.
|
||||||
|
* "empty" - A dummy node
|
||||||
|
* "camera" - A camera
|
||||||
|
*
|
||||||
|
* Each of these nodes can be animated.
|
||||||
|
*/
|
||||||
|
const char* sz = reader->getAttributeValueSafe("type");
|
||||||
|
Node* nd;
|
||||||
|
if (!ASSIMP_stricmp(sz,"mesh"))
|
||||||
|
{
|
||||||
|
nd = new Node(Node::MESH);
|
||||||
|
}
|
||||||
|
else if (!ASSIMP_stricmp(sz,"cube"))
|
||||||
|
{
|
||||||
|
nd = new Node(Node::CUBE);
|
||||||
|
meshes.push_back(StandardShapes::MakeMesh(&StandardShapes::MakeHexahedron));
|
||||||
|
}
|
||||||
|
else if (!ASSIMP_stricmp(sz,"skybox"))
|
||||||
|
{
|
||||||
|
nd = new Node(Node::SKYBOX);
|
||||||
|
}
|
||||||
|
else if (!ASSIMP_stricmp(sz,"camera"))
|
||||||
|
{
|
||||||
|
nd = new Node(Node::CAMERA);
|
||||||
|
|
||||||
|
// Setup a temporary name for the camera
|
||||||
|
aiCamera* cam = new aiCamera();
|
||||||
|
cam->mName.Set( nd->name );
|
||||||
|
cameras.push_back(cam);
|
||||||
|
}
|
||||||
|
else if (!ASSIMP_stricmp(sz,"light"))
|
||||||
|
{
|
||||||
|
nd = new Node(Node::LIGHT);
|
||||||
|
|
||||||
|
// Setup a temporary name for the light
|
||||||
|
aiLight* cam = new aiLight();
|
||||||
|
cam->mName.Set( nd->name );
|
||||||
|
lights.push_back(cam);
|
||||||
|
}
|
||||||
|
else if (!ASSIMP_stricmp(sz,"sphere"))
|
||||||
|
{
|
||||||
|
nd = new Node(Node::SPHERE);
|
||||||
|
}
|
||||||
|
else if (!ASSIMP_stricmp(sz,"animatedMesh"))
|
||||||
|
{
|
||||||
|
nd = new Node(Node::ANIMMESH);
|
||||||
|
}
|
||||||
|
else if (!ASSIMP_stricmp(sz,"empty"))
|
||||||
|
{
|
||||||
|
nd = new Node(Node::DUMMY);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DefaultLogger::get()->warn("IRR: Found unknown node: " + std::string(sz));
|
||||||
|
|
||||||
|
/* We skip the contents of nodes we don't know.
|
||||||
|
* We parse the transformation and all animators
|
||||||
|
* and skip the rest.
|
||||||
|
*/
|
||||||
|
nd = new Node(Node::DUMMY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attach the newly created node to the scenegraph
|
||||||
|
*/
|
||||||
|
curNode = nd;
|
||||||
|
nd->parent = curParent;
|
||||||
|
curParent->children.push_back(nd);
|
||||||
|
}
|
||||||
|
else if (!ASSIMP_stricmp(reader->getNodeName(),"materials"))
|
||||||
|
{
|
||||||
|
inMaterials = true;
|
||||||
|
}
|
||||||
|
else if (!ASSIMP_stricmp(reader->getNodeName(),"attributes"))
|
||||||
|
{
|
||||||
|
/* We should have a valid node here
|
||||||
|
*/
|
||||||
|
if (!curNode)
|
||||||
|
{
|
||||||
|
DefaultLogger::get()->error("IRR: Encountered <attributes> element, but "
|
||||||
|
"there is no node active");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inMaterials && curNode->type == Node::ANIMMESH ||
|
||||||
|
curNode->type == Node::MESH )
|
||||||
|
{
|
||||||
|
/* This is a material description - parse it!
|
||||||
|
*/
|
||||||
|
curNode->materials.push_back(std::pair< aiMaterial*, unsigned int > () );
|
||||||
|
std::pair< aiMaterial*, unsigned int >& p = curNode->materials.back();
|
||||||
|
|
||||||
|
p.first = ParseMaterial(p.second);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse all elements in the attributes block
|
||||||
|
* and process them.
|
||||||
|
*/
|
||||||
|
while (reader->read())
|
||||||
|
{
|
||||||
|
if (reader->getNodeType() == EXN_ELEMENT)
|
||||||
|
{
|
||||||
|
if (!ASSIMP_stricmp(reader->getNodeName(),"vector3d"))
|
||||||
|
{
|
||||||
|
VectorProperty prop;
|
||||||
|
ReadVectorProperty(prop);
|
||||||
|
|
||||||
|
// Convert to our coordinate system
|
||||||
|
std::swap( (float&)prop.value.z, (float&)prop.value.y );
|
||||||
|
prop.value.y *= -1.f;
|
||||||
|
if (prop.name == "Position")
|
||||||
|
{
|
||||||
|
curNode->position = prop.value;
|
||||||
|
}
|
||||||
|
else if (prop.name == "Rotation")
|
||||||
|
{
|
||||||
|
curNode->rotation = prop.value;
|
||||||
|
}
|
||||||
|
else if (prop.name == "Scale")
|
||||||
|
{
|
||||||
|
curNode->scaling = prop.value;
|
||||||
|
}
|
||||||
|
else if (Node::CAMERA == curNode->type)
|
||||||
|
{
|
||||||
|
aiCamera* cam = cameras.back();
|
||||||
|
if (prop.name == "Target")
|
||||||
|
{
|
||||||
|
cam->mLookAt = prop.value;
|
||||||
|
}
|
||||||
|
else if (prop.name == "UpVector")
|
||||||
|
{
|
||||||
|
cam->mUp = prop.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!ASSIMP_stricmp(reader->getNodeName(),"float"))
|
||||||
|
{
|
||||||
|
FloatProperty prop;
|
||||||
|
ReadFloatProperty(prop);
|
||||||
|
|
||||||
|
if (prop.name == "FramesPerSecond" &&
|
||||||
|
Node::ANIMMESH == curNode->type)
|
||||||
|
{
|
||||||
|
curNode->framesPerSecond = prop.value;
|
||||||
|
}
|
||||||
|
else if (Node::CAMERA == curNode->type)
|
||||||
|
{
|
||||||
|
/* This is the vertical, not the horizontal FOV.
|
||||||
|
* We need to compute the right FOV from the
|
||||||
|
* screen aspect which we don't know yet.
|
||||||
|
*/
|
||||||
|
if (prop.name == "Fovy")
|
||||||
|
{
|
||||||
|
cameras.back()->mHorizontalFOV = prop.value;
|
||||||
|
}
|
||||||
|
else if (prop.name == "Aspect")
|
||||||
|
{
|
||||||
|
cameras.back()->mAspect = prop.value;
|
||||||
|
}
|
||||||
|
else if (prop.name == "ZNear")
|
||||||
|
{
|
||||||
|
cameras.back()->mClipPlaneNear = prop.value;
|
||||||
|
}
|
||||||
|
else if (prop.name == "ZFar")
|
||||||
|
{
|
||||||
|
cameras.back()->mClipPlaneFar = prop.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!ASSIMP_stricmp(reader->getNodeName(),"string"))
|
||||||
|
{
|
||||||
|
StringProperty prop;
|
||||||
|
ReadStringProperty(prop);
|
||||||
|
if (prop.value.length())
|
||||||
|
{
|
||||||
|
if (prop.name == "Name")
|
||||||
|
{
|
||||||
|
curNode->name = prop.value;
|
||||||
|
|
||||||
|
/* If we're either a camera or a light source
|
||||||
|
* we need to update the name in the aiLight/
|
||||||
|
* aiCamera structure, too.
|
||||||
|
*/
|
||||||
|
if (Node::CAMERA == curNode->type)
|
||||||
|
{
|
||||||
|
cameras.back()->mName.Set(prop.value);
|
||||||
|
}
|
||||||
|
else if (Node::LIGHT == curNode->type)
|
||||||
|
{
|
||||||
|
lights.back()->mName.Set(prop.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (prop.name == "Mesh" && Node::MESH == curNode->type ||
|
||||||
|
Node::ANIMMESH == curNode->type)
|
||||||
|
{
|
||||||
|
/* This is the file name of the mesh - either
|
||||||
|
* animated or not. We don't need any postprocessing
|
||||||
|
* steps here. However, it would be useful it we'd
|
||||||
|
* be able to use RemoveVC to remove animations
|
||||||
|
* if this isn't an animated mesh. But that's not
|
||||||
|
* possible at the moment.
|
||||||
|
*/
|
||||||
|
batch.AddLoadRequest(prop.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (reader->getNodeType() == EXN_ELEMENT_END &&
|
||||||
|
!ASSIMP_stricmp(reader->getNodeName(),"attributes"))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EXN_ELEMENT_END:
|
||||||
|
|
||||||
|
if (!ASSIMP_stricmp(reader->getNodeName(),"node"))
|
||||||
|
{
|
||||||
|
if (!curNode)
|
||||||
|
{
|
||||||
|
// currently is no node set. We need to go
|
||||||
|
// back in the node hierarchy
|
||||||
|
curParent = curParent->parent;
|
||||||
|
if (!curParent)
|
||||||
|
{
|
||||||
|
curParent = root;
|
||||||
|
DefaultLogger::get()->error("IRR: Too many closing <node> elements");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else curNode = NULL;
|
||||||
|
}
|
||||||
|
else if (!ASSIMP_stricmp(reader->getNodeName(),"materials"))
|
||||||
|
{
|
||||||
|
inMaterials = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// GCC complains that not all enumeration values are handled
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now iterate through all cameras and compute their final (horizontal) FOV
|
||||||
|
*/
|
||||||
|
for (std::vector<aiCamera*>::iterator it = cameras.begin(), end = cameras.end();
|
||||||
|
it != end; ++it)
|
||||||
|
{
|
||||||
|
aiCamera* cam = *it;
|
||||||
|
if (cam->mAspect) // screen aspect could be missing
|
||||||
|
{
|
||||||
|
cam->mHorizontalFOV *= cam->mAspect;
|
||||||
|
}
|
||||||
|
else DefaultLogger::get()->warn("IRR: Camera aspect is not given, can't compute horizontal FOV");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,168 @@
|
||||||
|
/*
|
||||||
|
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 .irrMesh (Irrlight Engine Mesh Format)
|
||||||
|
importer class. */
|
||||||
|
#ifndef AI_IRRLOADER_H_INCLUDED
|
||||||
|
#define AI_IRRLOADER_H_INCLUDED
|
||||||
|
|
||||||
|
#include "IRRMeshLoader.h"
|
||||||
|
|
||||||
|
namespace Assimp {
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/** Irr importer class.
|
||||||
|
*
|
||||||
|
* Irr is the native scene file format of the Irrlight engine and its editor
|
||||||
|
* irrEdit. As IrrEdit itself is capable of importing quite many file formats,
|
||||||
|
* it might be a good file format for data exchange.
|
||||||
|
*/
|
||||||
|
class IRRImporter : public BaseImporter, public IrrlichtBase
|
||||||
|
{
|
||||||
|
friend class Importer;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** Constructor to be privately used by Importer */
|
||||||
|
IRRImporter();
|
||||||
|
|
||||||
|
/** Destructor, private as well */
|
||||||
|
~IRRImporter();
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* NOTE: The file extenxsion .xml is too generic. We'll
|
||||||
|
* need to open the file in CanRead() and check whether it is
|
||||||
|
* a real irrlicht file
|
||||||
|
*/
|
||||||
|
|
||||||
|
append.append("*.xml;*.irr");
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** 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:
|
||||||
|
|
||||||
|
/** Data structure for a scenegraph node in an IRR file
|
||||||
|
*/
|
||||||
|
struct Node
|
||||||
|
{
|
||||||
|
// Type of the node
|
||||||
|
enum ET
|
||||||
|
{
|
||||||
|
LIGHT,
|
||||||
|
CUBE,
|
||||||
|
MESH,
|
||||||
|
SKYBOX,
|
||||||
|
DUMMY,
|
||||||
|
CAMERA,
|
||||||
|
TERRAIN,
|
||||||
|
SPHERE,
|
||||||
|
ANIMMESH
|
||||||
|
} type;
|
||||||
|
|
||||||
|
Node(ET t)
|
||||||
|
: type (t)
|
||||||
|
, scaling (1.f,1.f,1.f) // assume uniform scaling by default
|
||||||
|
, animation (NULL)
|
||||||
|
, framesPerSecond (0.f)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Generate a default name for the node
|
||||||
|
char buffer[128];
|
||||||
|
static int cnt;
|
||||||
|
::sprintf(buffer,"IrrNode_%i",cnt++);
|
||||||
|
name = std::string(buffer);
|
||||||
|
|
||||||
|
// reserve space for up to 5 materials
|
||||||
|
materials.reserve(5);
|
||||||
|
|
||||||
|
// reserve space for up to 5 children
|
||||||
|
children.reserve(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transformation of the node
|
||||||
|
aiVector3D position, rotation, scaling;
|
||||||
|
|
||||||
|
// Name of the node
|
||||||
|
std::string name;
|
||||||
|
|
||||||
|
// List of all child nodes
|
||||||
|
std::vector<Node*> children;
|
||||||
|
|
||||||
|
// Parent node
|
||||||
|
Node* parent;
|
||||||
|
|
||||||
|
// Animation channels that belongs to this node
|
||||||
|
aiNodeAnim* animation;
|
||||||
|
|
||||||
|
// Animated meshes: frames per second
|
||||||
|
// 0.f if not specified
|
||||||
|
float framesPerSecond;
|
||||||
|
|
||||||
|
//! Meshes: List of materials to be assigned
|
||||||
|
//! along with their corresponding material flags
|
||||||
|
std::vector< std::pair<aiMaterial*, unsigned int> > materials;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end of namespace Assimp
|
||||||
|
|
||||||
|
#endif // AI_IRRIMPORTER_H_INC
|
|
@ -50,58 +50,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
|
/**** AT FIRST: IrrlightBase, base class for IrrMesh and Irr *******/
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Constructor to be privately used by Importer
|
|
||||||
IRRMeshImporter::IRRMeshImporter()
|
|
||||||
{
|
|
||||||
// nothing to do here
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
IRRMeshImporter::~IRRMeshImporter()
|
|
||||||
{
|
|
||||||
// nothing to do here
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Returns whether the class can handle the format of the given file.
|
|
||||||
bool IRRMeshImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler) const
|
|
||||||
{
|
|
||||||
/* NOTE: A simple check for the file extension is not enough
|
|
||||||
* here. Irrmesh and irr are easy, but xml is too generic
|
|
||||||
* and could be collada, too. So we need to open the file and
|
|
||||||
* search for typical tokens.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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 i = extension.begin(); i != extension.end();++i)
|
|
||||||
*i = ::tolower(*i);
|
|
||||||
|
|
||||||
if (extension == ".irrmesh")return true;
|
|
||||||
else if (extension == ".xml")
|
|
||||||
{
|
|
||||||
/* If CanRead() is called to check whether the loader
|
|
||||||
* supports a specific file extension in general we
|
|
||||||
* must return true here.
|
|
||||||
*/
|
|
||||||
if (!pIOHandler)return true;
|
|
||||||
const char* tokens[] = {"irrlicht","irrmesh"};
|
|
||||||
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,2);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// read a property in hexadecimal format (i.e. ffffffff)
|
// read a property in hexadecimal format (i.e. ffffffff)
|
||||||
void IRRMeshImporter::ReadHexProperty (HexProperty& out)
|
void IrrlichtBase::ReadHexProperty (HexProperty& out)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < reader->getAttributeCount();++i)
|
for (int i = 0; i < reader->getAttributeCount();++i)
|
||||||
{
|
{
|
||||||
|
@ -119,7 +72,7 @@ void IRRMeshImporter::ReadHexProperty (HexProperty& out)
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// read a string property
|
// read a string property
|
||||||
void IRRMeshImporter::ReadStringProperty (StringProperty& out)
|
void IrrlichtBase::ReadStringProperty (StringProperty& out)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < reader->getAttributeCount();++i)
|
for (int i = 0; i < reader->getAttributeCount();++i)
|
||||||
{
|
{
|
||||||
|
@ -137,7 +90,7 @@ void IRRMeshImporter::ReadStringProperty (StringProperty& out)
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// read a boolean property
|
// read a boolean property
|
||||||
void IRRMeshImporter::ReadBoolProperty (BoolProperty& out)
|
void IrrlichtBase::ReadBoolProperty (BoolProperty& out)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < reader->getAttributeCount();++i)
|
for (int i = 0; i < reader->getAttributeCount();++i)
|
||||||
{
|
{
|
||||||
|
@ -156,7 +109,7 @@ void IRRMeshImporter::ReadBoolProperty (BoolProperty& out)
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// read a float property
|
// read a float property
|
||||||
void IRRMeshImporter::ReadFloatProperty (FloatProperty& out)
|
void IrrlichtBase::ReadFloatProperty (FloatProperty& out)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < reader->getAttributeCount();++i)
|
for (int i = 0; i < reader->getAttributeCount();++i)
|
||||||
{
|
{
|
||||||
|
@ -166,12 +119,47 @@ void IRRMeshImporter::ReadFloatProperty (FloatProperty& out)
|
||||||
}
|
}
|
||||||
else if (!ASSIMP_stricmp(reader->getAttributeName(i),"value"))
|
else if (!ASSIMP_stricmp(reader->getAttributeName(i),"value"))
|
||||||
{
|
{
|
||||||
// true or false, case insensitive
|
// just parse the float
|
||||||
out.value = fast_atof( reader->getAttributeValue(i) );
|
out.value = fast_atof( reader->getAttributeValue(i) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// read a vector property
|
||||||
|
void IrrlichtBase::ReadVectorProperty (VectorProperty& out)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < reader->getAttributeCount();++i)
|
||||||
|
{
|
||||||
|
if (!ASSIMP_stricmp(reader->getAttributeName(i),"name"))
|
||||||
|
{
|
||||||
|
out.name = std::string( reader->getAttributeValue(i) );
|
||||||
|
}
|
||||||
|
else if (!ASSIMP_stricmp(reader->getAttributeName(i),"value"))
|
||||||
|
{
|
||||||
|
// three floats, separated with commas
|
||||||
|
const char* ptr = reader->getAttributeValue(i);
|
||||||
|
|
||||||
|
SkipSpaces(&ptr);
|
||||||
|
ptr = fast_atof_move( ptr,(float&)out.value.x );
|
||||||
|
SkipSpaces(&ptr);
|
||||||
|
if (',' != *ptr)
|
||||||
|
{
|
||||||
|
DefaultLogger::get()->error("IRR(MESH): Expected comma in vector definition");
|
||||||
|
}
|
||||||
|
else SkipSpaces(ptr+1,&ptr);
|
||||||
|
ptr = fast_atof_move( ptr,(float&)out.value.y );
|
||||||
|
SkipSpaces(&ptr);
|
||||||
|
if (',' != *ptr)
|
||||||
|
{
|
||||||
|
DefaultLogger::get()->error("IRR(MESH): Expected comma in vector definition");
|
||||||
|
}
|
||||||
|
else SkipSpaces(ptr+1,&ptr);
|
||||||
|
ptr = fast_atof_move( ptr,(float&)out.value.z );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ColorFromARGBPacked(uint32_t in, aiColor4D& clr)
|
void ColorFromARGBPacked(uint32_t in, aiColor4D& clr)
|
||||||
{
|
{
|
||||||
|
@ -194,7 +182,7 @@ int ConvertMappingMode(const std::string& mode)
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Parse a material from the XML file
|
// Parse a material from the XML file
|
||||||
aiMaterial* IRRMeshImporter::ParseMaterial(unsigned int& matFlags)
|
aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags)
|
||||||
{
|
{
|
||||||
MaterialHelper* mat = new MaterialHelper();
|
MaterialHelper* mat = new MaterialHelper();
|
||||||
aiColor4D clr;
|
aiColor4D clr;
|
||||||
|
@ -351,9 +339,11 @@ aiMaterial* IRRMeshImporter::ParseMaterial(unsigned int& matFlags)
|
||||||
|
|
||||||
/* Assume there are no further nested nodes in <material> elements
|
/* Assume there are no further nested nodes in <material> elements
|
||||||
*/
|
*/
|
||||||
|
if (/* IRRMESH */ !ASSIMP_stricmp(reader->getNodeName(),"material") ||
|
||||||
return mat;
|
/* IRR */ !ASSIMP_stricmp(reader->getNodeName(),"attributes"))
|
||||||
|
{
|
||||||
|
return mat;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
|
|
||||||
// GCC complains here ...
|
// GCC complains here ...
|
||||||
|
@ -364,6 +354,55 @@ aiMaterial* IRRMeshImporter::ParseMaterial(unsigned int& matFlags)
|
||||||
return mat;
|
return mat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Constructor to be privately used by Importer
|
||||||
|
IRRMeshImporter::IRRMeshImporter()
|
||||||
|
{
|
||||||
|
// nothing to do here
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Destructor, private as well
|
||||||
|
IRRMeshImporter::~IRRMeshImporter()
|
||||||
|
{
|
||||||
|
// nothing to do here
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Returns whether the class can handle the format of the given file.
|
||||||
|
bool IRRMeshImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler) const
|
||||||
|
{
|
||||||
|
/* NOTE: A simple check for the file extension is not enough
|
||||||
|
* here. Irrmesh and irr are easy, but xml is too generic
|
||||||
|
* and could be collada, too. So we need to open the file and
|
||||||
|
* search for typical tokens.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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 i = extension.begin(); i != extension.end();++i)
|
||||||
|
*i = ::tolower(*i);
|
||||||
|
|
||||||
|
if (extension == ".irrmesh")return true;
|
||||||
|
else if (extension == ".xml")
|
||||||
|
{
|
||||||
|
/* If CanRead() is called to check whether the loader
|
||||||
|
* supports a specific file extension in general we
|
||||||
|
* must return true here.
|
||||||
|
*/
|
||||||
|
if (!pIOHandler)return true;
|
||||||
|
const char* tokens[] = {"irrmesh"};
|
||||||
|
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Imports the given file into the given scene structure.
|
// Imports the given file into the given scene structure.
|
||||||
void IRRMeshImporter::InternReadFile( const std::string& pFile,
|
void IRRMeshImporter::InternReadFile( const std::string& pFile,
|
||||||
|
@ -428,6 +467,8 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
|
||||||
curNormals.clear();
|
curNormals.clear();
|
||||||
curUV2s.clear();
|
curUV2s.clear();
|
||||||
curUVs.clear();
|
curUVs.clear();
|
||||||
|
curTangents.clear();
|
||||||
|
curBitangents.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -591,7 +632,7 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
|
||||||
curUV2s.push_back(temp);
|
curUV2s.push_back(temp);
|
||||||
}
|
}
|
||||||
// read optional tangent and bitangent vectors
|
// read optional tangent and bitangent vectors
|
||||||
if (vertexFormat == 2)
|
else if (vertexFormat == 2)
|
||||||
{
|
{
|
||||||
// tangents
|
// tangents
|
||||||
sz = fast_atof_move(sz,(float&)temp.x);
|
sz = fast_atof_move(sz,(float&)temp.x);
|
||||||
|
@ -721,6 +762,9 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (materials.empty())
|
||||||
|
throw new ImportErrorException("IRRMESH: Unable to read a mesh from this file");
|
||||||
|
|
||||||
// now generate the output scene
|
// now generate the output scene
|
||||||
pScene->mNumMeshes = (unsigned int)meshes.size();
|
pScene->mNumMeshes = (unsigned int)meshes.size();
|
||||||
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
|
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
|
||||||
|
|
|
@ -52,6 +52,51 @@ namespace Assimp {
|
||||||
#define AI_IRRMESH_MAT_lightmap_m2 (AI_IRRMESH_MAT_lightmap|0x4)
|
#define AI_IRRMESH_MAT_lightmap_m2 (AI_IRRMESH_MAT_lightmap|0x4)
|
||||||
#define AI_IRRMESH_MAT_lightmap_m4 (AI_IRRMESH_MAT_lightmap|0x5)
|
#define AI_IRRMESH_MAT_lightmap_m4 (AI_IRRMESH_MAT_lightmap|0x5)
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/** Base class for the Irr and IrrMesh importers
|
||||||
|
*/
|
||||||
|
class IrrlichtBase
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct Property
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
T value;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef Property<uint32_t> HexProperty;
|
||||||
|
typedef Property<std::string> StringProperty;
|
||||||
|
typedef Property<bool> BoolProperty;
|
||||||
|
typedef Property<float> FloatProperty;
|
||||||
|
typedef Property<aiVector3D> VectorProperty;
|
||||||
|
|
||||||
|
/** XML reader instance
|
||||||
|
*/
|
||||||
|
IrrXMLReader* reader;
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Parse a material description from the XML
|
||||||
|
* @return The created material
|
||||||
|
* @param matFlags Receives AI_IRRMESH_MAT_XX flags
|
||||||
|
*/
|
||||||
|
aiMaterial* ParseMaterial(unsigned int& matFlags);
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Read a property of the specified type from the current XML element.
|
||||||
|
* @param out Recives output data
|
||||||
|
*/
|
||||||
|
void ReadHexProperty (HexProperty& out);
|
||||||
|
void ReadStringProperty (StringProperty& out);
|
||||||
|
void ReadBoolProperty (BoolProperty& out);
|
||||||
|
void ReadFloatProperty (FloatProperty& out);
|
||||||
|
void ReadVectorProperty (VectorProperty& out);
|
||||||
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** IrrMesh importer class.
|
/** IrrMesh importer class.
|
||||||
*
|
*
|
||||||
|
@ -59,7 +104,7 @@ namespace Assimp {
|
||||||
* irrEdit. As IrrEdit itself is capable of importing quite many file formats,
|
* irrEdit. As IrrEdit itself is capable of importing quite many file formats,
|
||||||
* it might be a good file format for data exchange.
|
* it might be a good file format for data exchange.
|
||||||
*/
|
*/
|
||||||
class IRRMeshImporter : public BaseImporter
|
class IRRMeshImporter : public BaseImporter, public IrrlichtBase
|
||||||
{
|
{
|
||||||
friend class Importer;
|
friend class Importer;
|
||||||
|
|
||||||
|
@ -102,40 +147,6 @@ protected:
|
||||||
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
||||||
IOSystem* pIOHandler);
|
IOSystem* pIOHandler);
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
struct Property
|
|
||||||
{
|
|
||||||
std::string name;
|
|
||||||
T value;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef Property<uint32_t> HexProperty;
|
|
||||||
typedef Property<std::string> StringProperty;
|
|
||||||
typedef Property<bool> BoolProperty;
|
|
||||||
typedef Property<float> FloatProperty;
|
|
||||||
|
|
||||||
IrrXMLReader* reader;
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** Parse a material description from the XML
|
|
||||||
* @return The created material
|
|
||||||
* @param matFlags Receives AI_IRRMESH_MAT_XX flags
|
|
||||||
*/
|
|
||||||
aiMaterial* ParseMaterial(unsigned int& matFlags);
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** Read a property of the specified type from the current XML element.
|
|
||||||
* @param out Recives output data
|
|
||||||
*/
|
|
||||||
void ReadHexProperty (HexProperty& out);
|
|
||||||
void ReadStringProperty (StringProperty& out);
|
|
||||||
void ReadBoolProperty (BoolProperty& out);
|
|
||||||
void ReadFloatProperty (FloatProperty& out);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
|
@ -119,7 +119,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef AI_BUILD_NO_IRRMESH_IMPORTER
|
#ifndef AI_BUILD_NO_IRRMESH_IMPORTER
|
||||||
# include "IRRMeshLoader.h"
|
# include "IRRMeshLoader.h"
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef AI_BUILD_NO_IRR_IMPORTER
|
||||||
|
# include "IRRLoader.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// PostProcess-Steps
|
// PostProcess-Steps
|
||||||
|
@ -270,6 +272,9 @@ Importer::Importer() :
|
||||||
#if (!defined AI_BUILD_NO_IRRMESH_IMPORTER)
|
#if (!defined AI_BUILD_NO_IRRMESH_IMPORTER)
|
||||||
mImporter.push_back( new IRRMeshImporter());
|
mImporter.push_back( new IRRMeshImporter());
|
||||||
#endif
|
#endif
|
||||||
|
#if (!defined AI_BUILD_NO_IRR_IMPORTER)
|
||||||
|
mImporter.push_back( new IRRImporter());
|
||||||
|
#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 -
|
||||||
|
@ -291,6 +296,10 @@ Importer::Importer() :
|
||||||
mPostProcessingSteps.push_back( new RemoveVCProcess());
|
mPostProcessingSteps.push_back( new RemoveVCProcess());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if (!defined AI_BUILD_NO_REMOVE_REDUNDANTMATERIALS_PROCESS)
|
||||||
|
mPostProcessingSteps.push_back( new RemoveRedundantMatsProcess());
|
||||||
|
#endif
|
||||||
#if (!defined AI_BUILD_NO_PRETRANSFORMVERTICES_PROCESS)
|
#if (!defined AI_BUILD_NO_PRETRANSFORMVERTICES_PROCESS)
|
||||||
mPostProcessingSteps.push_back( new PretransformVertices());
|
mPostProcessingSteps.push_back( new PretransformVertices());
|
||||||
#endif
|
#endif
|
||||||
|
@ -306,9 +315,6 @@ Importer::Importer() :
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if (!defined AI_BUILD_NO_REMOVE_REDUNDANTMATERIALS_PROCESS)
|
|
||||||
mPostProcessingSteps.push_back( new RemoveRedundantMatsProcess());
|
|
||||||
#endif
|
|
||||||
#if (!defined AI_BUILD_NO_OPTIMIZEGRAPH_PROCESS)
|
#if (!defined AI_BUILD_NO_OPTIMIZEGRAPH_PROCESS)
|
||||||
mPostProcessingSteps.push_back( new OptimizeGraphProcess());
|
mPostProcessingSteps.push_back( new OptimizeGraphProcess());
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -153,13 +153,16 @@ void ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshN
|
||||||
float fACMR = (float)iCacheMisses / pMesh->mNumFaces;
|
float fACMR = (float)iCacheMisses / pMesh->mNumFaces;
|
||||||
if (3.0 == fACMR)
|
if (3.0 == fACMR)
|
||||||
{
|
{
|
||||||
char szBuff[128]; // should be sufficiently large in every case
|
if (!DefaultLogger::isNullLogger())
|
||||||
|
{
|
||||||
|
char szBuff[128]; // should be sufficiently large in every case
|
||||||
|
|
||||||
// the JoinIdenticalVertices process has not been executed on this
|
// the JoinIdenticalVertices process has not been executed on this
|
||||||
// mesh, otherwise this value would normally be at least minimally#
|
// mesh, otherwise this value would normally be at least minimally#
|
||||||
// smaller than 3.0 ...
|
// smaller than 3.0 ...
|
||||||
::sprintf(szBuff,"Mesh %i: JIV-Step has not been executed properly (precondition)",meshNum);
|
::sprintf(szBuff,"Mesh %i: Not suitable for vcache optimization",meshNum);
|
||||||
DefaultLogger::get()->warn(szBuff);
|
DefaultLogger::get()->warn(szBuff);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,9 @@ bool LWOImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler) const
|
||||||
// Setup configuration properties
|
// Setup configuration properties
|
||||||
void LWOImporter::SetupProperties(const Importer* pImp)
|
void LWOImporter::SetupProperties(const Importer* pImp)
|
||||||
{
|
{
|
||||||
configSpeedFlag = ( 0 != pImp->GetPropertyInteger(AI_CONFIG_FAVOUR_SPEED,0) ? true : false);
|
configSpeedFlag = ( 0 != pImp->GetPropertyInteger(AI_CONFIG_FAVOUR_SPEED,0) ? true : false);
|
||||||
|
configLayerIndex = pImp->GetPropertyInteger (AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY,0xffffffff);
|
||||||
|
configLayerName = pImp->GetPropertyString (AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY,"");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -384,6 +384,8 @@ protected:
|
||||||
aiScene* pScene;
|
aiScene* pScene;
|
||||||
|
|
||||||
bool configSpeedFlag;
|
bool configSpeedFlag;
|
||||||
|
unsigned int configLayerIndex;
|
||||||
|
std::string configLayerName;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -147,7 +147,6 @@ void CountVerticesAndFaces( aiScene* pcScene, aiNode* pcNode, unsigned int iMat,
|
||||||
CountVerticesAndFaces(pcScene,pcNode->mChildren[i],iMat,
|
CountVerticesAndFaces(pcScene,pcNode->mChildren[i],iMat,
|
||||||
iVFormat,piFaces,piVertices);
|
iVFormat,piFaces,piVertices);
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -167,7 +166,7 @@ void CollectData( aiScene* pcScene, aiNode* pcNode, unsigned int iMat,
|
||||||
pcMeshOut->mVertices[aiCurrent[AI_PTVS_VERTEX]+n] =
|
pcMeshOut->mVertices[aiCurrent[AI_PTVS_VERTEX]+n] =
|
||||||
pcNode->mTransformation * pcMesh->mVertices[n];
|
pcNode->mTransformation * pcMesh->mVertices[n];
|
||||||
}
|
}
|
||||||
if (iVFormat & 0x1)
|
if (iVFormat & 0x2)
|
||||||
{
|
{
|
||||||
aiMatrix4x4 mWorldIT = pcNode->mTransformation;
|
aiMatrix4x4 mWorldIT = pcNode->mTransformation;
|
||||||
mWorldIT.Inverse().Transpose();
|
mWorldIT.Inverse().Transpose();
|
||||||
|
@ -182,7 +181,7 @@ void CollectData( aiScene* pcScene, aiNode* pcNode, unsigned int iMat,
|
||||||
m * pcMesh->mNormals[n];
|
m * pcMesh->mNormals[n];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (iVFormat & 0x2)
|
if (iVFormat & 0x4)
|
||||||
{
|
{
|
||||||
// copy tangents
|
// copy tangents
|
||||||
memcpy(pcMeshOut->mTangents + aiCurrent[AI_PTVS_VERTEX],
|
memcpy(pcMeshOut->mTangents + aiCurrent[AI_PTVS_VERTEX],
|
||||||
|
@ -250,7 +249,7 @@ void CollectData( aiScene* pcScene, aiNode* pcNode, unsigned int iMat,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
aiCurrent[AI_PTVS_VERTEX] += pcMesh->mNumVertices;
|
aiCurrent[AI_PTVS_VERTEX] += pcMesh->mNumVertices;
|
||||||
aiCurrent[AI_PTVS_FACE] += pcMesh->mNumFaces;
|
aiCurrent[AI_PTVS_FACE] += pcMesh->mNumFaces;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (unsigned int i = 0;i < pcNode->mNumChildren;++i)
|
for (unsigned int i = 0;i < pcNode->mNumChildren;++i)
|
||||||
|
@ -258,28 +257,22 @@ void CollectData( aiScene* pcScene, aiNode* pcNode, unsigned int iMat,
|
||||||
CollectData(pcScene,pcNode->mChildren[i],iMat,
|
CollectData(pcScene,pcNode->mChildren[i],iMat,
|
||||||
iVFormat,pcMeshOut,aiCurrent);
|
iVFormat,pcMeshOut,aiCurrent);
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Get a list of all vertex formats that occur for a given material index
|
// Get a list of all vertex formats that occur for a given material index
|
||||||
// The output list contains duplicate elements
|
// The output list contains duplicate elements
|
||||||
void GetVFormatList( aiScene* pcScene, aiNode* pcNode, unsigned int iMat,
|
void GetVFormatList( aiScene* pcScene, unsigned int iMat,
|
||||||
std::list<unsigned int>& aiOut)
|
std::list<unsigned int>& aiOut)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < pcNode->mNumMeshes;++i)
|
for (unsigned int i = 0; i < pcScene->mNumMeshes;++i)
|
||||||
{
|
{
|
||||||
aiMesh* pcMesh = pcScene->mMeshes[ pcNode->mMeshes[i] ];
|
aiMesh* pcMesh = pcScene->mMeshes[ i ];
|
||||||
if (iMat == pcMesh->mMaterialIndex)
|
if (iMat == pcMesh->mMaterialIndex)
|
||||||
{
|
{
|
||||||
aiOut.push_back(GetMeshVFormat(pcMesh));
|
aiOut.push_back(GetMeshVFormat(pcMesh));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (unsigned int i = 0;i < pcNode->mNumChildren;++i)
|
|
||||||
{
|
|
||||||
GetVFormatList(pcScene,pcNode->mChildren[i],iMat,aiOut);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -295,7 +288,6 @@ void ComputeAbsoluteTransform( aiNode* pcNode )
|
||||||
{
|
{
|
||||||
ComputeAbsoluteTransform(pcNode->mChildren[i]);
|
ComputeAbsoluteTransform(pcNode->mChildren[i]);
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -333,8 +325,8 @@ void PretransformVertices::Execute( aiScene* pScene)
|
||||||
{
|
{
|
||||||
// get the list of all vertex formats for this material
|
// get the list of all vertex formats for this material
|
||||||
aiVFormats.clear();
|
aiVFormats.clear();
|
||||||
GetVFormatList(pScene,pScene->mRootNode,i,aiVFormats);
|
GetVFormatList(pScene,i,aiVFormats);
|
||||||
aiVFormats.sort(std::less<unsigned int>());
|
aiVFormats.sort();
|
||||||
aiVFormats.unique();
|
aiVFormats.unique();
|
||||||
for (std::list<unsigned int>::const_iterator
|
for (std::list<unsigned int>::const_iterator
|
||||||
j = aiVFormats.begin();
|
j = aiVFormats.begin();
|
||||||
|
@ -352,11 +344,11 @@ void PretransformVertices::Execute( aiScene* pScene)
|
||||||
pcMesh->mFaces = new aiFace[iFaces];
|
pcMesh->mFaces = new aiFace[iFaces];
|
||||||
pcMesh->mVertices = new aiVector3D[iVertices];
|
pcMesh->mVertices = new aiVector3D[iVertices];
|
||||||
pcMesh->mMaterialIndex = i;
|
pcMesh->mMaterialIndex = i;
|
||||||
if ((*j) & 0x1)pcMesh->mNormals = new aiVector3D[iVertices];
|
if ((*j) & 0x2)pcMesh->mNormals = new aiVector3D[iVertices];
|
||||||
if ((*j) & 0x2)
|
if ((*j) & 0x4)
|
||||||
{
|
{
|
||||||
pcMesh->mTangents = new aiVector3D[iVertices];
|
pcMesh->mTangents = new aiVector3D[iVertices];
|
||||||
pcMesh->mBitangents = new aiVector3D[iVertices];
|
pcMesh->mBitangents = new aiVector3D[iVertices];
|
||||||
}
|
}
|
||||||
iFaces = 0;
|
iFaces = 0;
|
||||||
while ((*j) & (0x100 << iFaces))
|
while ((*j) & (0x100 << iFaces))
|
||||||
|
@ -396,17 +388,28 @@ void PretransformVertices::Execute( aiScene* pScene)
|
||||||
// the mesh array are not overridden. We set them to NULL to
|
// the mesh array are not overridden. We set them to NULL to
|
||||||
// make sure the developer gets notified when his application
|
// make sure the developer gets notified when his application
|
||||||
// attempts to access these fields ...
|
// attempts to access these fields ...
|
||||||
AI_DEBUG_INVALIDATE_PTR( pScene->mMeshes[i] );
|
pScene->mMeshes[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pScene->mNumMeshes = (unsigned int)apcOutMeshes.size();
|
// If no meshes are referenced in the node graph it is
|
||||||
if (apcOutMeshes.size() > pScene->mNumMeshes)
|
// possible that we get no output meshes. However, this
|
||||||
|
// is OK if we had no input meshes, too
|
||||||
|
if (apcOutMeshes.empty())
|
||||||
{
|
{
|
||||||
delete[] pScene->mMeshes;
|
if (pScene->mNumMeshes)
|
||||||
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
|
{
|
||||||
|
throw new ImportErrorException("No output meshes: all meshes are orphaned "
|
||||||
|
"and have no node references");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// It is impossible that we have more output meshes than
|
||||||
|
// input meshes, so we can easily reuse the old mesh array
|
||||||
|
pScene->mNumMeshes = (unsigned int)apcOutMeshes.size();
|
||||||
|
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
|
||||||
|
pScene->mMeshes[i] = apcOutMeshes[i];
|
||||||
}
|
}
|
||||||
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
|
|
||||||
pScene->mMeshes[i] = apcOutMeshes[i];
|
|
||||||
|
|
||||||
// --- we need to keep all cameras and lights
|
// --- we need to keep all cameras and lights
|
||||||
for (unsigned int i = 0; i < pScene->mNumCameras;++i)
|
for (unsigned int i = 0; i < pScene->mNumCameras;++i)
|
||||||
|
|
|
@ -132,6 +132,12 @@ bool SortByPTypeProcess::IsActive( unsigned int pFlags) const
|
||||||
return (pFlags & aiProcess_SortByPType) != 0;
|
return (pFlags & aiProcess_SortByPType) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void SortByPTypeProcess::SetupProperties(const Importer* pImp)
|
||||||
|
{
|
||||||
|
configRemoveMeshes = pImp->GetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE,0);
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Update changed meshes in all nodes
|
// Update changed meshes in all nodes
|
||||||
void UpdateNodes(const std::vector<unsigned int>& replaceMeshIndex, aiNode* node)
|
void UpdateNodes(const std::vector<unsigned int>& replaceMeshIndex, aiNode* node)
|
||||||
|
@ -143,26 +149,38 @@ void UpdateNodes(const std::vector<unsigned int>& replaceMeshIndex, aiNode* node
|
||||||
unsigned int newSize = 0;
|
unsigned int newSize = 0;
|
||||||
for (unsigned int m = 0; m< node->mNumMeshes; ++m)
|
for (unsigned int m = 0; m< node->mNumMeshes; ++m)
|
||||||
{
|
{
|
||||||
it = replaceMeshIndex.begin()+(node->mMeshes[m]*5u);
|
unsigned int add = node->mMeshes[m]<<2;
|
||||||
for (;*it != 0xcdcdcdcd;++it)
|
for (unsigned int i = 0; i < 4;++i)
|
||||||
{
|
{
|
||||||
if (0xffffffff != *it)++newSize;
|
if (0xffffffff != replaceMeshIndex[add+i])++newSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!newSize)
|
||||||
ai_assert(0 != newSize);
|
|
||||||
|
|
||||||
unsigned int* newMeshes = new unsigned int[newSize];
|
|
||||||
for (unsigned int m = 0; m< node->mNumMeshes; ++m)
|
|
||||||
{
|
{
|
||||||
it = replaceMeshIndex.begin()+(node->mMeshes[m]*5u);
|
delete[] node->mMeshes;
|
||||||
for (;*it != 0xcdcdcdcd;++it)
|
node->mNumMeshes = 0;
|
||||||
{
|
node->mMeshes = NULL;
|
||||||
if (0xffffffff != *it)*newMeshes++ = *it;
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
|
// Try to reuse the old array if possible
|
||||||
|
unsigned int* newMeshes = (newSize > node->mNumMeshes
|
||||||
|
? new unsigned int[newSize] : node->mMeshes);
|
||||||
|
|
||||||
|
for (unsigned int m = 0; m< node->mNumMeshes; ++m)
|
||||||
|
{
|
||||||
|
unsigned int add = node->mMeshes[m]<<2;
|
||||||
|
for (unsigned int i = 0; i < 4;++i)
|
||||||
|
{
|
||||||
|
if (0xffffffff != replaceMeshIndex[add+i])
|
||||||
|
*newMeshes++ = replaceMeshIndex[add+i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (newSize > node->mNumMeshes)
|
||||||
|
delete[] node->mMeshes;
|
||||||
|
|
||||||
|
node->mMeshes = newMeshes-(node->mNumMeshes = newSize);
|
||||||
}
|
}
|
||||||
delete[] node->mMeshes;
|
|
||||||
node->mMeshes = newMeshes-(node->mNumMeshes = newSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// call all subnodes recursively
|
// call all subnodes recursively
|
||||||
|
@ -189,7 +207,7 @@ void SortByPTypeProcess::Execute( aiScene* pScene)
|
||||||
|
|
||||||
bool bAnyChanges = false;
|
bool bAnyChanges = false;
|
||||||
|
|
||||||
std::vector<unsigned int> replaceMeshIndex(pScene->mNumMeshes*5,0xffffffff);
|
std::vector<unsigned int> replaceMeshIndex(pScene->mNumMeshes*4,0xffffffff);
|
||||||
std::vector<unsigned int>::iterator meshIdx = replaceMeshIndex.begin();
|
std::vector<unsigned int>::iterator meshIdx = replaceMeshIndex.begin();
|
||||||
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
|
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
|
||||||
{
|
{
|
||||||
|
@ -221,12 +239,14 @@ void SortByPTypeProcess::Execute( aiScene* pScene)
|
||||||
|
|
||||||
if (1 == num)
|
if (1 == num)
|
||||||
{
|
{
|
||||||
*meshIdx = (unsigned int) outMeshes.size();
|
if (!(configRemoveMeshes & mesh->mPrimitiveTypes))
|
||||||
outMeshes.push_back(mesh);
|
{
|
||||||
|
*meshIdx = (unsigned int) outMeshes.size();
|
||||||
|
outMeshes.push_back(mesh);
|
||||||
|
}
|
||||||
|
else bAnyChanges = true;
|
||||||
|
|
||||||
meshIdx += 4;
|
meshIdx += 4;
|
||||||
*meshIdx = 0xcdcdcdcd;
|
|
||||||
++meshIdx;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
bAnyChanges = true;
|
bAnyChanges = true;
|
||||||
|
@ -253,7 +273,7 @@ void SortByPTypeProcess::Execute( aiScene* pScene)
|
||||||
VertexWeightTable* avw = ComputeVertexBoneWeightTable(mesh);
|
VertexWeightTable* avw = ComputeVertexBoneWeightTable(mesh);
|
||||||
for (unsigned int real = 0; real < 4; ++real,++meshIdx)
|
for (unsigned int real = 0; real < 4; ++real,++meshIdx)
|
||||||
{
|
{
|
||||||
if ( !aiNumPerPType[real])
|
if ( !aiNumPerPType[real] || configRemoveMeshes & (1u << real))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -343,7 +363,7 @@ void SortByPTypeProcess::Execute( aiScene* pScene)
|
||||||
if (vert)
|
if (vert)
|
||||||
{
|
{
|
||||||
*vert++ = mesh->mVertices[idx];
|
*vert++ = mesh->mVertices[idx];
|
||||||
mesh->mVertices[idx].x = std::numeric_limits<float>::quiet_NaN();
|
//mesh->mVertices[idx].x = std::numeric_limits<float>::quiet_NaN();
|
||||||
}
|
}
|
||||||
if (nor )*nor++ = mesh->mNormals[idx];
|
if (nor )*nor++ = mesh->mNormals[idx];
|
||||||
if (tan )
|
if (tan )
|
||||||
|
@ -370,6 +390,7 @@ void SortByPTypeProcess::Execute( aiScene* pScene)
|
||||||
in.mIndices = NULL;
|
in.mIndices = NULL;
|
||||||
++outFaces;
|
++outFaces;
|
||||||
}
|
}
|
||||||
|
ai_assert(outFaces == out->mFaces + out->mNumFaces);
|
||||||
|
|
||||||
// now generate output bones
|
// now generate output bones
|
||||||
for (unsigned int q = 0; q < mesh->mNumBones;++q)
|
for (unsigned int q = 0; q < mesh->mNumBones;++q)
|
||||||
|
@ -399,9 +420,6 @@ void SortByPTypeProcess::Execute( aiScene* pScene)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*meshIdx = 0xcdcdcdcd;
|
|
||||||
++meshIdx;
|
|
||||||
|
|
||||||
// delete the per-vertex bone weights table
|
// delete the per-vertex bone weights table
|
||||||
delete[] avw;
|
delete[] avw;
|
||||||
|
|
||||||
|
@ -409,6 +427,12 @@ void SortByPTypeProcess::Execute( aiScene* pScene)
|
||||||
delete mesh;
|
delete mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (outMeshes.empty())
|
||||||
|
{
|
||||||
|
// This should not occur
|
||||||
|
throw new ImportErrorException("No meshes remaining");
|
||||||
|
}
|
||||||
|
|
||||||
// If we added at least one mesh process all nodes in the node
|
// If we added at least one mesh process all nodes in the node
|
||||||
// graph and update their respective mesh indices.
|
// graph and update their respective mesh indices.
|
||||||
if (bAnyChanges)
|
if (bAnyChanges)
|
||||||
|
@ -421,17 +445,17 @@ void SortByPTypeProcess::Execute( aiScene* pScene)
|
||||||
delete[] pScene->mMeshes;
|
delete[] pScene->mMeshes;
|
||||||
pScene->mNumMeshes = (unsigned int)outMeshes.size();
|
pScene->mNumMeshes = (unsigned int)outMeshes.size();
|
||||||
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
|
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
|
||||||
::memcpy(pScene->mMeshes,&outMeshes[0],pScene->mNumMeshes*sizeof(void*));
|
|
||||||
}
|
}
|
||||||
|
::memcpy(pScene->mMeshes,&outMeshes[0],pScene->mNumMeshes*sizeof(void*));
|
||||||
|
|
||||||
if (!DefaultLogger::isNullLogger())
|
if (!DefaultLogger::isNullLogger())
|
||||||
{
|
{
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
::sprintf(buffer,"Points: %i, Lines: %i, Triangles: %i, Polygons: %i (Meshes)",
|
::sprintf(buffer,"Points: %i%s, Lines: %i%s, Triangles: %i%s, Polygons: %i%s (Meshes, X = removed)",
|
||||||
aiNumMeshesPerPType[0],
|
aiNumMeshesPerPType[0], (configRemoveMeshes & aiPrimitiveType_POINT ? "X" : ""),
|
||||||
aiNumMeshesPerPType[1],
|
aiNumMeshesPerPType[1], (configRemoveMeshes & aiPrimitiveType_LINE ? "X" : ""),
|
||||||
aiNumMeshesPerPType[2],
|
aiNumMeshesPerPType[2], (configRemoveMeshes & aiPrimitiveType_TRIANGLE ? "X" : ""),
|
||||||
aiNumMeshesPerPType[3]);
|
aiNumMeshesPerPType[3], (configRemoveMeshes & aiPrimitiveType_POLYGON ? "X" : ""));
|
||||||
DefaultLogger::get()->info(buffer);
|
DefaultLogger::get()->info(buffer);
|
||||||
DefaultLogger::get()->debug("SortByPTypeProcess finished");
|
DefaultLogger::get()->debug("SortByPTypeProcess finished");
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,6 +102,13 @@ public:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
void SetupProperties(const Importer* pImp);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
int configRemoveMeshes;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -52,33 +52,36 @@ namespace Assimp {
|
||||||
positions.push_back(n1); \
|
positions.push_back(n1); \
|
||||||
positions.push_back(n0);
|
positions.push_back(n0);
|
||||||
|
|
||||||
#ifdef AI_STANDARD_SHAPES_OUTPUT_POLYGONS
|
|
||||||
|
|
||||||
# define ADD_PENTAGON(n0,n1,n2,n3,n4) \
|
# define ADD_PENTAGON(n0,n1,n2,n3,n4) \
|
||||||
positions.push_back(n0); \
|
if (polygons) \
|
||||||
positions.push_back(n1); \
|
{ \
|
||||||
positions.push_back(n2); \
|
positions.push_back(n0); \
|
||||||
positions.push_back(n3); \
|
positions.push_back(n1); \
|
||||||
positions.push_back(n4);
|
positions.push_back(n2); \
|
||||||
|
positions.push_back(n3); \
|
||||||
|
positions.push_back(n4); \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
ADD_TRIANGLE(n0, n1, n2) \
|
||||||
|
ADD_TRIANGLE(n0, n2, n3) \
|
||||||
|
ADD_TRIANGLE(n0, n3, n4) \
|
||||||
|
}
|
||||||
|
|
||||||
# define ADD_QUAD(n0,n1,n2,n3) \
|
# define ADD_QUAD(n0,n1,n2,n3) \
|
||||||
positions.push_back(n0); \
|
if (polygons) \
|
||||||
positions.push_back(n1); \
|
{ \
|
||||||
positions.push_back(n2); \
|
positions.push_back(n0); \
|
||||||
positions.push_back(n3);
|
positions.push_back(n1); \
|
||||||
|
positions.push_back(n2); \
|
||||||
|
positions.push_back(n3); \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
ADD_TRIANGLE(n0, n1, n2) \
|
||||||
|
ADD_TRIANGLE(n0, n2, n3) \
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
# define ADD_PENTAGON(n0,n1,n2,n3,n4) \
|
|
||||||
ADD_TRIANGLE(n0, n1, n2) \
|
|
||||||
ADD_TRIANGLE(n0, n2, n3) \
|
|
||||||
ADD_TRIANGLE(n0, n3, n4)
|
|
||||||
|
|
||||||
# define ADD_QUAD(n0,n1,n2,n3) \
|
|
||||||
ADD_TRIANGLE(n0, n1, n2) \
|
|
||||||
ADD_TRIANGLE(n0, n2, n3)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Subdivide(std::vector<aiVector3D>& positions)
|
void Subdivide(std::vector<aiVector3D>& positions)
|
||||||
|
@ -105,9 +108,74 @@ void Subdivide(std::vector<aiVector3D>& positions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
aiMesh* StandardShapes::MakeMesh(const std::vector<aiVector3D>& positions,
|
||||||
|
unsigned int numIndices)
|
||||||
|
{
|
||||||
|
if (positions.size() & numIndices || positions.empty() || !numIndices)return NULL;
|
||||||
|
|
||||||
|
aiMesh* out = new aiMesh();
|
||||||
|
switch (numIndices)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
out->mPrimitiveTypes = aiPrimitiveType_POINT;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
out->mPrimitiveTypes = aiPrimitiveType_LINE;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
out->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
out->mPrimitiveTypes = aiPrimitiveType_POLYGON;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
out->mNumFaces = (unsigned int)positions.size() / numIndices;
|
||||||
|
out->mFaces = new aiFace[out->mNumFaces];
|
||||||
|
for (unsigned int i = 0, a = 0; i < out->mNumFaces;++i)
|
||||||
|
{
|
||||||
|
aiFace& f = out->mFaces[i];
|
||||||
|
f.mNumIndices = numIndices;
|
||||||
|
f.mIndices = new unsigned int[numIndices];
|
||||||
|
for (unsigned int i = 0; i < numIndices;++i,++a)
|
||||||
|
f.mIndices[i] = a;
|
||||||
|
}
|
||||||
|
out->mNumVertices = (unsigned int)positions.size();
|
||||||
|
out->mVertices = new aiVector3D[out->mNumVertices];
|
||||||
|
::memcpy(out->mVertices,&positions[0],out->mNumVertices*sizeof(aiVector3D));
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void StandardShapes::MakeIcosahedron(std::vector<aiVector3D>& positions)
|
aiMesh* StandardShapes::MakeMesh ( unsigned int (*GenerateFunc)(
|
||||||
|
std::vector<aiVector3D>&))
|
||||||
|
{
|
||||||
|
std::vector<aiVector3D> temp;
|
||||||
|
unsigned num = (*GenerateFunc)(temp);
|
||||||
|
return MakeMesh(temp,num);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
aiMesh* StandardShapes::MakeMesh ( unsigned int (*GenerateFunc)(
|
||||||
|
std::vector<aiVector3D>&, bool))
|
||||||
|
{
|
||||||
|
std::vector<aiVector3D> temp;
|
||||||
|
unsigned num = (*GenerateFunc)(temp,true);
|
||||||
|
return MakeMesh(temp,num);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
aiMesh* StandardShapes::MakeMesh ( unsigned int (*GenerateFunc)(
|
||||||
|
unsigned int,std::vector<aiVector3D>&))
|
||||||
|
{
|
||||||
|
std::vector<aiVector3D> temp;
|
||||||
|
unsigned num = (*GenerateFunc)(4,temp);
|
||||||
|
return MakeMesh(temp,num);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
unsigned int StandardShapes::MakeIcosahedron(std::vector<aiVector3D>& positions)
|
||||||
{
|
{
|
||||||
positions.reserve(positions.size()+60);
|
positions.reserve(positions.size()+60);
|
||||||
|
|
||||||
|
@ -151,10 +219,12 @@ void StandardShapes::MakeIcosahedron(std::vector<aiVector3D>& positions)
|
||||||
ADD_TRIANGLE(v9,v4,v6);
|
ADD_TRIANGLE(v9,v4,v6);
|
||||||
ADD_TRIANGLE(v10,v5,v7);
|
ADD_TRIANGLE(v10,v5,v7);
|
||||||
ADD_TRIANGLE(v11,v7,v5);
|
ADD_TRIANGLE(v11,v7,v5);
|
||||||
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void StandardShapes::MakeDodecahedron(std::vector<aiVector3D>& positions)
|
unsigned int StandardShapes::MakeDodecahedron(std::vector<aiVector3D>& positions,
|
||||||
|
bool polygons /*= false*/)
|
||||||
{
|
{
|
||||||
positions.reserve(positions.size()+108);
|
positions.reserve(positions.size()+108);
|
||||||
|
|
||||||
|
@ -196,10 +266,11 @@ void StandardShapes::MakeDodecahedron(std::vector<aiVector3D>& positions)
|
||||||
ADD_PENTAGON(v7, v15, v5, v18, v19);
|
ADD_PENTAGON(v7, v15, v5, v18, v19);
|
||||||
ADD_PENTAGON(v7, v11, v6, v14, v15);
|
ADD_PENTAGON(v7, v11, v6, v14, v15);
|
||||||
ADD_PENTAGON(v7, v19, v3, v10, v11);
|
ADD_PENTAGON(v7, v19, v3, v10, v11);
|
||||||
|
return (polygons ? 5 : 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void StandardShapes::MakeOctahedron(std::vector<aiVector3D>& positions)
|
unsigned int StandardShapes::MakeOctahedron(std::vector<aiVector3D>& positions)
|
||||||
{
|
{
|
||||||
positions.reserve(positions.size()+24);
|
positions.reserve(positions.size()+24);
|
||||||
|
|
||||||
|
@ -219,10 +290,11 @@ void StandardShapes::MakeOctahedron(std::vector<aiVector3D>& positions)
|
||||||
ADD_TRIANGLE(v5,v1,v2);
|
ADD_TRIANGLE(v5,v1,v2);
|
||||||
ADD_TRIANGLE(v5,v3,v1);
|
ADD_TRIANGLE(v5,v3,v1);
|
||||||
ADD_TRIANGLE(v5,v0,v3);
|
ADD_TRIANGLE(v5,v0,v3);
|
||||||
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void StandardShapes::MakeTetrahedron(std::vector<aiVector3D>& positions)
|
unsigned int StandardShapes::MakeTetrahedron(std::vector<aiVector3D>& positions)
|
||||||
{
|
{
|
||||||
positions.reserve(positions.size()+9);
|
positions.reserve(positions.size()+9);
|
||||||
|
|
||||||
|
@ -238,10 +310,12 @@ void StandardShapes::MakeTetrahedron(std::vector<aiVector3D>& positions)
|
||||||
ADD_TRIANGLE(v0,v2,v3);
|
ADD_TRIANGLE(v0,v2,v3);
|
||||||
ADD_TRIANGLE(v0,v3,v1);
|
ADD_TRIANGLE(v0,v3,v1);
|
||||||
ADD_TRIANGLE(v1,v3,v2);
|
ADD_TRIANGLE(v1,v3,v2);
|
||||||
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void StandardShapes::MakeHexahedron(std::vector<aiVector3D>& positions)
|
unsigned int StandardShapes::MakeHexahedron(std::vector<aiVector3D>& positions,
|
||||||
|
bool polygons /*= false*/)
|
||||||
{
|
{
|
||||||
positions.reserve(positions.size()+36);
|
positions.reserve(positions.size()+36);
|
||||||
float length = 1.f/1.73205080f;
|
float length = 1.f/1.73205080f;
|
||||||
|
@ -261,9 +335,13 @@ void StandardShapes::MakeHexahedron(std::vector<aiVector3D>& positions)
|
||||||
ADD_QUAD(v6,v5,v1,v2);
|
ADD_QUAD(v6,v5,v1,v2);
|
||||||
ADD_QUAD(v6,v2,v3,v7);
|
ADD_QUAD(v6,v2,v3,v7);
|
||||||
ADD_QUAD(v6,v7,v4,v5);
|
ADD_QUAD(v6,v7,v4,v5);
|
||||||
|
return (polygons ? 4 : 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cleanup ...
|
||||||
#undef ADD_TRIANGLE
|
#undef ADD_TRIANGLE
|
||||||
|
#undef ADD_QUAD
|
||||||
|
#undef ADD_PENTAGON
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void StandardShapes::MakeSphere(unsigned int tess,
|
void StandardShapes::MakeSphere(unsigned int tess,
|
||||||
|
|
|
@ -60,45 +60,83 @@ class ASSIMP_API StandardShapes
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------
|
||||||
|
/** Generates a mesh from an array of vertex positions.
|
||||||
|
*
|
||||||
|
* @param positions List of vertex positions
|
||||||
|
* @param numIndices Number of indices per primitive
|
||||||
|
* @return Output mesh
|
||||||
|
*/
|
||||||
|
static aiMesh* MakeMesh(const std::vector<aiVector3D>& positions,
|
||||||
|
unsigned int numIndices);
|
||||||
|
|
||||||
|
|
||||||
|
static aiMesh* MakeMesh ( unsigned int (*GenerateFunc)
|
||||||
|
(std::vector<aiVector3D>&));
|
||||||
|
|
||||||
|
static aiMesh* MakeMesh ( unsigned int (*GenerateFunc)
|
||||||
|
(std::vector<aiVector3D>&, bool));
|
||||||
|
|
||||||
|
static aiMesh* MakeMesh ( unsigned int (*GenerateFunc)
|
||||||
|
(unsigned int,std::vector<aiVector3D>&));
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------
|
||||||
/** @brief Generates a hexahedron (cube)
|
/** @brief Generates a hexahedron (cube)
|
||||||
*
|
*
|
||||||
* Hexahedrons can be scaled on all axes.
|
* Hexahedrons can be scaled on all axes.
|
||||||
* @param positions Receives output triangles.
|
* @param positions Receives output triangles.
|
||||||
*
|
* @param polygons If you pass true here quads will be returned
|
||||||
* @note If you define AI_STANDARD_SHAPES_OUTPUT_POLYGONS quads
|
* @return Number of vertices per face
|
||||||
* instead of triangles are returned.
|
|
||||||
*/
|
*/
|
||||||
static void MakeHexahedron(std::vector<aiVector3D>& positions);
|
static unsigned int MakeHexahedron(
|
||||||
|
std::vector<aiVector3D>& positions,
|
||||||
|
bool polygons = false);
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------
|
||||||
/** @brief Generates an icosahedron
|
/** @brief Generates an icosahedron
|
||||||
*
|
*
|
||||||
* @param positions Receives output triangles.
|
* @param positions Receives output triangles.
|
||||||
|
* @return Number of vertices per face
|
||||||
*/
|
*/
|
||||||
static void MakeIcosahedron(std::vector<aiVector3D>& positions);
|
static unsigned int MakeIcosahedron(
|
||||||
|
std::vector<aiVector3D>& positions);
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------
|
||||||
/** @brief Generates a dodecahedron
|
/** @brief Generates a dodecahedron
|
||||||
*
|
*
|
||||||
* @param positions Receives output triangles
|
* @param positions Receives output triangles
|
||||||
* @note If you define AI_STANDARD_SHAPES_OUTPUT_POLYGONS pentagons
|
* @param polygons If you pass true here pentagons will be returned
|
||||||
* instead of triangles are returned.
|
* @return Number of vertices per face
|
||||||
*/
|
*/
|
||||||
static void MakeDodecahedron(std::vector<aiVector3D>& positions);
|
static unsigned int MakeDodecahedron(
|
||||||
|
std::vector<aiVector3D>& positions,
|
||||||
|
bool polygons = false);
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------
|
||||||
/** @brief Generates an octahedron
|
/** @brief Generates an octahedron
|
||||||
*
|
*
|
||||||
* @param positions Receives output triangles.
|
* @param positions Receives output triangles.
|
||||||
|
* @return Number of vertices per face
|
||||||
*/
|
*/
|
||||||
static void MakeOctahedron(std::vector<aiVector3D>& positions);
|
static unsigned int MakeOctahedron(
|
||||||
|
std::vector<aiVector3D>& positions);
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------
|
||||||
/** @brief Generates a tetrahedron
|
/** @brief Generates a tetrahedron
|
||||||
*
|
*
|
||||||
* @param positions Receives output triangles.
|
* @param positions Receives output triangles.
|
||||||
|
* @return Number of vertices per face
|
||||||
*/
|
*/
|
||||||
static void MakeTetrahedron(std::vector<aiVector3D>& positions);
|
static unsigned int MakeTetrahedron(
|
||||||
|
std::vector<aiVector3D>& positions);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------
|
||||||
/** @brief Generates a sphere
|
/** @brief Generates a sphere
|
||||||
*
|
*
|
||||||
* @param tess Number of subdivions - 0 generates a octahedron
|
* @param tess Number of subdivions - 0 generates a octahedron
|
||||||
|
@ -107,7 +145,9 @@ public:
|
||||||
static void MakeSphere(unsigned int tess,
|
static void MakeSphere(unsigned int tess,
|
||||||
std::vector<aiVector3D>& positions);
|
std::vector<aiVector3D>& positions);
|
||||||
|
|
||||||
/** @brief Generates a cone or a cylinder, either opened or closed.
|
|
||||||
|
// ----------------------------------------------------------------
|
||||||
|
/** @brief Generates a cone or a cylinder, either open or closed.
|
||||||
*
|
*
|
||||||
* @code
|
* @code
|
||||||
*
|
*
|
||||||
|
@ -136,6 +176,8 @@ public:
|
||||||
aiVector3D& center2,float radius2,unsigned int tess,
|
aiVector3D& center2,float radius2,unsigned int tess,
|
||||||
std::vector<aiVector3D>& positions,bool bOpened = false);
|
std::vector<aiVector3D>& positions,bool bOpened = false);
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------
|
||||||
/** @brief Generates a flat circle
|
/** @brief Generates a flat circle
|
||||||
*
|
*
|
||||||
* @param center Center point of the circle
|
* @param center Center point of the circle
|
||||||
|
|
|
@ -43,4 +43,4 @@ private:
|
||||||
|
|
||||||
} // ! Assimp
|
} // ! Assimp
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -69,7 +69,8 @@ SOURCES = AssimpPCH.cpp \
|
||||||
FindDegenerates.cpp \
|
FindDegenerates.cpp \
|
||||||
XFileParser.cpp \
|
XFileParser.cpp \
|
||||||
./irrXML/irrXML.cpp \
|
./irrXML/irrXML.cpp \
|
||||||
IRRMeshLoader.cpp
|
IRRMeshLoader.cpp \
|
||||||
|
IRRLoader.cpp
|
||||||
|
|
||||||
OBJECTS = $(SOURCES:.cpp=.o)
|
OBJECTS = $(SOURCES:.cpp=.o)
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,8 @@ SOURCES = AssimpPCH.cpp \
|
||||||
SkeletonMeshBuilder.cpp \
|
SkeletonMeshBuilder.cpp \
|
||||||
BVHLoader.cpp \
|
BVHLoader.cpp \
|
||||||
./irrXML/irrXML.cpp \
|
./irrXML/irrXML.cpp \
|
||||||
IRRMeshLoader.cpp
|
IRRMeshLoader.cpp \
|
||||||
|
IRRLoader.cpp
|
||||||
|
|
||||||
OBJECTS = $(SOURCES:.cpp=.o)
|
OBJECTS = $(SOURCES:.cpp=.o)
|
||||||
|
|
||||||
|
|
|
@ -120,6 +120,29 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define AI_CONFIG_IMPORT_AC_SEPARATE_BFCULL "imp.ac.sepbfcull"
|
#define AI_CONFIG_IMPORT_AC_SEPARATE_BFCULL "imp.ac.sepbfcull"
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/** \brief Configures the ASE loader to always reconstruct normal vectors
|
||||||
|
* basing on the smoothing groups loaded from the file.
|
||||||
|
*
|
||||||
|
* Many ASE files have invalid normals (they're not orthonormal). This
|
||||||
|
* is the fault of 3DS Max ASE exporter.
|
||||||
|
* Property type: integer (0: false; !0: true). Default value: false.
|
||||||
|
*/
|
||||||
|
#define AI_CONFIG_IMPORT_ASE_RECONSTRUCT_NORMALS "imp.ase.reconn"
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/** \brief Configures the LWO loader to load just one layer from the model.
|
||||||
|
*
|
||||||
|
* LWO files consist of layers and in some cases it could be useful to load
|
||||||
|
* only one of them. This property can be either a string - which specifies
|
||||||
|
* the name of the layer - or an integer - the index of the layer. If the
|
||||||
|
* property is not set the whole LWO model is loaded. Loading fails if the
|
||||||
|
* requested layer is not available.
|
||||||
|
*/
|
||||||
|
#define AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY "imp.lwo.layer"
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** \brief Specifies the maximum angle that may be between two vertex tangents
|
/** \brief Specifies the maximum angle that may be between two vertex tangents
|
||||||
* that their tangents and bitangents are smoothed.
|
* that their tangents and bitangents are smoothed.
|
||||||
|
@ -251,6 +274,16 @@ enum aiComponent
|
||||||
*/
|
*/
|
||||||
#define AI_CONFIG_PP_RVC_FLAGS "pp.rvc.flags"
|
#define AI_CONFIG_PP_RVC_FLAGS "pp.rvc.flags"
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/** \brief Input parameter to the #aiProcess_SortByPType step:
|
||||||
|
* Specifies which primitive types are removed by the step.
|
||||||
|
*
|
||||||
|
* This is a bitwise combination of the aiPrimitiveType flags.
|
||||||
|
* Specifying all of them is illegal, of course. A typical use would
|
||||||
|
* be to easily exclude all line and point meshes from the import. This
|
||||||
|
* is an integer property, its default value is 0.
|
||||||
|
*/
|
||||||
|
#define AI_CONFIG_PP_SBP_REMOVE "pp.sbp.remove"
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -264,4 +297,7 @@ enum aiComponent
|
||||||
*/
|
*/
|
||||||
#define AI_CONFIG_FAVOUR_SPEED "imp.speed_flag"
|
#define AI_CONFIG_FAVOUR_SPEED "imp.speed_flag"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // !! AI_CONFIG_H_INC
|
#endif // !! AI_CONFIG_H_INC
|
||||||
|
|
|
@ -213,7 +213,7 @@ struct aiBone
|
||||||
* However one could use the vertex color sets for any other purpose, too.
|
* However one could use the vertex color sets for any other purpose, too.
|
||||||
*
|
*
|
||||||
* \note Some internal structures expect (and assert) this value
|
* \note Some internal structures expect (and assert) this value
|
||||||
* to be at least 4
|
* to be at 4
|
||||||
*/
|
*/
|
||||||
# define AI_MAX_NUMBER_OF_COLOR_SETS 0x4
|
# define AI_MAX_NUMBER_OF_COLOR_SETS 0x4
|
||||||
|
|
||||||
|
@ -228,7 +228,7 @@ struct aiBone
|
||||||
* which UVW channel serves as data source for a texture,
|
* which UVW channel serves as data source for a texture,
|
||||||
*
|
*
|
||||||
* \note Some internal structures expect (and assert) this value
|
* \note Some internal structures expect (and assert) this value
|
||||||
* to be at least 4
|
* to be 4
|
||||||
*/
|
*/
|
||||||
# define AI_MAX_NUMBER_OF_TEXTURECOORDS 0x4
|
# define AI_MAX_NUMBER_OF_TEXTURECOORDS 0x4
|
||||||
|
|
||||||
|
@ -311,7 +311,7 @@ struct aiMesh
|
||||||
*/
|
*/
|
||||||
unsigned int mNumVertices;
|
unsigned int mNumVertices;
|
||||||
|
|
||||||
/** The number of primitives (triangles, polygones, lines) in this mesh.
|
/** The number of primitives (triangles, polygons, lines) in this mesh.
|
||||||
* This is also the size of the mFaces array
|
* This is also the size of the mFaces array
|
||||||
*/
|
*/
|
||||||
unsigned int mNumFaces;
|
unsigned int mNumFaces;
|
||||||
|
@ -329,7 +329,16 @@ struct aiMesh
|
||||||
* lines only may not have normal vectors. Meshes with mixed
|
* lines only may not have normal vectors. Meshes with mixed
|
||||||
* primitive types (i.e. lines and triangles) may have normals,
|
* primitive types (i.e. lines and triangles) may have normals,
|
||||||
* but the normals for vertices that are only referenced by
|
* but the normals for vertices that are only referenced by
|
||||||
* point or line primitives are undefined and set to QNaN.
|
* point or line primitives are undefined and set to QNaN (WARN:
|
||||||
|
* qNaN compares to inequal to *everything*, even to qNaN itself.
|
||||||
|
* Use code like this
|
||||||
|
* @code
|
||||||
|
* #define IS_QNAN(f) (f != f)
|
||||||
|
* @endcode
|
||||||
|
* to check whether a field is qnan).
|
||||||
|
* @note Normal vectors computed by Assimp are always unit-length.
|
||||||
|
* However, this needn't apply for normals that have been taken
|
||||||
|
* directly from the model file.
|
||||||
*/
|
*/
|
||||||
C_STRUCT aiVector3D* mNormals;
|
C_STRUCT aiVector3D* mNormals;
|
||||||
|
|
||||||
|
@ -342,7 +351,8 @@ struct aiMesh
|
||||||
* normals, but the normals for vertices that are only referenced by
|
* normals, but the normals for vertices that are only referenced by
|
||||||
* point or line primitives are undefined and set to QNaN.
|
* point or line primitives are undefined and set to QNaN.
|
||||||
* @note If the mesh contains tangents, it automatically also
|
* @note If the mesh contains tangents, it automatically also
|
||||||
* contains bitangents.
|
* contains bitangents (the bitangent is just the cross product of
|
||||||
|
* tangent and normal vectors).
|
||||||
*/
|
*/
|
||||||
C_STRUCT aiVector3D* mTangents;
|
C_STRUCT aiVector3D* mTangents;
|
||||||
|
|
||||||
|
|
|
@ -217,6 +217,9 @@ enum aiPostProcessSteps
|
||||||
* returns, just one bit is set in aiMesh::mPrimitiveTypes. This is
|
* returns, just one bit is set in aiMesh::mPrimitiveTypes. This is
|
||||||
* especially useful for real-time rendering where point and line
|
* especially useful for real-time rendering where point and line
|
||||||
* primitives are often ignored or rendered separately.
|
* primitives are often ignored or rendered separately.
|
||||||
|
* You can use the AI_CONFIG_PP_SBP_REMOVE option to specify which
|
||||||
|
* primitive types you need. This can be used to easily exclude
|
||||||
|
* lines and points, which are rarely used, from the import.
|
||||||
*/
|
*/
|
||||||
aiProcess_SortByPType = 0x8000,
|
aiProcess_SortByPType = 0x8000,
|
||||||
|
|
||||||
|
|
|
@ -282,12 +282,14 @@ public:
|
||||||
* read-only, the importer object keeps ownership of the data and will
|
* read-only, the importer object keeps ownership of the data and will
|
||||||
* destroy it upon destruction. If the import failes, NULL is returned.
|
* destroy it upon destruction. If the import failes, NULL is returned.
|
||||||
* A human-readable error description can be retrieved by calling
|
* A human-readable error description can be retrieved by calling
|
||||||
* GetErrorString().
|
* GetErrorString(). The previous scene will be deleted during this call.
|
||||||
* @param pFile Path and filename to the file to be imported.
|
* @param pFile Path and filename to the file to be imported.
|
||||||
* @param pFlags Optional post processing steps to be executed after
|
* @param pFlags Optional post processing steps to be executed after
|
||||||
* a successful import. Provide a bitwise combination of the
|
* a successful import. Provide a bitwise combination of the
|
||||||
* #aiPostProcessSteps flags.
|
* #aiPostProcessSteps flags.
|
||||||
* @return A pointer to the imported data, NULL if the import failed.
|
* @return A pointer to the imported data, NULL if the import failed.
|
||||||
|
* The pointer to the scene remains in possession of the Importer
|
||||||
|
* instance. Use GetOrphanedScene() to take ownership of it.
|
||||||
*/
|
*/
|
||||||
const aiScene* ReadFile( const std::string& pFile, unsigned int pFlags);
|
const aiScene* ReadFile( const std::string& pFile, unsigned int pFlags);
|
||||||
|
|
||||||
|
@ -339,11 +341,30 @@ public:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns the scene loaded by the last successful call to ReadFile()
|
/** Returns the scene loaded by the last successful call to ReadFile()
|
||||||
*
|
*
|
||||||
* @return Current scene or NULL if there is currently no scene loaded
|
* @return Current scene or NULL if there is currently no scene loaded
|
||||||
*/
|
*/
|
||||||
inline const aiScene* GetScene()
|
inline const aiScene* GetScene()
|
||||||
{return this->mScene;}
|
{
|
||||||
|
return mScene;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Returns the scene loaded by the last successful call to ReadFile()
|
||||||
|
* and releases the scene from the ownership of the Importer
|
||||||
|
* instance. The application is now resposible for deleting the
|
||||||
|
* scene. Any further calls to GetScene() or GetOrphanedScene()
|
||||||
|
* will return NULL - until a new scene has been loaded via ReadFile().
|
||||||
|
*
|
||||||
|
* @return Current scene or NULL if there is currently no scene loaded
|
||||||
|
*/
|
||||||
|
inline const aiScene* GetOrphanedScene()
|
||||||
|
{
|
||||||
|
aiScene* scene = mScene;
|
||||||
|
mScene = NULL;
|
||||||
|
return scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 64 KiB |
|
@ -0,0 +1,51 @@
|
||||||
|
Dwarf lowpoly model Pack
|
||||||
|
Copyright 2004, Psionic Design
|
||||||
|
e-mail: psionic@blueyonder.co.uk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
INSTALLATION INSTRUCTIONS:
|
||||||
|
|
||||||
|
To install, simply unzip to your hard drive with the "Use Folder Names" option turned on. And that's it you're ready to go!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
USAGE INFORMATION:
|
||||||
|
|
||||||
|
Each zip contains the models, textures and animation info for that particular format!
|
||||||
|
|
||||||
|
Please Read the "animationinfo.txt" file included in each zip for the exact frames of animation to use
|
||||||
|
|
||||||
|
Credits to me "Psionic" are really appreciated but are not essential ;-)
|
||||||
|
|
||||||
|
Any questions, screenshots of him in use etc drop by my site or email me at:-
|
||||||
|
|
||||||
|
website: http://www.psionic3d.co.uk
|
||||||
|
email: psionic@blueyonder.co.uk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
WHAT'S INCLUDED IN THE ZIP:
|
||||||
|
|
||||||
|
ReadMe.txt - This file
|
||||||
|
b3d.zip - Blitz 3D Format models and textures
|
||||||
|
ms3d.zip - Milkshape 3D Format models and textures
|
||||||
|
x.zip - DarkBasic Direct X 8 Format models and textures
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
RESTRICTIONS:
|
||||||
|
|
||||||
|
This model pack is available for use in freeware, shareware, commercial games/software with the following restrictions:-
|
||||||
|
|
||||||
|
**You may not sell/re-sell this model pack or claim it as your own.
|
||||||
|
***You may not redistribute this pack in some other model pack through a website or on a compilation CD of any kind, without my written consent.
|
||||||
|
|
||||||
|
|
||||||
|
Psi
|
||||||
|
http://www.psionic3d.co.uk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 82 KiB |
File diff suppressed because it is too large
Load Diff
|
@ -1954,6 +1954,10 @@ int CDisplay::RenderNode (aiNode* piNode,const aiMatrix4x4& piMatrix,
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < piNode->mNumMeshes;++i)
|
for (unsigned int i = 0; i < piNode->mNumMeshes;++i)
|
||||||
{
|
{
|
||||||
|
// fix: Render triangle meshes only
|
||||||
|
if (g_pcAsset->pcScene->mMeshes[piNode->mMeshes[i]]->mPrimitiveTypes != aiPrimitiveType_TRIANGLE)
|
||||||
|
continue;
|
||||||
|
|
||||||
// don't render the mesh if the render pass is incorrect
|
// don't render the mesh if the render pass is incorrect
|
||||||
if (g_sOptions.bRenderMats && (
|
if (g_sOptions.bRenderMats && (
|
||||||
g_pcAsset->apcMeshes[piNode->mMeshes[i]]->piOpacityTexture ||
|
g_pcAsset->apcMeshes[piNode->mMeshes[i]]->piOpacityTexture ||
|
||||||
|
|
|
@ -78,9 +78,9 @@ void HandleMouseInputFPS( void )
|
||||||
if( 0 != nXDiff )
|
if( 0 != nXDiff )
|
||||||
{
|
{
|
||||||
D3DXVECTOR3 v(0,1,0);
|
D3DXVECTOR3 v(0,1,0);
|
||||||
D3DXMatrixRotationAxis( &matRotation, (D3DXVECTOR3*)&v, D3DXToRadian((float)nXDiff / 6.0f) );
|
D3DXMatrixRotationAxis( &matRotation, (D3DXVECTOR3*)&g_sCamera.vUp, D3DXToRadian((float)nXDiff / 6.0f) );
|
||||||
D3DXVec3TransformCoord( (D3DXVECTOR3*)&g_sCamera.vLookAt, (D3DXVECTOR3*)&g_sCamera.vLookAt, &matRotation );
|
D3DXVec3TransformCoord( (D3DXVECTOR3*)&g_sCamera.vLookAt, (D3DXVECTOR3*)&g_sCamera.vLookAt, &matRotation );
|
||||||
D3DXVec3TransformCoord( (D3DXVECTOR3*)&g_sCamera.vUp,(D3DXVECTOR3*) &g_sCamera.vUp, &matRotation );
|
D3DXVec3TransformCoord( (D3DXVECTOR3*)&g_sCamera.vRight,(D3DXVECTOR3*) &g_sCamera.vRight, &matRotation );
|
||||||
|
|
||||||
CMeshRenderer::Instance().SetRotationChangedFlag();
|
CMeshRenderer::Instance().SetRotationChangedFlag();
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,6 +125,9 @@ DWORD WINAPI LoadThreadProc(LPVOID lpParameter)
|
||||||
// get current time
|
// get current time
|
||||||
double fCur = (double)timeGetTime();
|
double fCur = (double)timeGetTime();
|
||||||
|
|
||||||
|
// Remove allline and point meshes from the import
|
||||||
|
aiSetImportPropertyInteger(AI_CONFIG_PP_SBP_REMOVE,
|
||||||
|
aiPrimitiveType_LINE | aiPrimitiveType_POINT);
|
||||||
|
|
||||||
// call ASSIMPs C-API to load the file
|
// call ASSIMPs C-API to load the file
|
||||||
g_pcAsset->pcScene = (aiScene*)aiImportFile(g_szFileName,
|
g_pcAsset->pcScene = (aiScene*)aiImportFile(g_szFileName,
|
||||||
|
@ -136,7 +139,7 @@ DWORD WINAPI LoadThreadProc(LPVOID lpParameter)
|
||||||
aiProcess_SplitLargeMeshes | // split large, unrenderable meshes into submeshes
|
aiProcess_SplitLargeMeshes | // split large, unrenderable meshes into submeshes
|
||||||
aiProcess_ValidateDataStructure | aiProcess_ImproveCacheLocality
|
aiProcess_ValidateDataStructure | aiProcess_ImproveCacheLocality
|
||||||
| aiProcess_RemoveRedundantMaterials | aiProcess_SortByPType |
|
| aiProcess_RemoveRedundantMaterials | aiProcess_SortByPType |
|
||||||
aiProcess_FindInvalidData); // validate the output data structure
|
aiProcess_FindDegenerates | aiProcess_FindInvalidData); // validate the output data structure
|
||||||
|
|
||||||
// get the end time of zje operation, calculate delta t
|
// get the end time of zje operation, calculate delta t
|
||||||
double fEnd = (double)timeGetTime();
|
double fEnd = (double)timeGetTime();
|
||||||
|
|
|
@ -69,7 +69,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#endif // min
|
#endif // min
|
||||||
|
|
||||||
// default movement speed
|
// default movement speed
|
||||||
#define MOVE_SPEED 0.4f
|
#define MOVE_SPEED 3.f
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
|
|
|
@ -1362,6 +1362,18 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="IRR"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\code\IRRLoader.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\code\IRRLoader.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="PostProcess"
|
Name="PostProcess"
|
||||||
|
|
Loading…
Reference in New Issue