Finished loading of MD2, MD3, MDL2, MDL3, MDL4, MDL5, MDL7, MDL. First WIP version of the SMD loader. Additionals checks added to the validation step.
git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@60 67173fc5-114c-0410-ac8e-9d2fd5bffc1fpull/1/head
parent
758e092449
commit
b422d4e303
|
@ -40,11 +40,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file Implementation of the 3ds importer class */
|
/** @file Implementation of the 3ds importer class */
|
||||||
|
|
||||||
|
// internal headers
|
||||||
#include "3DSLoader.h"
|
#include "3DSLoader.h"
|
||||||
#include "MaterialSystem.h"
|
#include "MaterialSystem.h"
|
||||||
#include "TextureTransform.h"
|
#include "TextureTransform.h"
|
||||||
#include "StringComparison.h"
|
#include "StringComparison.h"
|
||||||
|
#include "qnan.h"
|
||||||
|
|
||||||
|
// public ASSIMP headers
|
||||||
#include "../include/DefaultLogger.h"
|
#include "../include/DefaultLogger.h"
|
||||||
#include "../include/IOStream.h"
|
#include "../include/IOStream.h"
|
||||||
#include "../include/IOSystem.h"
|
#include "../include/IOSystem.h"
|
||||||
|
@ -52,7 +56,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "../include/aiScene.h"
|
#include "../include/aiScene.h"
|
||||||
#include "../include/aiAssert.h"
|
#include "../include/aiAssert.h"
|
||||||
|
|
||||||
#include <boost/scoped_ptr.hpp>
|
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
|
@ -427,10 +430,12 @@ void Dot3DSImporter::ConvertMeshes(aiScene* pcOut)
|
||||||
a != (*i).mFaceMaterials.end();++a,++iNum)
|
a != (*i).mFaceMaterials.end();++a,++iNum)
|
||||||
{
|
{
|
||||||
// check range
|
// check range
|
||||||
if ((*a) >= this->mScene->mMaterials.size())
|
if ((*a) >= this->mScene->mMaterials.size())
|
||||||
{
|
{
|
||||||
// use the last material instead
|
DefaultLogger::get()->error("Face material index is out of range");
|
||||||
aiSplit[this->mScene->mMaterials.size()-1].push_back(iNum);
|
|
||||||
|
// use the last material instead
|
||||||
|
aiSplit[this->mScene->mMaterials.size()-1].push_back(iNum);
|
||||||
}
|
}
|
||||||
else aiSplit[*a].push_back(iNum);
|
else aiSplit[*a].push_back(iNum);
|
||||||
}
|
}
|
||||||
|
@ -450,15 +455,15 @@ void Dot3DSImporter::ConvertMeshes(aiScene* pcOut)
|
||||||
p_pcOut->mColors[0] = (aiColor4D*)new std::string((*i).mName);
|
p_pcOut->mColors[0] = (aiColor4D*)new std::string((*i).mName);
|
||||||
avOutMeshes.push_back(p_pcOut);
|
avOutMeshes.push_back(p_pcOut);
|
||||||
|
|
||||||
|
// (code for keyframe animation. however, this is currently not supported by Assimp)
|
||||||
|
#if 0
|
||||||
if (bFirst)
|
if (bFirst)
|
||||||
{
|
{
|
||||||
p_pcOut->mColors[1] = (aiColor4D*)new aiMatrix4x4();
|
p_pcOut->mColors[1] = (aiColor4D*)new aiMatrix4x4();
|
||||||
|
|
||||||
*((aiMatrix4x4*)p_pcOut->mColors[1]) = (*i).mMat;
|
*((aiMatrix4x4*)p_pcOut->mColors[1]) = (*i).mMat;
|
||||||
bFirst = false;
|
bFirst = false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// convert vertices
|
// convert vertices
|
||||||
p_pcOut->mNumVertices = (unsigned int)aiSplit[p].size()*3;
|
p_pcOut->mNumVertices = (unsigned int)aiSplit[p].size()*3;
|
||||||
|
@ -519,16 +524,6 @@ void Dot3DSImporter::ConvertMeshes(aiScene* pcOut)
|
||||||
// apply texture coordinate scalings
|
// apply texture coordinate scalings
|
||||||
TextureTransform::BakeScaleNOffset ( p_pcOut, &this->mScene->mMaterials[
|
TextureTransform::BakeScaleNOffset ( p_pcOut, &this->mScene->mMaterials[
|
||||||
p_pcOut->mMaterialIndex] );
|
p_pcOut->mMaterialIndex] );
|
||||||
|
|
||||||
// setup bitflags to indicate which texture coordinate
|
|
||||||
// channels are used
|
|
||||||
p_pcOut->mNumUVComponents[0] = 2;
|
|
||||||
if (p_pcOut->HasTextureCoords(1))
|
|
||||||
p_pcOut->mNumUVComponents[1] = 2;
|
|
||||||
if (p_pcOut->HasTextureCoords(2))
|
|
||||||
p_pcOut->mNumUVComponents[2] = 2;
|
|
||||||
if (p_pcOut->HasTextureCoords(3))
|
|
||||||
p_pcOut->mNumUVComponents[3] = 2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -579,6 +574,8 @@ void Dot3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,Dot3DS::Node*
|
||||||
{
|
{
|
||||||
const unsigned int iIndex = iArray[i];
|
const unsigned int iIndex = iArray[i];
|
||||||
|
|
||||||
|
// (code for keyframe animation. however, this is currently not supported by Assimp)
|
||||||
|
#if 0
|
||||||
if (NULL != pcSOut->mMeshes[iIndex]->mColors[1])
|
if (NULL != pcSOut->mMeshes[iIndex]->mColors[1])
|
||||||
{
|
{
|
||||||
pcOut->mTransformation = *((aiMatrix4x4*)
|
pcOut->mTransformation = *((aiMatrix4x4*)
|
||||||
|
@ -587,7 +584,7 @@ void Dot3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,Dot3DS::Node*
|
||||||
delete (aiMatrix4x4*)pcSOut->mMeshes[iIndex]->mColors[1];
|
delete (aiMatrix4x4*)pcSOut->mMeshes[iIndex]->mColors[1];
|
||||||
pcSOut->mMeshes[iIndex]->mColors[1] = NULL;
|
pcSOut->mMeshes[iIndex]->mColors[1] = NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
pcOut->mMeshes[i] = iIndex;
|
pcOut->mMeshes[i] = iIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -681,11 +678,17 @@ void Dot3DSImporter::GenerateNodeGraph(aiScene* pcOut)
|
||||||
pcNode->mMeshes[0] = i;
|
pcNode->mMeshes[0] = i;
|
||||||
pcNode->mNumMeshes = 1;
|
pcNode->mNumMeshes = 1;
|
||||||
|
|
||||||
std::string s;
|
char szBuffer[128];
|
||||||
std::stringstream ss(s);
|
int iLen;
|
||||||
ss << "UNNAMED[" << i << + "]";
|
#if _MSC_VER >= 1400
|
||||||
|
iLen = sprintf_s(szBuffer,"UNNAMED_%i",i);
|
||||||
pcNode->mName.Set(s);
|
#else
|
||||||
|
iLen = sprintf(szBuffer,"UNNAMED_%i",i);
|
||||||
|
#endif
|
||||||
|
ai_assert(0 < iLen);
|
||||||
|
::memcpy(pcNode->mName.data,szBuffer,iLen);
|
||||||
|
pcNode->mName.data[iLen] = '\0';
|
||||||
|
pcNode->mName.length = iLen;
|
||||||
|
|
||||||
// add the new child to the parent node
|
// add the new child to the parent node
|
||||||
pcOut->mRootNode->mChildren[i] = pcNode;
|
pcOut->mRootNode->mChildren[i] = pcNode;
|
||||||
|
|
|
@ -93,10 +93,22 @@ public:
|
||||||
//! From AutoDesk 3ds SDK
|
//! From AutoDesk 3ds SDK
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
// translated to gouraud shading with wireframe active
|
||||||
Wire = 0,
|
Wire = 0,
|
||||||
|
|
||||||
|
// if this material is set, no vertex normals will
|
||||||
|
// be calculated for the model. Face normals + gouraud
|
||||||
Flat = 1,
|
Flat = 1,
|
||||||
|
|
||||||
|
// standard gouraud shading
|
||||||
Gouraud = 2,
|
Gouraud = 2,
|
||||||
|
|
||||||
|
// phong shading
|
||||||
Phong = 3,
|
Phong = 3,
|
||||||
|
|
||||||
|
// cooktorrance or anistropic phong shading ...
|
||||||
|
// the exact meaning is unknown, if you know it
|
||||||
|
// feel free to tell me ;-)
|
||||||
Metal = 4,
|
Metal = 4,
|
||||||
|
|
||||||
// required by the ASE loader
|
// required by the ASE loader
|
||||||
|
@ -127,7 +139,8 @@ public:
|
||||||
CHUNK_PERCENTF = 0x0031, // float4 percentage
|
CHUNK_PERCENTF = 0x0031, // float4 percentage
|
||||||
// **************************************************************
|
// **************************************************************
|
||||||
|
|
||||||
// Unknown and ignored
|
// Unknown and ignored. Possibly a chunk used by PROJ (
|
||||||
|
// Discreet 3DS max Project File)?
|
||||||
CHUNK_PRJ = 0xC23D,
|
CHUNK_PRJ = 0xC23D,
|
||||||
|
|
||||||
// Unknown. Possibly a reference to an external .mli file?
|
// Unknown. Possibly a reference to an external .mli file?
|
||||||
|
@ -387,9 +400,10 @@ struct Material
|
||||||
mTwoSided (false)
|
mTwoSided (false)
|
||||||
{
|
{
|
||||||
static int iCnt = 0;
|
static int iCnt = 0;
|
||||||
std::stringstream ss;
|
|
||||||
ss << "$$_UNNAMED_" << iCnt++ << "_$$";
|
char szTemp[128];
|
||||||
ss >> mName;
|
sprintf(szTemp,"$$_UNNAMED_%i_$$",iCnt++);
|
||||||
|
mName = szTemp;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Name of the material
|
//! Name of the material
|
||||||
|
@ -442,9 +456,10 @@ struct Mesh
|
||||||
Mesh()
|
Mesh()
|
||||||
{
|
{
|
||||||
static int iCnt = 0;
|
static int iCnt = 0;
|
||||||
std::stringstream ss;
|
|
||||||
ss << "$$_UNNAMED_" << iCnt++ << "_$$";
|
char szTemp[128];
|
||||||
ss >> mName;
|
sprintf(szTemp,"$$_UNNAMED_%i_$$",iCnt++);
|
||||||
|
mName = szTemp;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Name of the mesh
|
//! Name of the mesh
|
||||||
|
@ -481,9 +496,10 @@ struct Node
|
||||||
|
|
||||||
{
|
{
|
||||||
static int iCnt = 0;
|
static int iCnt = 0;
|
||||||
std::stringstream ss;
|
|
||||||
ss << "$$_UNNAMED_" << iCnt++ << "_$$";
|
char szTemp[128];
|
||||||
ss >> mName;
|
sprintf(szTemp,"$$_UNNAMED_%i_$$",iCnt++);
|
||||||
|
mName = szTemp;
|
||||||
|
|
||||||
mHierarchyPos = 0;
|
mHierarchyPos = 0;
|
||||||
mHierarchyIndex = 0;
|
mHierarchyIndex = 0;
|
||||||
|
@ -538,26 +554,6 @@ struct Scene
|
||||||
Node* pcRootNode;
|
Node* pcRootNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
inline bool is_qnan(float p_fIn)
|
|
||||||
{
|
|
||||||
// NOTE: Comparison against qnan is generally problematic
|
|
||||||
// because qnan == qnan is false AFAIK
|
|
||||||
union FTOINT
|
|
||||||
{
|
|
||||||
float fFloat;
|
|
||||||
int32_t iInt;
|
|
||||||
} one, two;
|
|
||||||
one.fFloat = std::numeric_limits<float>::quiet_NaN();
|
|
||||||
two.fFloat = p_fIn;
|
|
||||||
|
|
||||||
return (one.iInt == two.iInt);
|
|
||||||
}
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
inline bool is_not_qnan(float p_fIn)
|
|
||||||
{
|
|
||||||
return !is_qnan(p_fIn);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end of namespace Dot3DS
|
} // end of namespace Dot3DS
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
|
@ -40,11 +40,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file Implementation of the 3ds importer class */
|
/** @file Implementation of the 3ds importer class */
|
||||||
|
|
||||||
|
// internal headers
|
||||||
#include "3DSLoader.h"
|
#include "3DSLoader.h"
|
||||||
#include "MaterialSystem.h"
|
#include "MaterialSystem.h"
|
||||||
#include "TextureTransform.h"
|
#include "TextureTransform.h"
|
||||||
#include "StringComparison.h"
|
#include "StringComparison.h"
|
||||||
|
#include "qnan.h"
|
||||||
|
|
||||||
|
// public ASSIMP headers
|
||||||
#include "../include/DefaultLogger.h"
|
#include "../include/DefaultLogger.h"
|
||||||
#include "../include/IOStream.h"
|
#include "../include/IOStream.h"
|
||||||
#include "../include/IOSystem.h"
|
#include "../include/IOSystem.h"
|
||||||
|
@ -52,14 +56,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "../include/aiScene.h"
|
#include "../include/aiScene.h"
|
||||||
#include "../include/aiAssert.h"
|
#include "../include/aiAssert.h"
|
||||||
|
|
||||||
|
// boost headers
|
||||||
#include <boost/scoped_ptr.hpp>
|
#include <boost/scoped_ptr.hpp>
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
#define ASSIMP_3DS_WARN_CHUNK_OVERFLOW_MSG \
|
#if (!defined ASSIMP_3DS_WARN_CHUNK_OVERFLOW_MSG)
|
||||||
"WARNING: Size of chunk data plus size of " \
|
# define ASSIMP_3DS_WARN_CHUNK_OVERFLOW_MSG \
|
||||||
"subordinate chunks is larger than the size " \
|
"WARNING: Size of chunk data plus size of " \
|
||||||
"specified in the higher-level chunk header." \
|
"subordinate chunks is larger than the size " \
|
||||||
|
"specified in the top-level chunk header."
|
||||||
|
#endif
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
|
@ -92,22 +99,6 @@ bool Dot3DSImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler) co
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// recursively delete a given node
|
|
||||||
void DeleteNodeRecursively (aiNode* p_piNode)
|
|
||||||
{
|
|
||||||
if (!p_piNode)return;
|
|
||||||
|
|
||||||
if (p_piNode->mChildren)
|
|
||||||
{
|
|
||||||
for (unsigned int i = 0 ; i < p_piNode->mNumChildren;++i)
|
|
||||||
{
|
|
||||||
DeleteNodeRecursively(p_piNode->mChildren[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete p_piNode;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Imports the given file into the given scene structure.
|
// Imports the given file into the given scene structure.
|
||||||
void Dot3DSImporter::InternReadFile(
|
void Dot3DSImporter::InternReadFile(
|
||||||
const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
|
const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
|
||||||
|
@ -125,7 +116,7 @@ void Dot3DSImporter::InternReadFile(
|
||||||
size_t fileSize = file->FileSize();
|
size_t fileSize = file->FileSize();
|
||||||
if( fileSize < 16)
|
if( fileSize < 16)
|
||||||
{
|
{
|
||||||
throw new ImportErrorException( ".3ds File is too small.");
|
throw new ImportErrorException( "3DS File is too small.");
|
||||||
}
|
}
|
||||||
|
|
||||||
this->mScene = new Dot3DS::Scene();
|
this->mScene = new Dot3DS::Scene();
|
||||||
|
@ -780,8 +771,9 @@ void Dot3DSImporter::ParseFaceChunk(int* piRemaining)
|
||||||
case Dot3DSFile::CHUNK_FACEMAT:
|
case Dot3DSFile::CHUNK_FACEMAT:
|
||||||
|
|
||||||
// at fist an asciiz with the material name
|
// at fist an asciiz with the material name
|
||||||
while (*sz++ != '\0')
|
while (*sz++)
|
||||||
{
|
{
|
||||||
|
// make sure we don't run over the end of the chunk
|
||||||
if (sz > pcCurNext-1)break;
|
if (sz > pcCurNext-1)break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -800,7 +792,7 @@ void Dot3DSImporter::ParseFaceChunk(int* piRemaining)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (iIndex == 0xFFFFFFFF)
|
if (0xFFFFFFFF == iIndex)
|
||||||
{
|
{
|
||||||
// this material is not known. Ignore this. We will later
|
// this material is not known. Ignore this. We will later
|
||||||
// assign the default material to all faces using *this*
|
// assign the default material to all faces using *this*
|
||||||
|
@ -818,13 +810,14 @@ void Dot3DSImporter::ParseFaceChunk(int* piRemaining)
|
||||||
|
|
||||||
// check range
|
// check range
|
||||||
if (iTemp >= mMesh.mFaceMaterials.size())
|
if (iTemp >= mMesh.mFaceMaterials.size())
|
||||||
{
|
{
|
||||||
|
DefaultLogger::get()->error("Invalid face index in face material list");
|
||||||
mMesh.mFaceMaterials[mMesh.mFaceMaterials.size()-1] = iIndex;
|
mMesh.mFaceMaterials[mMesh.mFaceMaterials.size()-1] = iIndex;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mMesh.mFaceMaterials[iTemp] = iIndex;
|
mMesh.mFaceMaterials[iTemp] = iIndex;
|
||||||
}
|
}
|
||||||
this->mCurrent += sizeof(uint16_t);
|
this->mCurrent += sizeof(uint16_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -959,8 +952,7 @@ void Dot3DSImporter::ParseMeshChunk(int* piRemaining)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if (defined _DEBUG)
|
#if 0
|
||||||
|
|
||||||
case Dot3DSFile::CHUNK_TXTINFO:
|
case Dot3DSFile::CHUNK_TXTINFO:
|
||||||
|
|
||||||
// for debugging purposes. Read two bytes to determine the mapping type
|
// for debugging purposes. Read two bytes to determine the mapping type
|
||||||
|
|
|
@ -40,13 +40,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file Implementation of the ASE importer class */
|
/** @file Implementation of the ASE importer class */
|
||||||
|
|
||||||
|
// internal headers
|
||||||
#include "ASELoader.h"
|
#include "ASELoader.h"
|
||||||
#include "3DSSpatialSort.h"
|
#include "3DSSpatialSort.h"
|
||||||
#include "MaterialSystem.h"
|
#include "MaterialSystem.h"
|
||||||
#include "StringComparison.h"
|
#include "StringComparison.h"
|
||||||
#include "TextureTransform.h"
|
#include "TextureTransform.h"
|
||||||
#include "fast_atof.h"
|
|
||||||
|
|
||||||
|
// utilities
|
||||||
|
#include "fast_atof.h"
|
||||||
|
#include "qnan.h"
|
||||||
|
|
||||||
|
// ASSIMP public headers
|
||||||
#include "../include/IOStream.h"
|
#include "../include/IOStream.h"
|
||||||
#include "../include/IOSystem.h"
|
#include "../include/IOSystem.h"
|
||||||
#include "../include/aiMesh.h"
|
#include "../include/aiMesh.h"
|
||||||
|
|
|
@ -111,7 +111,7 @@ public:
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Imports the given file and returns the imported data.
|
/** Imports the given file and returns the imported data.
|
||||||
* If the import succeeds, ownership of the data is transferred to
|
* If the import succeeds, ownership of the data is transferred to
|
||||||
* the caller. If the import failes, NULL is returned. The function
|
* the caller. If the import fails, NULL is returned. The function
|
||||||
* takes care that any partially constructed data is destroyed
|
* takes care that any partially constructed data is destroyed
|
||||||
* beforehand.
|
* beforehand.
|
||||||
*
|
*
|
||||||
|
@ -154,7 +154,15 @@ protected:
|
||||||
* an error. If it terminates normally, the data in aiScene is
|
* an error. If it terminates normally, the data in aiScene is
|
||||||
* expected to be correct. Override this function to implement the
|
* expected to be correct. Override this function to implement the
|
||||||
* actual importing.
|
* actual importing.
|
||||||
*
|
* <br>
|
||||||
|
* The output scene must meet the following conditions:<br>
|
||||||
|
* - at least one mesh must be there<br>
|
||||||
|
* - at least a root node must be there<br>
|
||||||
|
* - at least one material must be there<br>
|
||||||
|
* - there may be no meshes with 0 vertices or faces<br>
|
||||||
|
* This won't be checked (except by the validation step), Assimp will
|
||||||
|
* crash if one of the conditions is not met!
|
||||||
|
*
|
||||||
* @param pFile Path of the file to be imported.
|
* @param pFile Path of the file to be imported.
|
||||||
* @param pScene The scene object to hold the imported data.
|
* @param pScene The scene object to hold the imported data.
|
||||||
* NULL is not a valid parameter.
|
* NULL is not a valid parameter.
|
||||||
|
|
|
@ -53,7 +53,7 @@ DefaultIOStream::~DefaultIOStream()
|
||||||
{
|
{
|
||||||
if (this->mFile)
|
if (this->mFile)
|
||||||
{
|
{
|
||||||
fclose(this->mFile);
|
::fclose(this->mFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -61,20 +61,24 @@ size_t DefaultIOStream::Read(void* pvBuffer,
|
||||||
size_t pSize,
|
size_t pSize,
|
||||||
size_t pCount)
|
size_t pCount)
|
||||||
{
|
{
|
||||||
|
ai_assert(NULL != pvBuffer && 0 != pSize && 0 != pCount);
|
||||||
|
|
||||||
if (!this->mFile)
|
if (!this->mFile)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return fread(pvBuffer, pSize, pCount, this->mFile);
|
return ::fread(pvBuffer, pSize, pCount, this->mFile);
|
||||||
}
|
}
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
size_t DefaultIOStream::Write(const void* pvBuffer,
|
size_t DefaultIOStream::Write(const void* pvBuffer,
|
||||||
size_t pSize,
|
size_t pSize,
|
||||||
size_t pCount)
|
size_t pCount)
|
||||||
{
|
{
|
||||||
|
ai_assert(NULL != pvBuffer && 0 != pSize && 0 != pCount);
|
||||||
|
|
||||||
if (!this->mFile)return 0;
|
if (!this->mFile)return 0;
|
||||||
|
|
||||||
fseek(mFile, 0, SEEK_SET);
|
::fseek(mFile, 0, SEEK_SET);
|
||||||
return fwrite(pvBuffer, pSize, pCount, this->mFile);
|
return ::fwrite(pvBuffer, pSize, pCount, this->mFile);
|
||||||
}
|
}
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
aiReturn DefaultIOStream::Seek(size_t pOffset,
|
aiReturn DefaultIOStream::Seek(size_t pOffset,
|
||||||
|
@ -82,7 +86,7 @@ aiReturn DefaultIOStream::Seek(size_t pOffset,
|
||||||
{
|
{
|
||||||
if (!this->mFile)return AI_FAILURE;
|
if (!this->mFile)return AI_FAILURE;
|
||||||
|
|
||||||
return (0 == fseek(this->mFile, (long)pOffset,
|
return (0 == ::fseek(this->mFile, (long)pOffset,
|
||||||
(aiOrigin_CUR == pOrigin ? SEEK_CUR :
|
(aiOrigin_CUR == pOrigin ? SEEK_CUR :
|
||||||
(aiOrigin_END == pOrigin ? SEEK_END : SEEK_SET)))
|
(aiOrigin_END == pOrigin ? SEEK_END : SEEK_SET)))
|
||||||
? AI_SUCCESS : AI_FAILURE);
|
? AI_SUCCESS : AI_FAILURE);
|
||||||
|
@ -92,7 +96,7 @@ size_t DefaultIOStream::Tell() const
|
||||||
{
|
{
|
||||||
if (!this->mFile)return 0;
|
if (!this->mFile)return 0;
|
||||||
|
|
||||||
return ftell(this->mFile);
|
return ::ftell(this->mFile);
|
||||||
}
|
}
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
size_t DefaultIOStream::FileSize() const
|
size_t DefaultIOStream::FileSize() const
|
||||||
|
|
|
@ -65,11 +65,11 @@ DefaultIOSystem::~DefaultIOSystem()
|
||||||
// Tests for the existence of a file at the given path.
|
// Tests for the existence of a file at the given path.
|
||||||
bool DefaultIOSystem::Exists( const std::string& pFile) const
|
bool DefaultIOSystem::Exists( const std::string& pFile) const
|
||||||
{
|
{
|
||||||
FILE* file = fopen( pFile.c_str(), "rb");
|
FILE* file = ::fopen( pFile.c_str(), "rb");
|
||||||
if( !file)
|
if( !file)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
fclose( file);
|
::fclose( file);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ bool DefaultIOSystem::Exists( const std::string& pFile) const
|
||||||
// Open a new file with a given path.
|
// Open a new file with a given path.
|
||||||
IOStream* DefaultIOSystem::Open( const std::string& strFile, const std::string& strMode)
|
IOStream* DefaultIOSystem::Open( const std::string& strFile, const std::string& strMode)
|
||||||
{
|
{
|
||||||
FILE* file = fopen( strFile.c_str(), strMode.c_str());
|
FILE* file = ::fopen( strFile.c_str(), strMode.c_str());
|
||||||
if( NULL == file)
|
if( NULL == file)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,449 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
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 MDL importer class */
|
||||||
|
|
||||||
|
#include "MaterialSystem.h"
|
||||||
|
#include "HMPLoader.h"
|
||||||
|
|
||||||
|
#include "../include/DefaultLogger.h"
|
||||||
|
#include "../include/IOStream.h"
|
||||||
|
#include "../include/IOSystem.h"
|
||||||
|
#include "../include/aiMesh.h"
|
||||||
|
#include "../include/aiScene.h"
|
||||||
|
#include "../include/aiAssert.h"
|
||||||
|
|
||||||
|
#include <boost/scoped_ptr.hpp>
|
||||||
|
|
||||||
|
using namespace Assimp;
|
||||||
|
|
||||||
|
extern float g_avNormals[162][3];
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Constructor to be privately used by Importer
|
||||||
|
HMPImporter::HMPImporter()
|
||||||
|
{
|
||||||
|
// nothing to do here
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Destructor, private as well
|
||||||
|
HMPImporter::~HMPImporter()
|
||||||
|
{
|
||||||
|
// nothing to do here
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Returns whether the class can handle the format of the given file.
|
||||||
|
bool HMPImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler) const
|
||||||
|
{
|
||||||
|
// simple check of file extension is enough for the moment
|
||||||
|
std::string::size_type pos = pFile.find_last_of('.');
|
||||||
|
// no file extension - can't read
|
||||||
|
if( pos == std::string::npos)
|
||||||
|
return false;
|
||||||
|
std::string extension = pFile.substr( pos);
|
||||||
|
|
||||||
|
if (extension.length() < 4)return false;
|
||||||
|
if (extension[0] != '.')return false;
|
||||||
|
if (extension[1] != 'h' && extension[1] != 'H')return false;
|
||||||
|
if (extension[2] != 'm' && extension[2] != 'M')return false;
|
||||||
|
if (extension[3] != 'p' && extension[3] != 'P')return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Imports the given file into the given scene structure.
|
||||||
|
void HMPImporter::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 HMP file " + pFile + ".");
|
||||||
|
}
|
||||||
|
|
||||||
|
// check whether the ply file is large enough to contain
|
||||||
|
// at least the file header
|
||||||
|
size_t fileSize = file->FileSize();
|
||||||
|
if( fileSize < 50)
|
||||||
|
{
|
||||||
|
throw new ImportErrorException( ".hmp File is too small.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// allocate storage and copy the contents of the file to a memory buffer
|
||||||
|
this->pScene = pScene;
|
||||||
|
this->pIOHandler = pIOHandler;
|
||||||
|
this->mBuffer = new unsigned char[fileSize+1];
|
||||||
|
file->Read( (void*)mBuffer, 1, fileSize);
|
||||||
|
|
||||||
|
this->iFileSize = (unsigned int)fileSize;
|
||||||
|
|
||||||
|
// determine the file subtype and call the appropriate member function
|
||||||
|
uint32_t iMagic = *((uint32_t*)this->mBuffer);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
// HMP4 format
|
||||||
|
if (AI_HMP_MAGIC_NUMBER_LE_4 == iMagic ||
|
||||||
|
AI_HMP_MAGIC_NUMBER_BE_4 == iMagic)
|
||||||
|
{
|
||||||
|
DefaultLogger::get()->debug("HMP subtype: 3D GameStudio A4, magic word is HMP4");
|
||||||
|
this->InternReadFile_HMP4();
|
||||||
|
}
|
||||||
|
// HMP5 format
|
||||||
|
else if (AI_HMP_MAGIC_NUMBER_LE_5 == iMagic ||
|
||||||
|
AI_HMP_MAGIC_NUMBER_BE_5 == iMagic)
|
||||||
|
{
|
||||||
|
DefaultLogger::get()->debug("HMP subtype: 3D GameStudio A5, magic word is HMP5");
|
||||||
|
this->InternReadFile_HMP5();
|
||||||
|
}
|
||||||
|
// HMP7 format
|
||||||
|
else if (AI_HMP_MAGIC_NUMBER_LE_7 == iMagic ||
|
||||||
|
AI_HMP_MAGIC_NUMBER_BE_7 == iMagic)
|
||||||
|
{
|
||||||
|
DefaultLogger::get()->debug("HMP subtype: 3D GameStudio A7, magic word is HMP7");
|
||||||
|
this->InternReadFile_HMP7();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we're definitely unable to load this file
|
||||||
|
throw new ImportErrorException( "Unknown HMP subformat " + pFile +
|
||||||
|
". Magic word is not known");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (ImportErrorException* ex) {
|
||||||
|
delete[] this->mBuffer;
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete the file buffer
|
||||||
|
delete[] this->mBuffer;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void HMPImporter::InternReadFile_HMP4( )
|
||||||
|
{
|
||||||
|
throw new ImportErrorException("HMP4 is currently not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void HMPImporter::InternReadFile_HMP5( )
|
||||||
|
{
|
||||||
|
throw new ImportErrorException("HMP4 is currently not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void HMPImporter::InternReadFile_HMP7( )
|
||||||
|
{
|
||||||
|
if (120 > this->iFileSize)
|
||||||
|
{
|
||||||
|
throw new ImportErrorException("HMP7 file is too small (header size is "
|
||||||
|
"120 bytes, this file is smaller)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// read the file header and skip everything to byte 84
|
||||||
|
const HMP::Header_HMP5* pcHeader = (const HMP::Header_HMP5*)this->mBuffer;
|
||||||
|
const unsigned char* szCurrent = (const unsigned char*)(this->mBuffer+84);
|
||||||
|
|
||||||
|
if (!pcHeader->ftrisize_x || !pcHeader->ftrisize_y ||
|
||||||
|
pcHeader->fnumverts_x < 1.0f || (pcHeader->numverts/pcHeader->fnumverts_x) < 1.0f ||
|
||||||
|
!pcHeader->numframes)
|
||||||
|
{
|
||||||
|
throw new ImportErrorException("One or more of the values in the HMP7 "
|
||||||
|
"file header are invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate an output mesh
|
||||||
|
this->pScene->mNumMeshes = 1;
|
||||||
|
this->pScene->mMeshes = new aiMesh*[1];
|
||||||
|
aiMesh* pcMesh = this->pScene->mMeshes[0] = new aiMesh();
|
||||||
|
|
||||||
|
pcMesh->mMaterialIndex = 0;
|
||||||
|
pcMesh->mVertices = new aiVector3D[pcHeader->numverts];
|
||||||
|
pcMesh->mNormals = new aiVector3D[pcHeader->numverts];
|
||||||
|
|
||||||
|
const unsigned int height = (unsigned int)(pcHeader->numverts / pcHeader->fnumverts_x);
|
||||||
|
const unsigned int width = (unsigned int)pcHeader->fnumverts_x;
|
||||||
|
|
||||||
|
// we don't need to generate texture coordinates if
|
||||||
|
// we have no textures in the file ...
|
||||||
|
if (pcHeader->numskins)
|
||||||
|
{
|
||||||
|
pcMesh->mTextureCoords[0] = new aiVector3D[pcHeader->numverts];
|
||||||
|
pcMesh->mNumUVComponents[0] = 2;
|
||||||
|
|
||||||
|
// now read the first skin and skip all others
|
||||||
|
this->ReadFirstSkin(pcHeader->numskins,szCurrent,&szCurrent);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// generate a default material
|
||||||
|
const int iMode = (int)aiShadingMode_Gouraud;
|
||||||
|
MaterialHelper* pcHelper = new MaterialHelper();
|
||||||
|
pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
|
||||||
|
|
||||||
|
aiColor3D clr;
|
||||||
|
clr.b = clr.g = clr.r = 0.7f;
|
||||||
|
pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
|
||||||
|
pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
|
||||||
|
|
||||||
|
clr.b = clr.g = clr.r = 0.05f;
|
||||||
|
pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
|
||||||
|
|
||||||
|
aiString szName;
|
||||||
|
szName.Set(AI_DEFAULT_MATERIAL_NAME);
|
||||||
|
pcHelper->AddProperty(&szName,AI_MATKEY_NAME);
|
||||||
|
|
||||||
|
// add the material to the scene
|
||||||
|
this->pScene->mNumMaterials = 1;
|
||||||
|
this->pScene->mMaterials = new aiMaterial*[1];
|
||||||
|
this->pScene->mMaterials[0] = pcHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
// goto offset 120, I don't know why ...
|
||||||
|
// (fixme) is this the frame header? I assume yes since it starts
|
||||||
|
// with 2.
|
||||||
|
szCurrent += 36;
|
||||||
|
|
||||||
|
this->SizeCheck(szCurrent + sizeof(const HMP::Vertex_HMP7)*height*width);
|
||||||
|
|
||||||
|
// now load all vertices from the file
|
||||||
|
aiVector3D* pcVertOut = pcMesh->mVertices;
|
||||||
|
aiVector3D* pcNorOut = pcMesh->mNormals;
|
||||||
|
const HMP::Vertex_HMP7* src = (const HMP::Vertex_HMP7*) szCurrent;
|
||||||
|
for (unsigned int y = 0; y < height;++y)
|
||||||
|
{
|
||||||
|
for (unsigned int x = 0; x < width;++x)
|
||||||
|
{
|
||||||
|
pcVertOut->x = x * pcHeader->ftrisize_x;
|
||||||
|
pcVertOut->y = y * pcHeader->ftrisize_y;
|
||||||
|
// FIXME: What exctly is the correct scaling factor to use?
|
||||||
|
// possibly pcHeader->scale_origin[2] in combination with a
|
||||||
|
// signed interpretation of src->z?
|
||||||
|
pcVertOut->z = (((float)src->z / 0xffff)-0.5f) * pcHeader->ftrisize_x * 8.0f;
|
||||||
|
|
||||||
|
pcNorOut->x = ((float)src->normal_x / 0x80 ); // * pcHeader->scale_origin[0];
|
||||||
|
pcNorOut->y = ((float)src->normal_y / 0x80 ); // * pcHeader->scale_origin[1];
|
||||||
|
pcNorOut->z = 1.0f;
|
||||||
|
pcNorOut->Normalize();
|
||||||
|
|
||||||
|
++pcVertOut;++pcNorOut;++src;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate texture coordinates if necessary
|
||||||
|
if (pcHeader->numskins)
|
||||||
|
{
|
||||||
|
this->GenerateTextureCoords(width,height);
|
||||||
|
}
|
||||||
|
|
||||||
|
// now build a list of faces
|
||||||
|
const unsigned int iNumSquares = (width-1) * (height-1);
|
||||||
|
pcMesh->mNumFaces = iNumSquares << 1;
|
||||||
|
pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];
|
||||||
|
|
||||||
|
pcMesh->mNumVertices = pcMesh->mNumFaces*3;
|
||||||
|
aiVector3D* pcVertices = new aiVector3D[pcMesh->mNumVertices];
|
||||||
|
aiVector3D* pcNormals = new aiVector3D[pcMesh->mNumVertices];
|
||||||
|
|
||||||
|
aiFace* pcFaceOut(pcMesh->mFaces);
|
||||||
|
pcVertOut = pcVertices;
|
||||||
|
pcNorOut = pcNormals;
|
||||||
|
|
||||||
|
aiVector3D* pcUVs = pcMesh->mTextureCoords[0] ? new aiVector3D[pcMesh->mNumVertices] : NULL;
|
||||||
|
aiVector3D* pcUVOut(pcUVs);
|
||||||
|
|
||||||
|
unsigned int iCurrent = 0;
|
||||||
|
for (unsigned int y = 0; y < height-1;++y)
|
||||||
|
{
|
||||||
|
for (unsigned int x = 0; x < width-1;++x)
|
||||||
|
{
|
||||||
|
// first triangle of the square
|
||||||
|
pcFaceOut->mNumIndices = 3;
|
||||||
|
pcFaceOut->mIndices = new unsigned int[3];
|
||||||
|
|
||||||
|
*pcVertOut++ = pcMesh->mVertices[y*width+x];
|
||||||
|
*pcVertOut++ = pcMesh->mVertices[y*width+x+1];
|
||||||
|
*pcVertOut++ = pcMesh->mVertices[(y+1)*width+x];
|
||||||
|
|
||||||
|
*pcNorOut++ = pcMesh->mNormals[y*width+x];
|
||||||
|
*pcNorOut++ = pcMesh->mNormals[y*width+x+1];
|
||||||
|
*pcNorOut++ = pcMesh->mNormals[(y+1)*width+x];
|
||||||
|
|
||||||
|
if (pcMesh->mTextureCoords[0])
|
||||||
|
{
|
||||||
|
*pcUVOut++ = pcMesh->mTextureCoords[0][y*width+x];
|
||||||
|
*pcUVOut++ = pcMesh->mTextureCoords[0][y*width+x+1];
|
||||||
|
*pcUVOut++ = pcMesh->mTextureCoords[0][(y+1)*width+x];
|
||||||
|
}
|
||||||
|
|
||||||
|
pcFaceOut->mIndices[2] = iCurrent++;
|
||||||
|
pcFaceOut->mIndices[1] = iCurrent++;
|
||||||
|
pcFaceOut->mIndices[0] = iCurrent++;
|
||||||
|
++pcFaceOut;
|
||||||
|
|
||||||
|
// second triangle of the square
|
||||||
|
pcFaceOut->mNumIndices = 3;
|
||||||
|
pcFaceOut->mIndices = new unsigned int[3];
|
||||||
|
|
||||||
|
*pcVertOut++ = pcMesh->mVertices[(y+1)*width+x];
|
||||||
|
*pcVertOut++ = pcMesh->mVertices[y*width+x+1];
|
||||||
|
*pcVertOut++ = pcMesh->mVertices[(y+1)*width+x+1];
|
||||||
|
|
||||||
|
*pcNorOut++ = pcMesh->mNormals[(y+1)*width+x];
|
||||||
|
*pcNorOut++ = pcMesh->mNormals[y*width+x+1];
|
||||||
|
*pcNorOut++ = pcMesh->mNormals[(y+1)*width+x+1];
|
||||||
|
|
||||||
|
if (pcMesh->mTextureCoords[0])
|
||||||
|
{
|
||||||
|
*pcUVOut++ = pcMesh->mTextureCoords[0][(y+1)*width+x];
|
||||||
|
*pcUVOut++ = pcMesh->mTextureCoords[0][y*width+x+1];
|
||||||
|
*pcUVOut++ = pcMesh->mTextureCoords[0][(y+1)*width+x+1];
|
||||||
|
}
|
||||||
|
|
||||||
|
pcFaceOut->mIndices[2] = iCurrent++;
|
||||||
|
pcFaceOut->mIndices[1] = iCurrent++;
|
||||||
|
pcFaceOut->mIndices[0] = iCurrent++;
|
||||||
|
++pcFaceOut;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete[] pcMesh->mVertices;
|
||||||
|
pcMesh->mVertices = pcVertices;
|
||||||
|
|
||||||
|
delete[] pcMesh->mNormals;
|
||||||
|
pcMesh->mNormals = pcNormals;
|
||||||
|
|
||||||
|
if (pcMesh->mTextureCoords[0])
|
||||||
|
{
|
||||||
|
delete[] pcMesh->mTextureCoords[0];
|
||||||
|
pcMesh->mTextureCoords[0] = pcUVs;
|
||||||
|
}
|
||||||
|
|
||||||
|
// there is no nodegraph in HMP files. Simply assign the one mesh
|
||||||
|
// (no, not the one ring) to the root node
|
||||||
|
this->pScene->mRootNode = new aiNode();
|
||||||
|
this->pScene->mRootNode->mName.Set("terrain_root");
|
||||||
|
this->pScene->mRootNode->mNumMeshes = 1;
|
||||||
|
this->pScene->mRootNode->mMeshes = new unsigned int[1];
|
||||||
|
this->pScene->mRootNode->mMeshes[0] = 0;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void HMPImporter::ReadFirstSkin(unsigned int iNumSkins, const unsigned char* szCursor,
|
||||||
|
const unsigned char** szCursorOut)
|
||||||
|
{
|
||||||
|
ai_assert(0 != iNumSkins && NULL != szCursor);
|
||||||
|
|
||||||
|
// read the type of the skin ...
|
||||||
|
// sometimes we need to skip 12 bytes here, I don't know why ...
|
||||||
|
uint32_t iType = *((uint32_t*)szCursor);szCursor += sizeof(uint32_t);
|
||||||
|
if (0 == iType)
|
||||||
|
{
|
||||||
|
DefaultLogger::get()->warn("Skin type is 0. Skipping 12 bytes to "
|
||||||
|
"the next valid value, which seems to be the real skin type. "
|
||||||
|
"However, it is not known whether or not this is correct.");
|
||||||
|
szCursor += sizeof(uint32_t) * 2;
|
||||||
|
iType = *((uint32_t*)szCursor);szCursor += sizeof(uint32_t);
|
||||||
|
if (0 == iType)
|
||||||
|
{
|
||||||
|
throw new ImportErrorException("Unable to read HMP7 skin chunk");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// read width and height
|
||||||
|
uint32_t iWidth = *((uint32_t*)szCursor);szCursor += sizeof(uint32_t);
|
||||||
|
uint32_t iHeight = *((uint32_t*)szCursor);szCursor += sizeof(uint32_t);
|
||||||
|
|
||||||
|
// allocate an output material
|
||||||
|
MaterialHelper* pcMat = new MaterialHelper();
|
||||||
|
|
||||||
|
// read the skin, this works exactly as for MDL7
|
||||||
|
this->ParseSkinLump_3DGS_MDL7(szCursor,&szCursor,
|
||||||
|
pcMat,iType,iWidth,iHeight);
|
||||||
|
|
||||||
|
// now we need to skip any other skins ...
|
||||||
|
for (unsigned int i = 1; i< iNumSkins;++i)
|
||||||
|
{
|
||||||
|
iType = *((uint32_t*)szCursor);szCursor += sizeof(uint32_t);
|
||||||
|
iWidth = *((uint32_t*)szCursor);szCursor += sizeof(uint32_t);
|
||||||
|
iHeight = *((uint32_t*)szCursor);szCursor += sizeof(uint32_t);
|
||||||
|
|
||||||
|
this->SkipSkinLump_3DGS_MDL7(szCursor,&szCursor,
|
||||||
|
iType,iWidth,iHeight);
|
||||||
|
|
||||||
|
this->SizeCheck(szCursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup the material ...
|
||||||
|
this->pScene->mNumMaterials = 1;
|
||||||
|
this->pScene->mMaterials = new aiMaterial*[1];
|
||||||
|
this->pScene->mMaterials[0] = pcMat;
|
||||||
|
|
||||||
|
*szCursorOut = szCursor;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void HMPImporter::GenerateTextureCoords(
|
||||||
|
const unsigned int width, const unsigned int height)
|
||||||
|
{
|
||||||
|
ai_assert(NULL != this->pScene->mMeshes && NULL != this->pScene->mMeshes[0] &&
|
||||||
|
NULL != this->pScene->mMeshes[0]->mTextureCoords[0]);
|
||||||
|
|
||||||
|
aiVector3D* uv = this->pScene->mMeshes[0]->mTextureCoords[0];
|
||||||
|
|
||||||
|
const float fX = (1.0f / height) + (1.0f / height) / (height-1);
|
||||||
|
const float fY = (1.0f / width) + (1.0f / width) / (width-1);
|
||||||
|
|
||||||
|
for (unsigned int y = 0; y < height;++y)
|
||||||
|
{
|
||||||
|
for (unsigned int x = 0; x < width;++x)
|
||||||
|
{
|
||||||
|
uv->x = fX*x;
|
||||||
|
uv->y = 1.0f-fY*y;
|
||||||
|
++uv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
|
@ -0,0 +1,208 @@
|
||||||
|
/*
|
||||||
|
Open Asset Import Library (ASSIMP)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2008, ASSIMP Development Team
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the
|
||||||
|
following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the ASSIMP team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the ASSIMP Development Team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
//!
|
||||||
|
//! @file Definition of HMP importer class
|
||||||
|
//!
|
||||||
|
|
||||||
|
#ifndef AI_HMPLOADER_H_INCLUDED
|
||||||
|
#define AI_HMPLOADER_H_INCLUDED
|
||||||
|
|
||||||
|
#include "BaseImporter.h"
|
||||||
|
#include "../include/aiTypes.h"
|
||||||
|
#include "../include/aiTexture.h"
|
||||||
|
#include "../include/aiMaterial.h"
|
||||||
|
|
||||||
|
struct aiNode;
|
||||||
|
#include "MDLLoader.h"
|
||||||
|
|
||||||
|
namespace Assimp
|
||||||
|
{
|
||||||
|
class MaterialHelper;
|
||||||
|
|
||||||
|
#define AI_HMP_MAGIC_NUMBER_BE_4 'HMP4'
|
||||||
|
#define AI_HMP_MAGIC_NUMBER_LE_4 '4PMH'
|
||||||
|
|
||||||
|
#define AI_HMP_MAGIC_NUMBER_BE_5 'HMP5'
|
||||||
|
#define AI_HMP_MAGIC_NUMBER_LE_5 '5PMH'
|
||||||
|
|
||||||
|
#define AI_HMP_MAGIC_NUMBER_BE_7 'HMP7'
|
||||||
|
#define AI_HMP_MAGIC_NUMBER_LE_7 '7PMH'
|
||||||
|
|
||||||
|
namespace HMP
|
||||||
|
{
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/** Data structure for the header of a HMP5 file.
|
||||||
|
* This is also used by HMP4 and HMP7, but with modifications
|
||||||
|
*/
|
||||||
|
struct Header_HMP5
|
||||||
|
{
|
||||||
|
int8_t ident[4]; // "HMP5"
|
||||||
|
int32_t version;
|
||||||
|
|
||||||
|
// ignored
|
||||||
|
float scale[3];
|
||||||
|
float scale_origin[3];
|
||||||
|
float boundingradius;
|
||||||
|
|
||||||
|
//! Size of one triangle in x direction
|
||||||
|
float ftrisize_x;
|
||||||
|
//! Size of one triangle in y direction
|
||||||
|
float ftrisize_y;
|
||||||
|
//! Number of vertices in x direction
|
||||||
|
float fnumverts_x;
|
||||||
|
|
||||||
|
//! Number of skins in the file
|
||||||
|
int32_t numskins;
|
||||||
|
|
||||||
|
// can ignore this?
|
||||||
|
int32_t skinwidth;
|
||||||
|
int32_t skinheight;
|
||||||
|
|
||||||
|
//!Number of vertices in the file
|
||||||
|
int32_t numverts;
|
||||||
|
|
||||||
|
// ignored and zero
|
||||||
|
int32_t numtris;
|
||||||
|
|
||||||
|
//! only one supported ...
|
||||||
|
int32_t numframes;
|
||||||
|
|
||||||
|
//! Always 0 ...
|
||||||
|
int32_t num_stverts;
|
||||||
|
int32_t flags;
|
||||||
|
float size;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/** Data structure for a terrain vertex in a HMP7 file
|
||||||
|
*/
|
||||||
|
struct Vertex_HMP7
|
||||||
|
{
|
||||||
|
uint16_t z;
|
||||||
|
int8_t normal_x,normal_y;
|
||||||
|
};
|
||||||
|
|
||||||
|
}; //! namespace HMP
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/** Used to load 3D GameStudio HMP files (terrains)
|
||||||
|
*/
|
||||||
|
class HMPImporter : public MDLImporter
|
||||||
|
{
|
||||||
|
friend class Importer;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** Constructor to be privately used by Importer */
|
||||||
|
HMPImporter();
|
||||||
|
|
||||||
|
/** Destructor, private as well */
|
||||||
|
~HMPImporter();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Returns whether the class can handle the format of the given file.
|
||||||
|
* See BaseImporter::CanRead() for details. */
|
||||||
|
bool CanRead( const std::string& pFile, IOSystem* pIOHandler) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Called by Importer::GetExtensionList() for each loaded importer.
|
||||||
|
* See BaseImporter::GetExtensionList() for details
|
||||||
|
*/
|
||||||
|
void GetExtensionList(std::string& append)
|
||||||
|
{
|
||||||
|
append.append("*.hmp");
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Imports the given file into the given scene structure.
|
||||||
|
* See BaseImporter::InternReadFile() for details
|
||||||
|
*/
|
||||||
|
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
||||||
|
IOSystem* pIOHandler);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Import a HMP4 file
|
||||||
|
*/
|
||||||
|
void InternReadFile_HMP4( );
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Import a HMP5 file
|
||||||
|
*/
|
||||||
|
void InternReadFile_HMP5( );
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Import a HMP7 file
|
||||||
|
*/
|
||||||
|
void InternReadFile_HMP7( );
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Generate planar texture coordinates for a terrain
|
||||||
|
* \param width Width of the terrain, in vertices
|
||||||
|
* \param height Height of the terrain, in vertices
|
||||||
|
*/
|
||||||
|
void GenerateTextureCoords(const unsigned int width,
|
||||||
|
const unsigned int height);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Read the first skin from the file and skip all others ...
|
||||||
|
* \param iNumSkins Number of skins in the file
|
||||||
|
* \param szCursor Position of the first skin (offset 84)
|
||||||
|
*/
|
||||||
|
void ReadFirstSkin(unsigned int iNumSkins, const unsigned char* szCursor,
|
||||||
|
const unsigned char** szCursorOut);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
}; // end of namespace Assimp
|
||||||
|
|
||||||
|
#endif // AI_HMPIMPORTER_H_INC
|
|
@ -54,6 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "DefaultIOStream.h"
|
#include "DefaultIOStream.h"
|
||||||
#include "DefaultIOSystem.h"
|
#include "DefaultIOSystem.h"
|
||||||
|
|
||||||
|
// Importers
|
||||||
#if (!defined AI_BUILD_NO_X_IMPORTER)
|
#if (!defined AI_BUILD_NO_X_IMPORTER)
|
||||||
# include "XFileImporter.h"
|
# include "XFileImporter.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -81,18 +82,47 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#if (!defined AI_BUILD_NO_OBJ_IMPORTER)
|
#if (!defined AI_BUILD_NO_OBJ_IMPORTER)
|
||||||
# include "ObjFileImporter.h"
|
# include "ObjFileImporter.h"
|
||||||
#endif
|
#endif
|
||||||
|
#if (!defined AI_BUILD_NO_HMP_IMPORTER)
|
||||||
|
# include "HMPLoader.h"
|
||||||
|
#endif
|
||||||
|
#if (!defined AI_BUILD_NO_SMD_IMPORTER)
|
||||||
|
# include "SMDLoader.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "CalcTangentsProcess.h"
|
// PostProcess-Steps
|
||||||
#include "JoinVerticesProcess.h"
|
#if (!defined AI_BUILD_NO_CALCTANGENTS_PROCESS)
|
||||||
#include "ConvertToLHProcess.h"
|
# include "CalcTangentsProcess.h"
|
||||||
#include "TriangulateProcess.h"
|
#endif
|
||||||
#include "GenFaceNormalsProcess.h"
|
#if (!defined AI_BUILD_NO_JOINVERTICES_PROCESS)
|
||||||
#include "GenVertexNormalsProcess.h"
|
# include "JoinVerticesProcess.h"
|
||||||
#include "KillNormalsProcess.h"
|
#endif
|
||||||
#include "SplitLargeMeshes.h"
|
#if (!defined AI_BUILD_NO_CONVERTTOLH_PROCESS)
|
||||||
#include "PretransformVertices.h"
|
# include "ConvertToLHProcess.h"
|
||||||
#include "LimitBoneWeightsProcess.h"
|
#endif
|
||||||
#include "ValidateDataStructure.h"
|
#if (!defined AI_BUILD_NO_TRIANGULATE_PROCESS)
|
||||||
|
# include "TriangulateProcess.h"
|
||||||
|
#endif
|
||||||
|
#if (!defined AI_BUILD_NO_GENFACENORMALS_PROCESS)
|
||||||
|
# include "GenFaceNormalsProcess.h"
|
||||||
|
#endif
|
||||||
|
#if (!defined AI_BUILD_NO_GENVERTEXNORMALS_PROCESS)
|
||||||
|
# include "GenVertexNormalsProcess.h"
|
||||||
|
#endif
|
||||||
|
#if (!defined AI_BUILD_NO_KILLNORMALS_PROCESS)
|
||||||
|
# include "KillNormalsProcess.h"
|
||||||
|
#endif
|
||||||
|
#if (!defined AI_BUILD_NO_SPLITLARGEMESHES_PROCESS)
|
||||||
|
# include "SplitLargeMeshes.h"
|
||||||
|
#endif
|
||||||
|
#if (!defined AI_BUILD_NO_PRETRANSFORMVERTICES_PROCESS)
|
||||||
|
# include "PretransformVertices.h"
|
||||||
|
#endif
|
||||||
|
#if (!defined AI_BUILD_NO_LIMITBONEWEIGHTS_PROCESS)
|
||||||
|
# include "LimitBoneWeightsProcess.h"
|
||||||
|
#endif
|
||||||
|
#if (!defined AI_BUILD_NO_VALIDATEDS_PROCESS)
|
||||||
|
# include "ValidateDataStructure.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
|
@ -105,6 +135,7 @@ Importer::Importer() :
|
||||||
{
|
{
|
||||||
// allocate a default IO handler
|
// allocate a default IO handler
|
||||||
mIOHandler = new DefaultIOSystem;
|
mIOHandler = new DefaultIOSystem;
|
||||||
|
mIsDefaultHandler = true;
|
||||||
|
|
||||||
// add an instance of each worker class here
|
// add an instance of each worker class here
|
||||||
#if (!defined AI_BUILD_NO_X_IMPORTER)
|
#if (!defined AI_BUILD_NO_X_IMPORTER)
|
||||||
|
@ -134,20 +165,51 @@ Importer::Importer() :
|
||||||
#if (!defined AI_BUILD_NO_ASE_IMPORTER)
|
#if (!defined AI_BUILD_NO_ASE_IMPORTER)
|
||||||
mImporter.push_back( new ASEImporter());
|
mImporter.push_back( new ASEImporter());
|
||||||
#endif
|
#endif
|
||||||
|
#if (!defined AI_BUILD_NO_HMP_IMPORTER)
|
||||||
|
mImporter.push_back( new HMPImporter());
|
||||||
|
#endif
|
||||||
|
#if (!defined AI_BUILD_NO_SMD_IMPORTER)
|
||||||
|
mImporter.push_back( new SMDImporter());
|
||||||
|
#endif
|
||||||
|
|
||||||
// add an instance of each post processing step here in the order of sequence it is executed
|
// add an instance of each post processing step here in the order
|
||||||
|
// of sequence it is executed
|
||||||
|
#if (!defined AI_BUILD_NO_VALIDATEDS_PROCESS)
|
||||||
mPostProcessingSteps.push_back( new ValidateDSProcess());
|
mPostProcessingSteps.push_back( new ValidateDSProcess());
|
||||||
|
#endif
|
||||||
|
#if (!defined AI_BUILD_NO_TRIANGULATE_PROCESS)
|
||||||
mPostProcessingSteps.push_back( new TriangulateProcess());
|
mPostProcessingSteps.push_back( new TriangulateProcess());
|
||||||
|
#endif
|
||||||
|
#if (!defined AI_BUILD_NO_PRETRANSFORMVERTICES_PROCESS)
|
||||||
mPostProcessingSteps.push_back( new PretransformVertices());
|
mPostProcessingSteps.push_back( new PretransformVertices());
|
||||||
|
#endif
|
||||||
|
#if (!defined AI_BUILD_NO_SPLITLARGEMESHES_PROCESS)
|
||||||
mPostProcessingSteps.push_back( new SplitLargeMeshesProcess_Triangle());
|
mPostProcessingSteps.push_back( new SplitLargeMeshesProcess_Triangle());
|
||||||
|
#endif
|
||||||
|
#if (!defined AI_BUILD_NO_KILLNORMALS_PROCESS)
|
||||||
mPostProcessingSteps.push_back( new KillNormalsProcess());
|
mPostProcessingSteps.push_back( new KillNormalsProcess());
|
||||||
|
#endif
|
||||||
|
#if (!defined AI_BUILD_NO_GENFACENORMALS_PROCESS)
|
||||||
mPostProcessingSteps.push_back( new GenFaceNormalsProcess());
|
mPostProcessingSteps.push_back( new GenFaceNormalsProcess());
|
||||||
|
#endif
|
||||||
|
#if (!defined AI_BUILD_NO_GENVERTEXNORMALS_PROCESS)
|
||||||
mPostProcessingSteps.push_back( new GenVertexNormalsProcess());
|
mPostProcessingSteps.push_back( new GenVertexNormalsProcess());
|
||||||
|
#endif
|
||||||
|
#if (!defined AI_BUILD_NO_CALCTANGENTS_PROCESS)
|
||||||
mPostProcessingSteps.push_back( new CalcTangentsProcess());
|
mPostProcessingSteps.push_back( new CalcTangentsProcess());
|
||||||
|
#endif
|
||||||
|
#if (!defined AI_BUILD_NO_JOINVERTICES_PROCESS)
|
||||||
mPostProcessingSteps.push_back( new JoinVerticesProcess());
|
mPostProcessingSteps.push_back( new JoinVerticesProcess());
|
||||||
|
#endif
|
||||||
|
#if (!defined AI_BUILD_NO_SPLITLARGEMESHES_PROCESS)
|
||||||
mPostProcessingSteps.push_back( new SplitLargeMeshesProcess_Vertex());
|
mPostProcessingSteps.push_back( new SplitLargeMeshesProcess_Vertex());
|
||||||
|
#endif
|
||||||
|
#if (!defined AI_BUILD_NO_CONVERTTOLH_PROCESS)
|
||||||
mPostProcessingSteps.push_back( new ConvertToLHProcess());
|
mPostProcessingSteps.push_back( new ConvertToLHProcess());
|
||||||
|
#endif
|
||||||
|
#if (!defined AI_BUILD_NO_LIMITBONEWEIGHTS_PROCESS)
|
||||||
mPostProcessingSteps.push_back( new LimitBoneWeightsProcess());
|
mPostProcessingSteps.push_back( new LimitBoneWeightsProcess());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -170,19 +232,31 @@ Importer::~Importer()
|
||||||
// Supplies a custom IO handler to the importer to open and access files.
|
// Supplies a custom IO handler to the importer to open and access files.
|
||||||
void Importer::SetIOHandler( IOSystem* pIOHandler)
|
void Importer::SetIOHandler( IOSystem* pIOHandler)
|
||||||
{
|
{
|
||||||
if (NULL == pIOHandler)
|
if (!pIOHandler)
|
||||||
{
|
{
|
||||||
delete mIOHandler;
|
delete mIOHandler;
|
||||||
mIOHandler = new DefaultIOSystem();
|
mIOHandler = new DefaultIOSystem();
|
||||||
|
mIsDefaultHandler = true;
|
||||||
}
|
}
|
||||||
else if (mIOHandler != pIOHandler)
|
else if (mIOHandler != pIOHandler)
|
||||||
{
|
{
|
||||||
delete mIOHandler;
|
delete mIOHandler;
|
||||||
mIOHandler = pIOHandler;
|
mIOHandler = pIOHandler;
|
||||||
|
mIsDefaultHandler = false;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
IOSystem* Importer::GetIOHandler()
|
||||||
|
{
|
||||||
|
return mIOHandler;
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
bool Importer::IsDefaultIOHandler()
|
||||||
|
{
|
||||||
|
return mIsDefaultHandler;
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Validate post process step flags
|
// Validate post process step flags
|
||||||
bool ValidateFlags(unsigned int pFlags)
|
bool ValidateFlags(unsigned int pFlags)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,20 +1,80 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
/** Implementation of the LimitBoneWeightsProcess post processing step */
|
/** Implementation of the LimitBoneWeightsProcess post processing step */
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "LimitBoneWeightsProcess.h"
|
#include "LimitBoneWeightsProcess.h"
|
||||||
|
|
||||||
#include "../include/aiPostProcess.h"
|
#include "../include/aiPostProcess.h"
|
||||||
#include "../include/aiMesh.h"
|
#include "../include/aiMesh.h"
|
||||||
#include "../include/aiScene.h"
|
#include "../include/aiScene.h"
|
||||||
|
#include "../include/DefaultLogger.h"
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ unsigned int LimitBoneWeightsProcess::mMaxWeights = AI_LMW_MAX_WEIGHTS;
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
aiReturn aiSetBoneWeightLimit(unsigned int pLimit)
|
||||||
|
{
|
||||||
|
if (0 == pLimit)
|
||||||
|
{
|
||||||
|
LimitBoneWeightsProcess::mMaxWeights = 0xFFFFFFFF;
|
||||||
|
return AI_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
LimitBoneWeightsProcess::mMaxWeights = pLimit;
|
||||||
|
DefaultLogger::get()->debug("aiSetBoneWeightLimit() - bone weight limit was changed");
|
||||||
|
return AI_SUCCESS;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
LimitBoneWeightsProcess::LimitBoneWeightsProcess()
|
LimitBoneWeightsProcess::LimitBoneWeightsProcess()
|
||||||
{
|
{
|
||||||
// TODO: (thom) make this configurable from somewhere?
|
|
||||||
mMaxWeights = 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -1,3 +1,43 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
/** Defines a post processing step to limit the number of bones affecting a single vertex. */
|
/** Defines a post processing step to limit the number of bones affecting a single vertex. */
|
||||||
#ifndef AI_LIMITBONEWEIGHTSPROCESS_H_INC
|
#ifndef AI_LIMITBONEWEIGHTSPROCESS_H_INC
|
||||||
#define AI_LIMITBONEWEIGHTSPROCESS_H_INC
|
#define AI_LIMITBONEWEIGHTSPROCESS_H_INC
|
||||||
|
@ -9,6 +49,18 @@ struct aiMesh;
|
||||||
namespace Assimp
|
namespace Assimp
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// NOTE: If you change these limits, don't forget to change the
|
||||||
|
// corresponding values in all Assimp ports
|
||||||
|
|
||||||
|
// **********************************************************
|
||||||
|
// Java: PostProcessStep.java,
|
||||||
|
// PostProcessStep.DEFAULT_BONE_WEIGHT_LIMIT
|
||||||
|
// **********************************************************
|
||||||
|
|
||||||
|
#if (!defined AI_LMW_MAX_WEIGHTS)
|
||||||
|
# define AI_LMW_MAX_WEIGHTS 0x4
|
||||||
|
#endif // !! AI_LMW_MAX_WEIGHTS
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** This post processing step limits the number of bones affecting a vertex
|
/** This post processing step limits the number of bones affecting a vertex
|
||||||
* to a certain maximum value. If a vertex is affected by more than that number
|
* to a certain maximum value. If a vertex is affected by more than that number
|
||||||
|
@ -58,12 +110,14 @@ protected:
|
||||||
float mWeight; ///< Weight of that bone on this vertex
|
float mWeight; ///< Weight of that bone on this vertex
|
||||||
Weight() { }
|
Weight() { }
|
||||||
Weight( unsigned int pBone, float pWeight) { mBone = pBone; mWeight = pWeight; }
|
Weight( unsigned int pBone, float pWeight) { mBone = pBone; mWeight = pWeight; }
|
||||||
|
|
||||||
/** Comparision operator to sort bone weights by descending weight */
|
/** Comparision operator to sort bone weights by descending weight */
|
||||||
bool operator < (const Weight& pWeight) const { return mWeight > pWeight.mWeight; }
|
bool operator < (const Weight& pWeight) const { return mWeight > pWeight.mWeight; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
/** Maximum number of bones influencing any single vertex. */
|
/** Maximum number of bones influencing any single vertex. */
|
||||||
unsigned int mMaxWeights;
|
static unsigned int mMaxWeights;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
|
@ -80,34 +80,33 @@ namespace MD2
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** \brief Data structure for the MD2 main header
|
/** \brief Data structure for the MD2 main header
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
struct Header
|
struct Header
|
||||||
{
|
{
|
||||||
int32_t magic;
|
uint32_t magic;
|
||||||
int32_t version;
|
uint32_t version;
|
||||||
int32_t skinWidth;
|
uint32_t skinWidth;
|
||||||
int32_t skinHeight;
|
uint32_t skinHeight;
|
||||||
int32_t frameSize;
|
uint32_t frameSize;
|
||||||
int32_t numSkins;
|
uint32_t numSkins;
|
||||||
int32_t numVertices;
|
uint32_t numVertices;
|
||||||
int32_t numTexCoords;
|
uint32_t numTexCoords;
|
||||||
int32_t numTriangles;
|
uint32_t numTriangles;
|
||||||
int32_t numGlCommands;
|
uint32_t numGlCommands;
|
||||||
int32_t numFrames;
|
uint32_t numFrames;
|
||||||
int32_t offsetSkins;
|
uint32_t offsetSkins;
|
||||||
int32_t offsetTexCoords;
|
uint32_t offsetTexCoords;
|
||||||
int32_t offsetTriangles;
|
uint32_t offsetTriangles;
|
||||||
int32_t offsetFrames;
|
uint32_t offsetFrames;
|
||||||
int32_t offsetGlCommands;
|
uint32_t offsetGlCommands;
|
||||||
int32_t offsetEnd;
|
uint32_t offsetEnd;
|
||||||
|
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** \brief Data structure for a MD2 OpenGl draw command
|
/** \brief Data structure for a MD2 OpenGl draw command
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
struct GLCommand
|
struct GLCommand
|
||||||
{
|
{
|
||||||
float s, t;
|
float s, t;
|
||||||
|
@ -117,7 +116,6 @@ struct GLCommand
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** \brief Data structure for a MD2 triangle
|
/** \brief Data structure for a MD2 triangle
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
struct Triangle
|
struct Triangle
|
||||||
{
|
{
|
||||||
uint16_t vertexIndices[3];
|
uint16_t vertexIndices[3];
|
||||||
|
@ -127,7 +125,6 @@ struct Triangle
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** \brief Data structure for a MD2 vertex
|
/** \brief Data structure for a MD2 vertex
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
struct Vertex
|
struct Vertex
|
||||||
{
|
{
|
||||||
uint8_t vertex[3];
|
uint8_t vertex[3];
|
||||||
|
@ -137,7 +134,6 @@ struct Vertex
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** \brief Data structure for a MD2 frame
|
/** \brief Data structure for a MD2 frame
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
struct Frame
|
struct Frame
|
||||||
{
|
{
|
||||||
float scale[3];
|
float scale[3];
|
||||||
|
@ -149,7 +145,6 @@ struct Frame
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** \brief Data structure for a MD2 texture coordinate
|
/** \brief Data structure for a MD2 texture coordinate
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
struct TexCoord
|
struct TexCoord
|
||||||
{
|
{
|
||||||
int16_t s;
|
int16_t s;
|
||||||
|
@ -159,7 +154,6 @@ struct TexCoord
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** \brief Data structure for a MD2 skin
|
/** \brief Data structure for a MD2 skin
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
struct Skin
|
struct Skin
|
||||||
{
|
{
|
||||||
char name[AI_MD2_MAXQPATH]; /* texture file name */
|
char name[AI_MD2_MAXQPATH]; /* texture file name */
|
||||||
|
@ -171,6 +165,14 @@ struct Skin
|
||||||
#endif
|
#endif
|
||||||
#undef PACK_STRUCT
|
#undef PACK_STRUCT
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//! Lookup a normal vector from Quake's normal lookup table
|
||||||
|
//! \param index Input index (0-161)
|
||||||
|
//! \param vOut Receives the output normal
|
||||||
|
void LookupNormalIndex(uint8_t index,aiVector3D& vOut);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -42,40 +42,42 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
/** @file Implementation of the MD2 importer class */
|
/** @file Implementation of the MD2 importer class */
|
||||||
#include "MD2Loader.h"
|
#include "MD2Loader.h"
|
||||||
#include "MaterialSystem.h"
|
#include "MaterialSystem.h"
|
||||||
|
#include "MD2NormalTable.h" // shouldn't be included by other units
|
||||||
#include "MD2NormalTable.h"
|
|
||||||
|
|
||||||
#include "../include/IOStream.h"
|
#include "../include/IOStream.h"
|
||||||
#include "../include/IOSystem.h"
|
#include "../include/IOSystem.h"
|
||||||
#include "../include/aiMesh.h"
|
#include "../include/aiMesh.h"
|
||||||
#include "../include/aiScene.h"
|
#include "../include/aiScene.h"
|
||||||
#include "../include/aiAssert.h"
|
#include "../include/aiAssert.h"
|
||||||
|
#include "../include/DefaultLogger.h"
|
||||||
|
|
||||||
#include <boost/scoped_ptr.hpp>
|
#include <boost/scoped_ptr.hpp>
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
using namespace Assimp::MD2;
|
||||||
|
|
||||||
|
|
||||||
|
// helper macro to determine the size of an array
|
||||||
|
#if (!defined ARRAYSIZE)
|
||||||
|
# define ARRAYSIZE(_array) (int(sizeof(_array) / sizeof(_array[0])))
|
||||||
|
#endif
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
inline bool is_qnan(float p_fIn)
|
// Helper function to lookup a normal in Quake 2's precalculated table
|
||||||
|
void MD2::LookupNormalIndex(uint8_t iNormalIndex,aiVector3D& vOut)
|
||||||
{
|
{
|
||||||
// NOTE: Comparison against qnan is generally problematic
|
// make sure the normal index has a valid value
|
||||||
// because qnan == qnan is false AFAIK
|
if (iNormalIndex >= ARRAYSIZE(g_avNormals))
|
||||||
union FTOINT
|
|
||||||
{
|
{
|
||||||
float fFloat;
|
DefaultLogger::get()->warn("Index overflow in MDL7 normal vector list (the "
|
||||||
int32_t iInt;
|
" LUT has only 162 entries). ");
|
||||||
} one, two;
|
|
||||||
one.fFloat = std::numeric_limits<float>::quiet_NaN();
|
|
||||||
two.fFloat = p_fIn;
|
|
||||||
|
|
||||||
return (one.iInt == two.iInt);
|
iNormalIndex = ARRAYSIZE(g_avNormals) - 1;
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
vOut = *((const aiVector3D*)(&g_avNormals[iNormalIndex]));
|
||||||
inline bool is_not_qnan(float p_fIn)
|
|
||||||
{
|
|
||||||
return !is_qnan(p_fIn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
MD2Importer::MD2Importer()
|
MD2Importer::MD2Importer()
|
||||||
|
@ -99,12 +101,43 @@ bool MD2Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler) const
|
||||||
return false;
|
return false;
|
||||||
std::string extension = pFile.substr( pos);
|
std::string extension = pFile.substr( pos);
|
||||||
|
|
||||||
// not brilliant but working ;-)
|
if (extension.length() < 4)return false;
|
||||||
if( extension == ".md2" || extension == ".MD2" ||
|
if (extension[0] != '.')return false;
|
||||||
extension == ".mD2" || extension == ".Md2")
|
if (extension[1] != 'm' && extension[1] != 'M')return false;
|
||||||
return true;
|
if (extension[2] != 'd' && extension[2] != 'D')return false;
|
||||||
|
if (extension[3] != '2')return false;
|
||||||
|
|
||||||
return false;
|
return true;
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Validate the file header
|
||||||
|
void MD2Importer::ValidateHeader( )
|
||||||
|
{
|
||||||
|
/* to be validated:
|
||||||
|
int32_t offsetSkins;
|
||||||
|
int32_t offsetTexCoords;
|
||||||
|
int32_t offsetTriangles;
|
||||||
|
int32_t offsetFrames;
|
||||||
|
//int32_t offsetGlCommands;
|
||||||
|
int32_t offsetEnd;
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (this->m_pcHeader->offsetSkins + this->m_pcHeader->numSkins * sizeof (MD2::Skin) >= this->fileSize ||
|
||||||
|
this->m_pcHeader->offsetTexCoords + this->m_pcHeader->numTexCoords * sizeof (MD2::TexCoord) >= this->fileSize ||
|
||||||
|
this->m_pcHeader->offsetTriangles + this->m_pcHeader->numTriangles * sizeof (MD2::Triangle) >= this->fileSize ||
|
||||||
|
this->m_pcHeader->offsetFrames + this->m_pcHeader->numFrames * sizeof (MD2::Frame) >= this->fileSize ||
|
||||||
|
this->m_pcHeader->offsetEnd > this->fileSize)
|
||||||
|
{
|
||||||
|
throw new ImportErrorException("Invalid MD2 header: some offsets are outside the file");
|
||||||
|
delete[] this->mBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->m_pcHeader->numSkins > AI_MD2_MAX_SKINS)
|
||||||
|
DefaultLogger::get()->warn("The model contains more skins than Quake 2 supports");
|
||||||
|
if ( this->m_pcHeader->numFrames > AI_MD2_MAX_FRAMES)
|
||||||
|
DefaultLogger::get()->warn("The model contains more frames than Quake 2 supports");
|
||||||
|
if (this->m_pcHeader->numVertices > AI_MD2_MAX_VERTS)
|
||||||
|
DefaultLogger::get()->warn("The model contains more vertices than Quake 2 supports");
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Imports the given file into the given scene structure.
|
// Imports the given file into the given scene structure.
|
||||||
|
@ -121,10 +154,10 @@ void MD2Importer::InternReadFile(
|
||||||
|
|
||||||
// check whether the md3 file is large enough to contain
|
// check whether the md3 file is large enough to contain
|
||||||
// at least the file header
|
// at least the file header
|
||||||
size_t fileSize = file->FileSize();
|
fileSize = (unsigned int)file->FileSize();
|
||||||
if( fileSize < sizeof(MD2::Header))
|
if( fileSize < sizeof(MD2::Header))
|
||||||
{
|
{
|
||||||
throw new ImportErrorException( ".md2 File is too small.");
|
throw new ImportErrorException( "md2 File is too small.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate storage and copy the contents of the file to a memory buffer
|
// allocate storage and copy the contents of the file to a memory buffer
|
||||||
|
@ -137,22 +170,26 @@ void MD2Importer::InternReadFile(
|
||||||
if (this->m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_BE &&
|
if (this->m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_BE &&
|
||||||
this->m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_LE)
|
this->m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_LE)
|
||||||
{
|
{
|
||||||
|
delete[] this->mBuffer;
|
||||||
throw new ImportErrorException( "Invalid md2 file: Magic bytes not found");
|
throw new ImportErrorException( "Invalid md2 file: Magic bytes not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
// check file format version
|
// check file format version
|
||||||
if (this->m_pcHeader->version != 8)
|
if (this->m_pcHeader->version != 8)
|
||||||
{
|
{
|
||||||
throw new ImportErrorException( "Unsupported md3 file version");
|
DefaultLogger::get()->warn( "Unsupported md2 file version. Continuing happily ...");
|
||||||
}
|
}
|
||||||
|
this->ValidateHeader();
|
||||||
|
|
||||||
// check some values whether they are valid
|
// check some values whether they are valid
|
||||||
if (0 == this->m_pcHeader->numFrames)
|
if (0 == this->m_pcHeader->numFrames)
|
||||||
{
|
{
|
||||||
|
delete[] this->mBuffer;
|
||||||
throw new ImportErrorException( "Invalid md2 file: NUM_FRAMES is 0");
|
throw new ImportErrorException( "Invalid md2 file: NUM_FRAMES is 0");
|
||||||
}
|
}
|
||||||
if (this->m_pcHeader->offsetEnd > (int32_t)fileSize)
|
if (this->m_pcHeader->offsetEnd > (int32_t)fileSize)
|
||||||
{
|
{
|
||||||
|
delete[] this->mBuffer;
|
||||||
throw new ImportErrorException( "Invalid md2 file: File is too small");
|
throw new ImportErrorException( "Invalid md2 file: File is too small");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,39 +203,35 @@ void MD2Importer::InternReadFile(
|
||||||
pScene->mMaterials[0] = new MaterialHelper();
|
pScene->mMaterials[0] = new MaterialHelper();
|
||||||
pScene->mNumMeshes = 1;
|
pScene->mNumMeshes = 1;
|
||||||
pScene->mMeshes = new aiMesh*[1];
|
pScene->mMeshes = new aiMesh*[1];
|
||||||
pScene->mMeshes[0] = new aiMesh();
|
aiMesh* pcMesh = pScene->mMeshes[0] = new aiMesh();
|
||||||
|
|
||||||
// navigate to the begin of the frame data
|
// navigate to the begin of the frame data
|
||||||
const MD2::Frame* pcFrame = (const MD2::Frame*) ((unsigned char*)this->m_pcHeader +
|
const MD2::Frame* pcFrame = (const MD2::Frame*) (
|
||||||
this->m_pcHeader->offsetFrames);
|
(unsigned char*)this->m_pcHeader + this->m_pcHeader->offsetFrames);
|
||||||
|
|
||||||
// navigate to the begin of the triangle data
|
// navigate to the begin of the triangle data
|
||||||
MD2::Triangle* pcTriangles = (MD2::Triangle*) ((unsigned char*)this->m_pcHeader +
|
MD2::Triangle* pcTriangles = (MD2::Triangle*) (
|
||||||
this->m_pcHeader->offsetTriangles);
|
(unsigned char*)this->m_pcHeader + this->m_pcHeader->offsetTriangles);
|
||||||
|
|
||||||
// navigate to the begin of the tex coords data
|
// navigate to the begin of the tex coords data
|
||||||
const MD2::TexCoord* pcTexCoords = (const MD2::TexCoord*) ((unsigned char*)this->m_pcHeader +
|
const MD2::TexCoord* pcTexCoords = (const MD2::TexCoord*) (
|
||||||
this->m_pcHeader->offsetTexCoords);
|
(unsigned char*)this->m_pcHeader + this->m_pcHeader->offsetTexCoords);
|
||||||
|
|
||||||
// navigate to the begin of the vertex data
|
// navigate to the begin of the vertex data
|
||||||
const MD2::Vertex* pcVerts = (const MD2::Vertex*) (pcFrame->vertices);
|
const MD2::Vertex* pcVerts = (const MD2::Vertex*) (pcFrame->vertices);
|
||||||
|
|
||||||
pScene->mMeshes[0]->mNumFaces = this->m_pcHeader->numTriangles;
|
pcMesh->mNumFaces = this->m_pcHeader->numTriangles;
|
||||||
pScene->mMeshes[0]->mFaces = new aiFace[this->m_pcHeader->numTriangles];
|
pcMesh->mFaces = new aiFace[this->m_pcHeader->numTriangles];
|
||||||
|
|
||||||
// temporary vectors for position/texture coordinates/normals
|
// allocate output storage
|
||||||
std::vector<aiVector3D> vPositions;
|
pcMesh->mNumVertices = (unsigned int)pcMesh->mNumFaces*3;
|
||||||
std::vector<aiVector3D> vTexCoords;
|
pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices];
|
||||||
std::vector<aiVector3D> vNormals;
|
pcMesh->mNormals = new aiVector3D[pcMesh->mNumVertices];
|
||||||
|
|
||||||
vPositions.resize(pScene->mMeshes[0]->mNumFaces*3,aiVector3D());
|
|
||||||
vTexCoords.resize(pScene->mMeshes[0]->mNumFaces*3,aiVector3D(
|
|
||||||
std::numeric_limits<float>::quiet_NaN(),
|
|
||||||
std::numeric_limits<float>::quiet_NaN(),0.0f));
|
|
||||||
vNormals.resize(pScene->mMeshes[0]->mNumFaces*3,aiVector3D());
|
|
||||||
|
|
||||||
// not sure whether there are MD2 files without texture coordinates
|
// not sure whether there are MD2 files without texture coordinates
|
||||||
if (0 != this->m_pcHeader->numTexCoords && 0 != this->m_pcHeader->numSkins)
|
// NOTE: texture coordinates can be there without a texture,
|
||||||
|
// but a texture can't be there without a valid UV channel
|
||||||
|
if (this->m_pcHeader->numTexCoords && this->m_pcHeader->numSkins)
|
||||||
{
|
{
|
||||||
// navigate to the first texture associated with the mesh
|
// navigate to the first texture associated with the mesh
|
||||||
const MD2::Skin* pcSkins = (const MD2::Skin*) ((unsigned char*)this->m_pcHeader +
|
const MD2::Skin* pcSkins = (const MD2::Skin*) ((unsigned char*)this->m_pcHeader +
|
||||||
|
@ -216,12 +249,20 @@ void MD2Importer::InternReadFile(
|
||||||
clr.b = clr.g = clr.r = 0.05f;
|
clr.b = clr.g = clr.r = 0.05f;
|
||||||
pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
|
pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
|
||||||
|
|
||||||
aiString szString;
|
if (pcSkins->name[0])
|
||||||
const size_t iLen = strlen(pcSkins->name);
|
{
|
||||||
memcpy(szString.data,pcSkins->name,iLen+1);
|
aiString szString;
|
||||||
szString.length = iLen-1;
|
const size_t iLen = ::strlen(pcSkins->name);
|
||||||
|
::memcpy(szString.data,pcSkins->name,iLen);
|
||||||
|
szString.data[iLen] = '\0';
|
||||||
|
szString.length = iLen;
|
||||||
|
|
||||||
pcHelper->AddProperty(&szString,AI_MATKEY_TEXTURE_DIFFUSE(0));
|
pcHelper->AddProperty(&szString,AI_MATKEY_TEXTURE_DIFFUSE(0));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DefaultLogger::get()->warn("Texture file name has zero length. It will be skipped.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -237,13 +278,42 @@ void MD2Importer::InternReadFile(
|
||||||
|
|
||||||
clr.b = clr.g = clr.r = 0.05f;
|
clr.b = clr.g = clr.r = 0.05f;
|
||||||
pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
|
pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
|
||||||
|
|
||||||
|
aiString szName;
|
||||||
|
szName.Set(AI_DEFAULT_MATERIAL_NAME);
|
||||||
|
pcHelper->AddProperty(&szName,AI_MATKEY_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// now read all triangles of the first frame, apply scaling and translation
|
// now read all triangles of the first frame, apply scaling and translation
|
||||||
unsigned int iCurrent = 0;
|
unsigned int iCurrent = 0;
|
||||||
if (0 != this->m_pcHeader->numTexCoords)
|
if (this->m_pcHeader->numTexCoords)
|
||||||
{
|
{
|
||||||
|
// allocate storage for texture coordinates, too
|
||||||
|
pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
|
||||||
|
pcMesh->mNumUVComponents[0] = 2;
|
||||||
|
|
||||||
|
// check whether the skin width or height are zero (this would
|
||||||
|
// cause a division through zero)
|
||||||
|
float fDivisorU;
|
||||||
|
if (!this->m_pcHeader->skinWidth)
|
||||||
|
{
|
||||||
|
DefaultLogger::get()->error("Skin width is zero but there are "
|
||||||
|
"valid absolute texture coordinates. Unable to compute "
|
||||||
|
"relative texture coordinates ranging from 0 to 1");
|
||||||
|
fDivisorU = 1.0f;
|
||||||
|
}
|
||||||
|
else fDivisorU = (float)this->m_pcHeader->skinWidth;
|
||||||
|
|
||||||
|
float fDivisorV;
|
||||||
|
if (!this->m_pcHeader->skinHeight)
|
||||||
|
{
|
||||||
|
DefaultLogger::get()->error("Skin height is zero but there are "
|
||||||
|
"valid absolute texture coordinates. Unable to compute "
|
||||||
|
"relative texture coordinates ranging from 0 to 1");
|
||||||
|
fDivisorV = 1.0f;
|
||||||
|
}
|
||||||
|
else fDivisorV = (float)this->m_pcHeader->skinHeight;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < (unsigned int)this->m_pcHeader->numTriangles;++i)
|
for (unsigned int i = 0; i < (unsigned int)this->m_pcHeader->numTriangles;++i)
|
||||||
{
|
{
|
||||||
|
@ -259,13 +329,16 @@ void MD2Importer::InternReadFile(
|
||||||
{
|
{
|
||||||
// validate vertex indices
|
// validate vertex indices
|
||||||
if (pcTriangles[i].vertexIndices[c] >= this->m_pcHeader->numVertices)
|
if (pcTriangles[i].vertexIndices[c] >= this->m_pcHeader->numVertices)
|
||||||
|
{
|
||||||
|
DefaultLogger::get()->error("Vertex index is outside the allowed range");
|
||||||
pcTriangles[i].vertexIndices[c] = this->m_pcHeader->numVertices-1;
|
pcTriangles[i].vertexIndices[c] = this->m_pcHeader->numVertices-1;
|
||||||
|
}
|
||||||
|
|
||||||
// copy face indices
|
// copy face indices
|
||||||
unsigned int iIndex = (unsigned int)pcTriangles[i].vertexIndices[c];
|
unsigned int iIndex = (unsigned int)pcTriangles[i].vertexIndices[c];
|
||||||
|
|
||||||
// read x,y, and z component of the vertex
|
// read x,y, and z component of the vertex
|
||||||
aiVector3D& vec = vPositions[iCurrent];
|
aiVector3D& vec = pcMesh->mVertices[iCurrent];
|
||||||
|
|
||||||
vec.x = (float)pcVerts[iIndex].vertex[0] * pcFrame->scale[0];
|
vec.x = (float)pcVerts[iIndex].vertex[0] * pcFrame->scale[0];
|
||||||
vec.x += pcFrame->translate[0];
|
vec.x += pcFrame->translate[0];
|
||||||
|
@ -278,23 +351,28 @@ void MD2Importer::InternReadFile(
|
||||||
vec.y += pcFrame->translate[2];
|
vec.y += pcFrame->translate[2];
|
||||||
|
|
||||||
// read the normal vector from the precalculated normal table
|
// read the normal vector from the precalculated normal table
|
||||||
vNormals[iCurrent] = *((const aiVector3D*)(&g_avNormals[std::min(
|
aiVector3D& vNormal = pcMesh->mNormals[iCurrent];
|
||||||
int(pcVerts[iIndex].lightNormalIndex),
|
LookupNormalIndex(pcVerts[iIndex].lightNormalIndex,vNormal);
|
||||||
int(sizeof(g_avNormals) / sizeof(g_avNormals[0]))-1)]));
|
std::swap ( vNormal.y,vNormal.z );
|
||||||
|
|
||||||
std::swap ( vNormals[iCurrent].y,vNormals[iCurrent].z );
|
|
||||||
|
|
||||||
// validate texture coordinates
|
// validate texture coordinates
|
||||||
if (pcTriangles[iIndex].textureIndices[c] >= this->m_pcHeader->numTexCoords)
|
if (pcTriangles[iIndex].textureIndices[c] >= this->m_pcHeader->numTexCoords)
|
||||||
|
{
|
||||||
|
DefaultLogger::get()->error("UV index is outside the allowed range");
|
||||||
pcTriangles[iIndex].textureIndices[c] = this->m_pcHeader->numTexCoords-1;
|
pcTriangles[iIndex].textureIndices[c] = this->m_pcHeader->numTexCoords-1;
|
||||||
|
}
|
||||||
|
|
||||||
aiVector3D* pcOut = &vTexCoords[iCurrent];
|
aiVector3D& pcOut = pcMesh->mTextureCoords[0][iCurrent];
|
||||||
float u,v;
|
float u,v;
|
||||||
u = (float)pcTexCoords[pcTriangles[i].textureIndices[c]].s / this->m_pcHeader->skinWidth;
|
|
||||||
v = (float)pcTexCoords[pcTriangles[i].textureIndices[c]].t / this->m_pcHeader->skinHeight;
|
// the texture coordinates are absolute values but we
|
||||||
pcOut->x = u;
|
// need relative values between 0 and 1
|
||||||
pcOut->y = v;
|
u = (float)pcTexCoords[pcTriangles[i].textureIndices[c]].s / fDivisorU;
|
||||||
|
v = (float)pcTexCoords[pcTriangles[i].textureIndices[c]].t / fDivisorV;
|
||||||
|
pcOut.x = u;
|
||||||
|
pcOut.y = 1.0f - v; // FIXME: Is this correct for MD2?
|
||||||
}
|
}
|
||||||
|
// FIX: flip the face order for use with OpenGL
|
||||||
pScene->mMeshes[0]->mFaces[i].mIndices[0] = iTemp+2;
|
pScene->mMeshes[0]->mFaces[i].mIndices[0] = iTemp+2;
|
||||||
pScene->mMeshes[0]->mFaces[i].mIndices[1] = iTemp+1;
|
pScene->mMeshes[0]->mFaces[i].mIndices[1] = iTemp+1;
|
||||||
pScene->mMeshes[0]->mFaces[i].mIndices[2] = iTemp+0;
|
pScene->mMeshes[0]->mFaces[i].mIndices[2] = iTemp+0;
|
||||||
|
@ -316,13 +394,16 @@ void MD2Importer::InternReadFile(
|
||||||
{
|
{
|
||||||
// validate vertex indices
|
// validate vertex indices
|
||||||
if (pcTriangles[i].vertexIndices[c] >= this->m_pcHeader->numVertices)
|
if (pcTriangles[i].vertexIndices[c] >= this->m_pcHeader->numVertices)
|
||||||
|
{
|
||||||
|
DefaultLogger::get()->error("Vertex index is outside the allowed range");
|
||||||
pcTriangles[i].vertexIndices[c] = this->m_pcHeader->numVertices-1;
|
pcTriangles[i].vertexIndices[c] = this->m_pcHeader->numVertices-1;
|
||||||
|
}
|
||||||
|
|
||||||
// copy face indices
|
// copy face indices
|
||||||
unsigned int iIndex = (unsigned int)pcTriangles[i].vertexIndices[c];
|
unsigned int iIndex = (unsigned int)pcTriangles[i].vertexIndices[c];
|
||||||
|
|
||||||
// read x,y, and z component of the vertex
|
// read x,y, and z component of the vertex
|
||||||
aiVector3D& vec = vPositions[iCurrent];
|
aiVector3D& vec = pcMesh->mVertices[iCurrent];
|
||||||
|
|
||||||
vec.x = (float)pcVerts[iIndex].vertex[0] * pcFrame->scale[0];
|
vec.x = (float)pcVerts[iIndex].vertex[0] * pcFrame->scale[0];
|
||||||
vec.x += pcFrame->translate[0];
|
vec.x += pcFrame->translate[0];
|
||||||
|
@ -335,39 +416,17 @@ void MD2Importer::InternReadFile(
|
||||||
vec.y += pcFrame->translate[2];
|
vec.y += pcFrame->translate[2];
|
||||||
|
|
||||||
// read the normal vector from the precalculated normal table
|
// read the normal vector from the precalculated normal table
|
||||||
vNormals[iCurrent] = *((const aiVector3D*)(&g_avNormals[std::min(
|
aiVector3D& vNormal = pcMesh->mNormals[iCurrent];
|
||||||
int(pcVerts[iIndex].lightNormalIndex),
|
LookupNormalIndex(pcVerts[iIndex].lightNormalIndex,vNormal);
|
||||||
int(sizeof(g_avNormals) / sizeof(g_avNormals[0]))-1)]));
|
std::swap ( vNormal.y,vNormal.z );
|
||||||
|
|
||||||
std::swap ( vNormals[iCurrent].y,vNormals[iCurrent].z );
|
|
||||||
|
|
||||||
aiVector3D* pcOut = &vTexCoords[iCurrent];
|
|
||||||
pcOut->x = (float)pcTexCoords[pcTriangles[i].textureIndices[c]].s / this->m_pcHeader->skinWidth;
|
|
||||||
pcOut->y = (float)pcTexCoords[pcTriangles[i].textureIndices[c]].t / this->m_pcHeader->skinHeight;
|
|
||||||
}
|
}
|
||||||
|
// FIX: flip the face order for use with OpenGL
|
||||||
pScene->mMeshes[0]->mFaces[i].mIndices[0] = iTemp+2;
|
pScene->mMeshes[0]->mFaces[i].mIndices[0] = iTemp+2;
|
||||||
pScene->mMeshes[0]->mFaces[i].mIndices[1] = iTemp+1;
|
pScene->mMeshes[0]->mFaces[i].mIndices[1] = iTemp+1;
|
||||||
pScene->mMeshes[0]->mFaces[i].mIndices[2] = iTemp+0;
|
pScene->mMeshes[0]->mFaces[i].mIndices[2] = iTemp+0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// delete the file buffer and return
|
||||||
// allocate output storage
|
delete[] this->mBuffer;
|
||||||
pScene->mMeshes[0]->mNumVertices = (unsigned int)vPositions.size();
|
|
||||||
pScene->mMeshes[0]->mVertices = new aiVector3D[vPositions.size()];
|
|
||||||
pScene->mMeshes[0]->mNormals = new aiVector3D[vPositions.size()];
|
|
||||||
pScene->mMeshes[0]->mTextureCoords[0] = new aiVector3D[vPositions.size()];
|
|
||||||
|
|
||||||
// memcpy() the data to the c-syle arrays
|
|
||||||
memcpy(pScene->mMeshes[0]->mVertices, &vPositions[0],
|
|
||||||
vPositions.size() * sizeof(aiVector3D));
|
|
||||||
memcpy(pScene->mMeshes[0]->mNormals, &vNormals[0],
|
|
||||||
vPositions.size() * sizeof(aiVector3D));
|
|
||||||
|
|
||||||
if (0 != this->m_pcHeader->numTexCoords)
|
|
||||||
{
|
|
||||||
memcpy(pScene->mMeshes[0]->mTextureCoords[0], &vTexCoords[0],
|
|
||||||
vPositions.size() * sizeof(aiVector3D));
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
|
@ -93,6 +93,12 @@ protected:
|
||||||
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
||||||
IOSystem* pIOHandler);
|
IOSystem* pIOHandler);
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Validate the header of the file
|
||||||
|
*/
|
||||||
|
void ValidateHeader();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/** Header of the MD2 file */
|
/** Header of the MD2 file */
|
||||||
|
@ -100,6 +106,9 @@ protected:
|
||||||
|
|
||||||
/** Buffer to hold the loaded file */
|
/** Buffer to hold the loaded file */
|
||||||
const unsigned char* mBuffer;
|
const unsigned char* mBuffer;
|
||||||
|
|
||||||
|
/** Size of the file, in bytes */
|
||||||
|
unsigned int fileSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
|
@ -89,10 +89,10 @@ namespace MD3
|
||||||
struct Header
|
struct Header
|
||||||
{
|
{
|
||||||
//! magic number
|
//! magic number
|
||||||
int32_t IDENT;
|
uint32_t IDENT;
|
||||||
|
|
||||||
//! file format version
|
//! file format version
|
||||||
int32_t VERSION;
|
uint32_t VERSION;
|
||||||
|
|
||||||
//! original name in .pak archive
|
//! original name in .pak archive
|
||||||
unsigned char NAME[ AI_MD3_MAXQPATH ];
|
unsigned char NAME[ AI_MD3_MAXQPATH ];
|
||||||
|
@ -101,28 +101,28 @@ struct Header
|
||||||
int32_t FLAGS;
|
int32_t FLAGS;
|
||||||
|
|
||||||
//! number of frames in the file
|
//! number of frames in the file
|
||||||
int32_t NUM_FRAMES;
|
uint32_t NUM_FRAMES;
|
||||||
|
|
||||||
//! number of tags in the file
|
//! number of tags in the file
|
||||||
int32_t NUM_TAGS;
|
uint32_t NUM_TAGS;
|
||||||
|
|
||||||
//! number of surfaces in the file
|
//! number of surfaces in the file
|
||||||
int32_t NUM_SURFACES;
|
uint32_t NUM_SURFACES;
|
||||||
|
|
||||||
//! number of skins in the file
|
//! number of skins in the file
|
||||||
int32_t NUM_SKINS;
|
uint32_t NUM_SKINS;
|
||||||
|
|
||||||
//! offset of the first frame
|
//! offset of the first frame
|
||||||
int32_t OFS_FRAMES;
|
uint32_t OFS_FRAMES;
|
||||||
|
|
||||||
//! offset of the first tag
|
//! offset of the first tag
|
||||||
int32_t OFS_TAGS;
|
uint32_t OFS_TAGS;
|
||||||
|
|
||||||
//! offset of the first surface
|
//! offset of the first surface
|
||||||
int32_t OFS_SURFACES;
|
uint32_t OFS_SURFACES;
|
||||||
|
|
||||||
//! end of file
|
//! end of file
|
||||||
int32_t OFS_EOF;
|
uint32_t OFS_EOF;
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
|
||||||
|
@ -162,29 +162,29 @@ struct Surface
|
||||||
int32_t FLAGS;
|
int32_t FLAGS;
|
||||||
|
|
||||||
//! number of frames in the surface
|
//! number of frames in the surface
|
||||||
int32_t NUM_FRAMES;
|
uint32_t NUM_FRAMES;
|
||||||
|
|
||||||
//! number of shaders in the surface
|
//! number of shaders in the surface
|
||||||
int32_t NUM_SHADER;
|
uint32_t NUM_SHADER;
|
||||||
|
|
||||||
//! number of vertices in the surface
|
//! number of vertices in the surface
|
||||||
int32_t NUM_VERTICES;
|
uint32_t NUM_VERTICES;
|
||||||
|
|
||||||
//! number of triangles in the surface
|
//! number of triangles in the surface
|
||||||
int32_t NUM_TRIANGLES;
|
uint32_t NUM_TRIANGLES;
|
||||||
|
|
||||||
|
|
||||||
//! offset to the triangle data
|
//! offset to the triangle data
|
||||||
int32_t OFS_TRIANGLES;
|
uint32_t OFS_TRIANGLES;
|
||||||
|
|
||||||
//! offset to the shader data
|
//! offset to the shader data
|
||||||
int32_t OFS_SHADERS;
|
uint32_t OFS_SHADERS;
|
||||||
|
|
||||||
//! offset to the texture coordinate data
|
//! offset to the texture coordinate data
|
||||||
int32_t OFS_ST;
|
uint32_t OFS_ST;
|
||||||
|
|
||||||
//! offset to the vertex/normal data
|
//! offset to the vertex/normal data
|
||||||
int32_t OFS_XYZNORMAL;
|
uint32_t OFS_XYZNORMAL;
|
||||||
|
|
||||||
//! offset to the end of the Surface object
|
//! offset to the end of the Surface object
|
||||||
int32_t OFS_END;
|
int32_t OFS_END;
|
||||||
|
@ -200,7 +200,7 @@ struct Shader
|
||||||
unsigned char NAME[ AI_MD3_MAXQPATH ];
|
unsigned char NAME[ AI_MD3_MAXQPATH ];
|
||||||
|
|
||||||
//! index of the shader
|
//! index of the shader
|
||||||
int32_t SHADER_INDEX;
|
uint32_t SHADER_INDEX;
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
|
||||||
|
@ -211,7 +211,7 @@ struct Shader
|
||||||
struct Triangle
|
struct Triangle
|
||||||
{
|
{
|
||||||
//! triangle indices
|
//! triangle indices
|
||||||
int32_t INDEXES[3];
|
uint32_t INDEXES[3];
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
|
||||||
|
@ -236,7 +236,7 @@ struct Vertex
|
||||||
int16_t X,Y,Z;
|
int16_t X,Y,Z;
|
||||||
|
|
||||||
//! encoded normal vector
|
//! encoded normal vector
|
||||||
int16_t NORMAL;
|
uint16_t NORMAL;
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// reset packing to the original value
|
// reset packing to the original value
|
||||||
|
@ -254,9 +254,9 @@ struct Vertex
|
||||||
* \note This has been taken from q3 source (misc_model.c)
|
* \note This has been taken from q3 source (misc_model.c)
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
inline void LatLngNormalToVec3(int16_t p_iNormal, float* p_afOut)
|
inline void LatLngNormalToVec3(uint16_t p_iNormal, float* p_afOut)
|
||||||
{
|
{
|
||||||
float lat = (float)(( p_iNormal >> 8 ) & 0xff);
|
float lat = (float)(( p_iNormal >> 8u ) & 0xff);
|
||||||
float lng = (float)(( p_iNormal & 0xff ));
|
float lng = (float)(( p_iNormal & 0xff ));
|
||||||
lat *= 3.141926f/128.0f;
|
lat *= 3.141926f/128.0f;
|
||||||
lng *= 3.141926f/128.0f;
|
lng *= 3.141926f/128.0f;
|
||||||
|
|
|
@ -49,6 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "../include/aiMesh.h"
|
#include "../include/aiMesh.h"
|
||||||
#include "../include/aiScene.h"
|
#include "../include/aiScene.h"
|
||||||
#include "../include/aiAssert.h"
|
#include "../include/aiAssert.h"
|
||||||
|
#include "../include/DefaultLogger.h"
|
||||||
|
|
||||||
#include <boost/scoped_ptr.hpp>
|
#include <boost/scoped_ptr.hpp>
|
||||||
|
|
||||||
|
@ -78,12 +79,48 @@ bool MD3Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler) const
|
||||||
return false;
|
return false;
|
||||||
std::string extension = pFile.substr( pos);
|
std::string extension = pFile.substr( pos);
|
||||||
|
|
||||||
// not brilliant but working ;-)
|
if (extension.length() < 4)return false;
|
||||||
if( extension == ".md3" || extension == ".MD3" ||
|
if (extension[0] != '.')return false;
|
||||||
extension == ".mD3" || extension == ".Md3")
|
if (extension[1] != 'm' && extension[1] != 'M')return false;
|
||||||
return true;
|
if (extension[2] != 'd' && extension[2] != 'D')return false;
|
||||||
|
if (extension[3] != '3')return false;
|
||||||
|
|
||||||
return false;
|
return true;
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void MD3Importer::ValidateHeaderOffsets()
|
||||||
|
{
|
||||||
|
if (this->m_pcHeader->OFS_FRAMES >= this->fileSize ||
|
||||||
|
this->m_pcHeader->OFS_SURFACES >= this->fileSize ||
|
||||||
|
this->m_pcHeader->OFS_EOF > this->fileSize)
|
||||||
|
{
|
||||||
|
delete[] this->mBuffer;
|
||||||
|
throw new ImportErrorException("Invalid MD3 header: some offsets are outside the file");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void MD3Importer::ValidateSurfaceHeaderOffsets(const MD3::Surface* pcSurf)
|
||||||
|
{
|
||||||
|
// calculate the relative offset of the surface
|
||||||
|
int32_t ofs = int32_t((const unsigned char*)pcSurf-this->mBuffer);
|
||||||
|
|
||||||
|
if (pcSurf->OFS_TRIANGLES + ofs + pcSurf->NUM_TRIANGLES * sizeof(MD3::Triangle) > this->fileSize ||
|
||||||
|
pcSurf->OFS_SHADERS + ofs + pcSurf->NUM_SHADER * sizeof(MD3::Shader) > this->fileSize ||
|
||||||
|
pcSurf->OFS_ST + ofs + pcSurf->NUM_VERTICES * sizeof(MD3::TexCoord) > this->fileSize ||
|
||||||
|
pcSurf->OFS_XYZNORMAL + ofs + pcSurf->NUM_VERTICES * sizeof(MD3::Vertex) > this->fileSize)
|
||||||
|
{
|
||||||
|
delete[] this->mBuffer;
|
||||||
|
throw new ImportErrorException("Invalid MD3 surface header: some offsets are outside the file");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pcSurf->NUM_TRIANGLES > AI_MD3_MAX_TRIANGLES)
|
||||||
|
DefaultLogger::get()->warn("The model contains more triangles than Quake 3 supports");
|
||||||
|
if (pcSurf->NUM_SHADER > AI_MD3_MAX_SHADERS)
|
||||||
|
DefaultLogger::get()->warn("The model contains more shaders than Quake 3 supports");
|
||||||
|
if (pcSurf->NUM_VERTICES > AI_MD3_MAX_VERTS)
|
||||||
|
DefaultLogger::get()->warn("The model contains more vertices than Quake 3 supports");
|
||||||
|
if (pcSurf->NUM_FRAMES > AI_MD3_MAX_FRAMES)
|
||||||
|
DefaultLogger::get()->warn("The model contains more frames than Quake 3 supports");
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Imports the given file into the given scene structure.
|
// Imports the given file into the given scene structure.
|
||||||
|
@ -100,7 +137,7 @@ void MD3Importer::InternReadFile(
|
||||||
|
|
||||||
// check whether the md3 file is large enough to contain
|
// check whether the md3 file is large enough to contain
|
||||||
// at least the file header
|
// at least the file header
|
||||||
size_t fileSize = file->FileSize();
|
fileSize = (unsigned int)file->FileSize();
|
||||||
if( fileSize < sizeof(MD3::Header))
|
if( fileSize < sizeof(MD3::Header))
|
||||||
{
|
{
|
||||||
throw new ImportErrorException( ".md3 File is too small.");
|
throw new ImportErrorException( ".md3 File is too small.");
|
||||||
|
@ -116,28 +153,28 @@ void MD3Importer::InternReadFile(
|
||||||
if (this->m_pcHeader->IDENT != AI_MD3_MAGIC_NUMBER_BE &&
|
if (this->m_pcHeader->IDENT != AI_MD3_MAGIC_NUMBER_BE &&
|
||||||
this->m_pcHeader->IDENT != AI_MD3_MAGIC_NUMBER_LE)
|
this->m_pcHeader->IDENT != AI_MD3_MAGIC_NUMBER_LE)
|
||||||
{
|
{
|
||||||
|
delete[] this->mBuffer;
|
||||||
throw new ImportErrorException( "Invalid md3 file: Magic bytes not found");
|
throw new ImportErrorException( "Invalid md3 file: Magic bytes not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
// check file format version
|
// check file format version
|
||||||
if (this->m_pcHeader->VERSION > 15)
|
if (this->m_pcHeader->VERSION > 15)
|
||||||
{
|
{
|
||||||
throw new ImportErrorException( "Unsupported md3 file version");
|
DefaultLogger::get()->warn( "Unsupported md3 file version. Continuing happily ...");
|
||||||
}
|
}
|
||||||
|
|
||||||
// check some values whether they are valid
|
// check some values whether they are valid
|
||||||
if (0 == this->m_pcHeader->NUM_FRAMES)
|
if (0 == this->m_pcHeader->NUM_FRAMES)
|
||||||
{
|
{
|
||||||
|
delete[] this->mBuffer;
|
||||||
throw new ImportErrorException( "Invalid md3 file: NUM_FRAMES is 0");
|
throw new ImportErrorException( "Invalid md3 file: NUM_FRAMES is 0");
|
||||||
}
|
}
|
||||||
if (0 == this->m_pcHeader->NUM_SURFACES)
|
if (0 == this->m_pcHeader->NUM_SURFACES)
|
||||||
{
|
{
|
||||||
|
delete[] this->mBuffer;
|
||||||
throw new ImportErrorException( "Invalid md3 file: NUM_SURFACES is 0");
|
throw new ImportErrorException( "Invalid md3 file: NUM_SURFACES is 0");
|
||||||
}
|
}
|
||||||
if (this->m_pcHeader->OFS_EOF > (int32_t)fileSize)
|
this->ValidateHeaderOffsets();
|
||||||
{
|
|
||||||
throw new ImportErrorException( "Invalid md3 file: File is too small");
|
|
||||||
}
|
|
||||||
|
|
||||||
// now navigate to the list of surfaces
|
// now navigate to the list of surfaces
|
||||||
const MD3::Surface* pcSurfaces = (const MD3::Surface*)
|
const MD3::Surface* pcSurfaces = (const MD3::Surface*)
|
||||||
|
@ -150,11 +187,19 @@ void MD3Importer::InternReadFile(
|
||||||
pScene->mNumMaterials = this->m_pcHeader->NUM_SURFACES;
|
pScene->mNumMaterials = this->m_pcHeader->NUM_SURFACES;
|
||||||
pScene->mMaterials = new aiMaterial*[pScene->mNumMeshes];
|
pScene->mMaterials = new aiMaterial*[pScene->mNumMeshes];
|
||||||
|
|
||||||
|
// if an exception is thrown before the meshes are allocated ->
|
||||||
|
// otherwise the pointer value would be invalid and delete would crash
|
||||||
|
::memset(pScene->mMeshes,0,pScene->mNumMeshes*sizeof(aiMesh*));
|
||||||
|
::memset(pScene->mMaterials,0,pScene->mNumMaterials*sizeof(aiMaterial*));
|
||||||
|
|
||||||
unsigned int iNum = this->m_pcHeader->NUM_SURFACES;
|
unsigned int iNum = this->m_pcHeader->NUM_SURFACES;
|
||||||
unsigned int iNumMaterials = 0;
|
unsigned int iNumMaterials = 0;
|
||||||
unsigned int iDefaultMatIndex = 0xFFFFFFFF;
|
unsigned int iDefaultMatIndex = 0xFFFFFFFF;
|
||||||
while (iNum-- > 0)
|
while (iNum-- > 0)
|
||||||
{
|
{
|
||||||
|
// validate the surface
|
||||||
|
this->ValidateSurfaceHeaderOffsets(pcSurfaces);
|
||||||
|
|
||||||
// navigate to the vertex list of the surface
|
// navigate to the vertex list of the surface
|
||||||
const MD3::Vertex* pcVertices = (const MD3::Vertex*)
|
const MD3::Vertex* pcVertices = (const MD3::Vertex*)
|
||||||
(((unsigned char*)pcSurfaces) + pcSurfaces->OFS_XYZNORMAL);
|
(((unsigned char*)pcSurfaces) + pcSurfaces->OFS_XYZNORMAL);
|
||||||
|
@ -171,7 +216,6 @@ void MD3Importer::InternReadFile(
|
||||||
const MD3::Shader* pcShaders = (const MD3::Shader*)
|
const MD3::Shader* pcShaders = (const MD3::Shader*)
|
||||||
(((unsigned char*)pcSurfaces) + pcSurfaces->OFS_SHADERS);
|
(((unsigned char*)pcSurfaces) + pcSurfaces->OFS_SHADERS);
|
||||||
|
|
||||||
|
|
||||||
// if the submesh is empty ignore it
|
// if the submesh is empty ignore it
|
||||||
if (0 == pcSurfaces->NUM_VERTICES || 0 == pcSurfaces->NUM_TRIANGLES)
|
if (0 == pcSurfaces->NUM_VERTICES || 0 == pcSurfaces->NUM_TRIANGLES)
|
||||||
{
|
{
|
||||||
|
@ -185,14 +229,14 @@ void MD3Importer::InternReadFile(
|
||||||
aiMesh* pcMesh = pScene->mMeshes[iNum];
|
aiMesh* pcMesh = pScene->mMeshes[iNum];
|
||||||
|
|
||||||
pcMesh->mNumVertices = pcSurfaces->NUM_TRIANGLES*3;
|
pcMesh->mNumVertices = pcSurfaces->NUM_TRIANGLES*3;
|
||||||
pcMesh->mNumBones = 0;
|
//pcMesh->mNumBones = 0;
|
||||||
pcMesh->mColors[0] = pcMesh->mColors[1] = pcMesh->mColors[2] = pcMesh->mColors[3] = NULL;
|
//pcMesh->mColors[0] = pcMesh->mColors[1] = pcMesh->mColors[2] = pcMesh->mColors[3] = NULL;
|
||||||
pcMesh->mNumFaces = pcSurfaces->NUM_TRIANGLES;
|
pcMesh->mNumFaces = pcSurfaces->NUM_TRIANGLES;
|
||||||
pcMesh->mFaces = new aiFace[pcSurfaces->NUM_TRIANGLES];
|
pcMesh->mFaces = new aiFace[pcSurfaces->NUM_TRIANGLES];
|
||||||
pcMesh->mNormals = new aiVector3D[pcMesh->mNumVertices];
|
pcMesh->mNormals = new aiVector3D[pcMesh->mNumVertices];
|
||||||
pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices];
|
pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices];
|
||||||
pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
|
pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
|
||||||
pcMesh->mTextureCoords[1] = pcMesh->mTextureCoords[2] = pcMesh->mTextureCoords[3] = NULL;
|
//pcMesh->mTextureCoords[1] = pcMesh->mTextureCoords[2] = pcMesh->mTextureCoords[3] = NULL;
|
||||||
pcMesh->mNumUVComponents[0] = 2;
|
pcMesh->mNumUVComponents[0] = 2;
|
||||||
|
|
||||||
// fill in all triangles
|
// fill in all triangles
|
||||||
|
@ -221,6 +265,7 @@ void MD3Importer::InternReadFile(
|
||||||
pcMesh->mTextureCoords[0][iCurrent].x = pcUVs[ pcTriangles->INDEXES[c]].U;
|
pcMesh->mTextureCoords[0][iCurrent].x = pcUVs[ pcTriangles->INDEXES[c]].U;
|
||||||
pcMesh->mTextureCoords[0][iCurrent].y = 1.0f - pcUVs[ pcTriangles->INDEXES[c]].V;
|
pcMesh->mTextureCoords[0][iCurrent].y = 1.0f - pcUVs[ pcTriangles->INDEXES[c]].V;
|
||||||
}
|
}
|
||||||
|
// FIX: flip the face ordering for use with OpenGL
|
||||||
pcMesh->mFaces[i].mIndices[0] = iTemp+2;
|
pcMesh->mFaces[i].mIndices[0] = iTemp+2;
|
||||||
pcMesh->mFaces[i].mIndices[1] = iTemp+1;
|
pcMesh->mFaces[i].mIndices[1] = iTemp+1;
|
||||||
pcMesh->mFaces[i].mIndices[2] = iTemp+0;
|
pcMesh->mFaces[i].mIndices[2] = iTemp+0;
|
||||||
|
@ -233,11 +278,11 @@ void MD3Importer::InternReadFile(
|
||||||
// make a relative path.
|
// make a relative path.
|
||||||
// if the MD3's internal path itself and the given path are using
|
// if the MD3's internal path itself and the given path are using
|
||||||
// the same directory remove it
|
// the same directory remove it
|
||||||
const char* szEndDir1 = strrchr((const char*)this->m_pcHeader->NAME,'\\');
|
const char* szEndDir1 = ::strrchr((const char*)this->m_pcHeader->NAME,'\\');
|
||||||
if (!szEndDir1)szEndDir1 = strrchr((const char*)this->m_pcHeader->NAME,'/');
|
if (!szEndDir1)szEndDir1 = ::strrchr((const char*)this->m_pcHeader->NAME,'/');
|
||||||
|
|
||||||
const char* szEndDir2 = strrchr((const char*)pcShaders->NAME,'\\');
|
const char* szEndDir2 = ::strrchr((const char*)pcShaders->NAME,'\\');
|
||||||
if (!szEndDir2)szEndDir2 = strrchr((const char*)pcShaders->NAME,'/');
|
if (!szEndDir2)szEndDir2 = ::strrchr((const char*)pcShaders->NAME,'/');
|
||||||
|
|
||||||
if (szEndDir1 && szEndDir2)
|
if (szEndDir1 && szEndDir2)
|
||||||
{
|
{
|
||||||
|
@ -276,7 +321,7 @@ void MD3Importer::InternReadFile(
|
||||||
|
|
||||||
aiString szOut;
|
aiString szOut;
|
||||||
if(AI_SUCCESS == aiGetMaterialString ( (aiMaterial*)pScene->mMaterials[p],
|
if(AI_SUCCESS == aiGetMaterialString ( (aiMaterial*)pScene->mMaterials[p],
|
||||||
AI_MATKEY_TEXBLEND_DIFFUSE(0),&szOut))
|
AI_MATKEY_TEXTURE_DIFFUSE(0),&szOut))
|
||||||
{
|
{
|
||||||
if (0 == ASSIMP_stricmp(szOut.data,szEndDir2))
|
if (0 == ASSIMP_stricmp(szOut.data,szEndDir2))
|
||||||
{
|
{
|
||||||
|
@ -294,25 +339,35 @@ void MD3Importer::InternReadFile(
|
||||||
|
|
||||||
if (szEndDir2)
|
if (szEndDir2)
|
||||||
{
|
{
|
||||||
aiString szString;
|
if (szEndDir2[0])
|
||||||
const size_t iLen = strlen(szEndDir2);
|
{
|
||||||
memcpy(szString.data,szEndDir2,iLen+1);
|
aiString szString;
|
||||||
szString.length = iLen-1;
|
const size_t iLen = ::strlen(szEndDir2);
|
||||||
|
::memcpy(szString.data,szEndDir2,iLen);
|
||||||
|
szString.data[iLen] = '\0';
|
||||||
|
szString.length = iLen;
|
||||||
|
|
||||||
pcHelper->AddProperty(&szString,AI_MATKEY_TEXTURE_DIFFUSE(0));
|
pcHelper->AddProperty(&szString,AI_MATKEY_TEXTURE_DIFFUSE(0));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DefaultLogger::get()->warn("Texture file name has zero length. "
|
||||||
|
"It will be skipped.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int iMode = (int)aiShadingMode_Gouraud;
|
int iMode = (int)aiShadingMode_Gouraud;
|
||||||
pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
|
pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
|
||||||
|
|
||||||
|
// add a small ambient color value - Quake 3 seems to have one
|
||||||
aiColor3D clr;
|
aiColor3D clr;
|
||||||
clr.b = clr.g = clr.r = 1.0f;
|
|
||||||
pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
|
|
||||||
pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
|
|
||||||
|
|
||||||
clr.b = clr.g = clr.r = 0.05f;
|
clr.b = clr.g = clr.r = 0.05f;
|
||||||
pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
|
pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
|
||||||
|
|
||||||
|
aiString szName;
|
||||||
|
szName.Set(AI_DEFAULT_MATERIAL_NAME);
|
||||||
|
pcHelper->AddProperty(&szName,AI_MATKEY_NAME);
|
||||||
|
|
||||||
pScene->mMaterials[iNumMaterials] = (aiMaterial*)pcHelper;
|
pScene->mMaterials[iNumMaterials] = (aiMaterial*)pcHelper;
|
||||||
pcMesh->mMaterialIndex = iNumMaterials++;
|
pcMesh->mMaterialIndex = iNumMaterials++;
|
||||||
}
|
}
|
||||||
|
@ -343,31 +398,27 @@ void MD3Importer::InternReadFile(
|
||||||
pcMesh->mMaterialIndex = iNumMaterials++;
|
pcMesh->mMaterialIndex = iNumMaterials++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// go to the next surface
|
||||||
pcSurfaces = (const MD3::Surface*)(((unsigned char*)pcSurfaces) + pcSurfaces->OFS_END);
|
pcSurfaces = (const MD3::Surface*)(((unsigned char*)pcSurfaces) + pcSurfaces->OFS_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 == pScene->mNumMeshes)
|
if (0 == pScene->mNumMeshes)
|
||||||
{
|
{
|
||||||
// cleanup before returning
|
// cleanup before returning
|
||||||
delete pScene;
|
delete[] this->mBuffer;
|
||||||
throw new ImportErrorException( "Invalid md3 file: File contains no valid mesh");
|
throw new ImportErrorException( "Invalid md3 file: File contains no valid mesh");
|
||||||
}
|
}
|
||||||
pScene->mNumMaterials = iNumMaterials;
|
pScene->mNumMaterials = iNumMaterials;
|
||||||
|
|
||||||
// now we need to generate an empty node graph
|
// now we need to generate an empty node graph
|
||||||
pScene->mRootNode = new aiNode();
|
pScene->mRootNode = new aiNode();
|
||||||
pScene->mRootNode->mNumChildren = pScene->mNumMeshes;
|
pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
|
||||||
pScene->mRootNode->mChildren = new aiNode*[pScene->mNumMeshes];
|
pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
|
||||||
|
|
||||||
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
|
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
|
||||||
{
|
pScene->mRootNode->mMeshes[i] = i;
|
||||||
pScene->mRootNode->mChildren[i] = new aiNode();
|
|
||||||
pScene->mRootNode->mChildren[i]->mParent = pScene->mRootNode;
|
|
||||||
pScene->mRootNode->mChildren[i]->mNumMeshes = 1;
|
|
||||||
pScene->mRootNode->mChildren[i]->mMeshes = new unsigned int[1];
|
|
||||||
pScene->mRootNode->mChildren[i]->mMeshes[0] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// delete the file buffer and return
|
||||||
delete[] this->mBuffer;
|
delete[] this->mBuffer;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
|
@ -96,6 +96,13 @@ protected:
|
||||||
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
||||||
IOSystem* pIOHandler);
|
IOSystem* pIOHandler);
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Validate offsets in the header
|
||||||
|
*/
|
||||||
|
void ValidateHeaderOffsets();
|
||||||
|
void ValidateSurfaceHeaderOffsets(const MD3::Surface* pcSurfHeader);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/** Header of the MD3 file */
|
/** Header of the MD3 file */
|
||||||
|
@ -103,6 +110,9 @@ protected:
|
||||||
|
|
||||||
/** Buffer to hold the loaded file */
|
/** Buffer to hold the loaded file */
|
||||||
const unsigned char* mBuffer;
|
const unsigned char* mBuffer;
|
||||||
|
|
||||||
|
/** Size of the file, in bytes */
|
||||||
|
unsigned int fileSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
|
@ -109,7 +109,7 @@ void MD4Importer::InternReadFile(
|
||||||
size_t fileSize = file->FileSize();
|
size_t fileSize = file->FileSize();
|
||||||
if( fileSize < sizeof(MD4::Header))
|
if( fileSize < sizeof(MD4::Header))
|
||||||
{
|
{
|
||||||
throw new ImportErrorException( ".mdd File is too small.");
|
throw new ImportErrorException( ".md4 File is too small.");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
|
@ -43,8 +43,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
//! @file Definition of in-memory structures for the MDL file format.
|
//! @file Definition of in-memory structures for the MDL file format.
|
||||||
//
|
//
|
||||||
// The specification has been taken from various sources on the internet.
|
// The specification has been taken from various sources on the internet.
|
||||||
// http://tfc.duke.free.fr/coding/mdl-specs-en.html
|
// - http://tfc.duke.free.fr/coding/mdl-specs-en.html
|
||||||
|
// - Conitec's MED SDK
|
||||||
|
// - Many quite long HEX-editor sessions
|
||||||
|
|
||||||
#ifndef AI_MDLFILEHELPER_H_INC
|
#ifndef AI_MDLFILEHELPER_H_INC
|
||||||
#define AI_MDLFILEHELPER_H_INC
|
#define AI_MDLFILEHELPER_H_INC
|
||||||
|
@ -67,15 +68,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
# error Compiler not supported. Never do this again.
|
# error Compiler not supported. Never do this again.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp {
|
||||||
{
|
namespace MDL {
|
||||||
namespace MDL
|
|
||||||
{
|
|
||||||
|
|
||||||
// magic bytes used in Quake 1 MDL meshes
|
// magic bytes used in Quake 1 MDL meshes
|
||||||
#define AI_MDL_MAGIC_NUMBER_BE 'IDPO'
|
#define AI_MDL_MAGIC_NUMBER_BE 'IDPO'
|
||||||
#define AI_MDL_MAGIC_NUMBER_LE 'OPDI'
|
#define AI_MDL_MAGIC_NUMBER_LE 'OPDI'
|
||||||
|
|
||||||
|
// magic bytes used in GameStudio A<very low> MDL meshes
|
||||||
|
#define AI_MDL_MAGIC_NUMBER_BE_GS3 'MDL2'
|
||||||
|
#define AI_MDL_MAGIC_NUMBER_LE_GS3 '2LDM'
|
||||||
|
|
||||||
// magic bytes used in GameStudio A4 MDL meshes
|
// magic bytes used in GameStudio A4 MDL meshes
|
||||||
#define AI_MDL_MAGIC_NUMBER_BE_GS4 'MDL3'
|
#define AI_MDL_MAGIC_NUMBER_BE_GS4 'MDL3'
|
||||||
#define AI_MDL_MAGIC_NUMBER_LE_GS4 '3LDM'
|
#define AI_MDL_MAGIC_NUMBER_LE_GS4 '3LDM'
|
||||||
|
@ -96,7 +99,7 @@ namespace MDL
|
||||||
|
|
||||||
|
|
||||||
// common limitations for Quake1 meshes. The loader does not check them,
|
// common limitations for Quake1 meshes. The loader does not check them,
|
||||||
// but models should not exceed these limits.
|
// (however it warns) but models should not exceed these limits.
|
||||||
#if (!defined AI_MDL_VERSION)
|
#if (!defined AI_MDL_VERSION)
|
||||||
# define AI_MDL_VERSION 6
|
# define AI_MDL_VERSION 6
|
||||||
#endif
|
#endif
|
||||||
|
@ -113,11 +116,25 @@ namespace MDL
|
||||||
# define AI_MDL_MAX_TRIANGLES 2048
|
# define AI_MDL_MAX_TRIANGLES 2048
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// helper macro that sets a pointer to NULL in debug builds
|
||||||
|
#if (!defined DEBUG_INVALIDATE_PTR)
|
||||||
|
# if (defined _DEBUG)
|
||||||
|
# define DEBUG_INVALIDATE_PTR(x) x = NULL;
|
||||||
|
# else
|
||||||
|
# define DEBUG_INVALIDATE_PTR(x)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// material key that is set for dummy materials that are
|
||||||
|
// just referencing another material
|
||||||
|
#if (!defined AI_MDL7_REFERRER_MATERIAL)
|
||||||
|
# define AI_MDL7_REFERRER_MATERIAL "&&&referrer&&&"
|
||||||
|
#endif
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** \struct Header
|
/** \struct Header
|
||||||
* \brief Data structure for the MDL main header
|
* \brief Data structure for the MDL main header
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
struct Header
|
struct Header
|
||||||
{
|
{
|
||||||
//! magic number: "IDPO"
|
//! magic number: "IDPO"
|
||||||
|
@ -157,12 +174,13 @@ struct Header
|
||||||
int32_t num_frames;
|
int32_t num_frames;
|
||||||
|
|
||||||
//! 0 = synchron, 1 = random . Ignored
|
//! 0 = synchron, 1 = random . Ignored
|
||||||
|
//! (MDLn formats: number of texture coordinates)
|
||||||
int32_t synctype;
|
int32_t synctype;
|
||||||
|
|
||||||
//! State flag
|
//! State flag
|
||||||
int32_t flags;
|
int32_t flags;
|
||||||
|
|
||||||
//! ???
|
//! Could be the total size of the file (and not a float)
|
||||||
float size;
|
float size;
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
@ -171,7 +189,6 @@ struct Header
|
||||||
/** \struct Header_MDL7
|
/** \struct Header_MDL7
|
||||||
* \brief Data structure for the MDL 7 main header
|
* \brief Data structure for the MDL 7 main header
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
struct Header_MDL7
|
struct Header_MDL7
|
||||||
{
|
{
|
||||||
//! magic number: "MDL7"
|
//! magic number: "MDL7"
|
||||||
|
@ -181,13 +198,13 @@ struct Header_MDL7
|
||||||
int32_t version;
|
int32_t version;
|
||||||
|
|
||||||
//! Number of bones in file
|
//! Number of bones in file
|
||||||
int32_t bones_num;
|
uint32_t bones_num;
|
||||||
|
|
||||||
//! Number of groups in file
|
//! Number of groups in file
|
||||||
int32_t groups_num;
|
uint32_t groups_num;
|
||||||
|
|
||||||
//! Size of data in the file
|
//! Size of data in the file
|
||||||
int32_t data_size;
|
uint32_t data_size;
|
||||||
|
|
||||||
//! Ignored. Used to store entity specific information
|
//! Ignored. Used to store entity specific information
|
||||||
int32_t entlump_size;
|
int32_t entlump_size;
|
||||||
|
@ -195,45 +212,77 @@ struct Header_MDL7
|
||||||
//! Ignored. Used to store MED related data
|
//! Ignored. Used to store MED related data
|
||||||
int32_t medlump_size;
|
int32_t medlump_size;
|
||||||
|
|
||||||
// -------------------------------------------------------
|
//! Size of the Bone_MDL7 data structure used in the file
|
||||||
// Sizes of some file parts
|
|
||||||
|
|
||||||
uint16_t bone_stc_size;
|
uint16_t bone_stc_size;
|
||||||
|
|
||||||
|
//! Size of the Skin_MDL 7 data structure used in the file
|
||||||
uint16_t skin_stc_size;
|
uint16_t skin_stc_size;
|
||||||
|
|
||||||
|
//! Size of a single color (e.g. in a material)
|
||||||
uint16_t colorvalue_stc_size;
|
uint16_t colorvalue_stc_size;
|
||||||
|
|
||||||
|
//! Size of the Material_MDL7 data structure used in the file
|
||||||
uint16_t material_stc_size;
|
uint16_t material_stc_size;
|
||||||
|
|
||||||
|
//! Size of a texture coordinate set in the file
|
||||||
uint16_t skinpoint_stc_size;
|
uint16_t skinpoint_stc_size;
|
||||||
|
|
||||||
|
//! Size of a triangle in the file
|
||||||
uint16_t triangle_stc_size;
|
uint16_t triangle_stc_size;
|
||||||
|
|
||||||
|
//! Size of a normal vertex in the file
|
||||||
uint16_t mainvertex_stc_size;
|
uint16_t mainvertex_stc_size;
|
||||||
|
|
||||||
|
//! Size of a per-frame animated vertex in the file
|
||||||
|
//! (this is not supported)
|
||||||
uint16_t framevertex_stc_size;
|
uint16_t framevertex_stc_size;
|
||||||
|
|
||||||
|
//! Size of a bone animation matrix
|
||||||
uint16_t bonetrans_stc_size;
|
uint16_t bonetrans_stc_size;
|
||||||
|
|
||||||
|
//! Size of the Frame_MDL7 data structure used in the file
|
||||||
uint16_t frame_stc_size;
|
uint16_t frame_stc_size;
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
|
||||||
#define AI_MDL7_MAX_BONENAMESIZE 20
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** \struct Bone_MDL7
|
/** \struct Bone_MDL7
|
||||||
* \brief Bone in a MDL7 file
|
* \brief Data structure for a bone in a MDL7 file
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
struct Bone_MDL7
|
struct Bone_MDL7
|
||||||
{
|
{
|
||||||
|
//! Index of the parent bone of *this* bone. 0xffff means:
|
||||||
|
//! "hey, I have no parent, I'm an orphan"
|
||||||
uint16_t parent_index;
|
uint16_t parent_index;
|
||||||
uint8_t _unused_[2]; //
|
uint8_t _unused_[2];
|
||||||
|
|
||||||
|
//! Relative position of the bone (relative to the
|
||||||
|
//! parent bone)
|
||||||
float x,y,z;
|
float x,y,z;
|
||||||
|
|
||||||
char name[AI_MDL7_MAX_BONENAMESIZE];
|
//! Optional name of the bone
|
||||||
};
|
char name[1 /* DUMMY SIZE */];
|
||||||
|
} PACK_STRUCT;
|
||||||
|
|
||||||
#define AI_MDL7_MAX_GROUPNAMESIZE 16
|
#if (!defined AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_20_CHARS)
|
||||||
|
# define AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_20_CHARS (16 + 20)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (!defined AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_32_CHARS)
|
||||||
|
# define AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_32_CHARS (16 + 32)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (!defined AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_NOT_THERE)
|
||||||
|
# define AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_NOT_THERE (16)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (!defined AI_MDL7_MAX_GROUPNAMESIZE)
|
||||||
|
# define AI_MDL7_MAX_GROUPNAMESIZE 16
|
||||||
|
#endif // ! AI_MDL7_MAX_GROUPNAMESIZE
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** \struct Group_MDL7
|
/** \struct Group_MDL7
|
||||||
* \brief Group in a MDL7 file
|
* \brief Group in a MDL7 file
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
struct Group_MDL7
|
struct Group_MDL7
|
||||||
{
|
{
|
||||||
//! = '1' -> triangle based Mesh
|
//! = '1' -> triangle based Mesh
|
||||||
|
@ -268,14 +317,14 @@ struct Group_MDL7
|
||||||
#define AI_MDL7_SKINTYPE_MATERIAL_ASCDEF 0x20
|
#define AI_MDL7_SKINTYPE_MATERIAL_ASCDEF 0x20
|
||||||
#define AI_MDL7_SKINTYPE_RGBFLAG 0x80
|
#define AI_MDL7_SKINTYPE_RGBFLAG 0x80
|
||||||
|
|
||||||
|
#if (!defined AI_MDL7_MAX_BONENAMESIZE)
|
||||||
#define AI_MDL7_MAX_BONENAMESIZE 20
|
# define AI_MDL7_MAX_BONENAMESIZE 20
|
||||||
|
#endif // !! AI_MDL7_MAX_BONENAMESIZE
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** \struct Deformer_MDL7
|
/** \struct Deformer_MDL7
|
||||||
* \brief Deformer in a MDL7 file
|
* \brief Deformer in a MDL7 file
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
struct Deformer_MDL7
|
struct Deformer_MDL7
|
||||||
{
|
{
|
||||||
int8_t deformer_version; // 0
|
int8_t deformer_version; // 0
|
||||||
|
@ -291,7 +340,6 @@ struct Deformer_MDL7
|
||||||
/** \struct DeformerElement_MDL7
|
/** \struct DeformerElement_MDL7
|
||||||
* \brief Deformer element in a MDL7 file
|
* \brief Deformer element in a MDL7 file
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
struct DeformerElement_MDL7
|
struct DeformerElement_MDL7
|
||||||
{
|
{
|
||||||
//! bei deformer_typ==0 (==bones) element_index == bone index
|
//! bei deformer_typ==0 (==bones) element_index == bone index
|
||||||
|
@ -305,7 +353,6 @@ struct DeformerElement_MDL7
|
||||||
/** \struct DeformerWeight_MDL7
|
/** \struct DeformerWeight_MDL7
|
||||||
* \brief Deformer weight in a MDL7 file
|
* \brief Deformer weight in a MDL7 file
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
struct DeformerWeight_MDL7
|
struct DeformerWeight_MDL7
|
||||||
{
|
{
|
||||||
//! for deformer_typ==0 (==bones) index == vertex index
|
//! for deformer_typ==0 (==bones) index == vertex index
|
||||||
|
@ -313,27 +360,14 @@ struct DeformerWeight_MDL7
|
||||||
float weight;
|
float weight;
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// maximum length of texture file name
|
|
||||||
#define AI_MDL7_MAX_TEXNAMESIZE 0x10
|
|
||||||
|
|
||||||
// don't know why this was in the original headers ...
|
// don't know why this was in the original headers ...
|
||||||
// to be removed in future versions
|
|
||||||
typedef int32_t MD7_MATERIAL_ASCDEFSIZE;
|
typedef int32_t MD7_MATERIAL_ASCDEFSIZE;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** \struct Skin_MDL7
|
/** \struct ColorValue_MDL7
|
||||||
* \brief Skin in a MDL7 file
|
* \brief Data structure for a color value in a MDL7 file
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
struct Skin_MDL7
|
|
||||||
{
|
|
||||||
uint8_t typ;
|
|
||||||
int8_t _unused_[3];
|
|
||||||
int32_t width;
|
|
||||||
int32_t height;
|
|
||||||
char texture_name[AI_MDL7_MAX_TEXNAMESIZE];
|
|
||||||
} PACK_STRUCT;
|
|
||||||
|
|
||||||
struct ColorValue_MDL7
|
struct ColorValue_MDL7
|
||||||
{
|
{
|
||||||
float r,g,b,a;
|
float r,g,b,a;
|
||||||
|
@ -341,9 +375,8 @@ struct ColorValue_MDL7
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** \struct Material_MDL7
|
/** \struct Material_MDL7
|
||||||
* \brief Material in a MDL7 file
|
* \brief Data structure for a Material in a MDL7 file
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
struct Material_MDL7
|
struct Material_MDL7
|
||||||
{
|
{
|
||||||
//! Diffuse base color of the material
|
//! Diffuse base color of the material
|
||||||
|
@ -365,9 +398,8 @@ struct Material_MDL7
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** \struct Skin
|
/** \struct Skin
|
||||||
* \brief Skin data structure #1
|
* \brief Skin data structure #1 - used by Quake1, MDL2, MDL3 and MDL4
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
struct Skin
|
struct Skin
|
||||||
{
|
{
|
||||||
//! 0 = single (Skin), 1 = group (GroupSkin)
|
//! 0 = single (Skin), 1 = group (GroupSkin)
|
||||||
|
@ -387,12 +419,40 @@ struct Skin
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/** \struct Skin
|
||||||
|
* \brief Skin data structure #2 - used by MDL5, MDL6 and MDL7
|
||||||
|
* \see Skin
|
||||||
|
*/
|
||||||
struct Skin_MDL5
|
struct Skin_MDL5
|
||||||
{
|
{
|
||||||
int32_t size, width, height;
|
int32_t size, width, height;
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
// maximum length of texture file name
|
||||||
|
#if (!defined AI_MDL7_MAX_TEXNAMESIZE)
|
||||||
|
# define AI_MDL7_MAX_TEXNAMESIZE 0x10
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/** \struct Skin_MDL7
|
||||||
|
* \brief Skin data structure #3 - used by MDL7 and HMP7
|
||||||
|
*/
|
||||||
|
struct Skin_MDL7
|
||||||
|
{
|
||||||
|
uint8_t typ;
|
||||||
|
int8_t _unused_[3];
|
||||||
|
int32_t width;
|
||||||
|
int32_t height;
|
||||||
|
char texture_name[AI_MDL7_MAX_TEXNAMESIZE];
|
||||||
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/** \struct RGB565
|
||||||
|
* \brief Data structure for a RGB565 pixel in a texture
|
||||||
|
*/
|
||||||
struct RGB565
|
struct RGB565
|
||||||
{
|
{
|
||||||
uint16_t r : 5;
|
uint16_t r : 5;
|
||||||
|
@ -400,6 +460,10 @@ struct RGB565
|
||||||
uint16_t b : 5;
|
uint16_t b : 5;
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/** \struct ARGB4
|
||||||
|
* \brief Data structure for a ARGB4444 pixel in a texture
|
||||||
|
*/
|
||||||
struct ARGB4
|
struct ARGB4
|
||||||
{
|
{
|
||||||
uint16_t a : 4;
|
uint16_t a : 4;
|
||||||
|
@ -412,7 +476,6 @@ struct ARGB4
|
||||||
/** \struct GroupSkin
|
/** \struct GroupSkin
|
||||||
* \brief Skin data structure #2 (group of pictures)
|
* \brief Skin data structure #2 (group of pictures)
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
struct GroupSkin
|
struct GroupSkin
|
||||||
{
|
{
|
||||||
//! 0 = single (Skin), 1 = group (GroupSkin)
|
//! 0 = single (Skin), 1 = group (GroupSkin)
|
||||||
|
@ -430,9 +493,8 @@ struct GroupSkin
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** \struct TexCoord
|
/** \struct TexCoord
|
||||||
* \brief Texture coordinate data structure
|
* \brief Texture coordinate data structure used by the Quake1 MDL format
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
struct TexCoord
|
struct TexCoord
|
||||||
{
|
{
|
||||||
//! Is the vertex on the noundary between front and back piece?
|
//! Is the vertex on the noundary between front and back piece?
|
||||||
|
@ -445,7 +507,10 @@ struct TexCoord
|
||||||
int32_t t;
|
int32_t t;
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/** \struct TexCoord_MDL3
|
||||||
|
* \brief Data structure for an UV coordinate in the 3DGS MDL3 format
|
||||||
|
*/
|
||||||
struct TexCoord_MDL3
|
struct TexCoord_MDL3
|
||||||
{
|
{
|
||||||
//! position, horizontally in range 0..skinwidth-1
|
//! position, horizontally in range 0..skinwidth-1
|
||||||
|
@ -455,6 +520,10 @@ struct TexCoord_MDL3
|
||||||
int16_t v;
|
int16_t v;
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/** \struct TexCoord_MDL7
|
||||||
|
* \brief Data structure for an UV coordinate in the 3DGS MDL7 format
|
||||||
|
*/
|
||||||
struct TexCoord_MDL7
|
struct TexCoord_MDL7
|
||||||
{
|
{
|
||||||
//! position, horizontally in range 0..1
|
//! position, horizontally in range 0..1
|
||||||
|
@ -464,32 +533,13 @@ struct TexCoord_MDL7
|
||||||
float v;
|
float v;
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** \struct Triangle
|
/** \struct SkinSet_MDL7
|
||||||
* \brief Triangle data structure
|
* \brief Skin set data structure for the 3DGS MDL7 format
|
||||||
|
* MDL7 references UV coordinates per face via an index list.
|
||||||
|
* This allows the use of multiple skins per face with just one
|
||||||
|
* UV coordinate set.
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
struct Triangle
|
|
||||||
{
|
|
||||||
//! 0 = backface, 1 = frontface
|
|
||||||
int32_t facesfront;
|
|
||||||
|
|
||||||
//! Vertex indices
|
|
||||||
int32_t vertex[3];
|
|
||||||
} PACK_STRUCT;
|
|
||||||
|
|
||||||
|
|
||||||
struct Triangle_MDL3
|
|
||||||
{
|
|
||||||
//! Index of 3 3D vertices in range 0..numverts
|
|
||||||
uint16_t index_xyz[3];
|
|
||||||
|
|
||||||
//! Index of 3 skin vertices in range 0..numskinverts
|
|
||||||
uint16_t index_uv[3];
|
|
||||||
} PACK_STRUCT;
|
|
||||||
|
|
||||||
|
|
||||||
struct SkinSet_MDL7
|
struct SkinSet_MDL7
|
||||||
{
|
{
|
||||||
//! Index into the UV coordinate list
|
//! Index into the UV coordinate list
|
||||||
|
@ -499,7 +549,36 @@ struct SkinSet_MDL7
|
||||||
int32_t material; // size 4
|
int32_t material; // size 4
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/** \struct Triangle
|
||||||
|
* \brief Triangle data structure for the Quake1 MDL format
|
||||||
|
*/
|
||||||
|
struct Triangle
|
||||||
|
{
|
||||||
|
//! 0 = backface, 1 = frontface
|
||||||
|
int32_t facesfront;
|
||||||
|
|
||||||
|
//! Vertex indices
|
||||||
|
int32_t vertex[3];
|
||||||
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/** \struct Triangle_MDL3
|
||||||
|
* \brief Triangle data structure for the 3DGS MDL3 format
|
||||||
|
*/
|
||||||
|
struct Triangle_MDL3
|
||||||
|
{
|
||||||
|
//! Index of 3 3D vertices in range 0..numverts
|
||||||
|
uint16_t index_xyz[3];
|
||||||
|
|
||||||
|
//! Index of 3 skin vertices in range 0..numskinverts
|
||||||
|
uint16_t index_uv[3];
|
||||||
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/** \struct Triangle_MDL7
|
||||||
|
* \brief Triangle data structure for the 3DGS MDL7 format
|
||||||
|
*/
|
||||||
struct Triangle_MDL7
|
struct Triangle_MDL7
|
||||||
{
|
{
|
||||||
//! Vertex indices
|
//! Vertex indices
|
||||||
|
@ -509,6 +588,15 @@ struct Triangle_MDL7
|
||||||
SkinSet_MDL7 skinsets[2];
|
SkinSet_MDL7 skinsets[2];
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
#if (!defined AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV)
|
||||||
|
# define AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV (6+sizeof(SkinSet_MDL7)-sizeof(uint32_t))
|
||||||
|
#endif
|
||||||
|
#if (!defined AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV_WITH_MATINDEX)
|
||||||
|
# define AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV_WITH_MATINDEX (6+sizeof(SkinSet_MDL7))
|
||||||
|
#endif
|
||||||
|
#if (!defined AI_MDL7_TRIANGLE_STD_SIZE_TWO_UV)
|
||||||
|
# define AI_MDL7_TRIANGLE_STD_SIZE_TWO_UV (6+2*sizeof(SkinSet_MDL7))
|
||||||
|
#endif
|
||||||
|
|
||||||
// Helper constants for Triangle::facesfront
|
// Helper constants for Triangle::facesfront
|
||||||
#if (!defined AI_MDL_BACKFACE)
|
#if (!defined AI_MDL_BACKFACE)
|
||||||
|
@ -522,7 +610,6 @@ struct Triangle_MDL7
|
||||||
/** \struct Vertex
|
/** \struct Vertex
|
||||||
* \brief Vertex data structure
|
* \brief Vertex data structure
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
struct Vertex
|
struct Vertex
|
||||||
{
|
{
|
||||||
uint8_t v[3];
|
uint8_t v[3];
|
||||||
|
@ -530,6 +617,7 @@ struct Vertex
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
struct Vertex_MDL4
|
struct Vertex_MDL4
|
||||||
{
|
{
|
||||||
uint16_t v[3];
|
uint16_t v[3];
|
||||||
|
@ -544,13 +632,12 @@ struct Vertex_MDL4
|
||||||
/** \struct Vertex_MDL7
|
/** \struct Vertex_MDL7
|
||||||
* \brief Vertex data structure used in MDL7 files
|
* \brief Vertex data structure used in MDL7 files
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
struct Vertex_MDL7
|
struct Vertex_MDL7
|
||||||
{
|
{
|
||||||
float x,y,z;
|
float x,y,z;
|
||||||
uint16_t vertindex; // = bone index
|
uint16_t vertindex; // = bone index
|
||||||
union {
|
union {
|
||||||
uint16_t norm162index;
|
uint8_t norm162index;
|
||||||
float norm[3];
|
float norm[3];
|
||||||
};
|
};
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
@ -560,7 +647,6 @@ struct Vertex_MDL7
|
||||||
/** \struct BoneTransform_MDL7
|
/** \struct BoneTransform_MDL7
|
||||||
* \brief bone transformation matrix structure used in MDL7 files
|
* \brief bone transformation matrix structure used in MDL7 files
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
struct BoneTransform_MDL7
|
struct BoneTransform_MDL7
|
||||||
{
|
{
|
||||||
//! 4*3
|
//! 4*3
|
||||||
|
@ -582,7 +668,6 @@ struct BoneTransform_MDL7
|
||||||
/** \struct Frame_MDL7
|
/** \struct Frame_MDL7
|
||||||
* \brief Frame data structure used by MDL7 files
|
* \brief Frame data structure used by MDL7 files
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
struct Frame_MDL7
|
struct Frame_MDL7
|
||||||
{
|
{
|
||||||
char frame_name[AI_MDL7_MAX_FRAMENAMESIZE];
|
char frame_name[AI_MDL7_MAX_FRAMENAMESIZE];
|
||||||
|
@ -595,7 +680,6 @@ struct Frame_MDL7
|
||||||
/** \struct SimpleFrame
|
/** \struct SimpleFrame
|
||||||
* \brief Data structure for a simple frame
|
* \brief Data structure for a simple frame
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
struct SimpleFrame
|
struct SimpleFrame
|
||||||
{
|
{
|
||||||
//! Minimum vertex of the bounding box
|
//! Minimum vertex of the bounding box
|
||||||
|
@ -615,7 +699,6 @@ struct SimpleFrame
|
||||||
/** \struct Frame
|
/** \struct Frame
|
||||||
* \brief Model frame data structure
|
* \brief Model frame data structure
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
struct Frame
|
struct Frame
|
||||||
{
|
{
|
||||||
//! 0 = simple frame, !0 = group frame
|
//! 0 = simple frame, !0 = group frame
|
||||||
|
@ -626,6 +709,7 @@ struct Frame
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
struct SimpleFrame_MDLn_SP
|
struct SimpleFrame_MDLn_SP
|
||||||
{
|
{
|
||||||
//! Minimum vertex of the bounding box
|
//! Minimum vertex of the bounding box
|
||||||
|
@ -645,7 +729,6 @@ struct SimpleFrame_MDLn_SP
|
||||||
/** \struct GroupFrame
|
/** \struct GroupFrame
|
||||||
* \brief Data structure for a group of frames
|
* \brief Data structure for a group of frames
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
struct GroupFrame
|
struct GroupFrame
|
||||||
{
|
{
|
||||||
//! 0 = simple frame, !0 = group frame
|
//! 0 = simple frame, !0 = group frame
|
||||||
|
@ -675,7 +758,6 @@ struct GroupFrame
|
||||||
/** \struct IntFace_MDL7
|
/** \struct IntFace_MDL7
|
||||||
* \brief Internal data structure to temporarily represent a face
|
* \brief Internal data structure to temporarily represent a face
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
struct IntFace_MDL7
|
struct IntFace_MDL7
|
||||||
{
|
{
|
||||||
// provide a constructor for our own convenience
|
// provide a constructor for our own convenience
|
||||||
|
@ -700,7 +782,6 @@ struct IntFace_MDL7
|
||||||
* which has been created from two single materials along with the
|
* which has been created from two single materials along with the
|
||||||
* original material indices.
|
* original material indices.
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
struct IntMaterial_MDL7
|
struct IntMaterial_MDL7
|
||||||
{
|
{
|
||||||
// provide a constructor for our own convenience
|
// provide a constructor for our own convenience
|
||||||
|
@ -717,6 +798,188 @@ struct IntMaterial_MDL7
|
||||||
unsigned int iOldMatIndices[2];
|
unsigned int iOldMatIndices[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/** \struct IntBone_MDL7
|
||||||
|
* \brief Internal data structure to represent a bone in a MDL7 file with
|
||||||
|
* all of its animation channels assigned to it.
|
||||||
|
*/
|
||||||
|
struct IntBone_MDL7 : aiBone
|
||||||
|
{
|
||||||
|
//! Default constructor
|
||||||
|
IntBone_MDL7() : iParent (0xffff)
|
||||||
|
{
|
||||||
|
pkeyPositions.reserve(30);
|
||||||
|
pkeyScalings.reserve(30);
|
||||||
|
pkeyRotations.reserve(30);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Parent bone of the bone
|
||||||
|
uint64_t iParent;
|
||||||
|
|
||||||
|
//! Relative position of the bone
|
||||||
|
aiVector3D vPosition;
|
||||||
|
|
||||||
|
//! Array of position keys
|
||||||
|
std::vector<aiVectorKey> pkeyPositions;
|
||||||
|
|
||||||
|
//! Array of scaling keys
|
||||||
|
std::vector<aiVectorKey> pkeyScalings;
|
||||||
|
|
||||||
|
//! Array of rotation keys
|
||||||
|
std::vector<aiQuatKey> pkeyRotations;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//! Describes a MDL7 frame
|
||||||
|
struct IntFrameInfo_MDL7
|
||||||
|
{
|
||||||
|
//! Construction from an existing frame header
|
||||||
|
IntFrameInfo_MDL7(const MDL::Frame_MDL7* _pcFrame,unsigned int _iIndex)
|
||||||
|
: pcFrame(_pcFrame), iIndex(_iIndex)
|
||||||
|
{}
|
||||||
|
|
||||||
|
//! Index of the frame
|
||||||
|
unsigned int iIndex;
|
||||||
|
|
||||||
|
//! Points to the header of the frame
|
||||||
|
const MDL::Frame_MDL7* pcFrame;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//! Describes a MDL7 mesh group
|
||||||
|
struct IntGroupInfo_MDL7
|
||||||
|
{
|
||||||
|
//! Default constructor
|
||||||
|
IntGroupInfo_MDL7() :
|
||||||
|
iIndex(0),
|
||||||
|
pcGroup(NULL), pcGroupUVs(NULL),
|
||||||
|
pcGroupTris(NULL), pcGroupVerts(NULL)
|
||||||
|
{}
|
||||||
|
|
||||||
|
//! Construction from an existing group header
|
||||||
|
IntGroupInfo_MDL7(const MDL::Group_MDL7* _pcGroup,unsigned int _iIndex)
|
||||||
|
:
|
||||||
|
pcGroup(_pcGroup),iIndex(_iIndex)
|
||||||
|
{}
|
||||||
|
|
||||||
|
//! Index of the group
|
||||||
|
unsigned int iIndex;
|
||||||
|
|
||||||
|
//! Points to the header of the group
|
||||||
|
const MDL::Group_MDL7* pcGroup;
|
||||||
|
|
||||||
|
//! Points to the beginning of the uv coordinate section
|
||||||
|
const MDL::TexCoord_MDL7* pcGroupUVs;
|
||||||
|
|
||||||
|
//! Points to the beginning of the triangle section
|
||||||
|
const MDL::Triangle_MDL7* pcGroupTris;
|
||||||
|
|
||||||
|
//! Points to the beginning of the vertex section
|
||||||
|
const MDL::Vertex_MDL7* pcGroupVerts;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//! Holds the data that belongs to a MDL7 mesh group
|
||||||
|
struct IntGroupData_MDL7
|
||||||
|
{
|
||||||
|
IntGroupData_MDL7()
|
||||||
|
: pcFaces(NULL), bNeed2UV(false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
//! Array of faces that belong to the group
|
||||||
|
MDL::IntFace_MDL7* pcFaces;
|
||||||
|
|
||||||
|
//! Array of vertex positions
|
||||||
|
std::vector<aiVector3D> vPositions;
|
||||||
|
|
||||||
|
//! Array of vertex normals
|
||||||
|
std::vector<aiVector3D> vNormals;
|
||||||
|
|
||||||
|
//! Array of bones indices
|
||||||
|
std::vector<unsigned int> aiBones;
|
||||||
|
|
||||||
|
//! First UV coordinate set
|
||||||
|
std::vector<aiVector3D> vTextureCoords1;
|
||||||
|
|
||||||
|
//! Optional second UV coordinate set
|
||||||
|
std::vector<aiVector3D> vTextureCoords2;
|
||||||
|
|
||||||
|
//! Specifies whether there are two texture
|
||||||
|
//! coordinate sets required
|
||||||
|
bool bNeed2UV;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//! Holds data from an MDL7 file that is shared by all mesh groups
|
||||||
|
struct IntSharedData_MDL7
|
||||||
|
{
|
||||||
|
//! Default constructor
|
||||||
|
IntSharedData_MDL7()
|
||||||
|
{
|
||||||
|
abNeedMaterials.reserve(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Destruction: properly delete all allocated resources
|
||||||
|
~IntSharedData_MDL7()
|
||||||
|
{
|
||||||
|
// kill all bones
|
||||||
|
if (this->apcOutBones)
|
||||||
|
{
|
||||||
|
for (unsigned int m = 0; m < iNum;++m)
|
||||||
|
delete this->apcOutBones[m];
|
||||||
|
delete[] this->apcOutBones;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Specifies which materials are used
|
||||||
|
std::vector<bool> abNeedMaterials;
|
||||||
|
|
||||||
|
//! List of all materials
|
||||||
|
std::vector<MaterialHelper*> pcMats;
|
||||||
|
|
||||||
|
//! List of all bones
|
||||||
|
IntBone_MDL7** apcOutBones;
|
||||||
|
|
||||||
|
//! number of bones
|
||||||
|
unsigned int iNum;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//! Contains input data for GenerateOutputMeshes_3DGS_MDL7
|
||||||
|
struct IntSplittedGroupData_MDL7
|
||||||
|
{
|
||||||
|
//! Construction from a given shared data set
|
||||||
|
IntSplittedGroupData_MDL7(IntSharedData_MDL7& _shared,
|
||||||
|
std::vector<aiMesh*>& _avOutList)
|
||||||
|
|
||||||
|
: shared(_shared), avOutList(_avOutList)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Destruction: properly delete all allocated resources
|
||||||
|
~IntSplittedGroupData_MDL7()
|
||||||
|
{
|
||||||
|
// kill all face lists
|
||||||
|
if(this->aiSplit)
|
||||||
|
{
|
||||||
|
for (unsigned int m = 0; m < shared.pcMats.size();++m)
|
||||||
|
delete this->aiSplit[m];
|
||||||
|
delete[] this->aiSplit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Contains a list of all faces per material
|
||||||
|
std::vector<unsigned int>** aiSplit;
|
||||||
|
|
||||||
|
//! Shared data for all groups of the model
|
||||||
|
IntSharedData_MDL7& shared;
|
||||||
|
|
||||||
|
//! List of meshes
|
||||||
|
std::vector<aiMesh*>& avOutList;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
};}; // end namespaces
|
};}; // end namespaces
|
||||||
|
|
||||||
#endif // !! AI_MDLFILEHELPER_H_INC
|
#endif // !! AI_MDLFILEHELPER_H_INC
|
2520
code/MDLLoader.cpp
2520
code/MDLLoader.cpp
File diff suppressed because it is too large
Load Diff
387
code/MDLLoader.h
387
code/MDLLoader.h
|
@ -61,6 +61,11 @@ class MaterialHelper;
|
||||||
|
|
||||||
using namespace MDL;
|
using namespace MDL;
|
||||||
|
|
||||||
|
|
||||||
|
#if (!defined VALIDATE_FILE_SIZE)
|
||||||
|
# define VALIDATE_FILE_SIZE(msg) this->SizeCheck(msg,__FILE__,__LINE__)
|
||||||
|
#endif
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Used to load MDL files
|
/** Used to load MDL files
|
||||||
*/
|
*/
|
||||||
|
@ -104,120 +109,57 @@ protected:
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Import a quake 1 MDL file
|
/** Import a quake 1 MDL file (IDPO)
|
||||||
*/
|
*/
|
||||||
void InternReadFile_Quake1( );
|
void InternReadFile_Quake1( );
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Import a GameStudio A4/A5 file
|
/** Import a GameStudio A4/A5 file (MDL 3,4,5)
|
||||||
*/
|
*/
|
||||||
void InternReadFile_GameStudio( );
|
void InternReadFile_3DGS_MDL345( );
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Import a GameStudio A7 file
|
/** Import a GameStudio A7 file (MDL 7)
|
||||||
*/
|
*/
|
||||||
void InternReadFile_GameStudioA7( );
|
void InternReadFile_3DGS_MDL7( );
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Import a CS:S/HL2 MDL file
|
/** Import a CS:S/HL2 MDL file (not fully implemented)
|
||||||
*/
|
*/
|
||||||
void InternReadFile_HL2( );
|
void InternReadFile_HL2( );
|
||||||
|
|
||||||
|
|
||||||
|
// *******************************************************************
|
||||||
|
// Debugging/validation functions
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Load a paletized texture from the file and convert it to 32bpp
|
/** Check whether a given position is inside the valid range
|
||||||
|
* Throw a new ImportErrorException if it is not
|
||||||
|
* \param szPos Cursor position
|
||||||
|
* \param szFile Name of the source file from which the function was called
|
||||||
|
* \param iLine Source code line from which the function was called
|
||||||
*/
|
*/
|
||||||
void CreateTextureARGB8(const unsigned char* szData);
|
void SizeCheck(const void* szPos);
|
||||||
|
void SizeCheck(const void* szPos, const char* szFile, unsigned int iLine);
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** Used to load textures from MDL3/4
|
|
||||||
* \param szData Input data
|
|
||||||
* \param iType Color data type
|
|
||||||
* \param piSkip Receive: Size to skip
|
|
||||||
*/
|
|
||||||
void CreateTextureARGB8_GS4(const unsigned char* szData,
|
|
||||||
unsigned int iType,
|
|
||||||
unsigned int* piSkip);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** Used to load textures from MDL5
|
|
||||||
* \param szData Input data
|
|
||||||
* \param iType Color data type
|
|
||||||
* \param piSkip Receive: Size to skip
|
|
||||||
*/
|
|
||||||
void CreateTextureARGB8_GS5(const unsigned char* szData,
|
|
||||||
unsigned int iType,
|
|
||||||
unsigned int* piSkip);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** Parse a skin lump in a MDL7 file with all of its features
|
|
||||||
* \param szCurrent Current data pointer
|
|
||||||
* \param szCurrentOut Output data pointer
|
|
||||||
* \param pcMats Material list for this group. To be filled ...
|
|
||||||
*/
|
|
||||||
void ParseSkinLump_GameStudioA7(
|
|
||||||
const unsigned char* szCurrent,
|
|
||||||
const unsigned char** szCurrentOut,
|
|
||||||
std::vector<MaterialHelper*>& pcMats);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** Parse texture color data for MDL5, MDL6 and MDL7 formats
|
|
||||||
* \param szData Current data pointer
|
|
||||||
* \param iType type of the texture data. No DDS or external
|
|
||||||
* \param piSkip Receive the number of bytes to skip
|
|
||||||
* \param pcNew Must point to fully initialized data. Width and
|
|
||||||
* height must be set.
|
|
||||||
*/
|
|
||||||
void ParseTextureColorData(const unsigned char* szData,
|
|
||||||
unsigned int iType,
|
|
||||||
unsigned int* piSkip,
|
|
||||||
aiTexture* pcNew);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Validate the header data structure of a game studio MDL7 file
|
/** Validate the header data structure of a game studio MDL7 file
|
||||||
* \param pcHeader Input header to be validated
|
* \param pcHeader Input header to be validated
|
||||||
*/
|
*/
|
||||||
void ValidateHeader_GameStudioA7(const MDL::Header_MDL7* pcHeader);
|
void ValidateHeader_3DGS_MDL7(const MDL::Header_MDL7* pcHeader);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Join two materials / skins. Setup UV source ... etc
|
/** Validate the header data structure of a Quake 1 model
|
||||||
* \param pcMat1 First input material
|
* \param pcHeader Input header to be validated
|
||||||
* \param pcMat2 Second input material
|
|
||||||
* \param pcMatOut Output material instance to be filled. Must be empty
|
|
||||||
*/
|
*/
|
||||||
void JoinSkins_GameStudioA7(MaterialHelper* pcMat1,
|
void ValidateHeader_Quake1(const MDL::Header* pcHeader);
|
||||||
MaterialHelper* pcMat2,
|
|
||||||
MaterialHelper* pcMatOut);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** Generate the final output meshes for a7 models
|
|
||||||
* \param aiSplit Face-per-material list
|
|
||||||
* \param pcMats List of all materials
|
|
||||||
* \param avOutList Output: List of all meshes
|
|
||||||
* \param pcFaces List of all input faces
|
|
||||||
* \param vPositions List of all input vectors
|
|
||||||
* \param vNormals List of all input normal vectors
|
|
||||||
* \param vTextureCoords1 List of all input UV coords #1
|
|
||||||
* \param vTextureCoords2 List of all input UV coords #2
|
|
||||||
*/
|
|
||||||
void GenerateOutputMeshes_GameStudioA7(
|
|
||||||
const std::vector<unsigned int>** aiSplit,
|
|
||||||
const std::vector<MaterialHelper*>& pcMats,
|
|
||||||
std::vector<aiMesh*>& avOutList,
|
|
||||||
const MDL::IntFace_MDL7* pcFaces,
|
|
||||||
const std::vector<aiVector3D>& vPositions,
|
|
||||||
const std::vector<aiVector3D>& vNormals,
|
|
||||||
const std::vector<aiVector3D>& vTextureCoords1,
|
|
||||||
const std::vector<aiVector3D>& vTextureCoords2);
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// *******************************************************************
|
||||||
/** Calculate absolute bone animation matrices for each bone
|
// Material import
|
||||||
* \param pcBones Pointer to the bone section in the file
|
|
||||||
* \param apcOutBones Output bones array
|
|
||||||
*/
|
|
||||||
void CalculateAbsBoneAnimMatrices(const MDL::Bone_MDL7* pcBones,
|
|
||||||
aiBone** apcOutBones);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Try to load a palette from the current directory (colormap.lmp)
|
/** Try to load a palette from the current directory (colormap.lmp)
|
||||||
|
@ -230,6 +172,262 @@ protected:
|
||||||
*/
|
*/
|
||||||
void FreePalette(const unsigned char* pszColorMap);
|
void FreePalette(const unsigned char* pszColorMap);
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Load a paletized texture from the file and convert it to 32bpp
|
||||||
|
*/
|
||||||
|
void CreateTextureARGB8_3DGS_MDL3(const unsigned char* szData);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Used to load textures from MDL3/4
|
||||||
|
* \param szData Input data
|
||||||
|
* \param iType Color data type
|
||||||
|
* \param piSkip Receive: Size to skip, in bytes
|
||||||
|
*/
|
||||||
|
void CreateTexture_3DGS_MDL4(const unsigned char* szData,
|
||||||
|
unsigned int iType,
|
||||||
|
unsigned int* piSkip);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Used to load textures from MDL5
|
||||||
|
* \param szData Input data
|
||||||
|
* \param iType Color data type
|
||||||
|
* \param piSkip Receive: Size to skip, in bytes
|
||||||
|
*/
|
||||||
|
void CreateTexture_3DGS_MDL5(const unsigned char* szData,
|
||||||
|
unsigned int iType,
|
||||||
|
unsigned int* piSkip);
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Checks whether a texture can be replaced with a single color
|
||||||
|
* This is useful for all file formats before MDL7 (all those
|
||||||
|
* that are not containing material colors separate from textures).
|
||||||
|
* MED seems to write dummy 8x8 monochrome images instead.
|
||||||
|
* \param pcTexture Input texture
|
||||||
|
* \return aiColor.r is set to qnan if the function fails and no
|
||||||
|
* color can be found.
|
||||||
|
*/
|
||||||
|
aiColor4D ReplaceTextureWithColor(const aiTexture* pcTexture);
|
||||||
|
|
||||||
|
|
||||||
|
// *******************************************************************
|
||||||
|
// Quake1, MDL 3,4,5 import
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Converts the absolute texture coordinates in MDL5 files to
|
||||||
|
* relative in a range between 0 and 1
|
||||||
|
*/
|
||||||
|
void CalculateUVCoordinates_MDL5();
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Read an UV coordinate from the file. If the file format is not
|
||||||
|
* MDL5, the function calculates relative texture coordinates
|
||||||
|
* \param vOut Receives the output UV coord
|
||||||
|
* \param pcSrc UV coordinate buffer
|
||||||
|
* \param UV coordinate index
|
||||||
|
*/
|
||||||
|
void ImportUVCoordinate_3DGS_MDL345( aiVector3D& vOut,
|
||||||
|
const MDL::TexCoord_MDL3* pcSrc,
|
||||||
|
unsigned int iIndex);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Setup the material properties for Quake and MDL<7 models.
|
||||||
|
* These formats don't support more than one material per mesh,
|
||||||
|
* therefore the method processes only ONE skin and removes
|
||||||
|
* all others.
|
||||||
|
*/
|
||||||
|
void SetupMaterialProperties_3DGS_MDL5_Quake1( );
|
||||||
|
|
||||||
|
|
||||||
|
// *******************************************************************
|
||||||
|
// MDL7 import
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Parse a skin lump in a MDL7/HMP7 file with all of its features
|
||||||
|
* variant 1: Current cursor position is the beginning of the skin header
|
||||||
|
* \param szCurrent Current data pointer
|
||||||
|
* \param szCurrentOut Output data pointer
|
||||||
|
* \param pcMats Material list for this group. To be filled ...
|
||||||
|
*/
|
||||||
|
void ParseSkinLump_3DGS_MDL7(
|
||||||
|
const unsigned char* szCurrent,
|
||||||
|
const unsigned char** szCurrentOut,
|
||||||
|
std::vector<MaterialHelper*>& pcMats);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Parse a skin lump in a MDL7/HMP7 file with all of its features
|
||||||
|
* variant 2: Current cursor position is the beginning of the skin data
|
||||||
|
* \param szCurrent Current data pointer
|
||||||
|
* \param szCurrentOut Output data pointer
|
||||||
|
* \param pcMatOut Output material
|
||||||
|
* \param iType header.typ
|
||||||
|
* \param iWidth header.width
|
||||||
|
* \param iHeight header.height
|
||||||
|
*/
|
||||||
|
void ParseSkinLump_3DGS_MDL7(
|
||||||
|
const unsigned char* szCurrent,
|
||||||
|
const unsigned char** szCurrentOut,
|
||||||
|
MaterialHelper* pcMatOut,
|
||||||
|
unsigned int iType,
|
||||||
|
unsigned int iWidth,
|
||||||
|
unsigned int iHeight);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Skip a skin lump in a MDL7/HMP7 file
|
||||||
|
* \param szCurrent Current data pointer
|
||||||
|
* \param szCurrentOut Output data pointer. Points to the byte just
|
||||||
|
* behind the last byte of the skin.
|
||||||
|
* \param iType header.typ
|
||||||
|
* \param iWidth header.width
|
||||||
|
* \param iHeight header.height
|
||||||
|
*/
|
||||||
|
void SkipSkinLump_3DGS_MDL7(const unsigned char* szCurrent,
|
||||||
|
const unsigned char** szCurrentOut,
|
||||||
|
unsigned int iType,
|
||||||
|
unsigned int iWidth,
|
||||||
|
unsigned int iHeight);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Parse texture color data for MDL5, MDL6 and MDL7 formats
|
||||||
|
* \param szData Current data pointer
|
||||||
|
* \param iType type of the texture data. No DDS or external
|
||||||
|
* \param piSkip Receive the number of bytes to skip
|
||||||
|
* \param pcNew Must point to fully initialized data. Width and
|
||||||
|
* height must be set. If pcNew->pcData is set to 0xffffffff,
|
||||||
|
* piSkip will receive the size of the texture, in bytes, but no
|
||||||
|
* color data will be read.
|
||||||
|
*/
|
||||||
|
void ParseTextureColorData(const unsigned char* szData,
|
||||||
|
unsigned int iType,
|
||||||
|
unsigned int* piSkip,
|
||||||
|
aiTexture* pcNew);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Join two materials / skins. Setup UV source ... etc
|
||||||
|
* \param pcMat1 First input material
|
||||||
|
* \param pcMat2 Second input material
|
||||||
|
* \param pcMatOut Output material instance to be filled. Must be empty
|
||||||
|
*/
|
||||||
|
void JoinSkins_3DGS_MDL7(MaterialHelper* pcMat1,
|
||||||
|
MaterialHelper* pcMat2,
|
||||||
|
MaterialHelper* pcMatOut);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Add a bone transformation key to an animation
|
||||||
|
* \param iTrafo Index of the transformation (always==frame index?)
|
||||||
|
* No need to validate this index, it is always valid.
|
||||||
|
* \param pcBoneTransforms Bone transformation for this index
|
||||||
|
* \param apcOutBones Output bones array
|
||||||
|
*/
|
||||||
|
void AddAnimationBoneTrafoKey_3DGS_MDL7(unsigned int iTrafo,
|
||||||
|
const MDL::BoneTransform_MDL7* pcBoneTransforms,
|
||||||
|
MDL::IntBone_MDL7** apcBonesOut);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Load the bone list of a MDL7 file
|
||||||
|
* \return If the bones could be loaded successfully, a valid
|
||||||
|
* array containing pointers to a temporary bone
|
||||||
|
* representation. NULL if the bones could not be loaded.
|
||||||
|
*/
|
||||||
|
MDL::IntBone_MDL7** LoadBones_3DGS_MDL7();
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Load bone transformation keyframes from a file chunk
|
||||||
|
* \param groupInfo -> doc of data structure
|
||||||
|
* \param frame -> doc of data structure
|
||||||
|
* \param shared -> doc of data structure
|
||||||
|
*/
|
||||||
|
void ParseBoneTrafoKeys_3DGS_MDL7(
|
||||||
|
const MDL::IntGroupInfo_MDL7& groupInfo,
|
||||||
|
IntFrameInfo_MDL7& frame,
|
||||||
|
MDL::IntSharedData_MDL7& shared);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Calculate absolute bone animation matrices for each bone
|
||||||
|
* \param pcBones Pointer to the bone section in the file
|
||||||
|
* \param apcOutBones Output bones array
|
||||||
|
*/
|
||||||
|
void CalcAbsBoneMatrices_3DGS_MDL7(const MDL::Bone_MDL7* pcBones,
|
||||||
|
MDL::IntBone_MDL7** apcOutBones);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Add all bones to the nodegraph (as children of the root node)
|
||||||
|
* \param apcBonesOut List of bones
|
||||||
|
* \param pcParent Parent node. New nodes will be added to this node
|
||||||
|
* \param iParentIndex Index of the parent bone
|
||||||
|
*/
|
||||||
|
void AddBonesToNodeGraph_3DGS_MDL7(const MDL::IntBone_MDL7** apcBonesOut,
|
||||||
|
aiNode* pcParent,uint16_t iParentIndex);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Build output animations
|
||||||
|
* \param apcBonesOut List of bones
|
||||||
|
*/
|
||||||
|
void BuildOutputAnims_3DGS_MDL7(const MDL::IntBone_MDL7** apcBonesOut);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Handles materials that are just referencing another material
|
||||||
|
* There is no test file for this feature, but Conitec's doc
|
||||||
|
* say it is used.
|
||||||
|
*/
|
||||||
|
void HandleMaterialReferences_3DGS_MDL7();
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Copies only the material that are referenced by at least one
|
||||||
|
* mesh to the final output material list. All other materials
|
||||||
|
* will be discarded.
|
||||||
|
* \param shared -> doc of data structure
|
||||||
|
*/
|
||||||
|
void CopyMaterials_3DGS_MDL7(MDL::IntSharedData_MDL7 &shared);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Process the frame section at the end of a group
|
||||||
|
* \param groupInfo -> doc of data structure
|
||||||
|
* \param shared -> doc of data structure
|
||||||
|
* \param szCurrent Pointer to the start of the frame section
|
||||||
|
* \param szCurrentOut Receives a pointer to the first byte of the
|
||||||
|
* next data section.
|
||||||
|
* \return false to read no further groups (a small workaround for
|
||||||
|
* some tiny and unsolved problems ... )
|
||||||
|
*/
|
||||||
|
bool ProcessFrames_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInfo,
|
||||||
|
MDL::IntSharedData_MDL7& shared,
|
||||||
|
const unsigned char* szCurrent,
|
||||||
|
const unsigned char** szCurrentOut);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Sort all faces by their materials. If the mesh is using
|
||||||
|
* multiple materials per face (that are blended together) the function
|
||||||
|
* might create new materials.
|
||||||
|
* \param groupInfo -> doc of data structure
|
||||||
|
* \param groupData -> doc of data structure
|
||||||
|
* \param splittedGroupData -> doc of data structure
|
||||||
|
*/
|
||||||
|
void SortByMaterials_3DGS_MDL7(
|
||||||
|
const MDL::IntGroupInfo_MDL7& groupInfo,
|
||||||
|
MDL::IntGroupData_MDL7& groupData,
|
||||||
|
MDL::IntSplittedGroupData_MDL7& splittedGroupData);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Read all faces and vertices from a MDL7 group. The function fills
|
||||||
|
* preallocated memory buffers.
|
||||||
|
* \param groupInfo -> doc of data structure
|
||||||
|
* \param groupData -> doc of data structure
|
||||||
|
*/
|
||||||
|
void ReadFaces_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInfo,
|
||||||
|
MDL::IntGroupData_MDL7& groupData);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Generate the final output meshes for a7 models
|
||||||
|
* \param groupData -> doc of data structure
|
||||||
|
* \param splittedGroupData -> doc of data structure
|
||||||
|
*/
|
||||||
|
void GenerateOutputMeshes_3DGS_MDL7(
|
||||||
|
MDL::IntGroupData_MDL7& groupData,
|
||||||
|
MDL::IntSplittedGroupData_MDL7& splittedGroupData);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Try to determine whether the normals of the model are flipped
|
/** Try to determine whether the normals of the model are flipped
|
||||||
* Some MDL7 models seem to have flipped normals (and there is also
|
* Some MDL7 models seem to have flipped normals (and there is also
|
||||||
|
@ -239,16 +437,13 @@ protected:
|
||||||
*/
|
*/
|
||||||
void FlipNormals(aiMesh* pcMesh);
|
void FlipNormals(aiMesh* pcMesh);
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
|
|
||||||
/** Header of the MDL file */
|
|
||||||
const MDL::Header* m_pcHeader;
|
|
||||||
|
|
||||||
/** Buffer to hold the loaded file */
|
/** Buffer to hold the loaded file */
|
||||||
unsigned char* mBuffer;
|
unsigned char* mBuffer;
|
||||||
|
|
||||||
/** For GameStudio MDL files: The number in the magic
|
/** For GameStudio MDL files: The number in the magic word, either 3,4 or 5
|
||||||
word, either 3,4 or 5*/
|
* (MDL7 doesn't need this, the format has a separate loader) */
|
||||||
unsigned int iGSFileVersion;
|
unsigned int iGSFileVersion;
|
||||||
|
|
||||||
/** Output I/O handler. used to load external lmp files
|
/** Output I/O handler. used to load external lmp files
|
||||||
|
@ -258,6 +453,10 @@ private:
|
||||||
/** Output scene to be filled
|
/** Output scene to be filled
|
||||||
*/
|
*/
|
||||||
aiScene* pScene;
|
aiScene* pScene;
|
||||||
|
|
||||||
|
/** Size of the input file in bytes
|
||||||
|
*/
|
||||||
|
unsigned int iFileSize;
|
||||||
};
|
};
|
||||||
}; // end of namespace Assimp
|
}; // end of namespace Assimp
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,774 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
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 material part of the MDL importer class */
|
||||||
|
|
||||||
|
// internal headers
|
||||||
|
#include "MaterialSystem.h"
|
||||||
|
#include "MDLLoader.h"
|
||||||
|
#include "MDLDefaultColorMap.h"
|
||||||
|
#include "qnan.h"
|
||||||
|
|
||||||
|
// public ASSIMP headers
|
||||||
|
#include "../include/DefaultLogger.h"
|
||||||
|
#include "../include/IOStream.h"
|
||||||
|
#include "../include/IOSystem.h"
|
||||||
|
#include "../include/aiMesh.h"
|
||||||
|
#include "../include/aiScene.h"
|
||||||
|
#include "../include/aiAssert.h"
|
||||||
|
|
||||||
|
using namespace Assimp;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void MDLImporter::SearchPalette(const unsigned char** pszColorMap)
|
||||||
|
{
|
||||||
|
// now try to find the color map in the current directory
|
||||||
|
IOStream* pcStream = this->pIOHandler->Open("colormap.lmp","rb");
|
||||||
|
|
||||||
|
const unsigned char* szColorMap = (const unsigned char*)::g_aclrDefaultColorMap;
|
||||||
|
if(pcStream)
|
||||||
|
{
|
||||||
|
if (pcStream->FileSize() >= 768)
|
||||||
|
{
|
||||||
|
szColorMap = new unsigned char[256*3];
|
||||||
|
pcStream->Read(const_cast<unsigned char*>(szColorMap),256*3,1);
|
||||||
|
|
||||||
|
DefaultLogger::get()->info("Found valid colormap.lmp in directory. "
|
||||||
|
"It will be used to decode embedded textures in palletized formats.");
|
||||||
|
}
|
||||||
|
delete pcStream;
|
||||||
|
pcStream = NULL;
|
||||||
|
}
|
||||||
|
*pszColorMap = szColorMap;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void MDLImporter::FreePalette(const unsigned char* szColorMap)
|
||||||
|
{
|
||||||
|
if (szColorMap != (const unsigned char*)::g_aclrDefaultColorMap)
|
||||||
|
{
|
||||||
|
delete[] szColorMap;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
aiColor4D MDLImporter::ReplaceTextureWithColor(const aiTexture* pcTexture)
|
||||||
|
{
|
||||||
|
ai_assert(NULL != pcTexture);
|
||||||
|
|
||||||
|
aiColor4D clrOut;
|
||||||
|
clrOut.r = std::numeric_limits<float>::quiet_NaN();
|
||||||
|
if (!pcTexture->mHeight || !pcTexture->mWidth)return clrOut;
|
||||||
|
|
||||||
|
const unsigned int iNumPixels = pcTexture->mHeight*pcTexture->mWidth;
|
||||||
|
const aiTexel* pcTexel = pcTexture->pcData+1;
|
||||||
|
const aiTexel* const pcTexelEnd = &pcTexture->pcData[iNumPixels];
|
||||||
|
|
||||||
|
while (pcTexel != pcTexelEnd)
|
||||||
|
{
|
||||||
|
if (*pcTexel != *(pcTexel-1))
|
||||||
|
{
|
||||||
|
pcTexel = NULL;break;
|
||||||
|
}
|
||||||
|
++pcTexel;
|
||||||
|
}
|
||||||
|
if (pcTexel)
|
||||||
|
{
|
||||||
|
clrOut.r = pcTexture->pcData->r / 255.0f;
|
||||||
|
clrOut.g = pcTexture->pcData->g / 255.0f;
|
||||||
|
clrOut.b = pcTexture->pcData->b / 255.0f;
|
||||||
|
clrOut.a = pcTexture->pcData->a / 255.0f;
|
||||||
|
}
|
||||||
|
return clrOut;
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void MDLImporter::CreateTextureARGB8_3DGS_MDL3(const unsigned char* szData)
|
||||||
|
{
|
||||||
|
const MDL::Header* pcHeader = (const MDL::Header*)this->mBuffer;
|
||||||
|
VALIDATE_FILE_SIZE(szData + pcHeader->skinwidth *
|
||||||
|
pcHeader->skinheight);
|
||||||
|
|
||||||
|
// allocate a new texture object
|
||||||
|
aiTexture* pcNew = new aiTexture();
|
||||||
|
pcNew->mWidth = pcHeader->skinwidth;
|
||||||
|
pcNew->mHeight = pcHeader->skinheight;
|
||||||
|
|
||||||
|
pcNew->pcData = new aiTexel[pcNew->mWidth * pcNew->mHeight];
|
||||||
|
|
||||||
|
const unsigned char* szColorMap;
|
||||||
|
this->SearchPalette(&szColorMap);
|
||||||
|
|
||||||
|
// copy texture data
|
||||||
|
for (unsigned int i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
|
||||||
|
{
|
||||||
|
const unsigned char val = szData[i];
|
||||||
|
const unsigned char* sz = &szColorMap[val*3];
|
||||||
|
|
||||||
|
pcNew->pcData[i].a = 0xFF;
|
||||||
|
pcNew->pcData[i].r = *sz++;
|
||||||
|
pcNew->pcData[i].g = *sz++;
|
||||||
|
pcNew->pcData[i].b = *sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->FreePalette(szColorMap);
|
||||||
|
|
||||||
|
// store the texture
|
||||||
|
aiTexture** pc = this->pScene->mTextures;
|
||||||
|
this->pScene->mTextures = new aiTexture*[this->pScene->mNumTextures+1];
|
||||||
|
for (unsigned int i = 0; i < this->pScene->mNumTextures;++i)
|
||||||
|
this->pScene->mTextures[i] = pc[i];
|
||||||
|
|
||||||
|
this->pScene->mTextures[this->pScene->mNumTextures] = pcNew;
|
||||||
|
this->pScene->mNumTextures++;
|
||||||
|
delete[] pc;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void MDLImporter::CreateTexture_3DGS_MDL4(const unsigned char* szData,
|
||||||
|
unsigned int iType,
|
||||||
|
unsigned int* piSkip)
|
||||||
|
{
|
||||||
|
const MDL::Header* pcHeader = (const MDL::Header*)this->mBuffer;
|
||||||
|
|
||||||
|
ai_assert(NULL != piSkip);
|
||||||
|
|
||||||
|
if (iType == 1 || iType > 3)
|
||||||
|
{
|
||||||
|
DefaultLogger::get()->error("Unsupported texture file format");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bNoRead = *piSkip == 0xffffffff;
|
||||||
|
|
||||||
|
// allocate a new texture object
|
||||||
|
aiTexture* pcNew = new aiTexture();
|
||||||
|
pcNew->mWidth = pcHeader->skinwidth;
|
||||||
|
pcNew->mHeight = pcHeader->skinheight;
|
||||||
|
|
||||||
|
if (bNoRead)pcNew->pcData = (aiTexel*)0xffffffff;
|
||||||
|
this->ParseTextureColorData(szData,iType,piSkip,pcNew);
|
||||||
|
|
||||||
|
// store the texture
|
||||||
|
if (!bNoRead)
|
||||||
|
{
|
||||||
|
if (!this->pScene->mNumTextures)
|
||||||
|
{
|
||||||
|
this->pScene->mNumTextures = 1;
|
||||||
|
this->pScene->mTextures = new aiTexture*[1];
|
||||||
|
this->pScene->mTextures[0] = pcNew;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
aiTexture** pc = this->pScene->mTextures;
|
||||||
|
this->pScene->mTextures = new aiTexture*[this->pScene->mNumTextures+1];
|
||||||
|
for (unsigned int i = 0; i < this->pScene->mNumTextures;++i)
|
||||||
|
this->pScene->mTextures[i] = pc[i];
|
||||||
|
this->pScene->mTextures[this->pScene->mNumTextures] = pcNew;
|
||||||
|
this->pScene->mNumTextures++;
|
||||||
|
delete[] pc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else delete pcNew;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void MDLImporter::ParseTextureColorData(const unsigned char* szData,
|
||||||
|
unsigned int iType,
|
||||||
|
unsigned int* piSkip,
|
||||||
|
aiTexture* pcNew)
|
||||||
|
{
|
||||||
|
// allocate storage for the texture image
|
||||||
|
if ((aiTexel*)0xffffffff != pcNew->pcData)
|
||||||
|
pcNew->pcData = new aiTexel[pcNew->mWidth * pcNew->mHeight];
|
||||||
|
|
||||||
|
// R5G6B5 format (with or without MIPs)
|
||||||
|
// ****************************************************************
|
||||||
|
if (2 == iType || 10 == iType)
|
||||||
|
{
|
||||||
|
VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*2);
|
||||||
|
|
||||||
|
// copy texture data
|
||||||
|
unsigned int i;
|
||||||
|
if ((aiTexel*)0xffffffff != pcNew->pcData)
|
||||||
|
{
|
||||||
|
for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
|
||||||
|
{
|
||||||
|
MDL::RGB565 val = ((MDL::RGB565*)szData)[i];
|
||||||
|
|
||||||
|
pcNew->pcData[i].a = 0xFF;
|
||||||
|
pcNew->pcData[i].r = (unsigned char)val.b << 3;
|
||||||
|
pcNew->pcData[i].g = (unsigned char)val.g << 2;
|
||||||
|
pcNew->pcData[i].b = (unsigned char)val.r << 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else i = pcNew->mWidth*pcNew->mHeight;
|
||||||
|
*piSkip = i * 2;
|
||||||
|
|
||||||
|
// apply MIP maps
|
||||||
|
if (10 == iType)
|
||||||
|
{
|
||||||
|
*piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 1;
|
||||||
|
VALIDATE_FILE_SIZE(szData + *piSkip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ARGB4 format (with or without MIPs)
|
||||||
|
// ****************************************************************
|
||||||
|
else if (3 == iType || 11 == iType)
|
||||||
|
{
|
||||||
|
VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*4);
|
||||||
|
|
||||||
|
// copy texture data
|
||||||
|
unsigned int i;
|
||||||
|
if ((aiTexel*)0xffffffff != pcNew->pcData)
|
||||||
|
{
|
||||||
|
for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
|
||||||
|
{
|
||||||
|
MDL::ARGB4 val = ((MDL::ARGB4*)szData)[i];
|
||||||
|
|
||||||
|
pcNew->pcData[i].a = (unsigned char)val.a << 4;
|
||||||
|
pcNew->pcData[i].r = (unsigned char)val.r << 4;
|
||||||
|
pcNew->pcData[i].g = (unsigned char)val.g << 4;
|
||||||
|
pcNew->pcData[i].b = (unsigned char)val.b << 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else i = pcNew->mWidth*pcNew->mHeight;
|
||||||
|
*piSkip = i * 2;
|
||||||
|
|
||||||
|
// apply MIP maps
|
||||||
|
if (11 == iType)
|
||||||
|
{
|
||||||
|
*piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 1;
|
||||||
|
VALIDATE_FILE_SIZE(szData + *piSkip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// RGB8 format (with or without MIPs)
|
||||||
|
// ****************************************************************
|
||||||
|
else if (4 == iType || 12 == iType)
|
||||||
|
{
|
||||||
|
VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*3);
|
||||||
|
|
||||||
|
// copy texture data
|
||||||
|
unsigned int i;
|
||||||
|
if ((aiTexel*)0xffffffff != pcNew->pcData)
|
||||||
|
{
|
||||||
|
for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
|
||||||
|
{
|
||||||
|
const unsigned char* _szData = &szData[i*3];
|
||||||
|
|
||||||
|
pcNew->pcData[i].a = 0xFF;
|
||||||
|
pcNew->pcData[i].b = *_szData++;
|
||||||
|
pcNew->pcData[i].g = *_szData++;
|
||||||
|
pcNew->pcData[i].r = *_szData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else i = pcNew->mWidth*pcNew->mHeight;
|
||||||
|
|
||||||
|
|
||||||
|
// apply MIP maps
|
||||||
|
*piSkip = i * 3;
|
||||||
|
if (12 == iType)
|
||||||
|
{
|
||||||
|
*piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) *3;
|
||||||
|
VALIDATE_FILE_SIZE(szData + *piSkip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ARGB8 format (with ir without MIPs)
|
||||||
|
// ****************************************************************
|
||||||
|
else if (5 == iType || 13 == iType)
|
||||||
|
{
|
||||||
|
VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*4);
|
||||||
|
|
||||||
|
// copy texture data
|
||||||
|
unsigned int i;
|
||||||
|
if ((aiTexel*)0xffffffff != pcNew->pcData)
|
||||||
|
{
|
||||||
|
for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
|
||||||
|
{
|
||||||
|
const unsigned char* _szData = &szData[i*4];
|
||||||
|
|
||||||
|
pcNew->pcData[i].b = *_szData++;
|
||||||
|
pcNew->pcData[i].g = *_szData++;
|
||||||
|
pcNew->pcData[i].r = *_szData++;
|
||||||
|
pcNew->pcData[i].a = *_szData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else i = pcNew->mWidth*pcNew->mHeight;
|
||||||
|
|
||||||
|
// apply MIP maps
|
||||||
|
*piSkip = i << 2;
|
||||||
|
if (13 == iType)
|
||||||
|
{
|
||||||
|
*piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// palletized 8 bit texture. As for Quake 1
|
||||||
|
// ****************************************************************
|
||||||
|
else if (0 == iType)
|
||||||
|
{
|
||||||
|
VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight);
|
||||||
|
|
||||||
|
// copy texture data
|
||||||
|
unsigned int i;
|
||||||
|
if ((aiTexel*)0xffffffff != pcNew->pcData)
|
||||||
|
{
|
||||||
|
|
||||||
|
const unsigned char* szColorMap;
|
||||||
|
this->SearchPalette(&szColorMap);
|
||||||
|
|
||||||
|
for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
|
||||||
|
{
|
||||||
|
const unsigned char val = szData[i];
|
||||||
|
const unsigned char* sz = &szColorMap[val*3];
|
||||||
|
|
||||||
|
pcNew->pcData[i].a = 0xFF;
|
||||||
|
pcNew->pcData[i].r = *sz++;
|
||||||
|
pcNew->pcData[i].g = *sz++;
|
||||||
|
pcNew->pcData[i].b = *sz;
|
||||||
|
}
|
||||||
|
this->FreePalette(szColorMap);
|
||||||
|
|
||||||
|
}
|
||||||
|
else i = pcNew->mWidth*pcNew->mHeight;
|
||||||
|
*piSkip = i;
|
||||||
|
|
||||||
|
// FIXME: Also support for MIP maps?
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void MDLImporter::CreateTexture_3DGS_MDL5(const unsigned char* szData,
|
||||||
|
unsigned int iType,
|
||||||
|
unsigned int* piSkip)
|
||||||
|
{
|
||||||
|
ai_assert(NULL != piSkip);
|
||||||
|
|
||||||
|
bool bNoRead = *piSkip == 0xffffffff;
|
||||||
|
|
||||||
|
// allocate a new texture object
|
||||||
|
aiTexture* pcNew = new aiTexture();
|
||||||
|
|
||||||
|
VALIDATE_FILE_SIZE(szData+8);
|
||||||
|
|
||||||
|
// first read the size of the texture
|
||||||
|
pcNew->mWidth = *((uint32_t*)szData);
|
||||||
|
szData += sizeof(uint32_t);
|
||||||
|
|
||||||
|
pcNew->mHeight = *((uint32_t*)szData);
|
||||||
|
szData += sizeof(uint32_t);
|
||||||
|
|
||||||
|
if (bNoRead)pcNew->pcData = (aiTexel*)0xffffffff;
|
||||||
|
|
||||||
|
// this should not occur - at least the docs say it shouldn't
|
||||||
|
// however, you can easily try out what MED does if you have
|
||||||
|
// a model with a DDS texture and export it to MDL5 ...
|
||||||
|
// yes, you're right. It embedds the DDS texture ... :cry:
|
||||||
|
if (6 == iType)
|
||||||
|
{
|
||||||
|
// this is a compressed texture in DDS format
|
||||||
|
*piSkip = pcNew->mWidth;
|
||||||
|
VALIDATE_FILE_SIZE(szData + *piSkip);
|
||||||
|
|
||||||
|
if (!bNoRead)
|
||||||
|
{
|
||||||
|
// place a hint and let the application know that it's
|
||||||
|
// a DDS file
|
||||||
|
pcNew->mHeight = 0;
|
||||||
|
pcNew->achFormatHint[0] = 'd';
|
||||||
|
pcNew->achFormatHint[1] = 'd';
|
||||||
|
pcNew->achFormatHint[2] = 's';
|
||||||
|
pcNew->achFormatHint[3] = '\0';
|
||||||
|
|
||||||
|
pcNew->pcData = (aiTexel*) new unsigned char[pcNew->mWidth];
|
||||||
|
::memcpy(pcNew->pcData,szData,pcNew->mWidth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// parse the color data of the texture
|
||||||
|
this->ParseTextureColorData(szData,iType,
|
||||||
|
piSkip,pcNew);
|
||||||
|
}
|
||||||
|
*piSkip += sizeof(uint32_t) * 2;
|
||||||
|
|
||||||
|
if (!bNoRead)
|
||||||
|
{
|
||||||
|
// store the texture
|
||||||
|
if (!this->pScene->mNumTextures)
|
||||||
|
{
|
||||||
|
this->pScene->mNumTextures = 1;
|
||||||
|
this->pScene->mTextures = new aiTexture*[1];
|
||||||
|
this->pScene->mTextures[0] = pcNew;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
aiTexture** pc = this->pScene->mTextures;
|
||||||
|
this->pScene->mTextures = new aiTexture*[this->pScene->mNumTextures+1];
|
||||||
|
for (unsigned int i = 0; i < this->pScene->mNumTextures;++i)
|
||||||
|
this->pScene->mTextures[i] = pc[i];
|
||||||
|
|
||||||
|
this->pScene->mTextures[this->pScene->mNumTextures] = pcNew;
|
||||||
|
this->pScene->mNumTextures++;
|
||||||
|
delete[] pc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else delete pcNew;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void MDLImporter::ParseSkinLump_3DGS_MDL7(
|
||||||
|
const unsigned char* szCurrent,
|
||||||
|
const unsigned char** szCurrentOut,
|
||||||
|
MaterialHelper* pcMatOut,
|
||||||
|
unsigned int iType,
|
||||||
|
unsigned int iWidth,
|
||||||
|
unsigned int iHeight)
|
||||||
|
{
|
||||||
|
aiTexture* pcNew = NULL;
|
||||||
|
|
||||||
|
// get the type of the skin
|
||||||
|
unsigned int iMasked = (unsigned int)(iType & 0xF);
|
||||||
|
|
||||||
|
if (0x1 == iMasked)
|
||||||
|
{
|
||||||
|
// ***** REFERENCE TO ANOTHER SKIN INDEX *****
|
||||||
|
|
||||||
|
// NOTE: Documentation - if you can call it a documentation, I prefer
|
||||||
|
// the expression "rubbish" - states it is currently unused. However,
|
||||||
|
// I don't know what ideas the terrible developers of Conitec will
|
||||||
|
// have tomorrow, so Im going to implement it.
|
||||||
|
int referrer = (int)iWidth;
|
||||||
|
pcMatOut->AddProperty<int>(&referrer,1,AI_MDL7_REFERRER_MATERIAL);
|
||||||
|
}
|
||||||
|
else if (0x6 == iMasked)
|
||||||
|
{
|
||||||
|
// ***** EMBEDDED DDS FILE *****
|
||||||
|
if (1 != iHeight)
|
||||||
|
{
|
||||||
|
DefaultLogger::get()->warn("Found a reference to an embedded DDS texture, "
|
||||||
|
"but texture height is not equal to 1, which is not supported by MED");
|
||||||
|
}
|
||||||
|
|
||||||
|
pcNew = new aiTexture();
|
||||||
|
pcNew->mHeight = 0;
|
||||||
|
pcNew->mWidth = iWidth;
|
||||||
|
pcNew->achFormatHint[0] = 'd';
|
||||||
|
pcNew->achFormatHint[1] = 'd';
|
||||||
|
pcNew->achFormatHint[2] = 's';
|
||||||
|
pcNew->achFormatHint[3] = '\0';
|
||||||
|
|
||||||
|
pcNew->pcData = (aiTexel*) new unsigned char[pcNew->mWidth];
|
||||||
|
memcpy(pcNew->pcData,szCurrent,pcNew->mWidth);
|
||||||
|
szCurrent += iWidth;
|
||||||
|
}
|
||||||
|
if (0x7 == iMasked)
|
||||||
|
{
|
||||||
|
// ***** REFERENCE TO EXTERNAL FILE *****
|
||||||
|
if (1 != iHeight)
|
||||||
|
{
|
||||||
|
DefaultLogger::get()->warn("Found a reference to an external texture, "
|
||||||
|
"but texture height is not equal to 1, which is not supported by MED");
|
||||||
|
}
|
||||||
|
|
||||||
|
aiString szFile;
|
||||||
|
const size_t iLen = strlen((const char*)szCurrent);
|
||||||
|
size_t iLen2 = iLen+1;
|
||||||
|
iLen2 = iLen2 > MAXLEN ? MAXLEN : iLen2;
|
||||||
|
memcpy(szFile.data,(const char*)szCurrent,iLen2);
|
||||||
|
szFile.length = iLen;
|
||||||
|
|
||||||
|
szCurrent += iLen2;
|
||||||
|
|
||||||
|
// place this as diffuse texture
|
||||||
|
pcMatOut->AddProperty(&szFile,AI_MATKEY_TEXTURE_DIFFUSE(0));
|
||||||
|
}
|
||||||
|
else if (iMasked || !iType || (iType && iWidth && iHeight))
|
||||||
|
{
|
||||||
|
// ***** STANDARD COLOR TEXTURE *****
|
||||||
|
pcNew = new aiTexture();
|
||||||
|
if (!iHeight || !iWidth)
|
||||||
|
{
|
||||||
|
DefaultLogger::get()->warn("Found embedded texture, but its width "
|
||||||
|
"an height are both 0. Is this a joke?");
|
||||||
|
|
||||||
|
// generate an empty chess pattern
|
||||||
|
pcNew->mWidth = pcNew->mHeight = 8;
|
||||||
|
pcNew->pcData = new aiTexel[64];
|
||||||
|
for (unsigned int x = 0; x < 8;++x)
|
||||||
|
{
|
||||||
|
for (unsigned int y = 0; y < 8;++y)
|
||||||
|
{
|
||||||
|
bool bSet = false;
|
||||||
|
if (0 == x % 2 && 0 != y % 2 ||
|
||||||
|
0 != x % 2 && 0 == y % 2)bSet = true;
|
||||||
|
|
||||||
|
aiTexel* pc = &pcNew->pcData[y * 8 + x];
|
||||||
|
if (bSet)pc->r = pc->b = pc->g = 0xFF;
|
||||||
|
else pc->r = pc->b = pc->g = 0;
|
||||||
|
pc->a = 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// it is a standard color texture. Fill in width and height
|
||||||
|
// and call the same function we used for loading MDL5 files
|
||||||
|
|
||||||
|
pcNew->mWidth = iWidth;
|
||||||
|
pcNew->mHeight = iHeight;
|
||||||
|
|
||||||
|
unsigned int iSkip = 0;
|
||||||
|
this->ParseTextureColorData(szCurrent,iMasked,&iSkip,pcNew);
|
||||||
|
|
||||||
|
// skip length of texture data
|
||||||
|
szCurrent += iSkip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// sometimes there are MDL7 files which have a monochrome
|
||||||
|
// texture instead of material colors ... posssible they have
|
||||||
|
// been converted to MDL7 from other formats, such as MDL5
|
||||||
|
aiColor4D clrTexture = this->ReplaceTextureWithColor(pcNew);
|
||||||
|
|
||||||
|
// check whether a material definition is contained in the skin
|
||||||
|
if (iType & AI_MDL7_SKINTYPE_MATERIAL)
|
||||||
|
{
|
||||||
|
const MDL::Material_MDL7* pcMatIn = (const MDL::Material_MDL7*)szCurrent;
|
||||||
|
szCurrent = (unsigned char*)(pcMatIn+1);
|
||||||
|
VALIDATE_FILE_SIZE(szCurrent);
|
||||||
|
|
||||||
|
aiColor3D clrTemp;
|
||||||
|
|
||||||
|
#define COLOR_MULTIPLY_RGB() \
|
||||||
|
if (is_not_qnan(clrTexture.r)) \
|
||||||
|
{ \
|
||||||
|
clrTemp.r *= clrTexture.r; \
|
||||||
|
clrTemp.g *= clrTexture.g; \
|
||||||
|
clrTemp.b *= clrTexture.b; \
|
||||||
|
}
|
||||||
|
|
||||||
|
// read diffuse color
|
||||||
|
clrTemp.r = pcMatIn->Diffuse.r;
|
||||||
|
clrTemp.g = pcMatIn->Diffuse.g;
|
||||||
|
clrTemp.b = pcMatIn->Diffuse.b;
|
||||||
|
COLOR_MULTIPLY_RGB();
|
||||||
|
pcMatOut->AddProperty<aiColor3D>(&clrTemp,1,AI_MATKEY_COLOR_DIFFUSE);
|
||||||
|
|
||||||
|
// read specular color
|
||||||
|
clrTemp.r = pcMatIn->Specular.r;
|
||||||
|
clrTemp.g = pcMatIn->Specular.g;
|
||||||
|
clrTemp.b = pcMatIn->Specular.b;
|
||||||
|
COLOR_MULTIPLY_RGB();
|
||||||
|
pcMatOut->AddProperty<aiColor3D>(&clrTemp,1,AI_MATKEY_COLOR_SPECULAR);
|
||||||
|
|
||||||
|
// read ambient color
|
||||||
|
clrTemp.r = pcMatIn->Ambient.r;
|
||||||
|
clrTemp.g = pcMatIn->Ambient.g;
|
||||||
|
clrTemp.b = pcMatIn->Ambient.b;
|
||||||
|
COLOR_MULTIPLY_RGB();
|
||||||
|
pcMatOut->AddProperty<aiColor3D>(&clrTemp,1,AI_MATKEY_COLOR_AMBIENT);
|
||||||
|
|
||||||
|
// read emissive color
|
||||||
|
clrTemp.r = pcMatIn->Emissive.r;
|
||||||
|
clrTemp.g = pcMatIn->Emissive.g;
|
||||||
|
clrTemp.b = pcMatIn->Emissive.b;
|
||||||
|
pcMatOut->AddProperty<aiColor3D>(&clrTemp,1,AI_MATKEY_COLOR_EMISSIVE);
|
||||||
|
|
||||||
|
// FIX: Take the opacity from the ambient color
|
||||||
|
// the doc says something else, but it is fact that MED exports the
|
||||||
|
// opacity like this .... ARRRGGHH!
|
||||||
|
clrTemp.r = pcMatIn->Ambient.a;
|
||||||
|
if (is_not_qnan(clrTexture.r))clrTemp.r *= clrTexture.a;
|
||||||
|
pcMatOut->AddProperty<float>(&clrTemp.r,1,AI_MATKEY_OPACITY);
|
||||||
|
|
||||||
|
// read phong power
|
||||||
|
int iShadingMode = (int)aiShadingMode_Gouraud;
|
||||||
|
if (0.0f != pcMatIn->Power)
|
||||||
|
{
|
||||||
|
iShadingMode = (int)aiShadingMode_Phong;
|
||||||
|
pcMatOut->AddProperty<float>(&pcMatIn->Power,1,AI_MATKEY_SHININESS);
|
||||||
|
}
|
||||||
|
pcMatOut->AddProperty<int>(&iShadingMode,1,AI_MATKEY_SHADING_MODEL);
|
||||||
|
}
|
||||||
|
else if (is_not_qnan(clrTexture.r))
|
||||||
|
{
|
||||||
|
pcMatOut->AddProperty<aiColor4D>(&clrTexture,1,AI_MATKEY_COLOR_DIFFUSE);
|
||||||
|
pcMatOut->AddProperty<aiColor4D>(&clrTexture,1,AI_MATKEY_COLOR_SPECULAR);
|
||||||
|
}
|
||||||
|
// if the texture could be replaced by a single material color
|
||||||
|
// we don't need the texture anymore
|
||||||
|
if (is_not_qnan(clrTexture.r))
|
||||||
|
{
|
||||||
|
delete pcNew;
|
||||||
|
pcNew = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if an ASCII effect description (HLSL?) is contained in the file,
|
||||||
|
// we can simply ignore it ...
|
||||||
|
if (iType & AI_MDL7_SKINTYPE_MATERIAL_ASCDEF)
|
||||||
|
{
|
||||||
|
VALIDATE_FILE_SIZE(szCurrent);
|
||||||
|
int32_t iMe = *((int32_t*)szCurrent);
|
||||||
|
szCurrent += sizeof(char) * iMe + sizeof(int32_t);
|
||||||
|
VALIDATE_FILE_SIZE(szCurrent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if an embedded texture has been loaded setup the corresponding
|
||||||
|
// data structures in the aiScene instance
|
||||||
|
if (pcNew && this->pScene->mNumTextures <= 999)
|
||||||
|
{
|
||||||
|
|
||||||
|
// place this as diffuse texture
|
||||||
|
char szCurrent[5];
|
||||||
|
::sprintf(szCurrent,"*%i",this->pScene->mNumTextures);
|
||||||
|
|
||||||
|
aiString szFile;
|
||||||
|
const size_t iLen = strlen((const char*)szCurrent);
|
||||||
|
size_t iLen2 = iLen+1;
|
||||||
|
iLen2 = iLen2 > MAXLEN ? MAXLEN : iLen2;
|
||||||
|
::memcpy(szFile.data,(const char*)szCurrent,iLen2);
|
||||||
|
szFile.length = iLen;
|
||||||
|
|
||||||
|
pcMatOut->AddProperty(&szFile,AI_MATKEY_TEXTURE_DIFFUSE(0));
|
||||||
|
|
||||||
|
// store the texture
|
||||||
|
aiTexture** pc = this->pScene->mTextures;
|
||||||
|
this->pScene->mTextures = new aiTexture*[this->pScene->mNumTextures+1];
|
||||||
|
for (unsigned int i = 0; i < this->pScene->mNumTextures;++i)
|
||||||
|
this->pScene->mTextures[i] = pc[i];
|
||||||
|
|
||||||
|
this->pScene->mTextures[this->pScene->mNumTextures] = pcNew;
|
||||||
|
this->pScene->mNumTextures++;
|
||||||
|
delete[] pc;
|
||||||
|
|
||||||
|
}
|
||||||
|
VALIDATE_FILE_SIZE(szCurrent);
|
||||||
|
*szCurrentOut = szCurrent;
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void MDLImporter::SkipSkinLump_3DGS_MDL7(
|
||||||
|
const unsigned char* szCurrent,
|
||||||
|
const unsigned char** szCurrentOut,
|
||||||
|
unsigned int iType,
|
||||||
|
unsigned int iWidth,
|
||||||
|
unsigned int iHeight)
|
||||||
|
{
|
||||||
|
// get the type of the skin
|
||||||
|
unsigned int iMasked = (unsigned int)(iType & 0xF);
|
||||||
|
|
||||||
|
if (0x6 == iMasked)
|
||||||
|
{
|
||||||
|
szCurrent += iWidth;
|
||||||
|
}
|
||||||
|
if (0x7 == iMasked)
|
||||||
|
{
|
||||||
|
const size_t iLen = ::strlen((const char*)szCurrent);
|
||||||
|
szCurrent += iLen+1;
|
||||||
|
}
|
||||||
|
else if (iMasked || !iType)
|
||||||
|
{
|
||||||
|
if (iMasked || !iType || (iType && iWidth && iHeight))
|
||||||
|
{
|
||||||
|
// ParseTextureColorData(..., aiTexture::pcData == 0xffffffff) will simply
|
||||||
|
// return the size of the color data in bytes in iSkip
|
||||||
|
unsigned int iSkip = 0;
|
||||||
|
|
||||||
|
aiTexture tex;
|
||||||
|
tex.pcData = reinterpret_cast<aiTexel*>(0xffffffff);
|
||||||
|
tex.mHeight = iHeight;
|
||||||
|
tex.mWidth = iWidth;
|
||||||
|
this->ParseTextureColorData(szCurrent,iMasked,&iSkip,&tex);
|
||||||
|
|
||||||
|
// skip length of texture data
|
||||||
|
szCurrent += iSkip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check whether a material definition is contained in the skin
|
||||||
|
if (iType & AI_MDL7_SKINTYPE_MATERIAL)
|
||||||
|
{
|
||||||
|
const MDL::Material_MDL7* pcMatIn = (const MDL::Material_MDL7*)szCurrent;
|
||||||
|
szCurrent = (unsigned char*)(pcMatIn+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if an ASCII effect description (HLSL?) is contained in the file,
|
||||||
|
// we can simply ignore it ...
|
||||||
|
if (iType & AI_MDL7_SKINTYPE_MATERIAL_ASCDEF)
|
||||||
|
{
|
||||||
|
int32_t iMe = *((int32_t*)szCurrent);
|
||||||
|
szCurrent += sizeof(char) * iMe + sizeof(int32_t);
|
||||||
|
}
|
||||||
|
*szCurrentOut = szCurrent;
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void MDLImporter::ParseSkinLump_3DGS_MDL7(
|
||||||
|
const unsigned char* szCurrent,
|
||||||
|
const unsigned char** szCurrentOut,
|
||||||
|
std::vector<MaterialHelper*>& pcMats)
|
||||||
|
{
|
||||||
|
ai_assert(NULL != szCurrent);
|
||||||
|
ai_assert(NULL != szCurrentOut);
|
||||||
|
|
||||||
|
*szCurrentOut = szCurrent;
|
||||||
|
const MDL::Skin_MDL7* pcSkin = (const MDL::Skin_MDL7*)szCurrent;
|
||||||
|
szCurrent += 12;
|
||||||
|
|
||||||
|
// allocate an output material
|
||||||
|
MaterialHelper* pcMatOut = new MaterialHelper();
|
||||||
|
pcMats.push_back(pcMatOut);
|
||||||
|
|
||||||
|
// skip length of file name
|
||||||
|
szCurrent += AI_MDL7_MAX_TEXNAMESIZE;
|
||||||
|
|
||||||
|
this->ParseSkinLump_3DGS_MDL7(szCurrent,szCurrentOut,pcMatOut,
|
||||||
|
pcSkin->typ,pcSkin->width,pcSkin->height);
|
||||||
|
|
||||||
|
// place the name of the skin in the material
|
||||||
|
const size_t iLen = strlen(pcSkin->texture_name);
|
||||||
|
if (0 != iLen)
|
||||||
|
{
|
||||||
|
aiString szFile;
|
||||||
|
memcpy(szFile.data,pcSkin->texture_name,sizeof(pcSkin->texture_name));
|
||||||
|
szFile.length = iLen;
|
||||||
|
|
||||||
|
pcMatOut->AddProperty(&szFile,AI_MATKEY_NAME);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
|
@ -465,6 +465,7 @@ aiReturn aiGetMaterialTexture(const aiMaterial* pcMat,
|
||||||
};
|
};
|
||||||
|
|
||||||
char szKey[256];
|
char szKey[256];
|
||||||
|
if (iIndex > 100)return AI_FAILURE;
|
||||||
|
|
||||||
// get the path to the texture
|
// get the path to the texture
|
||||||
#if _MSC_VER >= 1400
|
#if _MSC_VER >= 1400
|
||||||
|
|
|
@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
namespace Assimp
|
namespace Assimp
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Internal material helper class. Can be used to fill an aiMaterial
|
/** Internal material helper class. Can be used to fill an aiMaterial
|
||||||
structure easily. */
|
structure easily. */
|
||||||
|
@ -209,4 +210,4 @@ inline aiReturn MaterialHelper::AddProperty<int> (const int* pInput,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif //!! AI_MATERIALSYSTEM_H_INC
|
#endif //!! AI_MATERIALSYSTEM_H_INC
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
/*
|
||||||
|
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 Defines helper functions for text parsing */
|
||||||
|
#ifndef AI_PARSING_UTILS_H_INC
|
||||||
|
#define AI_PARSING_UTILS_H_INC
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------
|
||||||
|
template <class char_t>
|
||||||
|
inline bool IsSpace( const char_t in)
|
||||||
|
{
|
||||||
|
return (in == (char_t)' ' || in == (char_t)'\t');
|
||||||
|
}
|
||||||
|
// ---------------------------------------------------------------------------------
|
||||||
|
template <class char_t>
|
||||||
|
inline bool IsLineEnd( const char_t in)
|
||||||
|
{
|
||||||
|
return (in == (char_t)'\r' || in == (char_t)'\n' || in == (char_t)'\0');
|
||||||
|
}
|
||||||
|
// ---------------------------------------------------------------------------------
|
||||||
|
template <class char_t>
|
||||||
|
inline bool IsSpaceOrNewLine( const char_t in)
|
||||||
|
{
|
||||||
|
return IsSpace<char_t>(in) || IsLineEnd<char_t>(in);
|
||||||
|
}
|
||||||
|
// ---------------------------------------------------------------------------------
|
||||||
|
template <class char_t>
|
||||||
|
inline bool SkipSpaces( const char_t* in, const char_t** out)
|
||||||
|
{
|
||||||
|
while (*in == (char_t)' ' || *in == (char_t)'\t')in++;
|
||||||
|
*out = in;
|
||||||
|
return !IsLineEnd<char_t>(*in);
|
||||||
|
}
|
||||||
|
// ---------------------------------------------------------------------------------
|
||||||
|
template <class char_t>
|
||||||
|
inline bool SkipSpaces( const char_t** inout)
|
||||||
|
{
|
||||||
|
return SkipSpaces<char_t>(*inout,inout);
|
||||||
|
}
|
||||||
|
// ---------------------------------------------------------------------------------
|
||||||
|
template <class char_t>
|
||||||
|
inline bool SkipLine( const char_t* in, const char_t** out)
|
||||||
|
{
|
||||||
|
while (*in != (char_t)'\r' && *in != (char_t)'\n' && *in != (char_t)'\0')in++;
|
||||||
|
|
||||||
|
if (*in == (char_t)'\0')
|
||||||
|
{
|
||||||
|
*out = in;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
in++;
|
||||||
|
*out = in;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// ---------------------------------------------------------------------------------
|
||||||
|
template <class char_t>
|
||||||
|
inline bool SkipLine( const char_t** inout)
|
||||||
|
{
|
||||||
|
return SkipLine<char_t>(*inout,inout);
|
||||||
|
}
|
||||||
|
// ---------------------------------------------------------------------------------
|
||||||
|
template <class char_t>
|
||||||
|
inline void SkipSpacesAndLineEnd( const char_t* in, const char_t** out)
|
||||||
|
{
|
||||||
|
while (*in == (char_t)' ' || *in == (char_t)'\t' ||
|
||||||
|
*in == (char_t)'\r' || *in == (char_t)'\n')in++;
|
||||||
|
*out = in;
|
||||||
|
}
|
||||||
|
// ---------------------------------------------------------------------------------
|
||||||
|
template <class char_t>
|
||||||
|
inline bool SkipSpacesAndLineEnd( const char_t** inout)
|
||||||
|
{
|
||||||
|
return SkipSpacesAndLineEnd<char_t>(*inout,inout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // ! AI_PARSING_UTILS_H_INC
|
|
@ -120,6 +120,7 @@ void PLYImporter::InternReadFile(
|
||||||
this->mBuffer[1] != 'L' && this->mBuffer[1] != 'l' ||
|
this->mBuffer[1] != 'L' && this->mBuffer[1] != 'l' ||
|
||||||
this->mBuffer[2] != 'Y' && this->mBuffer[2] != 'y')
|
this->mBuffer[2] != 'Y' && this->mBuffer[2] != 'y')
|
||||||
{
|
{
|
||||||
|
delete[] this->mBuffer;
|
||||||
throw new ImportErrorException( "Invalid .ply file: Magic number \'ply\' is no there");
|
throw new ImportErrorException( "Invalid .ply file: Magic number \'ply\' is no there");
|
||||||
}
|
}
|
||||||
char* szMe = (char*)&this->mBuffer[3];
|
char* szMe = (char*)&this->mBuffer[3];
|
||||||
|
@ -136,6 +137,7 @@ void PLYImporter::InternReadFile(
|
||||||
SkipLine(szMe,(const char**)&szMe);
|
SkipLine(szMe,(const char**)&szMe);
|
||||||
if(!PLY::DOM::ParseInstance(szMe,&sPlyDom, (unsigned int)fileSize))
|
if(!PLY::DOM::ParseInstance(szMe,&sPlyDom, (unsigned int)fileSize))
|
||||||
{
|
{
|
||||||
|
delete[] this->mBuffer;
|
||||||
throw new ImportErrorException( "Invalid .ply file: Unable to build DOM (#1)");
|
throw new ImportErrorException( "Invalid .ply file: Unable to build DOM (#1)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,16 +158,19 @@ void PLYImporter::InternReadFile(
|
||||||
SkipLine(szMe,(const char**)&szMe);
|
SkipLine(szMe,(const char**)&szMe);
|
||||||
if(!PLY::DOM::ParseInstanceBinary(szMe,&sPlyDom,bIsBE, (unsigned int)fileSize))
|
if(!PLY::DOM::ParseInstanceBinary(szMe,&sPlyDom,bIsBE, (unsigned int)fileSize))
|
||||||
{
|
{
|
||||||
|
delete[] this->mBuffer;
|
||||||
throw new ImportErrorException( "Invalid .ply file: Unable to build DOM (#2)");
|
throw new ImportErrorException( "Invalid .ply file: Unable to build DOM (#2)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
delete[] this->mBuffer;
|
||||||
throw new ImportErrorException( "Invalid .ply file: Unknown file format");
|
throw new ImportErrorException( "Invalid .ply file: Unknown file format");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
delete[] this->mBuffer;
|
||||||
throw new ImportErrorException( "Invalid .ply file: Missing format specification");
|
throw new ImportErrorException( "Invalid .ply file: Missing format specification");
|
||||||
}
|
}
|
||||||
this->pcDOM = &sPlyDom;
|
this->pcDOM = &sPlyDom;
|
||||||
|
@ -193,6 +198,7 @@ void PLYImporter::InternReadFile(
|
||||||
{
|
{
|
||||||
if (avPositions.size() < 3)
|
if (avPositions.size() < 3)
|
||||||
{
|
{
|
||||||
|
delete[] this->mBuffer;
|
||||||
throw new ImportErrorException( "Invalid .ply file: Not enough vertices to build "
|
throw new ImportErrorException( "Invalid .ply file: Not enough vertices to build "
|
||||||
"a face list. ");
|
"a face list. ");
|
||||||
}
|
}
|
||||||
|
@ -230,6 +236,7 @@ void PLYImporter::InternReadFile(
|
||||||
|
|
||||||
if (avMeshes.empty())
|
if (avMeshes.empty())
|
||||||
{
|
{
|
||||||
|
delete[] this->mBuffer;
|
||||||
throw new ImportErrorException( "Invalid .ply file: Unable to extract mesh data ");
|
throw new ImportErrorException( "Invalid .ply file: Unable to extract mesh data ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "ParsingUtils.h"
|
||||||
|
|
||||||
#include "../include/aiTypes.h"
|
#include "../include/aiTypes.h"
|
||||||
#include "../include/aiMesh.h"
|
#include "../include/aiMesh.h"
|
||||||
#include "../include/aiAnim.h"
|
#include "../include/aiAnim.h"
|
||||||
|
@ -551,48 +553,6 @@ TYPE PLY::PropertyInstance::ConvertTo(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
|
||||||
inline bool IsSpace( const char in)
|
|
||||||
{
|
|
||||||
return (in == ' ' || in == '\t');
|
|
||||||
}
|
|
||||||
// ---------------------------------------------------------------------------------
|
|
||||||
inline bool IsLineEnd( const char in)
|
|
||||||
{
|
|
||||||
return (in == '\r' || in == '\n' || in == '\0');
|
|
||||||
}
|
|
||||||
// ---------------------------------------------------------------------------------
|
|
||||||
inline bool IsSpaceOrNewLine( const char in)
|
|
||||||
{
|
|
||||||
return IsSpace(in) || IsLineEnd(in);
|
|
||||||
}
|
|
||||||
// ---------------------------------------------------------------------------------
|
|
||||||
inline bool SkipSpaces( const char* in, const char** out)
|
|
||||||
{
|
|
||||||
while (*in == ' ' || *in == '\t')in++;
|
|
||||||
*out = in;
|
|
||||||
return !IsLineEnd(*in);
|
|
||||||
}
|
|
||||||
// ---------------------------------------------------------------------------------
|
|
||||||
inline bool SkipLine( const char* in, const char** out)
|
|
||||||
{
|
|
||||||
while (*in != '\r' && *in != '\n' && *in != '\0')in++;
|
|
||||||
|
|
||||||
if (*in == '\0')
|
|
||||||
{
|
|
||||||
*out = in;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
in++;
|
|
||||||
*out = in;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// ---------------------------------------------------------------------------------
|
|
||||||
inline void SkipSpacesAndLineEnd( const char* in, const char** out)
|
|
||||||
{
|
|
||||||
while (*in == ' ' || *in == '\t' || *in == '\r' || *in == '\n')in++;
|
|
||||||
*out = in;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // !! include guard
|
#endif // !! include guard
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,408 @@
|
||||||
|
/*
|
||||||
|
Open Asset Import Library (ASSIMP)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2008, ASSIMP Development Team
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the
|
||||||
|
following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the ASSIMP team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the ASSIMP Development Team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
//!
|
||||||
|
//! @file Definition of SMD importer class
|
||||||
|
//!
|
||||||
|
|
||||||
|
#ifndef AI_SMDLOADER_H_INCLUDED
|
||||||
|
#define AI_SMDLOADER_H_INCLUDED
|
||||||
|
|
||||||
|
#include "BaseImporter.h"
|
||||||
|
#include "ParsingUtils.h"
|
||||||
|
|
||||||
|
#include "../include/aiTypes.h"
|
||||||
|
#include "../include/aiTexture.h"
|
||||||
|
#include "../include/aiAnim.h"
|
||||||
|
#include "../include/aiMaterial.h"
|
||||||
|
struct aiNode;
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace Assimp {
|
||||||
|
class MaterialHelper;
|
||||||
|
|
||||||
|
namespace SMD {
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/** Data structure for a vertex in a SMD file
|
||||||
|
*/
|
||||||
|
struct Vertex
|
||||||
|
{
|
||||||
|
Vertex() : iParentNode(0xffffffff)
|
||||||
|
{}
|
||||||
|
|
||||||
|
//! Vertex position, normal and texture coordinate
|
||||||
|
aiVector3D pos,nor,uv;
|
||||||
|
|
||||||
|
//! Vertex parent node
|
||||||
|
unsigned int iParentNode;
|
||||||
|
|
||||||
|
//! Links to bones: pair.first is the bone index,
|
||||||
|
//! pair.second is the vertex weight.
|
||||||
|
//! WARN: The remaining weight (to reach 1.0f) is assigned
|
||||||
|
//! to the parent node/bone
|
||||||
|
std::vector<std::pair<unsigned int, float> > aiBoneLinks;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/** Data structure for a face in a SMD file
|
||||||
|
*/
|
||||||
|
struct Face
|
||||||
|
{
|
||||||
|
Face() : iTexture(0x0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
//! Texture index for the face
|
||||||
|
unsigned int iTexture;
|
||||||
|
|
||||||
|
//! The three vertices of the face
|
||||||
|
Vertex avVertices[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/** Data structure for a bone in a SMD file
|
||||||
|
*/
|
||||||
|
struct Bone
|
||||||
|
{
|
||||||
|
//! Default constructor
|
||||||
|
Bone() : iParent(0xffffffff), bIsUsed(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Destructor
|
||||||
|
~Bone()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Name of the bone
|
||||||
|
std::string mName;
|
||||||
|
|
||||||
|
//! Parent of the bone
|
||||||
|
uint32_t iParent;
|
||||||
|
|
||||||
|
//! Animation of the bone
|
||||||
|
struct Animation
|
||||||
|
{
|
||||||
|
//! Public default constructor
|
||||||
|
Animation()
|
||||||
|
{
|
||||||
|
asKeys.reserve(20);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Data structure for a matrix key
|
||||||
|
struct MatrixKey
|
||||||
|
{
|
||||||
|
//! Matrix at this time
|
||||||
|
aiMatrix4x4 matrix;
|
||||||
|
|
||||||
|
//! Absolute transformation matrix
|
||||||
|
aiMatrix4x4 matrixAbsolute;
|
||||||
|
|
||||||
|
//! Position
|
||||||
|
aiVector3D vPos;
|
||||||
|
|
||||||
|
//! Rotation (euler angles)
|
||||||
|
aiVector3D vRot;
|
||||||
|
|
||||||
|
//! Current time. may be negative, this
|
||||||
|
//! will be fixed later
|
||||||
|
double dTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Index of the key with the smallest time value
|
||||||
|
uint32_t iFirstTimeKey;
|
||||||
|
|
||||||
|
//! Array of matrix keys
|
||||||
|
std::vector<MatrixKey> asKeys;
|
||||||
|
|
||||||
|
} sAnim;
|
||||||
|
|
||||||
|
//! Offset matrix of the bone
|
||||||
|
aiMatrix4x4 mOffsetMatrix;
|
||||||
|
|
||||||
|
//! true if the bone is referenced by at least one mesh
|
||||||
|
bool bIsUsed;
|
||||||
|
};
|
||||||
|
|
||||||
|
}; //! namespace SMD
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/** Used to load Half-life 1 and 2 SMD models
|
||||||
|
*/
|
||||||
|
class SMDImporter : public BaseImporter
|
||||||
|
{
|
||||||
|
friend class Importer;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** Constructor to be privately used by Importer */
|
||||||
|
SMDImporter();
|
||||||
|
|
||||||
|
/** Destructor, private as well */
|
||||||
|
~SMDImporter();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Returns whether the class can handle the format of the given file.
|
||||||
|
* See BaseImporter::CanRead() for details. */
|
||||||
|
bool CanRead( const std::string& pFile, IOSystem* pIOHandler) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Called by Importer::GetExtensionList() for each loaded importer.
|
||||||
|
* See BaseImporter::GetExtensionList() for details
|
||||||
|
*/
|
||||||
|
void GetExtensionList(std::string& append)
|
||||||
|
{
|
||||||
|
append.append("*.smd;*.vta");
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Imports the given file into the given scene structure.
|
||||||
|
* See BaseImporter::InternReadFile() for details
|
||||||
|
*/
|
||||||
|
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
||||||
|
IOSystem* pIOHandler);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Parse the SMD file and create the output scene
|
||||||
|
*/
|
||||||
|
void ParseFile();
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Parse the triangles section of the SMD file
|
||||||
|
* \param szCurrent Current position in the file. Points to the first
|
||||||
|
* data line of the section.
|
||||||
|
* \param szCurrentOut Receives a pointer to the heading line of
|
||||||
|
* the next section (or to EOF)
|
||||||
|
*/
|
||||||
|
void ParseTrianglesSection(const char* szCurrent,
|
||||||
|
const char** szCurrentOut);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Parse the vertex animation section in VTA files
|
||||||
|
* \param szCurrent Current position in the file. Points to the first
|
||||||
|
* data line of the section.
|
||||||
|
* \param szCurrentOut Receives a pointer to the heading line of
|
||||||
|
* the next section (or to EOF)
|
||||||
|
*/
|
||||||
|
void ParseVASection(const char* szCurrent,
|
||||||
|
const char** szCurrentOut);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Parse the nodes section of the SMD file
|
||||||
|
* \param szCurrent Current position in the file. Points to the first
|
||||||
|
* data line of the section.
|
||||||
|
* \param szCurrentOut Receives a pointer to the heading line of
|
||||||
|
* the next section (or to EOF)
|
||||||
|
*/
|
||||||
|
void ParseNodesSection(const char* szCurrent,
|
||||||
|
const char** szCurrentOut);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Parse the skeleton section of the SMD file
|
||||||
|
* \param szCurrent Current position in the file. Points to the first
|
||||||
|
* data line of the section.
|
||||||
|
* \param szCurrentOut Receives a pointer to the heading line of
|
||||||
|
* the next section (or to EOF)
|
||||||
|
*/
|
||||||
|
void ParseSkeletonSection(const char* szCurrent,
|
||||||
|
const char** szCurrentOut);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Parse a single triangle in the SMD file
|
||||||
|
* \param szCurrent Current position in the file. Points to the first
|
||||||
|
* data line of the section.
|
||||||
|
* \param szCurrentOut Receives the output cursor position
|
||||||
|
*/
|
||||||
|
void ParseTriangle(const char* szCurrent,
|
||||||
|
const char** szCurrentOut);
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Parse a single vertex in the SMD file
|
||||||
|
* \param szCurrent Current position in the file. Points to the first
|
||||||
|
* data line of the section.
|
||||||
|
* \param szCurrentOut Receives the output cursor position
|
||||||
|
* \param vertex Vertex to be filled
|
||||||
|
*/
|
||||||
|
void ParseVertex(const char* szCurrent,
|
||||||
|
const char** szCurrentOut, SMD::Vertex& vertex,
|
||||||
|
bool bVASection = false);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Get the index of a texture. If the texture was not yet known
|
||||||
|
* it will be added to the internal texture list.
|
||||||
|
* \param filename Name of the texture
|
||||||
|
* \return Value texture index
|
||||||
|
*/
|
||||||
|
unsigned int GetTextureIndex(const std::string& filename);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Computes absolute bone transformations
|
||||||
|
* All output transformations are in worldspace.
|
||||||
|
*/
|
||||||
|
void ComputeAbsoluteBoneTransformations();
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Parse a line in the skeleton section
|
||||||
|
*/
|
||||||
|
void ParseSkeletonElement(const char* szCurrent,
|
||||||
|
const char** szCurrentOut,int iTime);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Parse a line in the nodes section
|
||||||
|
*/
|
||||||
|
void ParseNodeInfo(const char* szCurrent,
|
||||||
|
const char** szCurrentOut);
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Parse a floating-point value
|
||||||
|
*/
|
||||||
|
bool ParseFloat(const char* szCurrent,
|
||||||
|
const char** szCurrentOut, float& out);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Parse an unsigned integer. There may be no sign!
|
||||||
|
*/
|
||||||
|
bool ParseUnsignedInt(const char* szCurrent,
|
||||||
|
const char** szCurrentOut, uint32_t& out);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Parse a signed integer. Signs (+,-) are handled.
|
||||||
|
*/
|
||||||
|
bool ParseSignedInt(const char* szCurrent,
|
||||||
|
const char** szCurrentOut, int32_t& out);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Fix invalid time values in the file
|
||||||
|
*/
|
||||||
|
void FixTimeValues();
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Add all children of a bone as subnodes to a node
|
||||||
|
* \param pcNode Parent node
|
||||||
|
* \param iParent Parent bone index
|
||||||
|
*/
|
||||||
|
void AddBoneChildren(aiNode* pcNode, uint32_t iParent);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Build output meshes/materials/nodes/animations
|
||||||
|
*/
|
||||||
|
void CreateOutputMeshes();
|
||||||
|
void CreateOutputNodes();
|
||||||
|
void CreateOutputAnimations();
|
||||||
|
void CreateOutputMaterials();
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Print a log message together with the current line number
|
||||||
|
*/
|
||||||
|
void LogErrorNoThrow(const char* msg);
|
||||||
|
void LogWarning(const char* msg);
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
inline bool SkipLine( const char* in, const char** out)
|
||||||
|
{
|
||||||
|
::SkipLine(in,out);
|
||||||
|
++iLineNumber;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
inline void SkipSpacesAndLineEnd( const char* in, const char** out)
|
||||||
|
{
|
||||||
|
::SkipSpacesAndLineEnd(in,out);
|
||||||
|
++iLineNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/** Buffer to hold the loaded file */
|
||||||
|
const char* mBuffer;
|
||||||
|
|
||||||
|
/** Output scene to be filled
|
||||||
|
*/
|
||||||
|
aiScene* pScene;
|
||||||
|
|
||||||
|
/** Size of the input file in bytes
|
||||||
|
*/
|
||||||
|
unsigned int iFileSize;
|
||||||
|
|
||||||
|
/** Array of textures found in the file
|
||||||
|
*/
|
||||||
|
std::vector<std::string> aszTextures;
|
||||||
|
|
||||||
|
/** Array of triangles found in the file
|
||||||
|
*/
|
||||||
|
std::vector<SMD::Face> asTriangles;
|
||||||
|
|
||||||
|
/** Array of bones found in the file
|
||||||
|
*/
|
||||||
|
std::vector<SMD::Bone> asBones;
|
||||||
|
|
||||||
|
/** Smallest frame index found in the skeleton
|
||||||
|
*/
|
||||||
|
int iSmallestFrame;
|
||||||
|
|
||||||
|
/** Length of the whole animation, in frames
|
||||||
|
*/
|
||||||
|
double dLengthOfAnim;
|
||||||
|
|
||||||
|
/** Do we have texture coordinates?
|
||||||
|
*/
|
||||||
|
bool bHasUVs;
|
||||||
|
|
||||||
|
/** Current line numer
|
||||||
|
*/
|
||||||
|
unsigned int iLineNumber;
|
||||||
|
|
||||||
|
};
|
||||||
|
}; // end of namespace Assimp
|
||||||
|
|
||||||
|
#endif // AI_SMDIMPORTER_H_INC
|
|
@ -54,8 +54,8 @@ namespace Assimp
|
||||||
class SplitLargeMeshesProcess_Triangle;
|
class SplitLargeMeshesProcess_Triangle;
|
||||||
class SplitLargeMeshesProcess_Vertex;
|
class SplitLargeMeshesProcess_Vertex;
|
||||||
|
|
||||||
// NOTE: If you change these limits, don't forget to also change the
|
// NOTE: If you change these limits, don't forget to change the
|
||||||
// corresponding values in the Assimp ports
|
// corresponding values in all Assimp ports
|
||||||
|
|
||||||
// **********************************************************
|
// **********************************************************
|
||||||
// Java: PostProcessStep.java,
|
// Java: PostProcessStep.java,
|
||||||
|
@ -64,10 +64,14 @@ class SplitLargeMeshesProcess_Vertex;
|
||||||
// **********************************************************
|
// **********************************************************
|
||||||
|
|
||||||
// default limit for vertices
|
// default limit for vertices
|
||||||
#define AI_SLM_DEFAULT_MAX_VERTICES 1000000
|
#if (!defined AI_SLM_DEFAULT_MAX_VERTICES)
|
||||||
|
# define AI_SLM_DEFAULT_MAX_VERTICES 1000000
|
||||||
|
#endif
|
||||||
|
|
||||||
// default limit for triangles
|
// default limit for triangles
|
||||||
#define AI_SLM_DEFAULT_MAX_TRIANGLES 1000000
|
#if (!defined AI_SLM_DEFAULT_MAX_TRIANGLES)
|
||||||
|
# define AI_SLM_DEFAULT_MAX_TRIANGLES 1000000
|
||||||
|
#endif
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Postprocessing filter to split large meshes into submeshes
|
/** Postprocessing filter to split large meshes into submeshes
|
||||||
|
|
|
@ -55,8 +55,7 @@ namespace Assimp
|
||||||
void TextureTransform::PreProcessUVTransform(
|
void TextureTransform::PreProcessUVTransform(
|
||||||
Dot3DS::Texture& rcIn)
|
Dot3DS::Texture& rcIn)
|
||||||
{
|
{
|
||||||
std::string s;
|
char szTemp[512];
|
||||||
std::stringstream ss;
|
|
||||||
int iField;
|
int iField;
|
||||||
|
|
||||||
if (rcIn.mOffsetU)
|
if (rcIn.mOffsetU)
|
||||||
|
@ -66,10 +65,10 @@ void TextureTransform::PreProcessUVTransform(
|
||||||
if (aiTextureMapMode_Wrap == rcIn.mMapMode)
|
if (aiTextureMapMode_Wrap == rcIn.mMapMode)
|
||||||
{
|
{
|
||||||
float fNew = rcIn.mOffsetU-(float)iField;
|
float fNew = rcIn.mOffsetU-(float)iField;
|
||||||
ss << "[wrap] Found texture coordinate U offset " << rcIn.mOffsetU << ". "
|
sprintf(szTemp,"[wrap] Found texture coordinate U offset %f. "
|
||||||
"This can be optimized to " << fNew;
|
"This can be optimized to %f",rcIn.mOffsetU,fNew);
|
||||||
ss >> s;
|
|
||||||
DefaultLogger::get()->info(s);
|
DefaultLogger::get()->info(szTemp);
|
||||||
rcIn.mOffsetU = fNew;
|
rcIn.mOffsetU = fNew;
|
||||||
}
|
}
|
||||||
else if (aiTextureMapMode_Mirror == rcIn.mMapMode)
|
else if (aiTextureMapMode_Mirror == rcIn.mMapMode)
|
||||||
|
@ -77,18 +76,18 @@ void TextureTransform::PreProcessUVTransform(
|
||||||
if (0 != (iField % 2))iField--;
|
if (0 != (iField % 2))iField--;
|
||||||
float fNew = rcIn.mOffsetU-(float)iField;
|
float fNew = rcIn.mOffsetU-(float)iField;
|
||||||
|
|
||||||
ss << "[mirror] Found texture coordinate U offset " << rcIn.mOffsetU << ". "
|
sprintf(szTemp,"[mirror] Found texture coordinate U offset %f. "
|
||||||
"This can be optimized to " << fNew;
|
"This can be optimized to %f",rcIn.mOffsetU,fNew);
|
||||||
ss >> s;
|
|
||||||
DefaultLogger::get()->info(s);
|
DefaultLogger::get()->info(szTemp);
|
||||||
rcIn.mOffsetU = fNew;
|
rcIn.mOffsetU = fNew;
|
||||||
}
|
}
|
||||||
else if (aiTextureMapMode_Clamp == rcIn.mMapMode)
|
else if (aiTextureMapMode_Clamp == rcIn.mMapMode)
|
||||||
{
|
{
|
||||||
ss << "[clamp] Found texture coordinate U offset " << rcIn.mOffsetU << ". "
|
sprintf(szTemp,"[clamp] Found texture coordinate U offset %f. "
|
||||||
"This can be clamped to 1.0f";
|
"This can be clamped to 1.0f",rcIn.mOffsetU);
|
||||||
ss >> s;
|
|
||||||
DefaultLogger::get()->info(s);
|
DefaultLogger::get()->info(szTemp);
|
||||||
rcIn.mOffsetU = 1.0f;
|
rcIn.mOffsetU = 1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,10 +99,10 @@ void TextureTransform::PreProcessUVTransform(
|
||||||
if (aiTextureMapMode_Wrap == rcIn.mMapMode)
|
if (aiTextureMapMode_Wrap == rcIn.mMapMode)
|
||||||
{
|
{
|
||||||
float fNew = rcIn.mOffsetV-(float)iField;
|
float fNew = rcIn.mOffsetV-(float)iField;
|
||||||
ss << "[wrap] Found texture coordinate V offset " << rcIn.mOffsetV << ". "
|
sprintf(szTemp,"[wrap] Found texture coordinate V offset %f. "
|
||||||
"This can be optimized to " << fNew;
|
"This can be optimized to %f",rcIn.mOffsetV,fNew);
|
||||||
ss >> s;
|
|
||||||
DefaultLogger::get()->info(s);
|
DefaultLogger::get()->info(szTemp);
|
||||||
rcIn.mOffsetV = fNew;
|
rcIn.mOffsetV = fNew;
|
||||||
}
|
}
|
||||||
else if (aiTextureMapMode_Mirror == rcIn.mMapMode)
|
else if (aiTextureMapMode_Mirror == rcIn.mMapMode)
|
||||||
|
@ -111,18 +110,18 @@ void TextureTransform::PreProcessUVTransform(
|
||||||
if (0 != (iField % 2))iField--;
|
if (0 != (iField % 2))iField--;
|
||||||
float fNew = rcIn.mOffsetV-(float)iField;
|
float fNew = rcIn.mOffsetV-(float)iField;
|
||||||
|
|
||||||
ss << "[mirror] Found texture coordinate V offset " << rcIn.mOffsetV << ". "
|
sprintf(szTemp,"[mirror] Found texture coordinate V offset %f. "
|
||||||
"This can be optimized to " << fNew;
|
"This can be optimized to %f",rcIn.mOffsetV,fNew);
|
||||||
ss >> s;
|
|
||||||
DefaultLogger::get()->info(s);
|
DefaultLogger::get()->info(szTemp);
|
||||||
rcIn.mOffsetV = fNew;
|
rcIn.mOffsetV = fNew;
|
||||||
}
|
}
|
||||||
else if (aiTextureMapMode_Clamp == rcIn.mMapMode)
|
else if (aiTextureMapMode_Clamp == rcIn.mMapMode)
|
||||||
{
|
{
|
||||||
ss << "[clamp] Found texture coordinate V offset " << rcIn.mOffsetV << ". "
|
sprintf(szTemp,"[clamp] Found texture coordinate U offset %f. "
|
||||||
"This can be clamped to 1.0f";
|
"This can be clamped to 1.0f",rcIn.mOffsetV);
|
||||||
ss >> s;
|
|
||||||
DefaultLogger::get()->info(s);
|
DefaultLogger::get()->info(szTemp);
|
||||||
rcIn.mOffsetV = 1.0f;
|
rcIn.mOffsetV = 1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,9 +131,11 @@ void TextureTransform::PreProcessUVTransform(
|
||||||
if (iField = (int)(rcIn.mRotation / 3.141592654f))
|
if (iField = (int)(rcIn.mRotation / 3.141592654f))
|
||||||
{
|
{
|
||||||
float fNew = rcIn.mRotation-(float)iField*3.141592654f;
|
float fNew = rcIn.mRotation-(float)iField*3.141592654f;
|
||||||
ss << "[wrap] Found texture coordinate rotation " << rcIn.mRotation << ". "
|
|
||||||
"This can be optimized to " << fNew;
|
sprintf(szTemp,"[wrap] Found texture coordinate rotation %f. "
|
||||||
DefaultLogger::get()->info(s);
|
"This can be optimized to %f",rcIn.mRotation,fNew);
|
||||||
|
DefaultLogger::get()->info(szTemp);
|
||||||
|
|
||||||
rcIn.mRotation = fNew;
|
rcIn.mRotation = fNew;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -300,10 +301,16 @@ void TextureTransform::BakeScaleNOffset(
|
||||||
// it is more efficient this way ...
|
// it is more efficient this way ...
|
||||||
|
|
||||||
if (!pcMesh->mTextureCoords[0])return;
|
if (!pcMesh->mTextureCoords[0])return;
|
||||||
if (1 == pcSrc->iBakeUVTransform)
|
if (0x1 == pcSrc->iBakeUVTransform)
|
||||||
{
|
{
|
||||||
char szTemp[512];
|
char szTemp[512];
|
||||||
sprintf(szTemp,"Transforming existing UV channel. Source UV: %i"
|
int iLen;
|
||||||
|
#if _MSC_VER >= 1400
|
||||||
|
iLen = ::sprintf_s(szTemp,
|
||||||
|
#else
|
||||||
|
iLen = ::sprintf(szTemp,
|
||||||
|
#endif
|
||||||
|
"Transforming existing UV channel. Source UV: %i"
|
||||||
" OffsetU: %f"
|
" OffsetU: %f"
|
||||||
" OffsetV: %f"
|
" OffsetV: %f"
|
||||||
" ScaleU: %f"
|
" ScaleU: %f"
|
||||||
|
@ -314,7 +321,9 @@ void TextureTransform::BakeScaleNOffset(
|
||||||
pcSrc->pcSingleTexture->mScaleU,
|
pcSrc->pcSingleTexture->mScaleU,
|
||||||
pcSrc->pcSingleTexture->mScaleV,
|
pcSrc->pcSingleTexture->mScaleV,
|
||||||
pcSrc->pcSingleTexture->mRotation);
|
pcSrc->pcSingleTexture->mRotation);
|
||||||
DefaultLogger::get()->info(std::string(szTemp));
|
|
||||||
|
ai_assert(0 < iLen);
|
||||||
|
DefaultLogger::get()->info(std::string(szTemp,iLen));
|
||||||
|
|
||||||
if (!pcSrc->pcSingleTexture->mRotation)
|
if (!pcSrc->pcSingleTexture->mRotation)
|
||||||
{
|
{
|
||||||
|
@ -349,7 +358,7 @@ void TextureTransform::BakeScaleNOffset(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (2 == pcSrc->iBakeUVTransform)
|
else if (0x2 == pcSrc->iBakeUVTransform)
|
||||||
{
|
{
|
||||||
// first save all texture coordinate sets
|
// first save all texture coordinate sets
|
||||||
aiVector3D* apvOriginalSets[AI_MAX_NUMBER_OF_TEXTURECOORDS];
|
aiVector3D* apvOriginalSets[AI_MAX_NUMBER_OF_TEXTURECOORDS];
|
||||||
|
@ -367,13 +376,14 @@ void TextureTransform::BakeScaleNOffset(
|
||||||
// now we need to find all textures in the material
|
// now we need to find all textures in the material
|
||||||
// which require scaling/offset operations
|
// which require scaling/offset operations
|
||||||
std::vector<STransformVecInfo> sOps;
|
std::vector<STransformVecInfo> sOps;
|
||||||
AddToList(sOps,&pcSrc->sTexDiffuse);
|
sOps.reserve(10);
|
||||||
AddToList(sOps,&pcSrc->sTexSpecular);
|
TextureTransform::AddToList(sOps,&pcSrc->sTexDiffuse);
|
||||||
AddToList(sOps,&pcSrc->sTexEmissive);
|
TextureTransform::AddToList(sOps,&pcSrc->sTexSpecular);
|
||||||
AddToList(sOps,&pcSrc->sTexOpacity);
|
TextureTransform::AddToList(sOps,&pcSrc->sTexEmissive);
|
||||||
AddToList(sOps,&pcSrc->sTexBump);
|
TextureTransform::AddToList(sOps,&pcSrc->sTexOpacity);
|
||||||
AddToList(sOps,&pcSrc->sTexShininess);
|
TextureTransform::AddToList(sOps,&pcSrc->sTexBump);
|
||||||
AddToList(sOps,&pcSrc->sTexAmbient);
|
TextureTransform::AddToList(sOps,&pcSrc->sTexShininess);
|
||||||
|
TextureTransform::AddToList(sOps,&pcSrc->sTexAmbient);
|
||||||
|
|
||||||
// check the list and find out how many we won't be able
|
// check the list and find out how many we won't be able
|
||||||
// to generate.
|
// to generate.
|
||||||
|
@ -446,7 +456,13 @@ void TextureTransform::BakeScaleNOffset(
|
||||||
pcMesh->mTextureCoords[iNum] = _pvOut;
|
pcMesh->mTextureCoords[iNum] = _pvOut;
|
||||||
|
|
||||||
char szTemp[512];
|
char szTemp[512];
|
||||||
sprintf(szTemp,"Generating additional UV channel. Source UV: %i"
|
int iLen;
|
||||||
|
#if _MSC_VER >= 1400
|
||||||
|
iLen = ::sprintf_s(szTemp,
|
||||||
|
#else
|
||||||
|
iLen = ::sprintf(szTemp,
|
||||||
|
#endif
|
||||||
|
"Generating additional UV channel. Source UV: %i"
|
||||||
" OffsetU: %f"
|
" OffsetU: %f"
|
||||||
" OffsetV: %f"
|
" OffsetV: %f"
|
||||||
" ScaleU: %f"
|
" ScaleU: %f"
|
||||||
|
@ -457,7 +473,8 @@ void TextureTransform::BakeScaleNOffset(
|
||||||
(**i).fScaleU,
|
(**i).fScaleU,
|
||||||
(**i).fScaleV,
|
(**i).fScaleV,
|
||||||
(**i).fRotation);
|
(**i).fRotation);
|
||||||
DefaultLogger::get()->info(std::string(szTemp));
|
ai_assert(0 < iLen);
|
||||||
|
DefaultLogger::get()->info(std::string(szTemp,iLen));
|
||||||
|
|
||||||
const aiVector3D* pvBase = _pvBase;
|
const aiVector3D* pvBase = _pvBase;
|
||||||
aiVector3D* pvOut = _pvOut;
|
aiVector3D* pvOut = _pvOut;
|
||||||
|
@ -516,6 +533,12 @@ void TextureTransform::BakeScaleNOffset(
|
||||||
if (apvOriginalSets[iNum])delete[] apvOriginalSets[iNum];
|
if (apvOriginalSets[iNum])delete[] apvOriginalSets[iNum];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setup bitflags to indicate which texture coordinate
|
||||||
|
// channels are used (this class works for 2d texture coordinates only)
|
||||||
|
|
||||||
|
unsigned int iIndex = 0;
|
||||||
|
while (pcMesh->HasTextureCoords(iIndex))pcMesh->mNumUVComponents[iIndex++] = 2;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -342,6 +342,8 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh)
|
||||||
void ValidateDSProcess::Validate( const aiMesh* pMesh,
|
void ValidateDSProcess::Validate( const aiMesh* pMesh,
|
||||||
const aiBone* pBone)
|
const aiBone* pBone)
|
||||||
{
|
{
|
||||||
|
this->Validate(&pBone->mName);
|
||||||
|
|
||||||
// check whether all vertices affected by this bone are valid
|
// check whether all vertices affected by this bone are valid
|
||||||
for (unsigned int i = 0; i < pBone->mNumWeights;++i)
|
for (unsigned int i = 0; i < pBone->mNumWeights;++i)
|
||||||
{
|
{
|
||||||
|
@ -359,6 +361,8 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh,
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ValidateDSProcess::Validate( const aiAnimation* pAnimation)
|
void ValidateDSProcess::Validate( const aiAnimation* pAnimation)
|
||||||
{
|
{
|
||||||
|
this->Validate(&pAnimation->mName);
|
||||||
|
|
||||||
// validate all materials
|
// validate all materials
|
||||||
if (pAnimation->mNumBones)
|
if (pAnimation->mNumBones)
|
||||||
{
|
{
|
||||||
|
@ -480,7 +484,7 @@ void ValidateDSProcess::Validate( const aiMaterial* pMaterial)
|
||||||
// check whether there are material keys that are obviously not legal
|
// check whether there are material keys that are obviously not legal
|
||||||
for (unsigned int i = 0; i < pMaterial->mNumProperties;++i)
|
for (unsigned int i = 0; i < pMaterial->mNumProperties;++i)
|
||||||
{
|
{
|
||||||
aiMaterialProperty* prop = pMaterial->mProperties[i];
|
const aiMaterialProperty* prop = pMaterial->mProperties[i];
|
||||||
if (!prop)
|
if (!prop)
|
||||||
{
|
{
|
||||||
this->ReportError("aiMaterial::mProperties[%i] is NULL (aiMaterial::mNumProperties is %i)",
|
this->ReportError("aiMaterial::mProperties[%i] is NULL (aiMaterial::mNumProperties is %i)",
|
||||||
|
@ -491,9 +495,39 @@ void ValidateDSProcess::Validate( const aiMaterial* pMaterial)
|
||||||
this->ReportError("aiMaterial::mProperties[%i].mDataLength or "
|
this->ReportError("aiMaterial::mProperties[%i].mDataLength or "
|
||||||
"aiMaterial::mProperties[%i].mData is 0",i,i);
|
"aiMaterial::mProperties[%i].mData is 0",i,i);
|
||||||
}
|
}
|
||||||
|
// check all predefined types
|
||||||
|
if (aiPTI_String == prop->mType)
|
||||||
|
{
|
||||||
|
if (prop->mDataLength < sizeof(aiString))
|
||||||
|
{
|
||||||
|
this->ReportError("aiMaterial::mProperties[%i].mDataLength is "
|
||||||
|
"too small to contain a string (%i, needed: %i)",
|
||||||
|
i,prop->mDataLength,sizeof(aiString));
|
||||||
|
}
|
||||||
|
this->Validate((const aiString*)prop->mData);
|
||||||
|
}
|
||||||
|
else if (aiPTI_Float == prop->mType)
|
||||||
|
{
|
||||||
|
if (prop->mDataLength < sizeof(float))
|
||||||
|
{
|
||||||
|
this->ReportError("aiMaterial::mProperties[%i].mDataLength is "
|
||||||
|
"too small to contain a float (%i, needed: %i)",
|
||||||
|
i,prop->mDataLength,sizeof(float));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (aiPTI_Integer == prop->mType)
|
||||||
|
{
|
||||||
|
if (prop->mDataLength < sizeof(int))
|
||||||
|
{
|
||||||
|
this->ReportError("aiMaterial::mProperties[%i].mDataLength is "
|
||||||
|
"too small to contain an integer (%i, needed: %i)",
|
||||||
|
i,prop->mDataLength,sizeof(int));
|
||||||
|
}
|
||||||
|
}
|
||||||
// TODO: check whether there is a key with an unknown name ...
|
// TODO: check whether there is a key with an unknown name ...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// make some more specific tests
|
||||||
float fTemp;
|
float fTemp;
|
||||||
int iShading;
|
int iShading;
|
||||||
if (AI_SUCCESS == aiGetMaterialInteger( pMaterial,AI_MATKEY_SHADING_MODEL,&iShading))
|
if (AI_SUCCESS == aiGetMaterialInteger( pMaterial,AI_MATKEY_SHADING_MODEL,&iShading))
|
||||||
|
@ -518,7 +552,6 @@ void ValidateDSProcess::Validate( const aiMaterial* pMaterial)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// check whether there are invalid texture keys
|
// check whether there are invalid texture keys
|
||||||
SearchForInvalidTextures(pMaterial,"diffuse");
|
SearchForInvalidTextures(pMaterial,"diffuse");
|
||||||
SearchForInvalidTextures(pMaterial,"specular");
|
SearchForInvalidTextures(pMaterial,"specular");
|
||||||
|
@ -563,6 +596,8 @@ void ValidateDSProcess::Validate( const aiTexture* pTexture)
|
||||||
void ValidateDSProcess::Validate( const aiAnimation* pAnimation,
|
void ValidateDSProcess::Validate( const aiAnimation* pAnimation,
|
||||||
const aiBoneAnim* pBoneAnim)
|
const aiBoneAnim* pBoneAnim)
|
||||||
{
|
{
|
||||||
|
this->Validate(&pBoneAnim->mBoneName);
|
||||||
|
|
||||||
// check whether there is a bone with this name ...
|
// check whether there is a bone with this name ...
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
for (; i < this->mScene->mNumMeshes;++i)
|
for (; i < this->mScene->mNumMeshes;++i)
|
||||||
|
@ -649,6 +684,8 @@ void ValidateDSProcess::Validate( const aiNode* pNode)
|
||||||
if (pNode != this->mScene->mRootNode && !pNode->mParent)
|
if (pNode != this->mScene->mRootNode && !pNode->mParent)
|
||||||
this->ReportError("A node has no valid parent (aiNode::mParent is NULL)");
|
this->ReportError("A node has no valid parent (aiNode::mParent is NULL)");
|
||||||
|
|
||||||
|
this->Validate(&pNode->mName);
|
||||||
|
|
||||||
// validate all meshes
|
// validate all meshes
|
||||||
if (pNode->mNumMeshes)
|
if (pNode->mNumMeshes)
|
||||||
{
|
{
|
||||||
|
@ -687,3 +724,25 @@ void ValidateDSProcess::Validate( const aiNode* pNode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void ValidateDSProcess::Validate( const aiString* pString)
|
||||||
|
{
|
||||||
|
if (pString->length > MAXLEN)
|
||||||
|
{
|
||||||
|
this->ReportError("aiString::length is too large (%i, maximum is %i)",
|
||||||
|
pString->length,MAXLEN);
|
||||||
|
}
|
||||||
|
const char* sz = pString->data;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if ('\0' == *sz)
|
||||||
|
{
|
||||||
|
if (pString->length != (unsigned int)(sz-pString->data))
|
||||||
|
this->ReportError("aiString::data is invalid: the terminal zero is at a wrong offset");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (sz >= &pString->data[MAXLEN])
|
||||||
|
this->ReportError("aiString::data is invalid. There is no terminal character");
|
||||||
|
++sz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@ struct aiBoneAnim;
|
||||||
struct aiTexture;
|
struct aiTexture;
|
||||||
struct aiMaterial;
|
struct aiMaterial;
|
||||||
struct aiNode;
|
struct aiNode;
|
||||||
|
struct aiString;
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp
|
||||||
{
|
{
|
||||||
|
@ -158,6 +159,12 @@ protected:
|
||||||
*/
|
*/
|
||||||
void Validate( const aiNode* pNode);
|
void Validate( const aiNode* pNode);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Validates a string
|
||||||
|
* @param pString Input string
|
||||||
|
*/
|
||||||
|
void Validate( const aiString* pString);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
aiScene* mScene;
|
aiScene* mScene;
|
||||||
|
|
|
@ -579,174 +579,188 @@ void XFileImporter::ConvertMaterials( aiScene* pScene, const std::vector<XFile::
|
||||||
|
|
||||||
// texture, if there is one
|
// texture, if there is one
|
||||||
if (1 == oldMat.mTextures.size())
|
if (1 == oldMat.mTextures.size())
|
||||||
|
{
|
||||||
|
if (oldMat.mTextures[0].length())
|
||||||
{
|
{
|
||||||
// if there is only one texture, assume it contains the
|
// if there is only one texture assume it contains the diffuse color
|
||||||
// diffuse color
|
aiString tex;
|
||||||
aiString tex;
|
tex.Set( oldMat.mTextures[0]);
|
||||||
tex.Set( oldMat.mTextures[0]);
|
mat->AddProperty( &tex, AI_MATKEY_TEXTURE_DIFFUSE(0));
|
||||||
|
|
||||||
mat->AddProperty( &tex, AI_MATKEY_TEXTURE_DIFFUSE(0));
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Otherwise ... try to search for typical strings in the
|
// Otherwise ... try to search for typical strings in the
|
||||||
// texture's file name like 'bump' or 'diffuse'
|
// texture's file name like 'bump' or 'diffuse'
|
||||||
unsigned int iHM = 0,iNM = 0,iDM = 0,iSM = 0,iAM = 0,iEM = 0;
|
unsigned int iHM = 0,iNM = 0,iDM = 0,iSM = 0,iAM = 0,iEM = 0;
|
||||||
for( unsigned int b = 0; b < oldMat.mTextures.size(); b++)
|
for( unsigned int b = 0; b < oldMat.mTextures.size(); b++)
|
||||||
{
|
{
|
||||||
std::string sz = oldMat.mTextures[b];
|
std::string sz = oldMat.mTextures[b];
|
||||||
|
if (!sz.length())continue;
|
||||||
|
|
||||||
char key[256];
|
char key[256];
|
||||||
|
|
||||||
// find the file name
|
// find the file name
|
||||||
const size_t iLen = sz.length();
|
const size_t iLen = sz.length();
|
||||||
std::string::size_type s = sz.rfind('\\',iLen-1);
|
std::string::size_type s = sz.rfind('\\',iLen-1);
|
||||||
if (std::string::npos == s)
|
if (std::string::npos == s)
|
||||||
{
|
{
|
||||||
s = sz.rfind('/',iLen-1);
|
s = sz.rfind('/',iLen-1);
|
||||||
if (std::string::npos == s)s = 0;
|
if (std::string::npos == s)s = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// cut off the file extension
|
// cut off the file extension
|
||||||
std::string::size_type sExt = sz.rfind('.',iLen-1);
|
std::string::size_type sExt = sz.rfind('.',iLen-1);
|
||||||
if (std::string::npos != sExt)
|
if (std::string::npos != sExt)
|
||||||
{
|
{
|
||||||
sz[sExt] = '\0';
|
sz[sExt] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
// bump map
|
// bump map
|
||||||
std::string::size_type s2 = sz.find("bump",s);
|
std::string::size_type s2 = sz.find("bump",s);
|
||||||
if (std::string::npos == s2)
|
if (std::string::npos == s2)
|
||||||
|
{
|
||||||
|
if (std::string::npos == (s2 = sz.find("BUMP",s)))
|
||||||
{
|
{
|
||||||
s2 = sz.find("BUMP",s);
|
if (std::string::npos == (s2 = sz.find("Bump",s)))
|
||||||
if (std::string::npos == s2)
|
|
||||||
{
|
{
|
||||||
s2 = sz.find("Bump",s);
|
if (std::string::npos == (s2 = sz.find("height",s)))
|
||||||
if (std::string::npos == s2)
|
|
||||||
{
|
{
|
||||||
s2 = sz.find("height",s);
|
if (std::string::npos == (s2 = sz.find("HEIGHT",s)))
|
||||||
if (std::string::npos == s2)
|
|
||||||
{
|
{
|
||||||
s2 = sz.find("HEIGHT",s);
|
|
||||||
if (std::string::npos == s2)
|
|
||||||
{
|
|
||||||
s2 = sz.find("Height",s);
|
s2 = sz.find("Height",s);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (std::string::npos != s2)
|
if (std::string::npos != s2)
|
||||||
{
|
{
|
||||||
sprintf(key,AI_MATKEY_TEXTURE_HEIGHT_ "[%i]",iHM++);
|
#if _MSC_VER >= 1400
|
||||||
}
|
::sprintf_s(key,AI_MATKEY_TEXTURE_HEIGHT_ "[%i]",iHM++);
|
||||||
|
#else
|
||||||
|
::sprintf(key,AI_MATKEY_TEXTURE_HEIGHT_ "[%i]",iHM++);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Normal map
|
// Normal map
|
||||||
std::string::size_type s2 = sz.find("normal",s);
|
std::string::size_type s2 = sz.find("normal",s);
|
||||||
if (std::string::npos == s2)
|
if (std::string::npos == s2)
|
||||||
|
{
|
||||||
|
if (std::string::npos == (s2 = sz.find("NORMAL",s)))
|
||||||
{
|
{
|
||||||
s2 = sz.find("NORMAL",s);
|
if (std::string::npos == (s2 = sz.find("nm",s)))
|
||||||
if (std::string::npos == s2)
|
{
|
||||||
{
|
if (std::string::npos == (s2 = sz.find("Normal",s)))
|
||||||
s2 = sz.find("nm",s); // not really unique
|
|
||||||
if (std::string::npos == s2)
|
|
||||||
{
|
{
|
||||||
s2 = sz.find("Normal",s);
|
|
||||||
if (std::string::npos == s2)
|
|
||||||
{
|
|
||||||
s2 = sz.find("NM",s);
|
s2 = sz.find("NM",s);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (std::string::npos != s2)
|
if (std::string::npos != s2)
|
||||||
{
|
{
|
||||||
sprintf(key,AI_MATKEY_TEXTURE_NORMALS_ "[%i]",iNM++);
|
#if _MSC_VER >= 1400
|
||||||
}
|
::sprintf_s(key,AI_MATKEY_TEXTURE_NORMALS_ "[%i]",iNM++);
|
||||||
|
#else
|
||||||
|
::sprintf(key,AI_MATKEY_TEXTURE_NORMALS_ "[%i]",iNM++);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
// specular color texture (not unique, too. Could
|
// specular color texture (not unique, too. Could
|
||||||
// also be the material's shininess)
|
// also be the material's shininess)
|
||||||
std::string::size_type s2 = sz.find("spec",s);
|
std::string::size_type s2 = sz.find("spec",s);
|
||||||
if (std::string::npos == s2)
|
if (std::string::npos == s2)
|
||||||
|
{
|
||||||
|
if (std::string::npos == (s2 = sz.find("Spec",s)))
|
||||||
{
|
{
|
||||||
s2 = sz.find("Spec",s);
|
if (std::string::npos == (sz.find("SPEC",s)))
|
||||||
if (std::string::npos == s2)
|
|
||||||
{
|
{
|
||||||
s2 = sz.find("SPEC",s);
|
if (std::string::npos == (s2 = sz.find("Glanz",s)))
|
||||||
if (std::string::npos == s2)
|
|
||||||
{
|
{
|
||||||
s2 = sz.find("Glanz",s);
|
|
||||||
if (std::string::npos == s2)
|
|
||||||
{
|
|
||||||
s2 = sz.find("glanz",s);
|
s2 = sz.find("glanz",s);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (std::string::npos != s2)
|
|
||||||
{
|
|
||||||
sprintf(key,AI_MATKEY_TEXTURE_SPECULAR_ "[%i]",iSM++);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// ambient color texture
|
|
||||||
std::string::size_type s2 = sz.find("ambi",s);
|
|
||||||
if (std::string::npos == s2)
|
|
||||||
{
|
|
||||||
s2 = sz.find("AMBI",s);
|
|
||||||
if (std::string::npos == s2)
|
|
||||||
{
|
|
||||||
s2 = sz.find("umgebungsfarbe",s);
|
|
||||||
if (std::string::npos == s2)
|
|
||||||
{
|
|
||||||
s2 = sz.find("Ambi",s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (std::string::npos != s2)
|
|
||||||
{
|
|
||||||
sprintf(key,AI_MATKEY_TEXTURE_AMBIENT_ "[%i]",iAM++);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// emissive color texture
|
|
||||||
std::string::size_type s2 = sz.find("emissive",s);
|
|
||||||
if (std::string::npos == s2)
|
|
||||||
{
|
|
||||||
s2 = sz.find("EMISSIVE",s);
|
|
||||||
if (std::string::npos == s2)
|
|
||||||
{
|
|
||||||
// self illumination
|
|
||||||
s2 = sz.find("self",s);
|
|
||||||
if (std::string::npos == s2)
|
|
||||||
{
|
|
||||||
s2 = sz.find("Emissive",s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (std::string::npos != s2)
|
|
||||||
{
|
|
||||||
sprintf(key,AI_MATKEY_TEXTURE_EMISSIVE_ "[%i]",iEM++);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// assume it is a diffuse texture
|
|
||||||
sprintf(key,AI_MATKEY_TEXTURE_DIFFUSE_ "[%i]",iDM++);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (std::string::npos != s2)
|
||||||
|
{
|
||||||
|
#if _MSC_VER >= 1400
|
||||||
|
::sprintf_s(key,AI_MATKEY_TEXTURE_SPECULAR_ "[%i]",iSM++);
|
||||||
|
#else
|
||||||
|
::sprintf(key,AI_MATKEY_TEXTURE_SPECULAR_ "[%i]",iSM++);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// ambient color texture
|
||||||
|
std::string::size_type s2 = sz.find("ambi",s);
|
||||||
|
if (std::string::npos == s2)
|
||||||
|
{
|
||||||
|
if (std::string::npos == (s2 = sz.find("AMBI",s)))
|
||||||
|
{
|
||||||
|
if (std::string::npos == (s2 = sz.find("env",s)))
|
||||||
|
{
|
||||||
|
s2 = sz.find("Ambi",s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (std::string::npos != s2)
|
||||||
|
{
|
||||||
|
#if _MSC_VER >= 1400
|
||||||
|
::sprintf_s(key,AI_MATKEY_TEXTURE_AMBIENT_ "[%i]",iAM++);
|
||||||
|
#else
|
||||||
|
::sprintf(key,AI_MATKEY_TEXTURE_AMBIENT_ "[%i]",iAM++);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// emissive color texture
|
||||||
|
std::string::size_type s2 = sz.find("emissive",s);
|
||||||
|
if (std::string::npos == s2)
|
||||||
|
{
|
||||||
|
s2 = sz.find("EMISSIVE",s);
|
||||||
|
if (std::string::npos == s2)
|
||||||
|
{
|
||||||
|
// self illumination
|
||||||
|
if (std::string::npos == (s2 = sz.find("self",s)))
|
||||||
|
{
|
||||||
|
s2 = sz.find("Emissive",s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (std::string::npos != s2)
|
||||||
|
{
|
||||||
|
#if _MSC_VER >= 1400
|
||||||
|
::sprintf_s(key,AI_MATKEY_TEXTURE_EMISSIVE_ "[%i]",iEM++);
|
||||||
|
#else
|
||||||
|
::sprintf(key,AI_MATKEY_TEXTURE_EMISSIVE_ "[%i]",iEM++);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// assume it is a diffuse texture
|
||||||
|
#if _MSC_VER >= 1400
|
||||||
|
::sprintf_s(key,AI_MATKEY_TEXTURE_DIFFUSE_ "[%i]",iDM++);
|
||||||
|
#else
|
||||||
|
::sprintf(key,AI_MATKEY_TEXTURE_DIFFUSE_ "[%i]",iDM++);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
aiString tex;
|
aiString tex;
|
||||||
tex.Set( oldMat.mTextures[b] );
|
tex.Set( oldMat.mTextures[b] );
|
||||||
|
|
||||||
mat->AddProperty( &tex, key);
|
mat->AddProperty( &tex, key);
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
pScene->mMaterials[pScene->mNumMaterials] = mat;
|
pScene->mMaterials[pScene->mNumMaterials] = mat;
|
||||||
mImportedMats[oldMat.mName] = pScene->mNumMaterials;
|
mImportedMats[oldMat.mName] = pScene->mNumMaterials;
|
||||||
pScene->mNumMaterials++;
|
pScene->mNumMaterials++;
|
||||||
|
|
|
@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "XFileHelper.h"
|
#include "XFileHelper.h"
|
||||||
#include "BaseImporter.h"
|
#include "BaseImporter.h"
|
||||||
#include "fast_atof.h"
|
#include "fast_atof.h"
|
||||||
|
#include "../include/DefaultLogger.h"
|
||||||
|
|
||||||
#include <boost/format.hpp>
|
#include <boost/format.hpp>
|
||||||
|
|
||||||
|
@ -150,11 +151,11 @@ void XFileParser::ParseFile()
|
||||||
if( objectName == "}")
|
if( objectName == "}")
|
||||||
{
|
{
|
||||||
// whatever?
|
// whatever?
|
||||||
// os::Printer::log("} found in dataObject", ELL_WARNING);
|
DefaultLogger::get()->warn("} found in dataObject");
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
// unknown format
|
// unknown format
|
||||||
//os::Printer::log("Unknown data object in animation of .x file", objectName.c_str(), ELL_WARNING);
|
DefaultLogger::get()->warn("Unknown data object in animation of .x file");
|
||||||
ParseUnknownDataObject();
|
ParseUnknownDataObject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -248,7 +249,7 @@ void XFileParser::ParseDataObjectFrame( Node* pParent)
|
||||||
ParseDataObjectMesh( mesh);
|
ParseDataObjectMesh( mesh);
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
// os::Printer::log("Unknown data object in frame in x file", objectName.c_str(), ELL_WARNING);
|
DefaultLogger::get()->warn("Unknown data object in frame in x file");
|
||||||
ParseUnknownDataObject();
|
ParseUnknownDataObject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -338,7 +339,7 @@ void XFileParser::ParseDataObjectMesh( Mesh* pMesh)
|
||||||
ParseDataObjectSkinWeights( pMesh);
|
ParseDataObjectSkinWeights( pMesh);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//os::Printer::log("Unknown data object in mesh in x file", objectName.c_str(), ELL_WARNING);
|
DefaultLogger::get()->warn("Unknown data object in mesh in x file");
|
||||||
ParseUnknownDataObject();
|
ParseUnknownDataObject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -533,7 +534,7 @@ void XFileParser::ParseDataObjectMeshMaterialList( Mesh* pMesh)
|
||||||
// ignore
|
// ignore
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
// os::Printer::log("Unknown data object in material list in x file", objectName.c_str(), ELL_WARNING);
|
DefaultLogger::get()->warn("Unknown data object in material list in x file");
|
||||||
ParseUnknownDataObject();
|
ParseUnknownDataObject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -571,7 +572,7 @@ void XFileParser::ParseDataObjectMaterial( Material* pMaterial)
|
||||||
pMaterial->mTextures.push_back( texname);
|
pMaterial->mTextures.push_back( texname);
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
// os::Printer::log("Unknown data object in material in .x file", objectName.c_str(), ELL_WARNING);
|
DefaultLogger::get()->warn("Unknown data object in material in x file");
|
||||||
ParseUnknownDataObject();
|
ParseUnknownDataObject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -608,7 +609,7 @@ void XFileParser::ParseDataObjectAnimationSet()
|
||||||
ParseDataObjectAnimation( anim);
|
ParseDataObjectAnimation( anim);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// os::Printer::log("Unknown data object in animation set in x file", objectName.c_str(), ELL_WARNING);
|
DefaultLogger::get()->warn("Unknown data object in animation set in x file");
|
||||||
ParseUnknownDataObject();
|
ParseUnknownDataObject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -644,7 +645,7 @@ void XFileParser::ParseDataObjectAnimation( Animation* pAnim)
|
||||||
CheckForClosingBrace();
|
CheckForClosingBrace();
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
//os::Printer::log("Unknown data object in animation in x file", objectName.c_str(), ELL_WARNING);
|
DefaultLogger::get()->warn("Unknown data object in animation in x file");
|
||||||
ParseUnknownDataObject();
|
ParseUnknownDataObject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -748,6 +749,12 @@ void XFileParser::ParseDataObjectTextureFilename( std::string& pName)
|
||||||
readHeadOfDataObject();
|
readHeadOfDataObject();
|
||||||
GetNextTokenAsString( pName);
|
GetNextTokenAsString( pName);
|
||||||
CheckForClosingBrace();
|
CheckForClosingBrace();
|
||||||
|
|
||||||
|
// FIX: some files (e.g. AnimationTest.x) have "" as texture file name
|
||||||
|
if (!pName.length())
|
||||||
|
{
|
||||||
|
DefaultLogger::get()->warn("Length of texture file name is zero. Skipping this texture.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -49,17 +49,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
MakeVerboseFormatProcess::MakeVerboseFormatProcess()
|
MakeVerboseFormatProcess::MakeVerboseFormatProcess()
|
||||||
{
|
{
|
||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
MakeVerboseFormatProcess::~MakeVerboseFormatProcess()
|
MakeVerboseFormatProcess::~MakeVerboseFormatProcess()
|
||||||
{
|
{
|
||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
// -------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Executes the post processing step on the given imported data.
|
// Executes the post processing step on the given imported data.
|
||||||
void MakeVerboseFormatProcess::Execute( aiScene* pScene)
|
void MakeVerboseFormatProcess::Execute( aiScene* pScene)
|
||||||
{
|
{
|
||||||
|
@ -76,8 +76,7 @@ void MakeVerboseFormatProcess::Execute( aiScene* pScene)
|
||||||
else DefaultLogger::get()->debug("MakeVerboseFormatProcess. There was nothing to do.");
|
else DefaultLogger::get()->debug("MakeVerboseFormatProcess. There was nothing to do.");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
// -------------------------------------------------------------------
|
|
||||||
// Executes the post processing step on the given imported data.
|
// Executes the post processing step on the given imported data.
|
||||||
bool MakeVerboseFormatProcess::MakeVerboseFormat(aiMesh* pcMesh)
|
bool MakeVerboseFormatProcess::MakeVerboseFormat(aiMesh* pcMesh)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
|
||||||
|
|
||||||
|
#if (!defined AI_QNAN_H_INCLUDED)
|
||||||
|
#define AI_QNAN_H_INCLUDED
|
||||||
|
|
||||||
|
#if (!defined ASSIMP_BUILD_CPP_09)
|
||||||
|
# include <boost/static_assert.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline bool is_qnan(const float in)
|
||||||
|
{
|
||||||
|
// _isnan() takes a double as argument and would
|
||||||
|
// require a cast. Therefore we must do it on our own ...
|
||||||
|
// Another method would be to check whether in != in.
|
||||||
|
// This should also wor since nan compares to inequal,
|
||||||
|
// even when compared with itself. However, this could
|
||||||
|
// case problems with other special floats like snan or inf
|
||||||
|
union _tagFPUNION
|
||||||
|
{
|
||||||
|
float f;
|
||||||
|
int32_t i;
|
||||||
|
} FPUNION1,FPUNION2;
|
||||||
|
|
||||||
|
// use a compile-time asertion if possible
|
||||||
|
#if (defined ASSIMP_BUILD_CPP_09)
|
||||||
|
static_assert(sizeof(float)==sizeof(int32_t),
|
||||||
|
"A float seems not to be 4 bytes on this platform");
|
||||||
|
#else
|
||||||
|
BOOST_STATIC_ASSERT(sizeof(float)==sizeof(int32_t));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FPUNION1.f = in;
|
||||||
|
FPUNION2.f = std::numeric_limits<float>::quiet_NaN();
|
||||||
|
return FPUNION1.i == FPUNION2.i;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool is_not_qnan(const float in)
|
||||||
|
{
|
||||||
|
return !is_qnan(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !! AI_QNAN_H_INCLUDED
|
50
doc/dox.h
50
doc/dox.h
|
@ -528,9 +528,9 @@ void ConvertMaterial( aiMaterial* matIn, D3DMATERIAL9* matOut )
|
||||||
|
|
||||||
Textures:
|
Textures:
|
||||||
|
|
||||||
Textures can have various types and purposes. Sometimes ASSIMP is not able to
|
Textures can have various types and intended purposes. Sometimes ASSIMP is not able to
|
||||||
determine the exact purpose of a texture. Normally it will assume diffuse as default
|
determine the exact designated use of a texture. Normally it will assume a texture to be
|
||||||
purpose. Possible purposes for a texture:
|
a diffuse color map by default. Texture types:
|
||||||
|
|
||||||
<b>1. Diffuse textures.</b> Diffuse textures are combined with the result of the diffuse lighting term.
|
<b>1. Diffuse textures.</b> Diffuse textures are combined with the result of the diffuse lighting term.
|
||||||
<br>
|
<br>
|
||||||
|
@ -549,10 +549,10 @@ normally grayscale images, black stands for fully transparent, white for fully o
|
||||||
<b>6. Height maps.</b> Height maps specify the relative height of a point on a triangle on a
|
<b>6. Height maps.</b> Height maps specify the relative height of a point on a triangle on a
|
||||||
per-texel base. Normally height maps (sometimes called "Bump maps") are converted to normal
|
per-texel base. Normally height maps (sometimes called "Bump maps") are converted to normal
|
||||||
maps before rendering. Height maps are normally grayscale textures. Height maps could also
|
maps before rendering. Height maps are normally grayscale textures. Height maps could also
|
||||||
be used as displacement maps on a highly tesselated surface.
|
be used as displacement maps on highly tesselated surfaces.
|
||||||
<br>
|
<br>
|
||||||
<b>7. Normal maps.</b> Normal maps contain normal vectors for a single texel, in tangent space.
|
<b>7. Normal maps.</b> Normal maps contain normal vectors for a single texel, in tangent space.
|
||||||
They are not bound to an object. However, all lighting omputations must be done in tangent space.
|
They are not bound to an object. However, all lighting computations must be done in tangent space.
|
||||||
There are many resources on Normal Mapping on the internet.
|
There are many resources on Normal Mapping on the internet.
|
||||||
<br>
|
<br>
|
||||||
<b>8. Shininess maps</b> Shininess maps (sometimes called "Gloss" or "SpecularMap") specify
|
<b>8. Shininess maps</b> Shininess maps (sometimes called "Gloss" or "SpecularMap") specify
|
||||||
|
@ -560,7 +560,7 @@ the shininess of a texel mapped on a surface. They are normally used together wi
|
||||||
to make flat surfaces look as if they were real 3d objects.
|
to make flat surfaces look as if they were real 3d objects.
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
Textures are generally defined by a set of parameters, including
|
Textures are generally defined by a set of parameters including
|
||||||
<br>
|
<br>
|
||||||
<b>1. The path to the texture.</b> This property is always set. If it is not set, a texture
|
<b>1. The path to the texture.</b> This property is always set. If it is not set, a texture
|
||||||
is not existing. This can either be a valid path (beware, sometimes
|
is not existing. This can either be a valid path (beware, sometimes
|
||||||
|
@ -585,26 +585,31 @@ else // your loading code to load from a path ...
|
||||||
<b>2. An UV coordinate index.</b> This is an index into the UV coordinate set list of the
|
<b>2. An UV coordinate index.</b> This is an index into the UV coordinate set list of the
|
||||||
corresponding mesh. Note: Some formats don't define this, so beware, it could be that
|
corresponding mesh. Note: Some formats don't define this, so beware, it could be that
|
||||||
a second diffuse texture in a mesh was originally intended to use a second UV channel although
|
a second diffuse texture in a mesh was originally intended to use a second UV channel although
|
||||||
ASSIMP states it uses the first one. UV coordinate source indices are defined by the
|
ASSIMP says it uses the first one. UV coordinate source indices are defined by the
|
||||||
<i>AI_MATKEY_UVWSRC_<textype>(<texindex>)</i> material property. Assume 0 as default value if
|
<i>AI_MATKEY_UVWSRC_<textype>(<texindex>)</i> material property. Assume 0 as default value if
|
||||||
this property is not set.
|
this property is not set.
|
||||||
<br>
|
<br>
|
||||||
<b>3. A blend factor.</b> This is used if multiple textures are assigned to a slot, e.g. two
|
<b>3. A blend factor.</b> This is used if multiple textures are assigned to a slot, e.g. two
|
||||||
or more textures on the diffuse channel. A texture's color value is multiplied with its
|
or more textures on the diffuse channel. A texture's color value is multiplied with its
|
||||||
blend factor before it is combined with the previous color value (from the last texture) using
|
blend factor before it is combined with the previous color value (from the last texture or the
|
||||||
a specific blend operation (see 4.). Blend factor are defined by the
|
diffuse/specular/ambient/emissive base color) using
|
||||||
|
a blend operation (see 4.). Blend factor are defined by the
|
||||||
<i>AI_MATKEY_TEXBLEND_<textype>(<texindex>)</i> material property. Assume 1.0f as default value
|
<i>AI_MATKEY_TEXBLEND_<textype>(<texindex>)</i> material property. Assume 1.0f as default value
|
||||||
if this property is not set.
|
if this property is not set.
|
||||||
<br>
|
<br>
|
||||||
<b>4. A blend operation.</b> This is used if multiple textures are assigned to a slot, e.g. two
|
<b>4. A blend operation.</b> This is used if multiple textures are assigned to a slot, e.g. two
|
||||||
or more textures on the diffuse channel. After a texture's color value has been multiplied
|
or more textures on the diffuse channel. After a texture's color value has been multiplied
|
||||||
with its blend factor, the blend operation is used to combine it with the previous color value.
|
with its blend factor, the blend operation is used to combine it with the previous color value
|
||||||
|
(from the last texture or the diffuse/specular/ambient/emissive base color).
|
||||||
Blend operations are stored as integer property, however their type is aiTextureOp.
|
Blend operations are stored as integer property, however their type is aiTextureOp.
|
||||||
Blend factor are defined by the <i>AI_TEXOP_BLEND_<textype>(<texindex>)</i> material property. Assume
|
Blend factor are defined by the <i>AI_TEXOP_BLEND_<textype>(<texindex>)</i> material property. Assume
|
||||||
aiTextureOp_Multiply as default value if this property is not set. The blend operation for
|
aiTextureOp_Multiply as default value if this property is not set.
|
||||||
the first texture in a texture slot (e.g. diffuse 0) specifies how the diffuse base color/
|
|
||||||
vertex color have to be combined with the texture color value.
|
|
||||||
<br>
|
<br>
|
||||||
|
<b>5. Mapping modes for all axes </b> The mapping mode for an axis specifies how the rendering
|
||||||
|
system should deal with UV coordinates beyond the 0-1 range. Mapping modes are
|
||||||
|
defined by the <i>AI_MATKEY_MAPPINGMODE_<axis>_<textype>(<texindex>)</i> material property.
|
||||||
|
<axis> is either U,V or W. The data type is int, however the real type is aiTextureMapMode.
|
||||||
|
The default value is aiTextureMapMode_Wrap.
|
||||||
|
|
||||||
You can use the aiGetMaterialTexture() function to read all texture parameters at once (maybe
|
You can use the aiGetMaterialTexture() function to read all texture parameters at once (maybe
|
||||||
if you're too lazy to read 4 or 5 values manually if there's a smart helper function
|
if you're too lazy to read 4 or 5 values manually if there's a smart helper function
|
||||||
|
@ -612,13 +617,15 @@ doing all the work for you ...).
|
||||||
|
|
||||||
@code
|
@code
|
||||||
if (AI_SUCCESS != aiGetMaterialTexture(
|
if (AI_SUCCESS != aiGetMaterialTexture(
|
||||||
pcMat, // Material object
|
pcMat, // aiMaterial structure
|
||||||
0, // first texture in the diffuse slot
|
0, // we want the first diffuse texture
|
||||||
AI_TEXTYPE_DIFFUSE, // purpose of texture is diffuse
|
AI_TEXTYPE_DIFFUSE, // we want the first diffuse texture
|
||||||
&path, // receives the path of the texture
|
&path, // receives the path of the texture
|
||||||
&uv, // receives the UV index of the texture
|
&uv, // receives the UV index of the texture
|
||||||
&blend, // receives the blend factor of the texture
|
&blend, // receives the blend factor of the texture
|
||||||
&op, // receives the blend operation of the texture
|
&op, // receives the blend operation of the texture
|
||||||
|
&mmodes, // receives an array of three aiMappingMode's, each specifying
|
||||||
|
// the mapping mode for a particular axis. Order: UV(W)
|
||||||
// (you may also specify 0 for a parameter if you don't need it)
|
// (you may also specify 0 for a parameter if you don't need it)
|
||||||
))
|
))
|
||||||
{
|
{
|
||||||
|
@ -626,6 +633,17 @@ if (AI_SUCCESS != aiGetMaterialTexture(
|
||||||
}
|
}
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
|
<br>
|
||||||
|
As you can see, there's much undefined and subject to speculations. When implementing
|
||||||
|
ASSIMP's material system the most important point was to keep it as flexible as possible.
|
||||||
|
The first step you should do when you implement ASSIMP materials into your application is
|
||||||
|
to make a list of all material properties your rendering engine supports, too. Then I suggest
|
||||||
|
you to take a look at the remaining material properties: many of them can be simplified and replaced
|
||||||
|
with other properties, e.g. a diffuse texture blend factor can often be premultiplied
|
||||||
|
with the diffuse base color! At last a few properties you do not support will remain. Forget them.
|
||||||
|
Most models won't look worse if only small details of its material cannot be rendered as it was intended
|
||||||
|
by the artist.
|
||||||
|
|
||||||
@section bones Bones
|
@section bones Bones
|
||||||
|
|
||||||
A mesh may have a set of bones in the form of aiBone structures.. Bones are a means to deform a mesh
|
A mesh may have a set of bones in the form of aiBone structures.. Bones are a means to deform a mesh
|
||||||
|
|
|
@ -27,7 +27,7 @@ namespace Assimp
|
||||||
* implementation for IOSystem that creates instances of your custom IO class.
|
* implementation for IOSystem that creates instances of your custom IO class.
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
class IOStream
|
class ASSIMP_API IOStream
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
/** Constructor protected, use IOSystem::Open() to create an instance. */
|
/** Constructor protected, use IOSystem::Open() to create an instance. */
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "aiDefines.h"
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -23,7 +25,7 @@ class IOStream;
|
||||||
* to the importer library. If you implement this interface, you also want to
|
* to the importer library. If you implement this interface, you also want to
|
||||||
* supply a custom implementation for IOStream.
|
* supply a custom implementation for IOStream.
|
||||||
*/
|
*/
|
||||||
class IOSystem
|
class ASSIMP_API IOSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/** Constructor. Create an instance of your derived class and assign it to
|
/** Constructor. Create an instance of your derived class and assign it to
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace Assimp
|
||||||
/** @class LogStream
|
/** @class LogStream
|
||||||
* @brief Abstract interface for log stream implementations.
|
* @brief Abstract interface for log stream implementations.
|
||||||
*/
|
*/
|
||||||
class LogStream
|
class ASSIMP_API LogStream
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
/** @brief Default constructor */
|
/** @brief Default constructor */
|
||||||
|
|
|
@ -1,7 +1,48 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef AI_LOGGER_H_INC
|
#ifndef AI_LOGGER_H_INC
|
||||||
#define AI_LOGGER_H_INC
|
#define AI_LOGGER_H_INC
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include "aiDefines.h"
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp
|
||||||
{
|
{
|
||||||
|
@ -12,7 +53,7 @@ class LogStream;
|
||||||
/** @class Logger
|
/** @class Logger
|
||||||
* @brief Abstract interface for logger implementations.
|
* @brief Abstract interface for logger implementations.
|
||||||
*/
|
*/
|
||||||
class Logger
|
class ASSIMP_API Logger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/** @enum LogSeverity
|
/** @enum LogSeverity
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
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.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AI_DEFINES_H_INC
|
||||||
|
#define AI_DEFINES_H_INC
|
||||||
|
|
||||||
|
// compiler specific includes and definitions
|
||||||
|
#if (defined _MSC_VER)
|
||||||
|
|
||||||
|
// include stdint.h from the C98 standard
|
||||||
|
# include "Compiler/VisualStudio/stdint.h"
|
||||||
|
|
||||||
|
# undef ASSIMP_API
|
||||||
|
|
||||||
|
// ************************************************************
|
||||||
|
// Define ASSIMP_BUILD_DLL_EXPORT to build a DLL of the library
|
||||||
|
// ************************************************************
|
||||||
|
# if (defined ASSIMP_BUILD_DLL_EXPORT)
|
||||||
|
# define ASSIMP_API __declspec(dllexport)
|
||||||
|
|
||||||
|
// ************************************************************
|
||||||
|
// Define ASSIMP_DLL before including Assimp to use ASSIMP in
|
||||||
|
// an external DLL (otherwise a static library is used)
|
||||||
|
// ************************************************************
|
||||||
|
# elif (defined ASSIMP_DLL)
|
||||||
|
# define ASSIMP_API __declspec(dllimport)
|
||||||
|
# else
|
||||||
|
# define ASSIMP_API
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#endif // (defined _MSC_VER)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
# define C_STRUCT
|
||||||
|
#else
|
||||||
|
// ************************************************************
|
||||||
|
// To build the documentation, make sure ASSIMP_DOXYGEN_BUILD
|
||||||
|
// is defined by Doxygen's preprocessor. The corresponding
|
||||||
|
// entries in the DoxyFile look like this:
|
||||||
|
#if 0
|
||||||
|
ENABLE_PREPROCESSING = YES
|
||||||
|
MACRO_EXPANSION = YES
|
||||||
|
EXPAND_ONLY_PREDEF = YES
|
||||||
|
SEARCH_INCLUDES = YES
|
||||||
|
INCLUDE_PATH =
|
||||||
|
INCLUDE_FILE_PATTERNS =
|
||||||
|
PREDEFINED = ASSIMP_DOXYGEN_BUILD=1
|
||||||
|
EXPAND_AS_DEFINED = C_STRUCT
|
||||||
|
SKIP_FUNCTION_MACROS = YES
|
||||||
|
#endif
|
||||||
|
// ************************************************************
|
||||||
|
# if (defined ASSIMP_DOXYGEN_BUILD)
|
||||||
|
# define C_STRUCT
|
||||||
|
# else
|
||||||
|
# define C_STRUCT struct
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // !! AI_DEFINES_H_INC
|
|
@ -52,6 +52,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Default material name
|
||||||
|
#define AI_DEFAULT_MATERIAL_NAME "aiDefaultMat"
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Defines type identifiers for use within the material system.
|
/** Defines type identifiers for use within the material system.
|
||||||
*
|
*
|
||||||
|
@ -235,6 +238,18 @@ struct aiMaterialProperty
|
||||||
char* mData;
|
char* mData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // need to end extern C block to allow template member functions
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define AI_TEXTYPE_OPACITY 0x0
|
||||||
|
#define AI_TEXTYPE_SPECULAR 0x1
|
||||||
|
#define AI_TEXTYPE_AMBIENT 0x2
|
||||||
|
#define AI_TEXTYPE_EMISSIVE 0x3
|
||||||
|
#define AI_TEXTYPE_HEIGHT 0x4
|
||||||
|
#define AI_TEXTYPE_NORMALS 0x5
|
||||||
|
#define AI_TEXTYPE_SHININESS 0x6
|
||||||
|
#define AI_TEXTYPE_DIFFUSE 0x7
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Data structure for a material
|
/** Data structure for a material
|
||||||
|
@ -245,13 +260,67 @@ struct aiMaterialProperty
|
||||||
* enough for nearly all purposes.
|
* enough for nearly all purposes.
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
struct aiMaterial
|
struct ASSIMP_API aiMaterial
|
||||||
{
|
{
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
protected:
|
protected:
|
||||||
aiMaterial() {}
|
aiMaterial() {}
|
||||||
public:
|
public:
|
||||||
#endif // __cplusplus
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Retrieve an array of Type values with a specific key
|
||||||
|
* from the material
|
||||||
|
*
|
||||||
|
* @param pKey Key to search for. One of the AI_MATKEY_XXX constants.
|
||||||
|
* @param pOut Pointer to a buffer to receive the result.
|
||||||
|
* @param pMax Specifies the size of the given buffer, in Type's.
|
||||||
|
* Receives the number of values (not bytes!) read.
|
||||||
|
* NULL is a valid value for this parameter.
|
||||||
|
*/
|
||||||
|
template <typename Type>
|
||||||
|
inline aiReturn Get(const char* pKey,Type* pOut,
|
||||||
|
unsigned int* pMax);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Retrieve a Type value with a specific key
|
||||||
|
* from the material
|
||||||
|
*
|
||||||
|
* @param pKey Key to search for. One of the AI_MATKEY_XXX constants.
|
||||||
|
* @param pOut Reference to receive the output value
|
||||||
|
*/
|
||||||
|
template <typename Type>
|
||||||
|
inline aiReturn Get(const char* pKey,Type& pOut);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Helper function to get a texture from a material
|
||||||
|
*
|
||||||
|
* This function is provided just for convinience.
|
||||||
|
* @param iIndex Index of the texture to retrieve. If the index is too
|
||||||
|
* large the function fails.
|
||||||
|
* @param iTexType One of the AI_TEXTYPE constants. Specifies the type of
|
||||||
|
* the texture to retrieve (e.g. diffuse, specular, height map ...)
|
||||||
|
* @param szPath Receives the output path
|
||||||
|
* NULL is no allowed as value
|
||||||
|
* @param piUVIndex Receives the UV index of the texture.
|
||||||
|
* NULL is allowed as value.
|
||||||
|
* @param pfBlendFactor Receives the blend factor for the texture
|
||||||
|
* NULL is allowed as value.
|
||||||
|
* @param peTextureOp Receives the texture operation to perform between
|
||||||
|
* this texture and the previous texture. NULL is allowed as value.
|
||||||
|
* @param peMapMode Receives the mapping modes to be used for the texture.
|
||||||
|
* The parameter may be NULL but if it is a valid pointer it MUST
|
||||||
|
* point to an array of 3 aiTextureMapMode variables (one for each
|
||||||
|
* axis: UVW order (=XYZ)).
|
||||||
|
*/
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
inline aiReturn GetTexture(unsigned int iIndex,
|
||||||
|
unsigned int iTexType,
|
||||||
|
C_STRUCT aiString* szPath,
|
||||||
|
unsigned int* piUVIndex = NULL,
|
||||||
|
float* pfBlendFactor = NULL,
|
||||||
|
aiTextureOp* peTextureOp = NULL,
|
||||||
|
aiTextureMapMode* peMapMode = NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
/** List of all material properties loaded.
|
/** List of all material properties loaded.
|
||||||
*/
|
*/
|
||||||
|
@ -263,6 +332,11 @@ public:
|
||||||
unsigned int mNumAllocated;
|
unsigned int mNumAllocated;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** @def AI_BUILD_KEY
|
/** @def AI_BUILD_KEY
|
||||||
* Builds a material texture key with a dynamic index.
|
* Builds a material texture key with a dynamic index.
|
||||||
|
@ -300,13 +374,27 @@ public:
|
||||||
* @param out Array of chars to receive the output value. It must be
|
* @param out Array of chars to receive the output value. It must be
|
||||||
* sufficiently large. This will be checked via a static assertion for
|
* sufficiently large. This will be checked via a static assertion for
|
||||||
* C++0x. For MSVC8 and later versions the security enhanced version of
|
* C++0x. For MSVC8 and later versions the security enhanced version of
|
||||||
* sprintf() will be used. However, if your buffer is at least 512 bytes
|
* sprintf() will be used. However, if your buffer is at least 256 bytes
|
||||||
* long you'll never overrun.
|
* long you'll never overrun.
|
||||||
*/
|
*/
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
#if _MSC_VER >= 1400
|
#if _MSC_VER >= 1400
|
||||||
|
|
||||||
|
// MSVC 8+. Use the sprintf_s function with security enhancements
|
||||||
# define AI_BUILD_KEY(base,index,out) \
|
# define AI_BUILD_KEY(base,index,out) \
|
||||||
::sprintf_s(out,"%s[%i]",base,index);
|
::sprintf_s(out,"%s[%i]",base,index);
|
||||||
|
|
||||||
|
#elif (defined ASSIMP_BUILD_CPP_09)
|
||||||
|
|
||||||
|
// C++09 compiler. Use a static assertion to validate the size
|
||||||
|
// of the output buffer
|
||||||
|
# define AI_BUILD_KEY(base,index,out) \
|
||||||
|
static_assert(sizeof(out) >= 180,"Output buffer is too small"); \
|
||||||
|
::sprintf(out,"%s[%i]",base,index);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
// otherwise ... simply hope the buffer is large enough :-)
|
||||||
# define AI_BUILD_KEY(base,index,out) \
|
# define AI_BUILD_KEY(base,index,out) \
|
||||||
::sprintf(out,"%s[%i]",base,index);
|
::sprintf(out,"%s[%i]",base,index);
|
||||||
#endif
|
#endif
|
||||||
|
@ -416,7 +504,7 @@ public:
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** @def AI_MATKEY_TEXTURE_DIFFUSE
|
/** @def AI_MATKEY_TEXTURE_DIFFUSE
|
||||||
* Defines a specified diffuse texture channel of the material
|
* Defines a specific diffuse texture channel of the material
|
||||||
* <br>
|
* <br>
|
||||||
* <b>Type:</b> string (aiString)<br>
|
* <b>Type:</b> string (aiString)<br>
|
||||||
* <b>Default value:</b> none <br>
|
* <b>Default value:</b> none <br>
|
||||||
|
@ -429,7 +517,7 @@ public:
|
||||||
#define AI_MATKEY_TEXTURE_DIFFUSE_ "$tex.file.diffuse"
|
#define AI_MATKEY_TEXTURE_DIFFUSE_ "$tex.file.diffuse"
|
||||||
|
|
||||||
/** @def AI_MATKEY_TEXTURE_AMBIENT
|
/** @def AI_MATKEY_TEXTURE_AMBIENT
|
||||||
* Defines a specified ambient texture channel of the material
|
* Defines a specific ambient texture channel of the material
|
||||||
* <br>
|
* <br>
|
||||||
* <b>Type:</b> string (aiString)<br>
|
* <b>Type:</b> string (aiString)<br>
|
||||||
* <b>Default value:</b> none <br>
|
* <b>Default value:</b> none <br>
|
||||||
|
@ -442,7 +530,7 @@ public:
|
||||||
#define AI_MATKEY_TEXTURE_AMBIENT_ "$tex.file.ambient"
|
#define AI_MATKEY_TEXTURE_AMBIENT_ "$tex.file.ambient"
|
||||||
|
|
||||||
/** @def AI_MATKEY_TEXTURE_SPECULAR
|
/** @def AI_MATKEY_TEXTURE_SPECULAR
|
||||||
* Defines a specified specular texture channel of the material
|
* Defines a specific specular texture channel of the material
|
||||||
* <br>
|
* <br>
|
||||||
* <b>Type:</b> string (aiString)<br>
|
* <b>Type:</b> string (aiString)<br>
|
||||||
* <b>Default value:</b> none <br>
|
* <b>Default value:</b> none <br>
|
||||||
|
@ -455,7 +543,7 @@ public:
|
||||||
#define AI_MATKEY_TEXTURE_SPECULAR_ "$tex.file.specular"
|
#define AI_MATKEY_TEXTURE_SPECULAR_ "$tex.file.specular"
|
||||||
|
|
||||||
/** @def AI_MATKEY_TEXTURE_EMISSIVE
|
/** @def AI_MATKEY_TEXTURE_EMISSIVE
|
||||||
* Defines a specified emissive texture channel of the material
|
* Defines a specific emissive texture channel of the material
|
||||||
* <br>
|
* <br>
|
||||||
* <b>Type:</b> string (aiString)<br>
|
* <b>Type:</b> string (aiString)<br>
|
||||||
* <b>Default value:</b> none <br>
|
* <b>Default value:</b> none <br>
|
||||||
|
@ -468,7 +556,7 @@ public:
|
||||||
#define AI_MATKEY_TEXTURE_EMISSIVE_ "$tex.file.emissive"
|
#define AI_MATKEY_TEXTURE_EMISSIVE_ "$tex.file.emissive"
|
||||||
|
|
||||||
/** @def AI_MATKEY_TEXTURE_NORMALS
|
/** @def AI_MATKEY_TEXTURE_NORMALS
|
||||||
* Defines a specified normal texture channel of the material
|
* Defines a specific normal texture channel of the material
|
||||||
* <br>
|
* <br>
|
||||||
* <b>Type:</b> string (aiString)<br>
|
* <b>Type:</b> string (aiString)<br>
|
||||||
* <b>Default value:</b> none <br>
|
* <b>Default value:</b> none <br>
|
||||||
|
@ -498,7 +586,7 @@ public:
|
||||||
#define AI_MATKEY_TEXTURE_HEIGHT_ "$tex.file.height"
|
#define AI_MATKEY_TEXTURE_HEIGHT_ "$tex.file.height"
|
||||||
|
|
||||||
/** @def AI_MATKEY_TEXTURE_SHININESS
|
/** @def AI_MATKEY_TEXTURE_SHININESS
|
||||||
* Defines a specified shininess texture channel of the material
|
* Defines a specific shininess texture channel of the material
|
||||||
* <br>
|
* <br>
|
||||||
* <b>Type:</b> string (aiString)<br>
|
* <b>Type:</b> string (aiString)<br>
|
||||||
* <b>Default value:</b> none <br>
|
* <b>Default value:</b> none <br>
|
||||||
|
@ -511,7 +599,7 @@ public:
|
||||||
#define AI_MATKEY_TEXTURE_SHININESS_ "$tex.file.shininess"
|
#define AI_MATKEY_TEXTURE_SHININESS_ "$tex.file.shininess"
|
||||||
|
|
||||||
/** @def AI_MATKEY_TEXTURE_OPACITY
|
/** @def AI_MATKEY_TEXTURE_OPACITY
|
||||||
* Defines a specified opacity texture channel of the material
|
* Defines a specific opacity texture channel of the material
|
||||||
* <br>
|
* <br>
|
||||||
* <b>Type:</b> string (aiString)<br>
|
* <b>Type:</b> string (aiString)<br>
|
||||||
* <b>Default value:</b> none <br>
|
* <b>Default value:</b> none <br>
|
||||||
|
@ -772,7 +860,7 @@ public:
|
||||||
* structure or NULL if the key has not been found.
|
* structure or NULL if the key has not been found.
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
aiReturn aiGetMaterialProperty(const C_STRUCT aiMaterial* pMat,
|
ASSIMP_API aiReturn aiGetMaterialProperty(const C_STRUCT aiMaterial* pMat,
|
||||||
const char* pKey,
|
const char* pKey,
|
||||||
const C_STRUCT aiMaterialProperty** pPropOut);
|
const C_STRUCT aiMaterialProperty** pPropOut);
|
||||||
|
|
||||||
|
@ -788,7 +876,7 @@ aiReturn aiGetMaterialProperty(const C_STRUCT aiMaterial* pMat,
|
||||||
* Receives the number of values (not bytes!) read.
|
* Receives the number of values (not bytes!) read.
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
aiReturn aiGetMaterialFloatArray(const C_STRUCT aiMaterial* pMat,
|
ASSIMP_API aiReturn aiGetMaterialFloatArray(const C_STRUCT aiMaterial* pMat,
|
||||||
const char* pKey,
|
const char* pKey,
|
||||||
float* pOut,
|
float* pOut,
|
||||||
unsigned int* pMax);
|
unsigned int* pMax);
|
||||||
|
@ -817,7 +905,7 @@ inline aiReturn aiGetMaterialFloat(const C_STRUCT aiMaterial* pMat,
|
||||||
* Receives the number of values (not bytes!) read.
|
* Receives the number of values (not bytes!) read.
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
aiReturn aiGetMaterialIntegerArray(const C_STRUCT aiMaterial* pMat,
|
ASSIMP_API aiReturn aiGetMaterialIntegerArray(const C_STRUCT aiMaterial* pMat,
|
||||||
const char* pKey,
|
const char* pKey,
|
||||||
int* pOut,
|
int* pOut,
|
||||||
unsigned int* pMax);
|
unsigned int* pMax);
|
||||||
|
@ -844,7 +932,7 @@ inline aiReturn aiGetMaterialInteger(const C_STRUCT aiMaterial* pMat,
|
||||||
* @param pOut Pointer to a buffer to receive the result.
|
* @param pOut Pointer to a buffer to receive the result.
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
aiReturn aiGetMaterialColor(const C_STRUCT aiMaterial* pMat,
|
ASSIMP_API aiReturn aiGetMaterialColor(const C_STRUCT aiMaterial* pMat,
|
||||||
const char* pKey,
|
const char* pKey,
|
||||||
aiColor4D* pOut);
|
aiColor4D* pOut);
|
||||||
|
|
||||||
|
@ -857,20 +945,11 @@ aiReturn aiGetMaterialColor(const C_STRUCT aiMaterial* pMat,
|
||||||
* @param pOut Pointer to a buffer to receive the result.
|
* @param pOut Pointer to a buffer to receive the result.
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
aiReturn aiGetMaterialString(const C_STRUCT aiMaterial* pMat,
|
ASSIMP_API aiReturn aiGetMaterialString(const C_STRUCT aiMaterial* pMat,
|
||||||
const char* pKey,
|
const char* pKey,
|
||||||
aiString* pOut);
|
aiString* pOut);
|
||||||
|
|
||||||
|
|
||||||
#define AI_TEXTYPE_OPACITY 0x0
|
|
||||||
#define AI_TEXTYPE_SPECULAR 0x1
|
|
||||||
#define AI_TEXTYPE_AMBIENT 0x2
|
|
||||||
#define AI_TEXTYPE_EMISSIVE 0x3
|
|
||||||
#define AI_TEXTYPE_HEIGHT 0x4
|
|
||||||
#define AI_TEXTYPE_NORMALS 0x5
|
|
||||||
#define AI_TEXTYPE_SHININESS 0x6
|
|
||||||
#define AI_TEXTYPE_DIFFUSE 0x7
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Helper function to get a texture from a material
|
/** Helper function to get a texture from a material
|
||||||
*
|
*
|
||||||
|
@ -895,7 +974,7 @@ aiReturn aiGetMaterialString(const C_STRUCT aiMaterial* pMat,
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* pMat,
|
ASSIMP_API aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* pMat,
|
||||||
unsigned int iIndex,
|
unsigned int iIndex,
|
||||||
unsigned int iTexType,
|
unsigned int iTexType,
|
||||||
C_STRUCT aiString* szPath,
|
C_STRUCT aiString* szPath,
|
||||||
|
@ -920,5 +999,4 @@ aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* pMat,
|
||||||
#include "aiMaterial.inl"
|
#include "aiMaterial.inl"
|
||||||
|
|
||||||
#endif //!__cplusplus
|
#endif //!__cplusplus
|
||||||
|
|
||||||
#endif //!!AI_MATERIAL_H_INC
|
#endif //!!AI_MATERIAL_H_INC
|
||||||
|
|
|
@ -46,46 +46,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef AI_MATERIAL_INL_INC
|
#ifndef AI_MATERIAL_INL_INC
|
||||||
#define AI_MATERIAL_INL_INC
|
#define AI_MATERIAL_INL_INC
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** @brief A class that provides easy access to the property list of a
|
inline aiReturn aiMaterial::GetTexture(unsigned int iIndex,
|
||||||
* material (aiMaterial) via template methods. You can cast an
|
unsigned int iTexType,
|
||||||
* aiMaterial* to aiMaterialCPP*
|
aiString* szPath,
|
||||||
* @note This extra class is necessary since template methods
|
unsigned int* piUVIndex ,
|
||||||
* are not allowed within C-linkage blocks (extern "C")
|
float* pfBlendFactor ,
|
||||||
*/
|
aiTextureOp* peTextureOp ,
|
||||||
class aiMaterialCPP : public aiMaterial
|
aiTextureMapMode* peMapMode )
|
||||||
{
|
{
|
||||||
public:
|
return aiGetMaterialTexture(this,iIndex,iTexType,szPath,
|
||||||
|
piUVIndex,pfBlendFactor,peTextureOp,peMapMode);
|
||||||
// -------------------------------------------------------------------
|
}
|
||||||
/** Retrieve an array of Type values with a specific key
|
|
||||||
* from the material
|
|
||||||
*
|
|
||||||
* @param pKey Key to search for. One of the AI_MATKEY_XXX constants.
|
|
||||||
* @param pOut Pointer to a buffer to receive the result.
|
|
||||||
* @param pMax Specifies the size of the given buffer, in Type's.
|
|
||||||
* Receives the number of values (not bytes!) read.
|
|
||||||
* NULL is a valid value for this parameter.
|
|
||||||
*/
|
|
||||||
template <typename Type>
|
|
||||||
inline aiReturn Get(const char* pKey,Type* pOut,
|
|
||||||
unsigned int* pMax);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** Retrieve a Type value with a specific key
|
|
||||||
* from the material
|
|
||||||
*
|
|
||||||
* @param pKey Key to search for. One of the AI_MATKEY_XXX constants.
|
|
||||||
* @param pOut Reference to receive the output value
|
|
||||||
*/
|
|
||||||
template <typename Type>
|
|
||||||
inline aiReturn Get(const char* pKey,Type& pOut);
|
|
||||||
};
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
inline aiReturn aiMaterialCPP::Get(const char* pKey,Type* pOut,
|
inline aiReturn aiMaterial::Get(const char* pKey,Type* pOut,
|
||||||
unsigned int* pMax)
|
unsigned int* pMax)
|
||||||
{
|
{
|
||||||
unsigned int iNum = pMax ? *pMax : 1;
|
unsigned int iNum = pMax ? *pMax : 1;
|
||||||
|
@ -105,7 +80,7 @@ inline aiReturn aiMaterialCPP::Get(const char* pKey,Type* pOut,
|
||||||
}
|
}
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
inline aiReturn aiMaterialCPP::Get(const char* pKey,Type& pOut)
|
inline aiReturn aiMaterial::Get(const char* pKey,Type& pOut)
|
||||||
{
|
{
|
||||||
aiMaterialProperty* prop;
|
aiMaterialProperty* prop;
|
||||||
aiReturn ret = aiGetMaterialProperty(this,pKey,&prop);
|
aiReturn ret = aiGetMaterialProperty(this,pKey,&prop);
|
||||||
|
@ -120,39 +95,39 @@ inline aiReturn aiMaterialCPP::Get(const char* pKey,Type& pOut)
|
||||||
}
|
}
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
template <>
|
template <>
|
||||||
inline aiReturn aiMaterialCPP::Get<float>(const char* pKey,float* pOut,
|
inline aiReturn aiMaterial::Get<float>(const char* pKey,float* pOut,
|
||||||
unsigned int* pMax)
|
unsigned int* pMax)
|
||||||
{
|
{
|
||||||
return aiGetMaterialFloatArray(this,pKey,pOut,pMax);
|
return aiGetMaterialFloatArray(this,pKey,pOut,pMax);
|
||||||
}
|
}
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
template <>
|
template <>
|
||||||
inline aiReturn aiMaterialCPP::Get<int>(const char* pKey,int* pOut,
|
inline aiReturn aiMaterial::Get<int>(const char* pKey,int* pOut,
|
||||||
unsigned int* pMax)
|
unsigned int* pMax)
|
||||||
{
|
{
|
||||||
return aiGetMaterialIntegerArray(this,pKey,pOut,pMax);
|
return aiGetMaterialIntegerArray(this,pKey,pOut,pMax);
|
||||||
}
|
}
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
template <>
|
template <>
|
||||||
inline aiReturn aiMaterialCPP::Get<float>(const char* pKey,float& pOut)
|
inline aiReturn aiMaterial::Get<float>(const char* pKey,float& pOut)
|
||||||
{
|
{
|
||||||
return aiGetMaterialFloat(this,pKey,&pOut);
|
return aiGetMaterialFloat(this,pKey,&pOut);
|
||||||
}
|
}
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
template <>
|
template <>
|
||||||
inline aiReturn aiMaterialCPP::Get<int>(const char* pKey,int& pOut)
|
inline aiReturn aiMaterial::Get<int>(const char* pKey,int& pOut)
|
||||||
{
|
{
|
||||||
return aiGetMaterialInteger(this,pKey,&pOut);
|
return aiGetMaterialInteger(this,pKey,&pOut);
|
||||||
}
|
}
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
template <>
|
template <>
|
||||||
inline aiReturn aiMaterialCPP::Get<aiColor4D>(const char* pKey,aiColor4D& pOut)
|
inline aiReturn aiMaterial::Get<aiColor4D>(const char* pKey,aiColor4D& pOut)
|
||||||
{
|
{
|
||||||
return aiGetMaterialColor(this,pKey,&pOut);
|
return aiGetMaterialColor(this,pKey,&pOut);
|
||||||
}
|
}
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
template <>
|
template <>
|
||||||
inline aiReturn aiMaterialCPP::Get<aiString>(const char* pKey,aiString& pOut)
|
inline aiReturn aiMaterial::Get<aiString>(const char* pKey,aiString& pOut)
|
||||||
{
|
{
|
||||||
return aiGetMaterialString(this,pKey,&pOut);
|
return aiGetMaterialString(this,pKey,&pOut);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ extern "C" {
|
||||||
struct aiMatrix4x4;
|
struct aiMatrix4x4;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Represents a column-major 3x3 matrix
|
/** Represents a row-major 3x3 matrix
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
struct aiMatrix3x3
|
struct aiMatrix3x3
|
||||||
|
@ -28,7 +28,8 @@ struct aiMatrix3x3
|
||||||
c1(_c1), c2(_c2), c3(_c3)
|
c1(_c1), c2(_c2), c3(_c3)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/** Construction from a 4x4 matrix. The remaining parts of the matrix are ignored. */
|
/** Construction from a 4x4 matrix. The remaining parts of the
|
||||||
|
matrix are ignored. */
|
||||||
explicit aiMatrix3x3( const aiMatrix4x4& pMatrix);
|
explicit aiMatrix3x3( const aiMatrix4x4& pMatrix);
|
||||||
|
|
||||||
aiMatrix3x3& operator *= (const aiMatrix3x3& m);
|
aiMatrix3x3& operator *= (const aiMatrix3x3& m);
|
||||||
|
|
|
@ -50,5 +50,6 @@ inline aiMatrix3x3& aiMatrix3x3::Transpose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
#endif // AI_MATRIX3x3_INL_INC
|
#endif // AI_MATRIX3x3_INL_INC
|
|
@ -7,6 +7,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct aiMatrix3x3;
|
struct aiMatrix3x3;
|
||||||
|
struct aiQuaternion;
|
||||||
|
|
||||||
// Set packing to 4
|
// Set packing to 4
|
||||||
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
|
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
|
||||||
|
@ -19,7 +20,7 @@ struct aiMatrix3x3;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Represents a column-major 4x4 matrix,
|
/** Represents a row-major 4x4 matrix,
|
||||||
* use this for homogenious coordinates
|
* use this for homogenious coordinates
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -57,6 +58,35 @@ struct aiMatrix4x4
|
||||||
inline bool operator== (const aiMatrix4x4 m) const;
|
inline bool operator== (const aiMatrix4x4 m) const;
|
||||||
inline bool operator!= (const aiMatrix4x4 m) const;
|
inline bool operator!= (const aiMatrix4x4 m) const;
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Decompose a trafo matrix into its original components
|
||||||
|
* \param scaling Receives the output scaling for the x,y,z axes
|
||||||
|
* \param rotation Receives the output rotation as a hamilton
|
||||||
|
* quaternion
|
||||||
|
* \param position Receives the output position for the x,y,z axes
|
||||||
|
*/
|
||||||
|
inline void Decompose (aiVector3D& scaling, aiQuaternion& rotation,
|
||||||
|
aiVector3D& position) const;
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Decompose a trafo matrix with no scaling into its
|
||||||
|
* original components
|
||||||
|
* \param rotation Receives the output rotation as a hamilton
|
||||||
|
* quaternion
|
||||||
|
* \param position Receives the output position for the x,y,z axes
|
||||||
|
*/
|
||||||
|
inline void DecomposeNoScaling (aiQuaternion& rotation,
|
||||||
|
aiVector3D& position) const;
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Creates a trafo matrix from a set of euler angles
|
||||||
|
* \param x Rotation angle for the x-axis, in radians
|
||||||
|
* \param y Rotation angle for the y-axis, in radians
|
||||||
|
* \param z Rotation angle for the z-axis, in radians
|
||||||
|
*/
|
||||||
|
inline void FromEulerAngles(float x, float y, float z);
|
||||||
|
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
float a1, a2, a3, a4;
|
float a1, a2, a3, a4;
|
||||||
|
|
|
@ -11,6 +11,9 @@
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "aiAssert.h"
|
||||||
|
#include "aiQuaternion.h"
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
inline aiMatrix4x4::aiMatrix4x4( const aiMatrix3x3& m)
|
inline aiMatrix4x4::aiMatrix4x4( const aiMatrix3x3& m)
|
||||||
{
|
{
|
||||||
|
@ -144,6 +147,96 @@ inline bool aiMatrix4x4::operator!= (const aiMatrix4x4 m) const
|
||||||
{
|
{
|
||||||
return !(*this == m);
|
return !(*this == m);
|
||||||
}
|
}
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
inline void aiMatrix4x4::Decompose (aiVector3D& scaling, aiQuaternion& rotation,
|
||||||
|
aiVector3D& position) const
|
||||||
|
{
|
||||||
|
const aiMatrix4x4& _this = *this;
|
||||||
|
|
||||||
|
// extract translation
|
||||||
|
position.x = _this[0][3];
|
||||||
|
position.y = _this[1][3];
|
||||||
|
position.z = _this[2][3];
|
||||||
|
|
||||||
|
// extract the rows of the matrix
|
||||||
|
aiVector3D vRows[3] = {
|
||||||
|
aiVector3D(_this[0][0],_this[1][1],_this[2][0]),
|
||||||
|
aiVector3D(_this[0][1],_this[1][1],_this[2][1]),
|
||||||
|
aiVector3D(_this[0][2],_this[1][2],_this[2][2])
|
||||||
|
};
|
||||||
|
|
||||||
|
// extract the scaling factors
|
||||||
|
scaling.x = vRows[0].Length();
|
||||||
|
scaling.y = vRows[1].Length();
|
||||||
|
scaling.z = vRows[2].Length();
|
||||||
|
|
||||||
|
// and remove all scaling from the matrix
|
||||||
|
if(scaling.x)
|
||||||
|
{
|
||||||
|
vRows[0].x /= scaling.x;
|
||||||
|
vRows[0].y /= scaling.x;
|
||||||
|
vRows[0].z /= scaling.x;
|
||||||
|
}
|
||||||
|
if(scaling.y)
|
||||||
|
{
|
||||||
|
vRows[1].x /= scaling.y;
|
||||||
|
vRows[1].y /= scaling.y;
|
||||||
|
vRows[1].z /= scaling.y;
|
||||||
|
}
|
||||||
|
if(scaling.z)
|
||||||
|
{
|
||||||
|
vRows[2].x /= scaling.z;
|
||||||
|
vRows[2].y /= scaling.z;
|
||||||
|
vRows[2].z /= scaling.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
// build a 3x3 rotation matrix
|
||||||
|
aiMatrix3x3 m(vRows[0].x,vRows[0].y,vRows[0].z,
|
||||||
|
vRows[1].x,vRows[1].y,vRows[1].z,
|
||||||
|
vRows[2].x,vRows[2].y,vRows[2].z);
|
||||||
|
|
||||||
|
// and generate the rotation quaternion from it
|
||||||
|
rotation = aiQuaternion(m);
|
||||||
|
}
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
inline void aiMatrix4x4::DecomposeNoScaling (aiQuaternion& rotation,
|
||||||
|
aiVector3D& position) const
|
||||||
|
{
|
||||||
|
const aiMatrix4x4& _this = *this;
|
||||||
|
|
||||||
|
// extract translation
|
||||||
|
position.x = _this[0][3];
|
||||||
|
position.y = _this[1][3];
|
||||||
|
position.z = _this[2][3];
|
||||||
|
|
||||||
|
// extract rotation
|
||||||
|
rotation = aiQuaternion((aiMatrix3x3)_this);
|
||||||
|
}
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
inline void aiMatrix4x4::FromEulerAngles(float x, float y, float z)
|
||||||
|
{
|
||||||
|
aiMatrix4x4& _this = *this;
|
||||||
|
|
||||||
|
const float A = ::cosf(x);
|
||||||
|
const float B = ::sinf(x);
|
||||||
|
const float C = ::cosf(y);
|
||||||
|
const float D = ::sinf(y);
|
||||||
|
const float E = ::cosf(z);
|
||||||
|
const float F = ::sinf(z);
|
||||||
|
const float AD = A * D;
|
||||||
|
const float BD = B * D;
|
||||||
|
_this.a1 = C * E;
|
||||||
|
_this.a2 = -C * F;
|
||||||
|
_this.a3 = D;
|
||||||
|
_this.b1 = BD * E + A * F;
|
||||||
|
_this.b2 = -BD * F + A * E;
|
||||||
|
_this.b3 = -B * C;
|
||||||
|
_this.c1 = -AD * E + B * F;
|
||||||
|
_this.c2 = AD * F + B * E;
|
||||||
|
_this.c3 = A * C;
|
||||||
|
_this.a4 = _this.b4 = _this.c4 = _this.d1 = _this.d2 = _this.d3 = 0.0f;
|
||||||
|
_this.d4 = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
#endif // AI_MATRIX4x4_INL_INC
|
#endif // AI_MATRIX4x4_INL_INC
|
||||||
|
|
|
@ -130,8 +130,10 @@ enum aiPostProcessSteps
|
||||||
* to a maximum value. If any vertex is affected by more than that number
|
* to a maximum value. If any vertex is affected by more than that number
|
||||||
* of bones, the least important vertex weights are removed and the remaining
|
* of bones, the least important vertex weights are removed and the remaining
|
||||||
* vertex weights are renormalized so that the weights still sum up to 1.
|
* vertex weights are renormalized so that the weights still sum up to 1.
|
||||||
* At the moment the maximum bone count is hardcoded to 4.
|
* The default bone weight limit is 4 (defined as AI_LMW_MAX_WEIGHTS in
|
||||||
*
|
* LimitBoneWeightsProcess.h), but you can use the aiSetBoneWeightLimit
|
||||||
|
* function to supply your own limit to the post processing step.
|
||||||
|
*
|
||||||
* If you intend to perform the skinning in hardware, this post processing step
|
* If you intend to perform the skinning in hardware, this post processing step
|
||||||
* might be of interest for you.
|
* might be of interest for you.
|
||||||
*/
|
*/
|
||||||
|
@ -156,8 +158,7 @@ enum aiPostProcessSteps
|
||||||
* \note The default value is AI_SLM_DEFAULT_MAX_VERTICES, defined in
|
* \note The default value is AI_SLM_DEFAULT_MAX_VERTICES, defined in
|
||||||
* the internal header file SplitLargeMeshes.h
|
* the internal header file SplitLargeMeshes.h
|
||||||
*/
|
*/
|
||||||
aiReturn aiSetVertexSplitLimit(unsigned int pLimit);
|
ASSIMP_API aiReturn aiSetVertexSplitLimit(unsigned int pLimit);
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** \brief Set the maximum number of triangles in a mesh.
|
/** \brief Set the maximum number of triangles in a mesh.
|
||||||
|
@ -168,7 +169,17 @@ aiReturn aiSetVertexSplitLimit(unsigned int pLimit);
|
||||||
* \note The default value is AI_SLM_DEFAULT_MAX_TRIANGLES, defined in
|
* \note The default value is AI_SLM_DEFAULT_MAX_TRIANGLES, defined in
|
||||||
* the internal header file SplitLargeMeshes.h
|
* the internal header file SplitLargeMeshes.h
|
||||||
*/
|
*/
|
||||||
aiReturn aiSetTriangleSplitLimit(unsigned int pLimit);
|
ASSIMP_API aiReturn aiSetTriangleSplitLimit(unsigned int pLimit);
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/** \brief Set the maximum number of bones affecting a single vertex
|
||||||
|
*
|
||||||
|
* This is used by the aiProcess_LimitBoneWeights PostProcess-Step.
|
||||||
|
* \param pLimit Bone limit
|
||||||
|
* \note The default value is AI_LMW_MAX_WEIGHTS, defined in
|
||||||
|
* the internal header file LimitBoneWeightsProcess.h
|
||||||
|
*/
|
||||||
|
ASSIMP_API aiReturn aiSetBoneWeightLimit(unsigned int pLimit);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // end of extern "C"
|
} // end of extern "C"
|
||||||
|
|
|
@ -16,9 +16,13 @@ struct aiQuaternion
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
aiQuaternion() : w(0.0f), x(0.0f), y(0.0f), z(0.0f) {}
|
aiQuaternion() : w(0.0f), x(0.0f), y(0.0f), z(0.0f) {}
|
||||||
aiQuaternion(float _w, float _x, float _y, float _z) : w(_w), x(_x), y(_y), z(_z) {}
|
aiQuaternion(float _w, float _x, float _y, float _z) : w(_w), x(_x), y(_y), z(_z) {}
|
||||||
|
|
||||||
/** Construct from rotation matrix. Result is undefined if the matrix is not orthonormal. */
|
/** Construct from rotation matrix. Result is undefined if the matrix is not orthonormal. */
|
||||||
aiQuaternion( const aiMatrix3x3& pRotMatrix);
|
aiQuaternion( const aiMatrix3x3& pRotMatrix);
|
||||||
|
|
||||||
|
/** Construct from euler angles */
|
||||||
|
aiQuaternion( float rotx, float roty, float rotz);
|
||||||
|
|
||||||
/** Returns a matrix representation of the quaternion */
|
/** Returns a matrix representation of the quaternion */
|
||||||
aiMatrix3x3 GetMatrix() const;
|
aiMatrix3x3 GetMatrix() const;
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
@ -73,6 +77,24 @@ inline aiQuaternion::aiQuaternion( const aiMatrix3x3 &pRotMatrix)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Construction from euler angles
|
||||||
|
inline aiQuaternion::aiQuaternion( float fPitch, float fYaw, float fRoll )
|
||||||
|
{
|
||||||
|
const float fSinPitch(sin(fPitch*0.5F));
|
||||||
|
const float fCosPitch(cos(fPitch*0.5F));
|
||||||
|
const float fSinYaw(sin(fYaw*0.5F));
|
||||||
|
const float fCosYaw(cos(fYaw*0.5F));
|
||||||
|
const float fSinRoll(sin(fRoll*0.5F));
|
||||||
|
const float fCosRoll(cos(fRoll*0.5F));
|
||||||
|
const float fCosPitchCosYaw(fCosPitch*fCosYaw);
|
||||||
|
const float fSinPitchSinYaw(fSinPitch*fSinYaw);
|
||||||
|
x = fSinRoll * fCosPitchCosYaw - fCosRoll * fSinPitchSinYaw;
|
||||||
|
y = fCosRoll * fSinPitch * fCosYaw + fSinRoll * fCosPitch * fSinYaw;
|
||||||
|
z = fCosRoll * fCosPitch * fSinYaw - fSinRoll * fSinPitch * fCosYaw;
|
||||||
|
w = fCosRoll * fCosPitchCosYaw + fSinRoll * fSinPitchSinYaw;
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Returns a matrix representation of the quaternion
|
// Returns a matrix representation of the quaternion
|
||||||
inline aiMatrix3x3 aiQuaternion::GetMatrix() const
|
inline aiMatrix3x3 aiQuaternion::GetMatrix() const
|
||||||
|
@ -91,6 +113,8 @@ inline aiMatrix3x3 aiQuaternion::GetMatrix() const
|
||||||
return resMatrix;
|
return resMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // end extern "C"
|
} // end extern "C"
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,7 @@ struct aiNode
|
||||||
/** Constructor */
|
/** Constructor */
|
||||||
aiNode()
|
aiNode()
|
||||||
{
|
{
|
||||||
|
// set all members to zero by default
|
||||||
mParent = NULL;
|
mParent = NULL;
|
||||||
mNumChildren = 0; mChildren = NULL;
|
mNumChildren = 0; mChildren = NULL;
|
||||||
mNumMeshes = 0; mMeshes = NULL;
|
mNumMeshes = 0; mMeshes = NULL;
|
||||||
|
@ -102,6 +103,7 @@ struct aiNode
|
||||||
/** Destructor */
|
/** Destructor */
|
||||||
~aiNode()
|
~aiNode()
|
||||||
{
|
{
|
||||||
|
// delete al children recursively
|
||||||
for( unsigned int a = 0; a < mNumChildren; a++)
|
for( unsigned int a = 0; a < mNumChildren; a++)
|
||||||
delete mChildren[a];
|
delete mChildren[a];
|
||||||
delete [] mChildren;
|
delete [] mChildren;
|
||||||
|
@ -127,6 +129,8 @@ struct aiScene
|
||||||
*/
|
*/
|
||||||
C_STRUCT aiNode* mRootNode;
|
C_STRUCT aiNode* mRootNode;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** The number of meshes in the scene. */
|
/** The number of meshes in the scene. */
|
||||||
unsigned int mNumMeshes;
|
unsigned int mNumMeshes;
|
||||||
|
|
||||||
|
@ -137,6 +141,8 @@ struct aiScene
|
||||||
*/
|
*/
|
||||||
C_STRUCT aiMesh** mMeshes;
|
C_STRUCT aiMesh** mMeshes;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** The number of materials in the scene. */
|
/** The number of materials in the scene. */
|
||||||
unsigned int mNumMaterials;
|
unsigned int mNumMaterials;
|
||||||
|
|
||||||
|
@ -147,6 +153,8 @@ struct aiScene
|
||||||
*/
|
*/
|
||||||
C_STRUCT aiMaterial** mMaterials;
|
C_STRUCT aiMaterial** mMaterials;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** The number of animations in the scene. */
|
/** The number of animations in the scene. */
|
||||||
unsigned int mNumAnimations;
|
unsigned int mNumAnimations;
|
||||||
|
|
||||||
|
@ -157,20 +165,25 @@ struct aiScene
|
||||||
*/
|
*/
|
||||||
C_STRUCT aiAnimation** mAnimations;
|
C_STRUCT aiAnimation** mAnimations;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** The number of textures embedded into the file */
|
/** The number of textures embedded into the file */
|
||||||
unsigned int mNumTextures;
|
unsigned int mNumTextures;
|
||||||
|
|
||||||
/** The array of embedded textures.
|
/** The array of embedded textures.
|
||||||
*
|
*
|
||||||
* Not many file formats embedd their textures into the file.
|
* Not many file formats embedd their textures into the file.
|
||||||
* Examples include Quake's MDL format (which is also used by
|
* An example is Quake's MDL format (which is also used by
|
||||||
* some GameStudio™ versions)
|
* some GameStudio™ versions)
|
||||||
*/
|
*/
|
||||||
C_STRUCT aiTexture** mTextures;
|
C_STRUCT aiTexture** mTextures;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
//! Default constructor
|
||||||
aiScene()
|
aiScene()
|
||||||
{
|
{
|
||||||
|
// set all members to zero by default
|
||||||
mRootNode = NULL;
|
mRootNode = NULL;
|
||||||
mNumMeshes = 0; mMeshes = NULL;
|
mNumMeshes = 0; mMeshes = NULL;
|
||||||
mNumMaterials = 0; mMaterials = NULL;
|
mNumMaterials = 0; mMaterials = NULL;
|
||||||
|
@ -178,8 +191,10 @@ struct aiScene
|
||||||
mNumTextures = 0; mTextures = NULL;
|
mNumTextures = 0; mTextures = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Destructor
|
||||||
~aiScene()
|
~aiScene()
|
||||||
{
|
{
|
||||||
|
// delete all subobjects recursively
|
||||||
delete mRootNode;
|
delete mRootNode;
|
||||||
for( unsigned int a = 0; a < mNumMeshes; a++)
|
for( unsigned int a = 0; a < mNumMeshes; a++)
|
||||||
delete mMeshes[a];
|
delete mMeshes[a];
|
||||||
|
|
|
@ -68,6 +68,21 @@ struct aiTexel
|
||||||
unsigned char g;
|
unsigned char g;
|
||||||
unsigned char r;
|
unsigned char r;
|
||||||
unsigned char a;
|
unsigned char a;
|
||||||
|
|
||||||
|
//! Comparison operator
|
||||||
|
bool operator== (const aiTexel& other) const
|
||||||
|
{
|
||||||
|
return b == other.b && r == other.r &&
|
||||||
|
g == other.g && a == other.a;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Negative comparison operator
|
||||||
|
bool operator!= (const aiTexel& other) const
|
||||||
|
{
|
||||||
|
return b != other.b || r != other.r ||
|
||||||
|
g != other.g || a != other.a;
|
||||||
|
}
|
||||||
|
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// reset packing to the original value
|
// reset packing to the original value
|
||||||
|
|
|
@ -45,10 +45,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
|
|
||||||
#if (defined _MSC_VER)
|
#include "aiDefines.h"
|
||||||
# include "Compiler/VisualStudio/stdint.h"
|
|
||||||
#endif // (defined _MSC_VER)
|
|
||||||
|
|
||||||
|
// include math helper classes and their implementations
|
||||||
#include "aiVector3D.h"
|
#include "aiVector3D.h"
|
||||||
#include "aiMatrix3x3.h"
|
#include "aiMatrix3x3.h"
|
||||||
#include "aiMatrix4x4.h"
|
#include "aiMatrix4x4.h"
|
||||||
|
@ -59,13 +58,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
# include <string>
|
# include <string>
|
||||||
extern "C" {
|
extern "C" {
|
||||||
# define C_STRUCT
|
|
||||||
#else
|
|
||||||
# if (defined ASSIMP_DOXYGEN_BUILD)
|
|
||||||
# define C_STRUCT
|
|
||||||
# else
|
|
||||||
# define C_STRUCT struct
|
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Maximum dimension for strings, ASSIMP strings are zero terminated */
|
/** Maximum dimension for strings, ASSIMP strings are zero terminated */
|
||||||
|
@ -145,14 +137,14 @@ struct aiString
|
||||||
inline aiString() :
|
inline aiString() :
|
||||||
length(0)
|
length(0)
|
||||||
{
|
{
|
||||||
// empty
|
data[0] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
//! construction from a given std::string
|
//! construction from a given std::string
|
||||||
inline aiString(const aiString& rOther) :
|
inline aiString(const aiString& rOther) :
|
||||||
length(rOther.length)
|
length(rOther.length)
|
||||||
{
|
{
|
||||||
memcpy( data, rOther.data, rOther.length);
|
::memcpy( data, rOther.data, rOther.length);
|
||||||
this->data[this->length] = '\0';
|
this->data[this->length] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,7 +154,7 @@ struct aiString
|
||||||
if( pString.length() > MAXLEN - 1)
|
if( pString.length() > MAXLEN - 1)
|
||||||
return;
|
return;
|
||||||
length = pString.length();
|
length = pString.length();
|
||||||
memcpy( data, pString.c_str(), length);
|
::memcpy( data, pString.c_str(), length);
|
||||||
data[length] = 0;
|
data[length] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,7 +169,7 @@ struct aiString
|
||||||
bool operator!=(const aiString& other) const
|
bool operator!=(const aiString& other) const
|
||||||
{
|
{
|
||||||
return (this->length != other.length ||
|
return (this->length != other.length ||
|
||||||
0 != strcmp(this->data,other.data));
|
0 != ::strcmp(this->data,other.data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -194,11 +186,10 @@ struct aiString
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Standard return type for all library functions.
|
/** Standard return type for all library functions.
|
||||||
*
|
*
|
||||||
* To check whether a function failed or not check against
|
* To check whether or not a function failed check against
|
||||||
* AI_SUCCESS.
|
* AI_SUCCESS. The error codes are mainly used by the C-API.
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
enum aiReturn
|
enum aiReturn
|
||||||
{
|
{
|
||||||
//! Indicates that a function was successful
|
//! Indicates that a function was successful
|
||||||
|
|
|
@ -71,7 +71,8 @@ struct aiString;
|
||||||
* @return Pointer to the imported data or NULL if the import failed.
|
* @return Pointer to the imported data or NULL if the import failed.
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
const C_STRUCT aiScene* aiImportFile( const char* pFile, unsigned int pFlags);
|
ASSIMP_API const C_STRUCT aiScene* aiImportFile( const char* pFile,
|
||||||
|
unsigned int pFlags);
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -94,8 +95,8 @@ const C_STRUCT aiScene* aiImportFile( const char* pFile, unsigned int pFlags);
|
||||||
* to this function. Therefore the C-API is thread-safe.
|
* to this function. Therefore the C-API is thread-safe.
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
const C_STRUCT aiScene* aiImportFileEx( const C_STRUCT aiFileIO* pFile);
|
ASSIMP_API const C_STRUCT aiScene* aiImportFileEx(
|
||||||
|
const C_STRUCT aiFileIO* pFile);
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -105,7 +106,7 @@ const C_STRUCT aiScene* aiImportFileEx( const C_STRUCT aiFileIO* pFile);
|
||||||
* @param pScene The imported data to release. NULL is a valid value.
|
* @param pScene The imported data to release. NULL is a valid value.
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
void aiReleaseImport( const C_STRUCT aiScene* pScene);
|
ASSIMP_API void aiReleaseImport( const C_STRUCT aiScene* pScene);
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -115,7 +116,7 @@ void aiReleaseImport( const C_STRUCT aiScene* pScene);
|
||||||
* import process. NULL if there was no error.
|
* import process. NULL if there was no error.
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
const char* aiGetErrorString();
|
ASSIMP_API const char* aiGetErrorString();
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -126,7 +127,7 @@ const char* aiGetErrorString();
|
||||||
* @return 1 if the extension is supported, 0 otherwise
|
* @return 1 if the extension is supported, 0 otherwise
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
int aiIsExtensionSupported(const char* szExtension);
|
ASSIMP_API int aiIsExtensionSupported(const char* szExtension);
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -138,7 +139,7 @@ int aiIsExtensionSupported(const char* szExtension);
|
||||||
* Format of the list: "*.3ds;*.obj;*.dae". NULL is not a valid parameter.
|
* Format of the list: "*.3ds;*.obj;*.dae". NULL is not a valid parameter.
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
void aiGetExtensionList(C_STRUCT aiString* szOut);
|
ASSIMP_API void aiGetExtensionList(C_STRUCT aiString* szOut);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "aiDefines.h"
|
||||||
|
|
||||||
struct aiScene;
|
struct aiScene;
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp
|
||||||
|
@ -81,7 +83,7 @@ class IOSystem;
|
||||||
* @note One Importer instance is not thread-safe. If you use multiple
|
* @note One Importer instance is not thread-safe. If you use multiple
|
||||||
* threads for loading each thread should manage its own Importer instance.
|
* threads for loading each thread should manage its own Importer instance.
|
||||||
*/
|
*/
|
||||||
class Importer
|
class ASSIMP_API Importer
|
||||||
{
|
{
|
||||||
// used internally
|
// used internally
|
||||||
friend class BaseProcess;
|
friend class BaseProcess;
|
||||||
|
@ -101,6 +103,7 @@ public:
|
||||||
*/
|
*/
|
||||||
~Importer();
|
~Importer();
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Supplies a custom IO handler to the importer to use to open and
|
/** Supplies a custom IO handler to the importer to use to open and
|
||||||
* access files. If you need the importer to use custion IO logic to
|
* access files. If you need the importer to use custion IO logic to
|
||||||
|
@ -112,10 +115,31 @@ public:
|
||||||
* afterwards. The previously assigned handler will be deleted.
|
* afterwards. The previously assigned handler will be deleted.
|
||||||
*
|
*
|
||||||
* @param pIOHandler The IO handler to be used in all file accesses
|
* @param pIOHandler The IO handler to be used in all file accesses
|
||||||
* of the Importer. NULL resets it to the default handler.
|
* of the Importer. NULL resets it to the default handler.
|
||||||
*/
|
*/
|
||||||
void SetIOHandler( IOSystem* pIOHandler);
|
void SetIOHandler( IOSystem* pIOHandler);
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Retrieves the IO handler that is currently set.
|
||||||
|
* You can use IsDefaultIOHandler() to check whether the returned
|
||||||
|
* interface is the default IO handler provided by ASSIMP. The default
|
||||||
|
* handler is active as long the application doesn't supply its own
|
||||||
|
* custom IO handler via SetIOHandler().
|
||||||
|
* @return A valid IOSystem interface
|
||||||
|
*/
|
||||||
|
IOSystem* GetIOHandler();
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Checks whether a default IO handler is active
|
||||||
|
* A default handler is active as long the application doesn't
|
||||||
|
* supply its own custom IO handler via SetIOHandler().
|
||||||
|
* @return true by default
|
||||||
|
*/
|
||||||
|
bool IsDefaultIOHandler();
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Reads the given file and returns its contents if successful.
|
/** Reads the given file and returns its contents if successful.
|
||||||
*
|
*
|
||||||
|
@ -127,18 +151,19 @@ public:
|
||||||
* GetErrorString().
|
* GetErrorString().
|
||||||
* @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 #aiPostProcessSteps
|
* a successful import. Provide a bitwise combination of the
|
||||||
* 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.
|
||||||
*/
|
*/
|
||||||
const aiScene* ReadFile( const std::string& pFile, unsigned int pFlags);
|
const aiScene* ReadFile( const std::string& pFile, unsigned int pFlags);
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns an error description of an error that occured in ReadFile().
|
/** Returns an error description of an error that occured in ReadFile().
|
||||||
*
|
*
|
||||||
* Returns an empty string if no error occured.
|
* Returns an empty string if no error occured.
|
||||||
* @return A description of the last error, an empty string if no
|
* @return A description of the last error, an empty string if no
|
||||||
* error occured.
|
* error occured.
|
||||||
*/
|
*/
|
||||||
inline const std::string& GetErrorString() const
|
inline const std::string& GetErrorString() const
|
||||||
{ return mErrorString; }
|
{ return mErrorString; }
|
||||||
|
@ -147,20 +172,20 @@ public:
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether a given file extension is supported by ASSIMP
|
/** Returns whether a given file extension is supported by ASSIMP
|
||||||
*
|
*
|
||||||
* @param szExtension Extension for which the function queries support.
|
* @param szExtension Extension to be checked.
|
||||||
* Must include a leading dot '.'. Example: ".3ds", ".md3"
|
* Must include a leading dot '.'. Example: ".3ds", ".md3"
|
||||||
* @return true if the extension is supported, false otherwise
|
* @return true if the extension is supported, false otherwise
|
||||||
*/
|
*/
|
||||||
bool IsExtensionSupported(const std::string& szExtension);
|
bool IsExtensionSupported(const std::string& szExtension);
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Get a full list of all file extensions generally supported by ASSIMP.
|
/** Get a full list of all file extensions supported by ASSIMP.
|
||||||
*
|
*
|
||||||
* If a file extension is contained in the list this does, of course, not
|
* If a file extension is contained in the list this does, of course, not
|
||||||
* mean that ASSIMP is able to load all files with this extension.
|
* mean that ASSIMP is able to load all files with this extension.
|
||||||
* @param szOut String to receive the extension list.
|
* @param szOut String to receive the extension list.
|
||||||
* Format of the list: "*.3ds;*.obj;*.dae". NULL is not a valid parameter.
|
* Format of the list: "*.3ds;*.obj;*.dae".
|
||||||
*/
|
*/
|
||||||
void GetExtensionList(std::string& szOut);
|
void GetExtensionList(std::string& szOut);
|
||||||
|
|
||||||
|
@ -174,12 +199,15 @@ public:
|
||||||
{return this->mScene;}
|
{return this->mScene;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/** Empty copy constructor. */
|
/** Empty copy constructor. */
|
||||||
Importer(const Importer &other);
|
Importer(const Importer &other);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/** IO handler to use for all file accesses. */
|
/** IO handler to use for all file accesses. */
|
||||||
IOSystem* mIOHandler;
|
IOSystem* mIOHandler;
|
||||||
|
bool mIsDefaultHandler;
|
||||||
|
|
||||||
/** Format-specific importer worker objects -
|
/** Format-specific importer worker objects -
|
||||||
* one for each format we can read. */
|
* one for each format we can read. */
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<attribute name="URI" value="/" />
|
<attribute name="URI" value="/" />
|
||||||
</containerElement>
|
</containerElement>
|
||||||
</containerInfo>
|
</containerInfo>
|
||||||
<setting name="jarPath" value="J:\Programmieren\ASSIMP\assimp2\port\jAssimp\assimp.jar" />
|
<setting name="jarPath" value="J:\Programmieren\ASSIMP\assimp\port\jAssimp\assimp.jar" />
|
||||||
<setting name="buildJar" value="true" />
|
<setting name="buildJar" value="true" />
|
||||||
<setting name="mainClass" value="" />
|
<setting name="mainClass" value="" />
|
||||||
</component>
|
</component>
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package assimp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by IntelliJ IDEA.
|
||||||
|
* User: Alex
|
||||||
|
* Date: 08.06.2008
|
||||||
|
* Time: 15:31:01
|
||||||
|
* To change this template use File | Settings | File Templates.
|
||||||
|
*/
|
||||||
|
public class Bone {
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package assimp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by IntelliJ IDEA.
|
||||||
|
* User: Alex
|
||||||
|
* Date: 15.06.2008
|
||||||
|
* Time: 19:51:45
|
||||||
|
* To change this template use File | Settings | File Templates.
|
||||||
|
*/
|
||||||
|
public interface IOStream {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
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.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package assimp;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface IOSystem {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called to check whether a file is existing
|
||||||
|
*
|
||||||
|
* @param file Filename
|
||||||
|
* @return true if the file is existing and accessible
|
||||||
|
*/
|
||||||
|
boolean Exists(String file);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a file and return an <code> IOStream </code> interface
|
||||||
|
* to access it.
|
||||||
|
*
|
||||||
|
* @param file File name of the file to be opened
|
||||||
|
* @return A valid IOStream interface
|
||||||
|
* @throws FileNotFoundException if the file can't be accessed
|
||||||
|
*/
|
||||||
|
IOStream Open(String file) throws FileNotFoundException;
|
||||||
|
|
||||||
|
}
|
|
@ -43,6 +43,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
package assimp;
|
package assimp;
|
||||||
|
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.ref.Reference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main class of jAssimp. The class is a simple wrapper for the native
|
* Main class of jAssimp. The class is a simple wrapper for the native
|
||||||
|
@ -59,6 +64,65 @@ import java.util.Vector;
|
||||||
*/
|
*/
|
||||||
public class Importer {
|
public class Importer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default implementation of <code>IOStream</code>.
|
||||||
|
* <br>
|
||||||
|
* This might become a performance bottleneck: The application
|
||||||
|
* needs to map the data read by this interface into a C-style
|
||||||
|
* array. For every single read operation! Therefore it is a good
|
||||||
|
* optimization to use the default C IOStream handler if no custom
|
||||||
|
* java handler was specified. Assuming that the Java Runtime is using
|
||||||
|
* the fXXX-family of functions internally too, the result should be
|
||||||
|
* the same. The problem is: we can't be sure we'll be able to open
|
||||||
|
* the file for reading from both Java and native code. Therefore we
|
||||||
|
* need to close our Java <code>FileReader</code> handle before
|
||||||
|
* control is given to native code.
|
||||||
|
*/
|
||||||
|
private class DefaultIOStream implements IOStream {
|
||||||
|
|
||||||
|
private FileReader reader = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construction with a given path
|
||||||
|
* @param file Path to the file to be opened
|
||||||
|
* @throws FileNotFoundException If the file isn't accessible at all
|
||||||
|
*/
|
||||||
|
public DefaultIOStream(final String file) throws FileNotFoundException {
|
||||||
|
reader = new FileReader(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default implementation of <code>IOSystem</code>.
|
||||||
|
*/
|
||||||
|
private class DefaultIOSystem implements IOSystem {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called to check whether a file is existing
|
||||||
|
*
|
||||||
|
* @param file Filename
|
||||||
|
* @return true if the file is existing and accessible
|
||||||
|
*/
|
||||||
|
public boolean Exists(String file) {
|
||||||
|
File f = new File(file);
|
||||||
|
return f.exists();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a file and return an <code> IOStream </code> interface
|
||||||
|
* to access it.
|
||||||
|
*
|
||||||
|
* @param file File name of the file to be opened
|
||||||
|
* @return A valid IOStream interface
|
||||||
|
* @throws FileNotFoundException if the file can't be accessed
|
||||||
|
*/
|
||||||
|
public IOStream Open(String file) throws FileNotFoundException {
|
||||||
|
return new DefaultIOStream(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of all postprocess steps to apply to the model
|
* List of all postprocess steps to apply to the model
|
||||||
* Empty by default.
|
* Empty by default.
|
||||||
|
@ -83,17 +147,27 @@ public class Importer {
|
||||||
*/
|
*/
|
||||||
private String path = null;
|
private String path = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* I/O system to be used
|
||||||
|
*/
|
||||||
|
private IOSystem ioSystem = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Public constructor. Initialises the JNI bridge to the native
|
* Public constructor. Initialises the JNI bridge to the native
|
||||||
* ASSIMP library. A native Assimp::Importer object is constructed and
|
* ASSIMP library. A native Assimp::Importer object is constructed and
|
||||||
* initialized. The flag list is set to zero, a default I/O handler
|
* initialized. The flag list is set to zero, a default I/O handler
|
||||||
* is constructed.
|
* is initialized.
|
||||||
*
|
*
|
||||||
|
* @param iVersion Version of the JNI interface to be used.
|
||||||
* @throws NativeError Thrown if the jassimp library could not be loaded
|
* @throws NativeError Thrown if the jassimp library could not be loaded
|
||||||
* or if the entry point to the module wasn't found. if this exception
|
* or if the entry point to the module wasn't found. if this exception
|
||||||
* is not thrown, you can assume that jAssimp is fully available.
|
* is not thrown, you can assume that jAssimp is fully available.
|
||||||
*/
|
*/
|
||||||
public Importer() throws NativeError {
|
public Importer(int iVersion) throws NativeError {
|
||||||
|
|
||||||
|
// allocate a default I/O system
|
||||||
|
ioSystem = new DefaultIOSystem();
|
||||||
|
|
||||||
/** try to load the jassimp library. First try to load the
|
/** try to load the jassimp library. First try to load the
|
||||||
* x64 version, in case of failure the x86 version
|
* x64 version, in case of failure the x86 version
|
||||||
*/
|
*/
|
||||||
|
@ -111,7 +185,7 @@ public class Importer {
|
||||||
// now create the native Importer class and setup our internal
|
// now create the native Importer class and setup our internal
|
||||||
// data structures outside the VM.
|
// data structures outside the VM.
|
||||||
try {
|
try {
|
||||||
if (0xffffffffffffffffl == (this.m_iNativeHandle = _NativeInitContext())) {
|
if (0xffffffffffffffffl == (this.m_iNativeHandle = _NativeInitContext(iVersion))) {
|
||||||
throw new NativeError(
|
throw new NativeError(
|
||||||
"Unable to initialize the native library context." +
|
"Unable to initialize the native library context." +
|
||||||
"The initialization routine has failed");
|
"The initialization routine has failed");
|
||||||
|
@ -125,6 +199,32 @@ public class Importer {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Importer() throws NativeError {
|
||||||
|
this(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the I/O system (<code>IOSystem</code>) to be used for loading
|
||||||
|
* assets. If no custom implementation was provided via <code>setIoSystem()</code>
|
||||||
|
* a default implementation will be used. Use <code>isDefaultIoSystem()</code>
|
||||||
|
* to check this.
|
||||||
|
* @return Always a valid <code>IOSystem</code> object, never null.
|
||||||
|
*/
|
||||||
|
public IOSystem getIoSystem() {
|
||||||
|
return ioSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether a default IO system is currently being used to load
|
||||||
|
* assets. Using the default IO system has many performance benefits,
|
||||||
|
* but it is possible to provide a custom IO system (<code>setIoSystem()</code>).
|
||||||
|
* This allows applications to add support for archives like ZIP.
|
||||||
|
* @return true if a default <code>IOSystem</code> is active,
|
||||||
|
*/
|
||||||
|
public boolean isDefaultIoSystem() {
|
||||||
|
return ioSystem instanceof DefaultIOSystem;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a postprocess step to the list of steps to be executed on
|
* Add a postprocess step to the list of steps to be executed on
|
||||||
|
@ -213,6 +313,8 @@ public class Importer {
|
||||||
else if (step.equals(PostProcessStep.GenSmoothNormals)) flags |= 0x40;
|
else if (step.equals(PostProcessStep.GenSmoothNormals)) flags |= 0x40;
|
||||||
else if (step.equals(PostProcessStep.SplitLargeMeshes)) flags |= 0x80;
|
else if (step.equals(PostProcessStep.SplitLargeMeshes)) flags |= 0x80;
|
||||||
else if (step.equals(PostProcessStep.PreTransformVertices)) flags |= 0x100;
|
else if (step.equals(PostProcessStep.PreTransformVertices)) flags |= 0x100;
|
||||||
|
else if (step.equals(PostProcessStep.LimitBoneWeights)) flags |= 0x200;
|
||||||
|
else if (step.equals(PostProcessStep.ValidateDataStructure)) flags |= 0x400;
|
||||||
}
|
}
|
||||||
|
|
||||||
// now load the mesh
|
// now load the mesh
|
||||||
|
@ -227,6 +329,7 @@ public class Importer {
|
||||||
}
|
}
|
||||||
catch (NativeError exc) {
|
catch (NativeError exc) {
|
||||||
|
|
||||||
|
// delete everything ...
|
||||||
this.scene = null;
|
this.scene = null;
|
||||||
this.path = null;
|
this.path = null;
|
||||||
throw exc;
|
throw exc;
|
||||||
|
@ -247,9 +350,8 @@ public class Importer {
|
||||||
|
|
||||||
final Importer importer = (Importer) o;
|
final Importer importer = (Importer) o;
|
||||||
|
|
||||||
if (m_iNativeHandle != importer.m_iNativeHandle) return false;
|
return m_iNativeHandle == importer.m_iNativeHandle;
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -268,7 +370,6 @@ public class Importer {
|
||||||
if (0xffffffff == _NativeFreeContext(this.m_iNativeHandle)) {
|
if (0xffffffff == _NativeFreeContext(this.m_iNativeHandle)) {
|
||||||
throw new NativeError("Unable to destroy the native library context");
|
throw new NativeError("Unable to destroy the native library context");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -306,9 +407,10 @@ public class Importer {
|
||||||
* library functions are available, too. If they are not, an <code>
|
* library functions are available, too. If they are not, an <code>
|
||||||
* UnsatisfiedLinkError</code> will be thrown during model loading.
|
* UnsatisfiedLinkError</code> will be thrown during model loading.
|
||||||
*
|
*
|
||||||
|
* @param version Version of the JNI bridge requested
|
||||||
* @return Unique handle for the class or 0xffffffff if an error occured
|
* @return Unique handle for the class or 0xffffffff if an error occured
|
||||||
*/
|
*/
|
||||||
private native int _NativeInitContext();
|
private native int _NativeInitContext(int version);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JNI bridge call. For internal use only
|
* JNI bridge call. For internal use only
|
||||||
|
|
|
@ -43,6 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
package assimp;
|
package assimp;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to wrap materials. Materials are represented in ASSIMP as a list of
|
* Class to wrap materials. Materials are represented in ASSIMP as a list of
|
||||||
* key/value pairs, the key being a <code>String</code> and the value being
|
* key/value pairs, the key being a <code>String</code> and the value being
|
||||||
|
@ -52,6 +53,74 @@ package assimp;
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*/
|
*/
|
||||||
public class Material extends Mappable {
|
public class Material extends Mappable {
|
||||||
|
|
||||||
|
|
||||||
|
public static final String MATKEY_NAME = "$mat.name";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the blend operation to be used to combine the Nth
|
||||||
|
* diffuse texture with the (N-1)th diffuse texture (or the diffuse
|
||||||
|
* base color for the first diffuse texture)
|
||||||
|
* <br>
|
||||||
|
* <b>Type:</b> int (TextureOp)<br>
|
||||||
|
* <b>Default value:</b> 0<br>
|
||||||
|
* <b>Requires:</b> MATKEY_TEXTURE_DIFFUSE(0)<br>
|
||||||
|
*/
|
||||||
|
public static String MATKEY_TEXOP_DIFFUSE(int N) {
|
||||||
|
return "$tex.op.diffuse[" + N + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see MATKEY_TEXOP_DIFFUSE()
|
||||||
|
*/
|
||||||
|
public static String MATKEY_TEXOP_SPECULAR(int N) {
|
||||||
|
return "$tex.op.specular[" + N + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see MATKEY_TEXOP_DIFFUSE()
|
||||||
|
*/
|
||||||
|
public static String MATKEY_TEXOP_AMBIENT(int N) {
|
||||||
|
return "$tex.op.ambient[" + N + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see MATKEY_TEXOP_DIFFUSE()
|
||||||
|
*/
|
||||||
|
public static String MATKEY_TEXOP_EMISSIVE(int N) {
|
||||||
|
return "$tex.op.emissive[" + N + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see MATKEY_TEXOP_DIFFUSE()
|
||||||
|
*/
|
||||||
|
public static String MATKEY_TEXOP_NORMALS(int N) {
|
||||||
|
return "$tex.op.normals[" + N + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see MATKEY_TEXOP_DIFFUSE()
|
||||||
|
*/
|
||||||
|
public static String MATKEY_TEXOP_HEIGHT(int N) {
|
||||||
|
return "$tex.op.height[" + N + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see MATKEY_TEXOP_DIFFUSE()
|
||||||
|
*/
|
||||||
|
public static String MATKEY_TEXOP_SHININESS(int N) {
|
||||||
|
return "$tex.op.shininess[" + N + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see MATKEY_TEXOP_DIFFUSE()
|
||||||
|
*/
|
||||||
|
public static String MATKEY_TEXOP_OPACITY(int N) {
|
||||||
|
return "$tex.op.opacity[" + N + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construction from a given parent object and array index
|
* Construction from a given parent object and array index
|
||||||
*
|
*
|
||||||
|
|
|
@ -183,29 +183,9 @@ public class Mesh extends Mappable {
|
||||||
assert (parent instanceof Scene);
|
assert (parent instanceof Scene);
|
||||||
|
|
||||||
Scene sc = (Scene) parent;
|
Scene sc = (Scene) parent;
|
||||||
if (0xffffffff == (this.m_iPresentFlags = this._NativeGetPresenceFlags(
|
if (0xffffffff == this._NativeInitMembers(
|
||||||
sc.getImporter().getContext(), this.getArrayIndex()))) {
|
sc.getImporter().getContext(), this.getArrayIndex())) {
|
||||||
throw new NativeError("Unable to obtain a list of vertex presence flags");
|
throw new NativeError("Unable to intiailise class members via JNI");
|
||||||
}
|
|
||||||
if (0xffffffff == (this.m_iNumVertices = this._NativeGetNumVertices(
|
|
||||||
sc.getImporter().getContext(), this.getArrayIndex()))) {
|
|
||||||
throw new NativeError("Unable to obtain the number of vertices in the mesh");
|
|
||||||
}
|
|
||||||
if (0xffffffff == (this.m_iNumFaces = this._NativeGetNumFaces(
|
|
||||||
sc.getImporter().getContext(), this.getArrayIndex()))) {
|
|
||||||
throw new NativeError("Unable to obtain the number of faces in the mesh");
|
|
||||||
}
|
|
||||||
if (0xffffffff == (this.m_iNumBones = this._NativeGetNumBones(
|
|
||||||
sc.getImporter().getContext(), this.getArrayIndex()))) {
|
|
||||||
throw new NativeError("Unable to obtain the number of bones in the mesh");
|
|
||||||
}
|
|
||||||
if (0xffffffff == (this.m_iMaterialIndex = this._NativeGetMaterialIndex(
|
|
||||||
sc.getImporter().getContext(), this.getArrayIndex()))) {
|
|
||||||
throw new NativeError("Unable to obtain the material index of the mesh");
|
|
||||||
}
|
|
||||||
if (0xffffffff == this._NativeGetNumUVComponents(
|
|
||||||
sc.getImporter().getContext(), this.getArrayIndex(), this.m_aiNumUVComponents)) {
|
|
||||||
throw new NativeError("Unable to obtain the number of UV components");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -821,18 +801,12 @@ public class Mesh extends Mappable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JNI bridge function - for internal use only
|
* JNI bridge function - for internal use only
|
||||||
* Retrieve the number of vertices in the mesh
|
* Initialise class members
|
||||||
*
|
*
|
||||||
* @param context Current importer context (imp.hashCode)
|
* @param context Current importer context (imp.hashCode)
|
||||||
* @return Number of vertices in the mesh
|
* @return Number of vertices in the mesh
|
||||||
*/
|
*/
|
||||||
private native int _NativeGetNumVertices(long context, long index);
|
private native int _NativeInitMembers(long context, long index);
|
||||||
|
|
||||||
private native int _NativeGetNumFaces(long context, long index);
|
|
||||||
|
|
||||||
private native int _NativeGetNumBones(long context, long index);
|
|
||||||
|
|
||||||
private native int _NativeGetMaterialIndex(long context, long index);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JNI bridge function - for internal use only
|
* JNI bridge function - for internal use only
|
||||||
|
|
|
@ -1,11 +1,223 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
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.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
package assimp;
|
package assimp;
|
||||||
|
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by IntelliJ IDEA.
|
* A node in the imported hierarchy.
|
||||||
* User: Alex
|
* <p/>
|
||||||
* Date: 22.05.2008
|
* Each node has name, a parent node (except for the root node),
|
||||||
* Time: 13:05:12
|
* a transformation relative to its parent and possibly several child nodes.
|
||||||
* To change this template use File | Settings | File Templates.
|
* Simple file formats don't support hierarchical structures, for these formats
|
||||||
|
* the imported scene does consist of only a single root node with no childs.
|
||||||
|
*
|
||||||
|
* @author Aramis (Alexander Gessler)
|
||||||
|
* @version 1.0
|
||||||
*/
|
*/
|
||||||
public class Node {
|
public class Node {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of all meshes of this node.
|
||||||
|
* The array contains indices into the Scene's mesh list
|
||||||
|
*/
|
||||||
|
private int[] meshIndices = null;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Local transformation matrix of the node
|
||||||
|
* Stored in row-major order.
|
||||||
|
*/
|
||||||
|
private float[] nodeTransform = null;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of the node
|
||||||
|
* The name might be empty (length of zero) but all nodes which
|
||||||
|
* need to be accessed afterwards by bones or anims are usually named.
|
||||||
|
*/
|
||||||
|
private String name = "";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of all child nodes
|
||||||
|
* May be empty
|
||||||
|
*/
|
||||||
|
private Vector<Node> children = null;
|
||||||
|
private int numChildren = 0; // temporary
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parent scene
|
||||||
|
*/
|
||||||
|
private Scene parentScene = null;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parent node or null if we're the root node of the scene
|
||||||
|
*/
|
||||||
|
private Node parent = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new node and initializes it
|
||||||
|
* @param parentScene Parent scene object
|
||||||
|
* @param parentNode Parent node or null for root nodes
|
||||||
|
* @param index Unique index of the node
|
||||||
|
*/
|
||||||
|
public Node(Scene parentScene, Node parentNode, int index) {
|
||||||
|
|
||||||
|
this.parentScene = parentScene;
|
||||||
|
this.parent = parentNode;
|
||||||
|
|
||||||
|
// Initialize JNI class members, including numChildren
|
||||||
|
this._NativeInitMembers(parentScene.getImporter().getContext(),index);
|
||||||
|
|
||||||
|
// get all children of the node
|
||||||
|
for (int i = 0; i < numChildren;++i) {
|
||||||
|
this.children.add(new Node(parentScene, this, ++index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of all meshes of this node
|
||||||
|
*
|
||||||
|
* @return Array containing indices into the Scene's mesh list
|
||||||
|
*/
|
||||||
|
int[] getMeshes() {
|
||||||
|
return meshIndices;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the local transformation matrix of the node in row-major
|
||||||
|
* order:
|
||||||
|
* <code>
|
||||||
|
* a1 a2 a3 a4 (the translational part of the matrix is stored
|
||||||
|
* b1 b2 b3 b4 in (a4|b4|c4))
|
||||||
|
* c1 c2 c3 c4
|
||||||
|
* d1 d2 d3 d4
|
||||||
|
* </code>
|
||||||
|
*
|
||||||
|
* @return Row-major transformation matrix
|
||||||
|
*/
|
||||||
|
float[] getTransformRowMajor() {
|
||||||
|
return nodeTransform;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the local transformation matrix of the node in column-major
|
||||||
|
* order:
|
||||||
|
* <code>
|
||||||
|
* a1 b1 c1 d1 (the translational part of the matrix is stored
|
||||||
|
* a2 b2 c2 d2 in (a4|b4|c4))
|
||||||
|
* a3 b3 c3 d3
|
||||||
|
* a4 b4 c4 d4
|
||||||
|
* </code>
|
||||||
|
*
|
||||||
|
* @return Column-major transformation matrix
|
||||||
|
*/
|
||||||
|
float[] getTransformColumnMajor() {
|
||||||
|
|
||||||
|
float[] transform = new float[16];
|
||||||
|
transform[0] = nodeTransform[0];
|
||||||
|
transform[1] = nodeTransform[4];
|
||||||
|
transform[2] = nodeTransform[8];
|
||||||
|
transform[3] = nodeTransform[12];
|
||||||
|
transform[4] = nodeTransform[1];
|
||||||
|
transform[5] = nodeTransform[5];
|
||||||
|
transform[6] = nodeTransform[9];
|
||||||
|
transform[7] = nodeTransform[13];
|
||||||
|
transform[8] = nodeTransform[2];
|
||||||
|
transform[9] = nodeTransform[6];
|
||||||
|
transform[10] = nodeTransform[10];
|
||||||
|
transform[11] = nodeTransform[14];
|
||||||
|
transform[12] = nodeTransform[3];
|
||||||
|
transform[13] = nodeTransform[7];
|
||||||
|
transform[15] = nodeTransform[11];
|
||||||
|
transform[16] = nodeTransform[15];
|
||||||
|
return transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private native int _NativeInitMembers(long context, int nodeIndex);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the name of the node.
|
||||||
|
* The name might be empty (length of zero) but all nodes which
|
||||||
|
* need to be accessed afterwards by bones or anims are usually named.
|
||||||
|
*
|
||||||
|
* @return Node name
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of all child nodes of *this* node
|
||||||
|
* @return List of children. May be empty.
|
||||||
|
*/
|
||||||
|
public Vector<Node> getChildren() {
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the parent node of the node
|
||||||
|
* @return Parent node
|
||||||
|
*/
|
||||||
|
public Node getParent() {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the parent scene of the node
|
||||||
|
* @return Never null
|
||||||
|
*/
|
||||||
|
public Scene getParentScene() {
|
||||||
|
return parentScene;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ package assimp;
|
||||||
/**
|
/**
|
||||||
* Enumeration class that defines postprocess steps that can be executed on a model
|
* Enumeration class that defines postprocess steps that can be executed on a model
|
||||||
* after it has been loaded. All PPSteps are implemented in C++, so their performance
|
* after it has been loaded. All PPSteps are implemented in C++, so their performance
|
||||||
* is awesome. Most steps are O(n * log(n)).
|
* is awesome. Most steps are O(n * log(n)). ;-)
|
||||||
*
|
*
|
||||||
* @author Aramis (Alexander Gessler)
|
* @author Aramis (Alexander Gessler)
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
|
@ -62,8 +62,15 @@ public class PostProcessStep {
|
||||||
*/
|
*/
|
||||||
public static final int DEFAULT_TRIANGLE_SPLIT_LIMIT = 1000000;
|
public static final int DEFAULT_TRIANGLE_SPLIT_LIMIT = 1000000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default bone weight limit for the LimitBoneWeight process
|
||||||
|
*/
|
||||||
|
public static final int DEFAULT_BONE_WEIGHT_LIMIT = 4;
|
||||||
|
|
||||||
|
|
||||||
private static int s_iVertexSplitLimit = DEFAULT_VERTEX_SPLIT_LIMIT;
|
private static int s_iVertexSplitLimit = DEFAULT_VERTEX_SPLIT_LIMIT;
|
||||||
private static int s_iTriangleSplitLimit = DEFAULT_TRIANGLE_SPLIT_LIMIT;
|
private static int s_iTriangleSplitLimit = DEFAULT_TRIANGLE_SPLIT_LIMIT;
|
||||||
|
private static int s_iBoneWeightLimit = DEFAULT_BONE_WEIGHT_LIMIT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identifies and joins identical vertex data sets within all imported
|
* Identifies and joins identical vertex data sets within all imported
|
||||||
|
@ -154,6 +161,31 @@ public class PostProcessStep {
|
||||||
public static final PostProcessStep PreTransformVertices =
|
public static final PostProcessStep PreTransformVertices =
|
||||||
new PostProcessStep("PreTransformVertices");
|
new PostProcessStep("PreTransformVertices");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Limits the number of bones simultaneously affecting a single vertex
|
||||||
|
* to a maximum value. If any vertex is affected by more than that number
|
||||||
|
* of bones, the least important vertex weights are removed and the remaining
|
||||||
|
* vertex weights are renormalized so that the weights still sum up to 1.
|
||||||
|
* The default bone weight limit is 4 (DEFAULT_BONE_WEIGHT_LIMIT).
|
||||||
|
* However, you can use setBoneWeightLimit() to supply your own limit.
|
||||||
|
* If you intend to perform the skinning in hardware, this post processing step
|
||||||
|
* might be of interest for you.
|
||||||
|
*/
|
||||||
|
public static final PostProcessStep LimitBoneWeights =
|
||||||
|
new PostProcessStep("LimitBoneWeights");
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the aiScene data structure before it is returned.
|
||||||
|
* This makes sure that all indices are valid, all animations and
|
||||||
|
* bones are linked correctly, all material are correct and so on ...
|
||||||
|
* This is primarily intended for our internal debugging stuff,
|
||||||
|
* however, it could be of interest for applications like editors
|
||||||
|
* where stability is more important than loading performance.
|
||||||
|
*/
|
||||||
|
public static final PostProcessStep ValidateDataStructure =
|
||||||
|
new PostProcessStep("ValidateDataStructure");
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the vertex split limit for the "SplitLargeMeshes" process
|
* Set the vertex split limit for the "SplitLargeMeshes" process
|
||||||
|
@ -191,6 +223,22 @@ public class PostProcessStep {
|
||||||
return limit;
|
return limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the bone weight limit for the "LimitBoneWeights" process
|
||||||
|
* If a mesh exceeds this limit it will be splitted
|
||||||
|
*
|
||||||
|
* @param limit new bone weight limit. Pass 0xffffffff to disable it.
|
||||||
|
* @return Old bone weight limit
|
||||||
|
*/
|
||||||
|
public static synchronized int setSetBoneWeightLimit(int limit) {
|
||||||
|
if (s_iBoneWeightLimit != limit) {
|
||||||
|
// send to the JNI bridge ...
|
||||||
|
s_iBoneWeightLimit = limit;
|
||||||
|
_NativeSetBoneWeightLimit(limit);
|
||||||
|
}
|
||||||
|
return limit;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JNI bridge call. For internal use only
|
* JNI bridge call. For internal use only
|
||||||
*
|
*
|
||||||
|
@ -205,6 +253,13 @@ public class PostProcessStep {
|
||||||
*/
|
*/
|
||||||
private native static void _NativeSetTriangleSplitLimit(int limit);
|
private native static void _NativeSetTriangleSplitLimit(int limit);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JNI bridge call. For internal use only
|
||||||
|
*
|
||||||
|
* @param limit New bone weight limit
|
||||||
|
*/
|
||||||
|
private native static void _NativeSetBoneWeightLimit(int limit);
|
||||||
|
|
||||||
|
|
||||||
private final String myName; // for debug only
|
private final String myName; // for debug only
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
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.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
package assimp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines all shading models supported by the library
|
||||||
|
* <p/>
|
||||||
|
* NOTE: The list of shading modes has been taken from Blender3D.
|
||||||
|
* See Blender3D documentation for more information. The API does
|
||||||
|
* not distinguish between "specular" and "diffuse" shaders (thus the
|
||||||
|
* specular term for diffuse shading models like Oren-Nayar remains
|
||||||
|
* undefined)
|
||||||
|
*/
|
||||||
|
public class ShadingMode {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flat shading. Shading is done on per-face base,
|
||||||
|
* diffuse only.
|
||||||
|
*/
|
||||||
|
int Flat = 0x1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Diffuse gouraud shading. Shading on per-vertex base
|
||||||
|
*/
|
||||||
|
int Gouraud = 0x2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Diffuse/Specular Phong-Shading
|
||||||
|
* <p/>
|
||||||
|
* Shading is applied on per-pixel base. This is the
|
||||||
|
* slowest algorithm, but generates the best results.
|
||||||
|
*/
|
||||||
|
int Phong = 0x3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Diffuse/Specular Phong-Blinn-Shading
|
||||||
|
* <p/>
|
||||||
|
* Shading is applied on per-pixel base. This is a little
|
||||||
|
* bit faster than phong and in some cases even
|
||||||
|
* more realistic
|
||||||
|
*/
|
||||||
|
int Blinn = 0x4;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toon-Shading per pixel
|
||||||
|
* <p/>
|
||||||
|
* Shading is applied on per-pixel base. The output looks
|
||||||
|
* like a comic. Often combined with edge detection.
|
||||||
|
*/
|
||||||
|
int Toon = 0x5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OrenNayar-Shading per pixel
|
||||||
|
* <p/>
|
||||||
|
* Extension to standard lambertian shading, taking the
|
||||||
|
* roughness of the material into account
|
||||||
|
*/
|
||||||
|
int OrenNayar = 0x6;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minnaert-Shading per pixel
|
||||||
|
* <p/>
|
||||||
|
* Extension to standard lambertian shading, taking the
|
||||||
|
* "darkness" of the material into account
|
||||||
|
*/
|
||||||
|
int Minnaert = 0x7;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CookTorrance-Shading per pixel
|
||||||
|
*/
|
||||||
|
int CookTorrance = 0x8;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No shading at all
|
||||||
|
*/
|
||||||
|
int NoShading = 0x8;
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
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.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
package assimp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by IntelliJ IDEA.
|
||||||
|
* User: Alex
|
||||||
|
* Date: 08.06.2008
|
||||||
|
* Time: 17:27:11
|
||||||
|
* To change this template use File | Settings | File Templates.
|
||||||
|
*/
|
||||||
|
public class TextureMapMode {
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
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.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
package assimp;
|
||||||
|
|
||||||
|
public class TextureOp {
|
||||||
|
|
||||||
|
private TextureOp() {}
|
||||||
|
|
||||||
|
/** T = T1 * T2
|
||||||
|
*/
|
||||||
|
public static int Add = 0x0;
|
||||||
|
|
||||||
|
/** T = T1 * T2
|
||||||
|
*/
|
||||||
|
public static int Multiply = 0x1;
|
||||||
|
|
||||||
|
/** T = T1 - T2
|
||||||
|
*/
|
||||||
|
public static int Subtract = 0x2;
|
||||||
|
|
||||||
|
/** T = T1 / T2
|
||||||
|
*/
|
||||||
|
public static int Divide = 0x3;
|
||||||
|
|
||||||
|
/** T = (T1 + T2) - (T1 * T2)
|
||||||
|
*/
|
||||||
|
public static int SmoothAdd = 0x4;
|
||||||
|
|
||||||
|
/** T = T1 + (T2-0.5)
|
||||||
|
*/
|
||||||
|
public static int SignedAdd = 0x5;
|
||||||
|
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,15 @@
|
||||||
|
version 1
|
||||||
|
|
||||||
|
nodes
|
||||||
|
0 "TriangleTest0" -1
|
||||||
|
end
|
||||||
|
skeleton
|
||||||
|
time 0
|
||||||
|
0 0.0 0.0 0.0 0.0 0.0 0.0
|
||||||
|
end
|
||||||
|
triangles
|
||||||
|
none.quak
|
||||||
|
0 0.0 0.0 0.0 1.0 1.0 1.0 0.0 0.0
|
||||||
|
0 1.0 0.0 0.0 1.0 1.0 1.0 1.0 0.0
|
||||||
|
0 1.0 1.0 0.0 1.0 1.0 1.0 1.0 1.0
|
||||||
|
end
|
|
@ -137,7 +137,6 @@ int CMaterialManager::SetDefaultTexture(IDirect3DTexture9** p_ppiOut)
|
||||||
bool CMaterialManager::TryLongerPath(char* szTemp,aiString* p_szString)
|
bool CMaterialManager::TryLongerPath(char* szTemp,aiString* p_szString)
|
||||||
{
|
{
|
||||||
char szTempB[MAX_PATH];
|
char szTempB[MAX_PATH];
|
||||||
|
|
||||||
strcpy(szTempB,szTemp);
|
strcpy(szTempB,szTemp);
|
||||||
|
|
||||||
// go to the beginning of the file name
|
// go to the beginning of the file name
|
||||||
|
@ -146,7 +145,9 @@ bool CMaterialManager::TryLongerPath(char* szTemp,aiString* p_szString)
|
||||||
|
|
||||||
char* szFile2 = szTemp + (szFile - szTempB)+1;
|
char* szFile2 = szTemp + (szFile - szTempB)+1;
|
||||||
szFile++;
|
szFile++;
|
||||||
char* szExt = strrchr(szFile,'.')+1;
|
char* szExt = strrchr(szFile,'.');
|
||||||
|
if (!szExt)return false;
|
||||||
|
szExt++;
|
||||||
*szFile = 0;
|
*szFile = 0;
|
||||||
|
|
||||||
strcat(szTempB,"*.*");
|
strcat(szTempB,"*.*");
|
||||||
|
@ -163,9 +164,10 @@ bool CMaterialManager::TryLongerPath(char* szTemp,aiString* p_szString)
|
||||||
{
|
{
|
||||||
if (!(strcmp(info.cFileName, ".") == 0 || strcmp(info.cFileName, "..") == 0))
|
if (!(strcmp(info.cFileName, ".") == 0 || strcmp(info.cFileName, "..") == 0))
|
||||||
{
|
{
|
||||||
char* szExtFound = strrchr(info.cFileName, '.')+1;
|
char* szExtFound = strrchr(info.cFileName, '.');
|
||||||
if ((char*)0x1 != szExtFound)
|
if (szExtFound)
|
||||||
{
|
{
|
||||||
|
++szExtFound;
|
||||||
if (0 == ASSIMP_stricmp(szExtFound,szExt))
|
if (0 == ASSIMP_stricmp(szExtFound,szExt))
|
||||||
{
|
{
|
||||||
const unsigned int iSizeFound = (const unsigned int) (
|
const unsigned int iSizeFound = (const unsigned int) (
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
<option name="MAXIMUM_HEAP_SIZE" value="128" />
|
<option name="MAXIMUM_HEAP_SIZE" value="128" />
|
||||||
</component>
|
</component>
|
||||||
<component name="JavadocGenerationManager">
|
<component name="JavadocGenerationManager">
|
||||||
<option name="OUTPUT_DIRECTORY" value="J:/Programmieren/ASSIMP/assimp2/doc/javadoc" />
|
<option name="OUTPUT_DIRECTORY" value="J:/Programmieren/ASSIMP/assimp/doc/javadoc" />
|
||||||
<option name="OPTION_SCOPE" value="package" />
|
<option name="OPTION_SCOPE" value="package" />
|
||||||
<option name="OPTION_HIERARCHY" value="true" />
|
<option name="OPTION_HIERARCHY" value="true" />
|
||||||
<option name="OPTION_NAVIGATOR" value="true" />
|
<option name="OPTION_NAVIGATOR" value="true" />
|
||||||
|
@ -178,7 +178,7 @@
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectModuleManager">
|
<component name="ProjectModuleManager">
|
||||||
<modules>
|
<modules>
|
||||||
<module fileurl="file://J:/Programmieren/ASSIMP/assimp2/port/jAssimp/assimp.iml" filepath="J:/Programmieren/ASSIMP/assimp2/port/jAssimp/assimp.iml" />
|
<module fileurl="file://J:/Programmieren/ASSIMP/ASSIMP/port/jAssimp/assimp.iml" filepath="J:/Programmieren/ASSIMP/ASSIMP/port/jAssimp/assimp.iml" />
|
||||||
</modules>
|
</modules>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" assert-keyword="true" jdk-15="true" project-jdk-name="1.6" />
|
<component name="ProjectRootManager" version="2" assert-keyword="true" jdk-15="true" project-jdk-name="1.6" />
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
RuntimeLibrary="1"
|
RuntimeLibrary="1"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
WarningLevel="3"
|
WarningLevel="3"
|
||||||
Detect64BitPortabilityProblems="true"
|
Detect64BitPortabilityProblems="false"
|
||||||
DebugInformationFormat="4"
|
DebugInformationFormat="4"
|
||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
|
@ -174,6 +174,7 @@
|
||||||
BufferSecurityCheck="false"
|
BufferSecurityCheck="false"
|
||||||
EnableEnhancedInstructionSet="2"
|
EnableEnhancedInstructionSet="2"
|
||||||
WarningLevel="3"
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="false"
|
||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCManagedResourceCompilerTool"
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
@ -294,11 +295,12 @@
|
||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
FavorSizeOrSpeed="1"
|
FavorSizeOrSpeed="1"
|
||||||
AdditionalIncludeDirectories=""
|
AdditionalIncludeDirectories=""
|
||||||
PreprocessorDefinitions="NDEBUG, _SCL_SECURE_NO_WARNINGS, _CRT_SECURE_NO_WARNINGS,WIN32"
|
PreprocessorDefinitions="NDEBUG;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;ASSIMP_BUILD_DLL_EXPORT"
|
||||||
StringPooling="true"
|
StringPooling="true"
|
||||||
BufferSecurityCheck="false"
|
BufferSecurityCheck="false"
|
||||||
EnableEnhancedInstructionSet="2"
|
EnableEnhancedInstructionSet="2"
|
||||||
WarningLevel="3"
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="false"
|
||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCManagedResourceCompilerTool"
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
@ -367,7 +369,7 @@
|
||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
FavorSizeOrSpeed="1"
|
FavorSizeOrSpeed="1"
|
||||||
AdditionalIncludeDirectories=""
|
AdditionalIncludeDirectories=""
|
||||||
PreprocessorDefinitions="NDEBUG, _SCL_SECURE_NO_WARNINGS, _CRT_SECURE_NO_WARNINGS,WIN32"
|
PreprocessorDefinitions="NDEBUG;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;ASSIMP_BUILD_DLL_EXPORT"
|
||||||
StringPooling="true"
|
StringPooling="true"
|
||||||
BufferSecurityCheck="false"
|
BufferSecurityCheck="false"
|
||||||
EnableEnhancedInstructionSet="2"
|
EnableEnhancedInstructionSet="2"
|
||||||
|
@ -437,12 +439,13 @@
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories=""
|
AdditionalIncludeDirectories=""
|
||||||
PreprocessorDefinitions="DEBUG, _SCL_SECURE_NO_WARNINGS, _CRT_SECURE_NO_WARNINGS,WIN32"
|
PreprocessorDefinitions="DEBUG;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;ASSIMP_BUILD_DLL_EXPORT"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
SmallerTypeCheck="true"
|
SmallerTypeCheck="true"
|
||||||
RuntimeLibrary="1"
|
RuntimeLibrary="1"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
WarningLevel="3"
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="false"
|
||||||
DebugInformationFormat="4"
|
DebugInformationFormat="4"
|
||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
|
@ -509,7 +512,7 @@
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories=""
|
AdditionalIncludeDirectories=""
|
||||||
PreprocessorDefinitions="DEBUG, _SCL_SECURE_NO_WARNINGS, _CRT_SECURE_NO_WARNINGS,WIN32"
|
PreprocessorDefinitions="DEBUG;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;ASSIMP_BUILD_DLL_EXPORT"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
SmallerTypeCheck="true"
|
SmallerTypeCheck="true"
|
||||||
RuntimeLibrary="1"
|
RuntimeLibrary="1"
|
||||||
|
@ -584,11 +587,12 @@
|
||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
FavorSizeOrSpeed="1"
|
FavorSizeOrSpeed="1"
|
||||||
AdditionalIncludeDirectories=""$(JAVA_HOME)\include";"$(JAVA_HOME)\include\win32""
|
AdditionalIncludeDirectories=""$(JAVA_HOME)\include";"$(JAVA_HOME)\include\win32""
|
||||||
PreprocessorDefinitions="NDEBUG;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;ASSIMP_JNI_EXPORT"
|
PreprocessorDefinitions="NDEBUG;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;ASSIMP_JNI_EXPORT;ASSIMP_BUILD_DLL_EXPORT"
|
||||||
StringPooling="true"
|
StringPooling="true"
|
||||||
BufferSecurityCheck="false"
|
BufferSecurityCheck="false"
|
||||||
EnableEnhancedInstructionSet="2"
|
EnableEnhancedInstructionSet="2"
|
||||||
WarningLevel="3"
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="false"
|
||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCManagedResourceCompilerTool"
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
@ -658,7 +662,7 @@
|
||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
FavorSizeOrSpeed="1"
|
FavorSizeOrSpeed="1"
|
||||||
AdditionalIncludeDirectories=""$(JAVA_HOME)\include";"$(JAVA_HOME)\include\win32""
|
AdditionalIncludeDirectories=""$(JAVA_HOME)\include";"$(JAVA_HOME)\include\win32""
|
||||||
PreprocessorDefinitions="NDEBUG;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;ASSIMP_JNI_EXPORT"
|
PreprocessorDefinitions="NDEBUG;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;ASSIMP_JNI_EXPORT;ASSIMP_BUILD_DLL_EXPORT"
|
||||||
StringPooling="true"
|
StringPooling="true"
|
||||||
BufferSecurityCheck="false"
|
BufferSecurityCheck="false"
|
||||||
EnableEnhancedInstructionSet="2"
|
EnableEnhancedInstructionSet="2"
|
||||||
|
@ -729,12 +733,13 @@
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories=""$(JAVA_HOME)\include";"$(JAVA_HOME)\include\win32""
|
AdditionalIncludeDirectories=""$(JAVA_HOME)\include";"$(JAVA_HOME)\include\win32""
|
||||||
PreprocessorDefinitions="DEBUG;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;ASSIMP_JNI_EXPORT"
|
PreprocessorDefinitions="DEBUG;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;ASSIMP_JNI_EXPORT;ASSIMP_BUILD_DLL_EXPORT"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
SmallerTypeCheck="true"
|
SmallerTypeCheck="true"
|
||||||
RuntimeLibrary="1"
|
RuntimeLibrary="1"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
WarningLevel="3"
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="false"
|
||||||
DebugInformationFormat="4"
|
DebugInformationFormat="4"
|
||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
|
@ -802,7 +807,7 @@
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories=""$(JAVA_HOME)\include";"$(JAVA_HOME)\include\win32""
|
AdditionalIncludeDirectories=""$(JAVA_HOME)\include";"$(JAVA_HOME)\include\win32""
|
||||||
PreprocessorDefinitions="DEBUG;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;ASSIMP_JNI_EXPORT"
|
PreprocessorDefinitions="DEBUG;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;ASSIMP_JNI_EXPORT;ASSIMP_BUILD_DLL_EXPORT"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
SmallerTypeCheck="true"
|
SmallerTypeCheck="true"
|
||||||
RuntimeLibrary="1"
|
RuntimeLibrary="1"
|
||||||
|
@ -865,6 +870,10 @@
|
||||||
RelativePath="..\..\include\aiAssert.h"
|
RelativePath="..\..\include\aiAssert.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\include\aiDefines.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\include\aiFileIO.h"
|
RelativePath="..\..\include\aiFileIO.h"
|
||||||
>
|
>
|
||||||
|
@ -1021,10 +1030,18 @@
|
||||||
RelativePath="..\..\code\MaterialSystem.h"
|
RelativePath="..\..\code\MaterialSystem.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\code\ParsingUtils.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\code\PretransformVertices.h"
|
RelativePath="..\..\code\PretransformVertices.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\code\qnan.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\code\SpatialSort.h"
|
RelativePath="..\..\code\SpatialSort.h"
|
||||||
>
|
>
|
||||||
|
@ -1217,39 +1234,39 @@
|
||||||
Name="jAssimp"
|
Name="jAssimp"
|
||||||
>
|
>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\code\jAssimp\assimp_Importer.h"
|
RelativePath="..\..\port\jAssimp\jni_bridge\assimp_Importer.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\code\jAssimp\assimp_Material.h"
|
RelativePath="..\..\port\jAssimp\jni_bridge\assimp_Material.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\code\jAssimp\assimp_Mesh.h"
|
RelativePath="..\..\port\jAssimp\jni_bridge\jAssimp\assimp_Mesh.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\code\jAssimp\assimp_Node.h"
|
RelativePath="..\..\port\jAssimp\jni_bridge\jAssimp\assimp_Node.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\code\jAssimp\assimp_PostProcessStep.h"
|
RelativePath="..\..\port\jAssimp\jni_bridge\assimp_PostProcessStep.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\code\jAssimp\assimp_Scene.h"
|
RelativePath="..\..\port\jAssimp\jni_bridge\assimp_Scene.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\code\jAssimp\assimp_Texture.h"
|
RelativePath="..\..\port\jAssimp\jni_bridge\assimp_Texture.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\code\jAssimp\JNIEnvironment.h"
|
RelativePath="..\..\port\jAssimp\jni_bridge\JNIEnvironment.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\code\jAssimp\JNILogger.h"
|
RelativePath="..\..\port\jAssimp\jni_bridge\JNILogger.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
@ -1261,6 +1278,22 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="HMPLoader"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\code\HMPLoader.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="SMDLoader"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\code\SMDLoader.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="sources"
|
Name="sources"
|
||||||
|
@ -1436,6 +1469,10 @@
|
||||||
RelativePath="..\..\code\MDLLoader.cpp"
|
RelativePath="..\..\code\MDLLoader.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\code\MDLMaterialLoader.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="ASELoader"
|
Name="ASELoader"
|
||||||
|
@ -1461,15 +1498,15 @@
|
||||||
Name="jAssimp"
|
Name="jAssimp"
|
||||||
>
|
>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\code\jAssimp\JNICalls.cpp"
|
RelativePath="..\..\port\jAssimp\jni_bridge\JNICalls.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\code\jAssimp\JNIEnvironment.cpp"
|
RelativePath="..\..\port\jAssimp\jni_bridge\JNIEnvironment.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\code\jAssimp\JNILogger.cpp"
|
RelativePath="..\..\port\jAssimp\jni_bridge\JNILogger.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
@ -1481,6 +1518,22 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="HMPLoader"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\code\HMPLoader.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="SMDLoader"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\code\SMDLoader.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="doc"
|
Name="doc"
|
||||||
|
|
Loading…
Reference in New Issue