Fixed HMP typo.
Further work on 3DS target animations. FixNormals-Step inverts face order now. Further work on the doc to aiCamera.h, added helper function to get a view matrix. git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@312 67173fc5-114c-0410-ac8e-9d2fd5bffc1fpull/1/head
parent
601d1c572e
commit
4727ad6c6a
|
@ -54,14 +54,14 @@ using namespace Assimp;
|
||||||
// Setup final material indices, generae a default material if necessary
|
// Setup final material indices, generae a default material if necessary
|
||||||
void Discreet3DSImporter::ReplaceDefaultMaterial()
|
void Discreet3DSImporter::ReplaceDefaultMaterial()
|
||||||
{
|
{
|
||||||
// *******************************************************************
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// try to find an existing material that matches the
|
// Try to find an existing material that matches the
|
||||||
// typical default material setting:
|
// typical default material setting:
|
||||||
// - no textures
|
// - no textures
|
||||||
// - diffuse color (in grey!)
|
// - diffuse color (in grey!)
|
||||||
// NOTE: This is here to workaround the fact that some
|
// NOTE: This is here to workaround the fact that some
|
||||||
// exporters are writing a default material, too.
|
// exporters are writing a default material, too.
|
||||||
// *******************************************************************
|
//////////////////////////////////////////////////////////////////////////
|
||||||
unsigned int idx = 0xcdcdcdcd;
|
unsigned int idx = 0xcdcdcdcd;
|
||||||
for (unsigned int i = 0; i < mScene->mMaterials.size();++i)
|
for (unsigned int i = 0; i < mScene->mMaterials.size();++i)
|
||||||
{
|
{
|
||||||
|
@ -490,6 +490,9 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup the name of the node
|
||||||
|
pcOut->mName.Set(pcIn->mName);
|
||||||
|
|
||||||
// Now build the transformation matrix of the node
|
// Now build the transformation matrix of the node
|
||||||
// ROTATION
|
// ROTATION
|
||||||
if (pcIn->aRotationKeys.size())
|
if (pcIn->aRotationKeys.size())
|
||||||
|
@ -546,7 +549,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,
|
||||||
q.mValue = aiQuaternion(0.f,0.f,AI_DEG_TO_RAD(- f.mValue));
|
q.mValue = aiQuaternion(0.f,0.f,AI_DEG_TO_RAD(- f.mValue));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
if (pcIn->aTargetPositionKeys.size() > 1)
|
if (pcIn->aTargetPositionKeys.size() > 1)
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->debug("3DS: Converting target track ...");
|
DefaultLogger::get()->debug("3DS: Converting target track ...");
|
||||||
|
@ -583,9 +586,24 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,
|
||||||
nda->mPositionKeys = new aiVectorKey[nda->mNumPositionKeys];
|
nda->mPositionKeys = new aiVectorKey[nda->mNumPositionKeys];
|
||||||
::memcpy(nda->mPositionKeys,&distanceTrack[0],
|
::memcpy(nda->mPositionKeys,&distanceTrack[0],
|
||||||
sizeof(aiVectorKey)*nda->mNumPositionKeys);
|
sizeof(aiVectorKey)*nda->mNumPositionKeys);
|
||||||
}
|
|
||||||
|
|
||||||
// Allocate a new nda, increment the nda index
|
// The target animation is now encoded in the local transformation
|
||||||
|
// matrix of the camera, so we must clear the corresponding
|
||||||
|
// fields in aiCamera or aiLight.
|
||||||
|
for (unsigned int n = 0; n < pcSOut->mNumCameras;++n) {
|
||||||
|
if (pcSOut->mCameras[n]->mName == pcOut->mName) {
|
||||||
|
pcSOut->mCameras[n]->mLookAt = aiVector3D(0.f,0.f,1.f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (unsigned int n = 0; n < pcSOut->mNumLights;++n) {
|
||||||
|
if (pcSOut->mLights[n]->mName == pcOut->mName) {
|
||||||
|
pcSOut->mLights[n]->mDirection = aiVector3D(0.f,0.f,1.f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Allocate a new node anim and setup its name
|
||||||
aiNodeAnim* nda = anim->mChannels[anim->mNumChannels++] = new aiNodeAnim();
|
aiNodeAnim* nda = anim->mChannels[anim->mNumChannels++] = new aiNodeAnim();
|
||||||
nda->mNodeName.Set(pcIn->mName);
|
nda->mNodeName.Set(pcIn->mName);
|
||||||
|
|
||||||
|
@ -626,9 +644,6 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup the name of the node
|
|
||||||
pcOut->mName.Set(pcIn->mName);
|
|
||||||
|
|
||||||
// Allocate storage for children
|
// Allocate storage for children
|
||||||
pcOut->mNumChildren = (unsigned int)pcIn->mChildren.size();
|
pcOut->mNumChildren = (unsigned int)pcIn->mChildren.size();
|
||||||
pcOut->mChildren = new aiNode*[pcIn->mChildren.size()];
|
pcOut->mChildren = new aiNode*[pcIn->mChildren.size()];
|
||||||
|
@ -647,6 +662,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,
|
||||||
// Find out how many node animation channels we'll have finally
|
// Find out how many node animation channels we'll have finally
|
||||||
void CountTracks(D3DS::Node* node, unsigned int& cnt)
|
void CountTracks(D3DS::Node* node, unsigned int& cnt)
|
||||||
{
|
{
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// We will never generate more than one channel for a node, so
|
// We will never generate more than one channel for a node, so
|
||||||
// this is rather easy here.
|
// this is rather easy here.
|
||||||
|
|
||||||
|
@ -656,6 +672,7 @@ void CountTracks(D3DS::Node* node, unsigned int& cnt)
|
||||||
{
|
{
|
||||||
++cnt;
|
++cnt;
|
||||||
|
|
||||||
|
// account for the additional channel for the camera/spotlight target position
|
||||||
if (node->aTargetPositionKeys.size() > 1)++cnt;
|
if (node->aTargetPositionKeys.size() > 1)++cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -669,10 +686,10 @@ void CountTracks(D3DS::Node* node, unsigned int& cnt)
|
||||||
void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut)
|
void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut)
|
||||||
{
|
{
|
||||||
pcOut->mRootNode = new aiNode();
|
pcOut->mRootNode = new aiNode();
|
||||||
|
|
||||||
if (0 == mRootNode->mChildren.size())
|
if (0 == mRootNode->mChildren.size())
|
||||||
{
|
{
|
||||||
// seems the file has not even a hierarchy.
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// It seems the file is so fucked up that it has not even a hierarchy.
|
||||||
// generate a flat hiearachy which looks like this:
|
// generate a flat hiearachy which looks like this:
|
||||||
//
|
//
|
||||||
// ROOT_NODE
|
// ROOT_NODE
|
||||||
|
@ -747,18 +764,10 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut)
|
||||||
|
|
||||||
aiMatrix4x4 m;
|
aiMatrix4x4 m;
|
||||||
AddNodeToGraph(pcOut, pcOut->mRootNode, mRootNode,m);
|
AddNodeToGraph(pcOut, pcOut->mRootNode, mRootNode,m);
|
||||||
|
|
||||||
// If the root node is unnamed name it "<3DSRoot>"
|
|
||||||
if (::strstr( pcOut->mRootNode->mName.data, "UNNAMED" )
|
|
||||||
|| pcOut->mRootNode->mName.data[0] == '$'
|
|
||||||
&& pcOut->mRootNode->mName.data[1] == '$')
|
|
||||||
{
|
|
||||||
pcOut->mRootNode->mName.Set("<3DSRoot>");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We used the first vertex color set to store some
|
// We used the first vertex color set to store some
|
||||||
// temporary values, so we need to cleanup here
|
// temporary values so we need to cleanup here
|
||||||
for (unsigned int a = 0; a < pcOut->mNumMeshes;++a)
|
for (unsigned int a = 0; a < pcOut->mNumMeshes;++a)
|
||||||
pcOut->mMeshes[a]->mColors[0] = NULL;
|
pcOut->mMeshes[a]->mColors[0] = NULL;
|
||||||
|
|
||||||
|
@ -771,6 +780,13 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut)
|
||||||
pcOld->mChildren[0] = NULL;
|
pcOld->mChildren[0] = NULL;
|
||||||
delete pcOld;
|
delete pcOld;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the root node is unnamed name it "<3DSRoot>"
|
||||||
|
if (::strstr( pcOut->mRootNode->mName.data, "UNNAMED" ) ||
|
||||||
|
pcOut->mRootNode->mName.data[0] == '$' && pcOut->mRootNode->mName.data[1] == '$')
|
||||||
|
{
|
||||||
|
pcOut->mRootNode->mName.Set("<3DSRoot>");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -415,7 +415,7 @@ void Discreet3DSImporter::ParseChunk(const char* name, unsigned int num)
|
||||||
|
|
||||||
// And finally - the camera rotation angle, in
|
// And finally - the camera rotation angle, in
|
||||||
// counter clockwise direction
|
// counter clockwise direction
|
||||||
float angle = AI_DEG_TO_RAD( stream->GetF4() );
|
const float angle = AI_DEG_TO_RAD( stream->GetF4() );
|
||||||
aiQuaternion quat(camera->mLookAt,angle);
|
aiQuaternion quat(camera->mLookAt,angle);
|
||||||
camera->mUp = quat.GetMatrix() * aiVector3D(0.f,1.f,0.f);
|
camera->mUp = quat.GetMatrix() * aiVector3D(0.f,1.f,0.f);
|
||||||
|
|
||||||
|
@ -576,12 +576,12 @@ void Discreet3DSImporter::SkipTCBInfo()
|
||||||
|
|
||||||
if (!flags)
|
if (!flags)
|
||||||
{
|
{
|
||||||
// ******************************************************************
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// Currently we can't do anything with these values. They occur
|
// Currently we can't do anything with these values. They occur
|
||||||
// quite rare, so it wouldn't be worth the effort implementing
|
// quite rare, so it wouldn't be worth the effort implementing
|
||||||
// them. 3DS ist not really suitable for complex animations,
|
// them. 3DS ist not really suitable for complex animations,
|
||||||
// so full support is not required.
|
// so full support is not required.
|
||||||
// ******************************************************************
|
//////////////////////////////////////////////////////////////////////////
|
||||||
DefaultLogger::get()->warn("3DS: Skipping TCB animation info");
|
DefaultLogger::get()->warn("3DS: Skipping TCB animation info");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -696,7 +696,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
// **************************************************************
|
// ////////////////////////////////////////////////////////////////////
|
||||||
// POSITION KEYFRAME
|
// POSITION KEYFRAME
|
||||||
case Discreet3DS::CHUNK_TRACKPOS:
|
case Discreet3DS::CHUNK_TRACKPOS:
|
||||||
{
|
{
|
||||||
|
@ -744,7 +744,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// **************************************************************
|
// ////////////////////////////////////////////////////////////////////
|
||||||
// CAMERA ROLL KEYFRAME
|
// CAMERA ROLL KEYFRAME
|
||||||
case Discreet3DS::CHUNK_TRACKROLL:
|
case Discreet3DS::CHUNK_TRACKROLL:
|
||||||
{
|
{
|
||||||
|
@ -789,7 +789,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
// **************************************************************
|
// ////////////////////////////////////////////////////////////////////
|
||||||
// CAMERA FOV KEYFRAME
|
// CAMERA FOV KEYFRAME
|
||||||
case Discreet3DS::CHUNK_TRACKFOV:
|
case Discreet3DS::CHUNK_TRACKFOV:
|
||||||
{
|
{
|
||||||
|
@ -799,7 +799,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
// **************************************************************
|
// ////////////////////////////////////////////////////////////////////
|
||||||
// ROTATION KEYFRAME
|
// ROTATION KEYFRAME
|
||||||
case Discreet3DS::CHUNK_TRACKROTATE:
|
case Discreet3DS::CHUNK_TRACKROTATE:
|
||||||
{
|
{
|
||||||
|
@ -846,7 +846,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
|
||||||
}}
|
}}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// **************************************************************
|
// ////////////////////////////////////////////////////////////////////
|
||||||
// SCALING KEYFRAME
|
// SCALING KEYFRAME
|
||||||
case Discreet3DS::CHUNK_TRACKSCALE:
|
case Discreet3DS::CHUNK_TRACKSCALE:
|
||||||
{
|
{
|
||||||
|
@ -956,13 +956,11 @@ void Discreet3DSImporter::ParseFaceChunk()
|
||||||
|
|
||||||
// Now continue and read all material indices
|
// Now continue and read all material indices
|
||||||
cnt = (uint16_t)stream->GetI2();
|
cnt = (uint16_t)stream->GetI2();
|
||||||
for (unsigned int i = 0; i < cnt;++i)
|
for (unsigned int i = 0; i < cnt;++i) {
|
||||||
{
|
|
||||||
unsigned int fidx = (uint16_t)stream->GetI2();
|
unsigned int fidx = (uint16_t)stream->GetI2();
|
||||||
|
|
||||||
// check range
|
// check range
|
||||||
if (fidx >= mMesh.mFaceMaterials.size())
|
if (fidx >= mMesh.mFaceMaterials.size()) {
|
||||||
{
|
|
||||||
DefaultLogger::get()->error("3DS: Invalid face index in face material list");
|
DefaultLogger::get()->error("3DS: Invalid face index in face material list");
|
||||||
}
|
}
|
||||||
else mMesh.mFaceMaterials[fidx] = idx;
|
else mMesh.mFaceMaterials[fidx] = idx;
|
||||||
|
@ -1020,8 +1018,7 @@ void Discreet3DSImporter::ParseMeshChunk()
|
||||||
// Now check whether the matrix has got a negative determinant
|
// Now check whether the matrix has got a negative determinant
|
||||||
// If yes, we need to flip all vertices' Z axis ....
|
// If yes, we need to flip all vertices' Z axis ....
|
||||||
// This code has been taken from lib3ds
|
// This code has been taken from lib3ds
|
||||||
if (mMesh.mMat.Determinant() < 0.0f)
|
if (mMesh.mMat.Determinant() < 0.0f) {
|
||||||
{
|
|
||||||
// Compute the inverse of the matrix
|
// Compute the inverse of the matrix
|
||||||
aiMatrix4x4 mInv = mMesh.mMat;
|
aiMatrix4x4 mInv = mMesh.mMat;
|
||||||
mInv.Inverse();
|
mInv.Inverse();
|
||||||
|
@ -1431,7 +1428,6 @@ void Discreet3DSImporter::ParseColorChunk(aiColor3D* out,
|
||||||
|
|
||||||
default:
|
default:
|
||||||
stream->IncPtr(diff);
|
stream->IncPtr(diff);
|
||||||
|
|
||||||
// Skip unknown chunks, hope this won't cause any problems.
|
// Skip unknown chunks, hope this won't cause any problems.
|
||||||
return ParseColorChunk(out,acceptPercent);
|
return ParseColorChunk(out,acceptPercent);
|
||||||
};
|
};
|
||||||
|
|
|
@ -47,14 +47,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
// internal headers
|
// internal headers
|
||||||
#include "FixNormalsStep.h"
|
#include "FixNormalsStep.h"
|
||||||
#include "SpatialSort.h"
|
|
||||||
|
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
# define sprintf sprintf_s
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
|
@ -87,8 +82,9 @@ void FixInfacingNormalsProcess::Execute( aiScene* pScene)
|
||||||
for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
|
for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
|
||||||
if(ProcessMesh( pScene->mMeshes[a],a))bHas = true;
|
if(ProcessMesh( pScene->mMeshes[a],a))bHas = true;
|
||||||
|
|
||||||
if (bHas)DefaultLogger::get()->debug("FixInfacingNormalsProcess finished. At least one mesh' normals have been flipped.");
|
if (bHas)
|
||||||
else DefaultLogger::get()->debug("FixInfacingNormalsProcess finished");
|
DefaultLogger::get()->debug("FixInfacingNormalsProcess finished. Found issues.");
|
||||||
|
else DefaultLogger::get()->debug("FixInfacingNormalsProcess finished. No changes to the scene.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -97,18 +93,19 @@ bool FixInfacingNormalsProcess::ProcessMesh( aiMesh* pcMesh, unsigned int index)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != pcMesh);
|
ai_assert(NULL != pcMesh);
|
||||||
|
|
||||||
|
// Nothing to do if there are no model normals
|
||||||
if (!pcMesh->HasNormals())return false;
|
if (!pcMesh->HasNormals())return false;
|
||||||
|
|
||||||
// compute the bounding box of both the model vertices + normals and
|
// Compute the bounding box of both the model vertices + normals and
|
||||||
// the umodified model vertices. Then check whether the first BB
|
// the umodified model vertices. Then check whether the first BB
|
||||||
// is smaller than the second. In this case we can assume that the
|
// is smaller than the second. In this case we can assume that the
|
||||||
// normals need to be flipped, although there are a few special cases ..
|
// normals need to be flipped, although there are a few special cases ..
|
||||||
// convex, concave, planar models ...
|
// convex, concave, planar models ...
|
||||||
|
|
||||||
aiVector3D vMin0(1e10f,1e10f,1e10f);
|
aiVector3D vMin0 (1e10f,1e10f,1e10f);
|
||||||
aiVector3D vMin1(1e10f,1e10f,1e10f);
|
aiVector3D vMin1 (1e10f,1e10f,1e10f);
|
||||||
aiVector3D vMax0(-1e10f,-1e10f,-1e10f);
|
aiVector3D vMax0 (-1e10f,-1e10f,-1e10f);
|
||||||
aiVector3D vMax1(-1e10f,-1e10f,-1e10f);
|
aiVector3D vMax1 (-1e10f,-1e10f,-1e10f);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < pcMesh->mNumVertices;++i)
|
for (unsigned int i = 0; i < pcMesh->mNumVertices;++i)
|
||||||
{
|
{
|
||||||
|
@ -120,7 +117,7 @@ bool FixInfacingNormalsProcess::ProcessMesh( aiMesh* pcMesh, unsigned int index)
|
||||||
vMax1.y = std::max(vMax1.y,pcMesh->mVertices[i].y);
|
vMax1.y = std::max(vMax1.y,pcMesh->mVertices[i].y);
|
||||||
vMax1.z = std::max(vMax1.z,pcMesh->mVertices[i].z);
|
vMax1.z = std::max(vMax1.z,pcMesh->mVertices[i].z);
|
||||||
|
|
||||||
aiVector3D vWithNormal = pcMesh->mVertices[i] + pcMesh->mNormals[i];
|
const aiVector3D vWithNormal = pcMesh->mVertices[i] + pcMesh->mNormals[i];
|
||||||
|
|
||||||
vMin0.x = std::min(vMin0.x,vWithNormal.x);
|
vMin0.x = std::min(vMin0.x,vWithNormal.x);
|
||||||
vMin0.y = std::min(vMin0.y,vWithNormal.y);
|
vMin0.y = std::min(vMin0.y,vWithNormal.y);
|
||||||
|
@ -139,20 +136,19 @@ bool FixInfacingNormalsProcess::ProcessMesh( aiMesh* pcMesh, unsigned int index)
|
||||||
const float fDelta1_y = (vMax1.y - vMin1.y);
|
const float fDelta1_y = (vMax1.y - vMin1.y);
|
||||||
const float fDelta1_z = (vMax1.z - vMin1.z);
|
const float fDelta1_z = (vMax1.z - vMin1.z);
|
||||||
|
|
||||||
// check the case where the boxes are overlapping
|
// Check whether the boxes are overlapping
|
||||||
if (fDelta0_x > 0.0f != fDelta1_x > 0.0f)return false;
|
if (fDelta0_x > 0.0f != fDelta1_x > 0.0f)return false;
|
||||||
if (fDelta0_y > 0.0f != fDelta1_y > 0.0f)return false;
|
if (fDelta0_y > 0.0f != fDelta1_y > 0.0f)return false;
|
||||||
if (fDelta0_z > 0.0f != fDelta1_z > 0.0f)return false;
|
if (fDelta0_z > 0.0f != fDelta1_z > 0.0f)return false;
|
||||||
|
|
||||||
|
// Check whether this is a planar surface
|
||||||
// check the case of a very planar surface
|
|
||||||
const float fDelta1_yz = fDelta1_y * fDelta1_z;
|
const float fDelta1_yz = fDelta1_y * fDelta1_z;
|
||||||
|
|
||||||
if (fDelta1_x < 0.05f * sqrtf( fDelta1_yz ))return false;
|
if (fDelta1_x < 0.05f * sqrtf( fDelta1_yz ))return false;
|
||||||
if (fDelta1_y < 0.05f * sqrtf( fDelta1_z * fDelta1_x ))return false;
|
if (fDelta1_y < 0.05f * sqrtf( fDelta1_z * fDelta1_x ))return false;
|
||||||
if (fDelta1_z < 0.05f * sqrtf( fDelta1_y * fDelta1_x ))return false;
|
if (fDelta1_z < 0.05f * sqrtf( fDelta1_y * fDelta1_x ))return false;
|
||||||
|
|
||||||
// now compare the volume of the bounding boxes
|
// now compare the volumes of the bounding boxes
|
||||||
if (::fabsf(fDelta0_x * fDelta1_yz) <
|
if (::fabsf(fDelta0_x * fDelta1_yz) <
|
||||||
::fabsf(fDelta1_x * fDelta1_y * fDelta1_z))
|
::fabsf(fDelta1_x * fDelta1_y * fDelta1_z))
|
||||||
{
|
{
|
||||||
|
@ -163,9 +159,16 @@ bool FixInfacingNormalsProcess::ProcessMesh( aiMesh* pcMesh, unsigned int index)
|
||||||
DefaultLogger::get()->info(buffer);
|
DefaultLogger::get()->info(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Invert normals
|
||||||
for (unsigned int i = 0; i < pcMesh->mNumVertices;++i)
|
for (unsigned int i = 0; i < pcMesh->mNumVertices;++i)
|
||||||
{
|
|
||||||
pcMesh->mNormals[i] *= -1.0f;
|
pcMesh->mNormals[i] *= -1.0f;
|
||||||
|
|
||||||
|
// ... and flip faces
|
||||||
|
for (unsigned int i = 0; i < pcMesh->mNumFaces;++i)
|
||||||
|
{
|
||||||
|
aiFace& face = pcMesh->mFaces[i];
|
||||||
|
for( unsigned int b = 0; b < face.mNumIndices / 2; b++)
|
||||||
|
std::swap( face.mIndices[b], face.mIndices[ face.mNumIndices - 1 - b]);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,7 @@ HMPImporter::~HMPImporter()
|
||||||
// Returns whether the class can handle the format of the given file.
|
// Returns whether the class can handle the format of the given file.
|
||||||
bool HMPImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler) const
|
bool HMPImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler) const
|
||||||
{
|
{
|
||||||
|
(void)pIOHandler; //this avoids the compiler warning of unused element
|
||||||
// simple check of file extension is enough for the moment
|
// simple check of file extension is enough for the moment
|
||||||
std::string::size_type pos = pFile.find_last_of('.');
|
std::string::size_type pos = pFile.find_last_of('.');
|
||||||
// no file extension - can't read
|
// no file extension - can't read
|
||||||
|
@ -84,8 +85,10 @@ bool HMPImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler) const
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Imports the given file into the given scene structure.
|
// Imports the given file into the given scene structure.
|
||||||
void HMPImporter::InternReadFile( const std::string& pFile,
|
void HMPImporter::InternReadFile( const std::string& pFile,
|
||||||
aiScene* pScene, IOSystem* pIOHandler)
|
aiScene* _pScene, IOSystem* _pIOHandler)
|
||||||
{
|
{
|
||||||
|
pScene = _pScene;
|
||||||
|
pIOHandler = _pIOHandler;
|
||||||
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
|
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
|
||||||
|
|
||||||
// Check whether we can read from the file
|
// Check whether we can read from the file
|
||||||
|
@ -99,17 +102,13 @@ void HMPImporter::InternReadFile( const std::string& pFile,
|
||||||
throw new ImportErrorException( "HMP File is too small.");
|
throw new ImportErrorException( "HMP 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
|
||||||
this->pScene = pScene;
|
|
||||||
this->pIOHandler = pIOHandler;
|
|
||||||
|
|
||||||
std::vector<uint8_t> buffer(fileSize);
|
std::vector<uint8_t> buffer(fileSize);
|
||||||
mBuffer = &buffer[0];
|
mBuffer = &buffer[0];
|
||||||
file->Read( (void*)mBuffer, 1, fileSize);
|
file->Read( (void*)mBuffer, 1, fileSize);
|
||||||
iFileSize = (unsigned int)fileSize;
|
iFileSize = (unsigned int)fileSize;
|
||||||
|
|
||||||
// Determine the file subtype and call the appropriate member function
|
// Determine the file subtype and call the appropriate member function
|
||||||
uint32_t iMagic = *((uint32_t*)this->mBuffer);
|
const uint32_t iMagic = *((uint32_t*)this->mBuffer);
|
||||||
|
|
||||||
|
|
||||||
// HMP4 format
|
// HMP4 format
|
||||||
if (AI_HMP_MAGIC_NUMBER_LE_4 == iMagic ||
|
if (AI_HMP_MAGIC_NUMBER_LE_4 == iMagic ||
|
||||||
|
|
|
@ -39,30 +39,25 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
//
|
/**
|
||||||
//! @file Definition of in-memory structures for the MDL file format.
|
* @file MDLFileData.h
|
||||||
//
|
* @brief Definition of in-memory structures for the MDL file format.
|
||||||
// The specification has been taken from various sources on the internet.
|
*
|
||||||
// - http://tfc.duke.free.fr/coding/mdl-specs-en.html
|
* The specification has been taken from various sources on the internet.
|
||||||
// - Conitec's MED SDK
|
* - http://tfc.duke.free.fr/coding/mdl-specs-en.html
|
||||||
// - Many quite long HEX-editor sessions
|
* - 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
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "../include/aiTypes.h"
|
|
||||||
#include "../include/aiMesh.h"
|
|
||||||
#include "../include/aiAnim.h"
|
|
||||||
#include "../include/aiMaterial.h"
|
|
||||||
|
|
||||||
#include "./../include/Compiler/pushpack1.h"
|
#include "./../include/Compiler/pushpack1.h"
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace MDL {
|
namespace MDL {
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------
|
||||||
// to make it easier for ourselfes, we test the magic word against both "endianesses"
|
// to make it easier for ourselfes, we test the magic word against both "endianesses"
|
||||||
#define MDL_MAKE(string) ((uint32_t)((string[0] << 24) + (string[1] << 16) + (string[2] << 8) + string[3]))
|
#define MDL_MAKE(string) ((uint32_t)((string[0] << 24) + (string[1] << 16) + (string[2] << 8) + string[3]))
|
||||||
|
|
||||||
|
@ -113,7 +108,7 @@ namespace MDL {
|
||||||
# define AI_MDL7_REFERRER_MATERIAL "&&&referrer&&&",0,0
|
# define AI_MDL7_REFERRER_MATERIAL "&&&referrer&&&",0,0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Header
|
/** \struct Header
|
||||||
* \brief Data structure for the MDL main header
|
* \brief Data structure for the MDL main header
|
||||||
*/
|
*/
|
||||||
|
@ -167,7 +162,7 @@ struct Header
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Header_MDL7
|
/** \struct Header_MDL7
|
||||||
* \brief Data structure for the MDL 7 main header
|
* \brief Data structure for the MDL 7 main header
|
||||||
*/
|
*/
|
||||||
|
@ -226,7 +221,8 @@ struct Header_MDL7
|
||||||
uint16_t frame_stc_size;
|
uint16_t frame_stc_size;
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Bone_MDL7
|
/** \struct Bone_MDL7
|
||||||
* \brief Data structure for a bone in a MDL7 file
|
* \brief Data structure for a bone in a MDL7 file
|
||||||
*/
|
*/
|
||||||
|
@ -261,7 +257,7 @@ struct Bone_MDL7
|
||||||
# define AI_MDL7_MAX_GROUPNAMESIZE 16
|
# define AI_MDL7_MAX_GROUPNAMESIZE 16
|
||||||
#endif // ! AI_MDL7_MAX_GROUPNAMESIZE
|
#endif // ! AI_MDL7_MAX_GROUPNAMESIZE
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Group_MDL7
|
/** \struct Group_MDL7
|
||||||
* \brief Group in a MDL7 file
|
* \brief Group in a MDL7 file
|
||||||
*/
|
*/
|
||||||
|
@ -303,7 +299,7 @@ struct Group_MDL7
|
||||||
# define AI_MDL7_MAX_BONENAMESIZE 20
|
# define AI_MDL7_MAX_BONENAMESIZE 20
|
||||||
#endif // !! AI_MDL7_MAX_BONENAMESIZE
|
#endif // !! AI_MDL7_MAX_BONENAMESIZE
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Deformer_MDL7
|
/** \struct Deformer_MDL7
|
||||||
* \brief Deformer in a MDL7 file
|
* \brief Deformer in a MDL7 file
|
||||||
*/
|
*/
|
||||||
|
@ -318,7 +314,7 @@ struct Deformer_MDL7
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct DeformerElement_MDL7
|
/** \struct DeformerElement_MDL7
|
||||||
* \brief Deformer element in a MDL7 file
|
* \brief Deformer element in a MDL7 file
|
||||||
*/
|
*/
|
||||||
|
@ -331,7 +327,7 @@ struct DeformerElement_MDL7
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct DeformerWeight_MDL7
|
/** \struct DeformerWeight_MDL7
|
||||||
* \brief Deformer weight in a MDL7 file
|
* \brief Deformer weight in a MDL7 file
|
||||||
*/
|
*/
|
||||||
|
@ -346,7 +342,7 @@ struct DeformerWeight_MDL7
|
||||||
// don't know why this was in the original headers ...
|
// don't know why this was in the original headers ...
|
||||||
typedef int32_t MD7_MATERIAL_ASCDEFSIZE;
|
typedef int32_t MD7_MATERIAL_ASCDEFSIZE;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct ColorValue_MDL7
|
/** \struct ColorValue_MDL7
|
||||||
* \brief Data structure for a color value in a MDL7 file
|
* \brief Data structure for a color value in a MDL7 file
|
||||||
*/
|
*/
|
||||||
|
@ -355,7 +351,7 @@ struct ColorValue_MDL7
|
||||||
float r,g,b,a;
|
float r,g,b,a;
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Material_MDL7
|
/** \struct Material_MDL7
|
||||||
* \brief Data structure for a Material in a MDL7 file
|
* \brief Data structure for a Material in a MDL7 file
|
||||||
*/
|
*/
|
||||||
|
@ -378,7 +374,7 @@ struct Material_MDL7
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Skin
|
/** \struct Skin
|
||||||
* \brief Skin data structure #1 - used by Quake1, MDL2, MDL3 and MDL4
|
* \brief Skin data structure #1 - used by Quake1, MDL2, MDL3 and MDL4
|
||||||
*/
|
*/
|
||||||
|
@ -402,7 +398,7 @@ struct Skin
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Skin
|
/** \struct Skin
|
||||||
* \brief Skin data structure #2 - used by MDL5, MDL6 and MDL7
|
* \brief Skin data structure #2 - used by MDL5, MDL6 and MDL7
|
||||||
* \see Skin
|
* \see Skin
|
||||||
|
@ -431,7 +427,7 @@ struct Skin_MDL7
|
||||||
char texture_name[AI_MDL7_MAX_TEXNAMESIZE];
|
char texture_name[AI_MDL7_MAX_TEXNAMESIZE];
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct RGB565
|
/** \struct RGB565
|
||||||
* \brief Data structure for a RGB565 pixel in a texture
|
* \brief Data structure for a RGB565 pixel in a texture
|
||||||
*/
|
*/
|
||||||
|
@ -442,7 +438,7 @@ struct RGB565
|
||||||
uint16_t b : 5;
|
uint16_t b : 5;
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct ARGB4
|
/** \struct ARGB4
|
||||||
* \brief Data structure for a ARGB4444 pixel in a texture
|
* \brief Data structure for a ARGB4444 pixel in a texture
|
||||||
*/
|
*/
|
||||||
|
@ -454,7 +450,7 @@ struct ARGB4
|
||||||
uint16_t b : 4;
|
uint16_t b : 4;
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct GroupSkin
|
/** \struct GroupSkin
|
||||||
* \brief Skin data structure #2 (group of pictures)
|
* \brief Skin data structure #2 (group of pictures)
|
||||||
*/
|
*/
|
||||||
|
@ -473,7 +469,7 @@ struct GroupSkin
|
||||||
uint8_t **data;
|
uint8_t **data;
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct TexCoord
|
/** \struct TexCoord
|
||||||
* \brief Texture coordinate data structure used by the Quake1 MDL format
|
* \brief Texture coordinate data structure used by the Quake1 MDL format
|
||||||
*/
|
*/
|
||||||
|
@ -489,7 +485,7 @@ struct TexCoord
|
||||||
int32_t t;
|
int32_t t;
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct TexCoord_MDL3
|
/** \struct TexCoord_MDL3
|
||||||
* \brief Data structure for an UV coordinate in the 3DGS MDL3 format
|
* \brief Data structure for an UV coordinate in the 3DGS MDL3 format
|
||||||
*/
|
*/
|
||||||
|
@ -502,7 +498,7 @@ struct TexCoord_MDL3
|
||||||
int16_t v;
|
int16_t v;
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct TexCoord_MDL7
|
/** \struct TexCoord_MDL7
|
||||||
* \brief Data structure for an UV coordinate in the 3DGS MDL7 format
|
* \brief Data structure for an UV coordinate in the 3DGS MDL7 format
|
||||||
*/
|
*/
|
||||||
|
@ -515,7 +511,7 @@ struct TexCoord_MDL7
|
||||||
float v;
|
float v;
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct SkinSet_MDL7
|
/** \struct SkinSet_MDL7
|
||||||
* \brief Skin set data structure for the 3DGS MDL7 format
|
* \brief Skin set data structure for the 3DGS MDL7 format
|
||||||
* MDL7 references UV coordinates per face via an index list.
|
* MDL7 references UV coordinates per face via an index list.
|
||||||
|
@ -531,7 +527,7 @@ struct SkinSet_MDL7
|
||||||
int32_t material; // size 4
|
int32_t material; // size 4
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Triangle
|
/** \struct Triangle
|
||||||
* \brief Triangle data structure for the Quake1 MDL format
|
* \brief Triangle data structure for the Quake1 MDL format
|
||||||
*/
|
*/
|
||||||
|
@ -544,7 +540,7 @@ struct Triangle
|
||||||
int32_t vertex[3];
|
int32_t vertex[3];
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Triangle_MDL3
|
/** \struct Triangle_MDL3
|
||||||
* \brief Triangle data structure for the 3DGS MDL3 format
|
* \brief Triangle data structure for the 3DGS MDL3 format
|
||||||
*/
|
*/
|
||||||
|
@ -557,7 +553,7 @@ struct Triangle_MDL3
|
||||||
uint16_t index_uv[3];
|
uint16_t index_uv[3];
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Triangle_MDL7
|
/** \struct Triangle_MDL7
|
||||||
* \brief Triangle data structure for the 3DGS MDL7 format
|
* \brief Triangle data structure for the 3DGS MDL7 format
|
||||||
*/
|
*/
|
||||||
|
@ -588,7 +584,7 @@ struct Triangle_MDL7
|
||||||
# define AI_MDL_FRONTFACE 0x1
|
# define AI_MDL_FRONTFACE 0x1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Vertex
|
/** \struct Vertex
|
||||||
* \brief Vertex data structure
|
* \brief Vertex data structure
|
||||||
*/
|
*/
|
||||||
|
@ -599,7 +595,7 @@ struct Vertex
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
struct Vertex_MDL4
|
struct Vertex_MDL4
|
||||||
{
|
{
|
||||||
uint16_t v[3];
|
uint16_t v[3];
|
||||||
|
@ -610,7 +606,7 @@ struct Vertex_MDL4
|
||||||
#define AI_MDL7_FRAMEVERTEX120503_STCSIZE 16
|
#define AI_MDL7_FRAMEVERTEX120503_STCSIZE 16
|
||||||
#define AI_MDL7_FRAMEVERTEX030305_STCSIZE 26
|
#define AI_MDL7_FRAMEVERTEX030305_STCSIZE 26
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Vertex_MDL7
|
/** \struct Vertex_MDL7
|
||||||
* \brief Vertex data structure used in MDL7 files
|
* \brief Vertex data structure used in MDL7 files
|
||||||
*/
|
*/
|
||||||
|
@ -625,7 +621,7 @@ struct Vertex_MDL7
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct BoneTransform_MDL7
|
/** \struct BoneTransform_MDL7
|
||||||
* \brief bone transformation matrix structure used in MDL7 files
|
* \brief bone transformation matrix structure used in MDL7 files
|
||||||
*/
|
*/
|
||||||
|
@ -646,7 +642,7 @@ struct BoneTransform_MDL7
|
||||||
#define AI_MDL7_MAX_FRAMENAMESIZE 16
|
#define AI_MDL7_MAX_FRAMENAMESIZE 16
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Frame_MDL7
|
/** \struct Frame_MDL7
|
||||||
* \brief Frame data structure used by MDL7 files
|
* \brief Frame data structure used by MDL7 files
|
||||||
*/
|
*/
|
||||||
|
@ -658,7 +654,7 @@ struct Frame_MDL7
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct SimpleFrame
|
/** \struct SimpleFrame
|
||||||
* \brief Data structure for a simple frame
|
* \brief Data structure for a simple frame
|
||||||
*/
|
*/
|
||||||
|
@ -677,7 +673,7 @@ struct SimpleFrame
|
||||||
Vertex *verts;
|
Vertex *verts;
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Frame
|
/** \struct Frame
|
||||||
* \brief Model frame data structure
|
* \brief Model frame data structure
|
||||||
*/
|
*/
|
||||||
|
@ -691,7 +687,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
|
||||||
|
@ -707,7 +703,7 @@ struct SimpleFrame_MDLn_SP
|
||||||
Vertex_MDL4 *verts;
|
Vertex_MDL4 *verts;
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct GroupFrame
|
/** \struct GroupFrame
|
||||||
* \brief Data structure for a group of frames
|
* \brief Data structure for a group of frames
|
||||||
*/
|
*/
|
||||||
|
@ -731,8 +727,7 @@ struct GroupFrame
|
||||||
|
|
||||||
#include "./../include/Compiler/poppack1.h"
|
#include "./../include/Compiler/poppack1.h"
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
/** \struct IntFace_MDL7
|
/** \struct IntFace_MDL7
|
||||||
* \brief Internal data structure to temporarily represent a face
|
* \brief Internal data structure to temporarily represent a face
|
||||||
*/
|
*/
|
||||||
|
@ -753,8 +748,7 @@ struct IntFace_MDL7
|
||||||
unsigned int iMatIndex[2];
|
unsigned int iMatIndex[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
/** \struct IntMaterial_MDL7
|
/** \struct IntMaterial_MDL7
|
||||||
* \brief Internal data structure to temporarily represent a material
|
* \brief Internal data structure to temporarily represent a material
|
||||||
* which has been created from two single materials along with the
|
* which has been created from two single materials along with the
|
||||||
|
@ -776,8 +770,7 @@ struct IntMaterial_MDL7
|
||||||
unsigned int iOldMatIndices[2];
|
unsigned int iOldMatIndices[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
/** \struct IntBone_MDL7
|
/** \struct IntBone_MDL7
|
||||||
* \brief Internal data structure to represent a bone in a MDL7 file with
|
* \brief Internal data structure to represent a bone in a MDL7 file with
|
||||||
* all of its animation channels assigned to it.
|
* all of its animation channels assigned to it.
|
||||||
|
@ -808,7 +801,7 @@ struct IntBone_MDL7 : aiBone
|
||||||
std::vector<aiQuatKey> pkeyRotations;
|
std::vector<aiQuatKey> pkeyRotations;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
//! Describes a MDL7 frame
|
//! Describes a MDL7 frame
|
||||||
struct IntFrameInfo_MDL7
|
struct IntFrameInfo_MDL7
|
||||||
{
|
{
|
||||||
|
@ -825,7 +818,7 @@ struct IntFrameInfo_MDL7
|
||||||
BE_NCONST MDL::Frame_MDL7* pcFrame;
|
BE_NCONST MDL::Frame_MDL7* pcFrame;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
//! Describes a MDL7 mesh group
|
//! Describes a MDL7 mesh group
|
||||||
struct IntGroupInfo_MDL7
|
struct IntGroupInfo_MDL7
|
||||||
{
|
{
|
||||||
|
@ -860,7 +853,7 @@ struct IntGroupInfo_MDL7
|
||||||
BE_NCONST MDL::Vertex_MDL7* pcGroupVerts;
|
BE_NCONST MDL::Vertex_MDL7* pcGroupVerts;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
//! Holds the data that belongs to a MDL7 mesh group
|
//! Holds the data that belongs to a MDL7 mesh group
|
||||||
struct IntGroupData_MDL7
|
struct IntGroupData_MDL7
|
||||||
{
|
{
|
||||||
|
@ -891,7 +884,7 @@ struct IntGroupData_MDL7
|
||||||
bool bNeed2UV;
|
bool bNeed2UV;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
//! Holds data from an MDL7 file that is shared by all mesh groups
|
//! Holds data from an MDL7 file that is shared by all mesh groups
|
||||||
struct IntSharedData_MDL7
|
struct IntSharedData_MDL7
|
||||||
{
|
{
|
||||||
|
@ -926,7 +919,7 @@ struct IntSharedData_MDL7
|
||||||
unsigned int iNum;
|
unsigned int iNum;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
//! Contains input data for GenerateOutputMeshes_3DGS_MDL7
|
//! Contains input data for GenerateOutputMeshes_3DGS_MDL7
|
||||||
struct IntSplittedGroupData_MDL7
|
struct IntSplittedGroupData_MDL7
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,7 +39,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file Implementation of the main parts of the MDL importer class */
|
/** @file MDLLoader.cpp
|
||||||
|
* @brief Implementation of the main parts of the MDL importer class
|
||||||
|
* *TODO* Cleanup and further testing of some parts necessary
|
||||||
|
*/
|
||||||
|
|
||||||
// internal headers
|
// internal headers
|
||||||
#include "AssimpPCH.h"
|
#include "AssimpPCH.h"
|
||||||
|
@ -52,34 +55,25 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// macros used by the MDL7 loader
|
// Ugly stuff ... nevermind
|
||||||
|
#define _AI_MDL7_ACCESS(_data, _index, _limit, _type) \
|
||||||
#if (!defined _AI_MDL7_ACCESS)
|
|
||||||
# define _AI_MDL7_ACCESS(_data, _index, _limit, _type) \
|
|
||||||
(*((const _type*)(((const char*)_data) + _index * _limit)))
|
(*((const _type*)(((const char*)_data) + _index * _limit)))
|
||||||
#endif
|
|
||||||
#if (!defined _AI_MDL7_ACCESS_PTR)
|
#define _AI_MDL7_ACCESS_PTR(_data, _index, _limit, _type) \
|
||||||
# define _AI_MDL7_ACCESS_PTR(_data, _index, _limit, _type) \
|
|
||||||
((BE_NCONST _type*)(((const char*)_data) + _index * _limit))
|
((BE_NCONST _type*)(((const char*)_data) + _index * _limit))
|
||||||
#endif
|
|
||||||
#if (!defined _AI_MDL7_ACCESS_VERT)
|
#define _AI_MDL7_ACCESS_VERT(_data, _index, _limit) \
|
||||||
# define _AI_MDL7_ACCESS_VERT(_data, _index, _limit) \
|
|
||||||
_AI_MDL7_ACCESS(_data,_index,_limit,MDL::Vertex_MDL7)
|
_AI_MDL7_ACCESS(_data,_index,_limit,MDL::Vertex_MDL7)
|
||||||
#endif
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
MDLImporter::MDLImporter()
|
MDLImporter::MDLImporter()
|
||||||
{
|
{}
|
||||||
// nothing to do here
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Destructor, private as well
|
// Destructor, private as well
|
||||||
MDLImporter::~MDLImporter()
|
MDLImporter::~MDLImporter()
|
||||||
{
|
{}
|
||||||
// nothing to do here
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the class can handle the format of the given file.
|
// Returns whether the class can handle the format of the given file.
|
||||||
|
@ -91,15 +85,12 @@ bool MDLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler) const
|
||||||
// no file extension - can't read
|
// no file extension - can't read
|
||||||
if( pos == std::string::npos)
|
if( pos == std::string::npos)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::string extension = pFile.substr( pos);
|
std::string extension = pFile.substr( pos);
|
||||||
|
for( std::string::iterator it = extension.begin(); it != extension.end(); ++it)
|
||||||
|
*it = tolower( *it);
|
||||||
|
|
||||||
if (extension.length() < 4)return false;
|
return extension == ".mdl";
|
||||||
if (extension[0] != '.')return false;
|
|
||||||
if (extension[1] != 'm' && extension[1] != 'M')return false;
|
|
||||||
if (extension[2] != 'd' && extension[2] != 'D')return false;
|
|
||||||
if (extension[3] != 'l' && extension[3] != 'L')return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Setup configuration properties
|
// Setup configuration properties
|
||||||
|
@ -107,93 +98,99 @@ void MDLImporter::SetupProperties(const Importer* pImp)
|
||||||
{
|
{
|
||||||
// The AI_CONFIG_IMPORT_MDL_KEYFRAME option overrides the
|
// The AI_CONFIG_IMPORT_MDL_KEYFRAME option overrides the
|
||||||
// AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
|
// AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
|
||||||
if(0xffffffff == (this->configFrameID = pImp->GetPropertyInteger(
|
if(0xffffffff == (configFrameID = pImp->GetPropertyInteger(
|
||||||
AI_CONFIG_IMPORT_MDL_KEYFRAME,0xffffffff)))
|
AI_CONFIG_IMPORT_MDL_KEYFRAME,0xffffffff)))
|
||||||
{
|
{
|
||||||
this->configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
|
configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
|
||||||
}
|
}
|
||||||
this->configPalette = pImp->GetPropertyString(AI_CONFIG_IMPORT_MDL_COLORMAP,"colormap.lmp");
|
configPalette = pImp->GetPropertyString(AI_CONFIG_IMPORT_MDL_COLORMAP,"colormap.lmp");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Get a list of all supported extensions
|
||||||
|
void MDLImporter::GetExtensionList(std::string& append)
|
||||||
|
{
|
||||||
|
append.append( ".mdl" );
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Imports the given file into the given scene structure.
|
// Imports the given file into the given scene structure.
|
||||||
void MDLImporter::InternReadFile( const std::string& pFile,
|
void MDLImporter::InternReadFile( const std::string& pFile,
|
||||||
aiScene* pScene, IOSystem* pIOHandler)
|
aiScene* _pScene, IOSystem* _pIOHandler)
|
||||||
{
|
{
|
||||||
|
pScene = _pScene;
|
||||||
|
pIOHandler = _pIOHandler;
|
||||||
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
|
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
|
||||||
|
|
||||||
// Check whether we can read from the file
|
// Check whether we can read from the file
|
||||||
if( file.get() == NULL)
|
if( file.get() == NULL)
|
||||||
throw new ImportErrorException( "Failed to open MDL file " + pFile + ".");
|
throw new ImportErrorException( "Failed to open MDL file " + pFile + ".");
|
||||||
|
|
||||||
|
// This should work for all other types of MDL files, too ...
|
||||||
// this should work for all other types of MDL files, too ...
|
|
||||||
// the quake header is one of the smallest, afaik
|
// the quake header is one of the smallest, afaik
|
||||||
this->iFileSize = (unsigned int)file->FileSize();
|
iFileSize = (unsigned int)file->FileSize();
|
||||||
if( this->iFileSize < sizeof(MDL::Header))
|
if( iFileSize < sizeof(MDL::Header))
|
||||||
throw new ImportErrorException( "MDL File is too small.");
|
throw new ImportErrorException( "MDL 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
|
||||||
this->pScene = pScene;
|
mBuffer = new unsigned char[iFileSize+1];
|
||||||
this->pIOHandler = pIOHandler;
|
file->Read( (void*)mBuffer, 1, iFileSize);
|
||||||
this->mBuffer = new unsigned char[this->iFileSize+1];
|
|
||||||
file->Read( (void*)mBuffer, 1, this->iFileSize);
|
|
||||||
|
|
||||||
// append a binary zero to the end of the buffer.
|
// Append a binary zero to the end of the buffer.
|
||||||
// this is just for safety that string parsing routines
|
// this is just for safety that string parsing routines
|
||||||
// find the end of the buffer ...
|
// find the end of the buffer ...
|
||||||
this->mBuffer[this->iFileSize] = '\0';
|
mBuffer[this->iFileSize] = '\0';
|
||||||
uint32_t iMagicWord = *((uint32_t*)this->mBuffer);
|
const uint32_t iMagicWord = *((uint32_t*)this->mBuffer);
|
||||||
|
|
||||||
// determine the file subtype and call the appropriate member function
|
// Determine the file subtype and call the appropriate member function
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// Original Quake1 format
|
// Original Quake1 format
|
||||||
if (AI_MDL_MAGIC_NUMBER_BE == iMagicWord ||
|
if (AI_MDL_MAGIC_NUMBER_BE == iMagicWord ||
|
||||||
AI_MDL_MAGIC_NUMBER_LE == iMagicWord)
|
AI_MDL_MAGIC_NUMBER_LE == iMagicWord)
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->debug("MDL subtype: Quake 1, magic word is IDPO");
|
DefaultLogger::get()->debug("MDL subtype: Quake 1, magic word is IDPO");
|
||||||
this->iGSFileVersion = 0;
|
iGSFileVersion = 0;
|
||||||
this->InternReadFile_Quake1();
|
InternReadFile_Quake1();
|
||||||
}
|
}
|
||||||
// GameStudio A<old> MDL2 format - used by some test models that come with 3DGS
|
// GameStudio A<old> MDL2 format - used by some test models that come with 3DGS
|
||||||
else if (AI_MDL_MAGIC_NUMBER_BE_GS3 == iMagicWord ||
|
else if (AI_MDL_MAGIC_NUMBER_BE_GS3 == iMagicWord ||
|
||||||
AI_MDL_MAGIC_NUMBER_LE_GS3 == iMagicWord)
|
AI_MDL_MAGIC_NUMBER_LE_GS3 == iMagicWord)
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A2, magic word is MDL2");
|
DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A2, magic word is MDL2");
|
||||||
this->iGSFileVersion = 2;
|
iGSFileVersion = 2;
|
||||||
this->InternReadFile_Quake1();
|
InternReadFile_Quake1();
|
||||||
}
|
}
|
||||||
// GameStudio A4 MDL3 format
|
// GameStudio A4 MDL3 format
|
||||||
else if (AI_MDL_MAGIC_NUMBER_BE_GS4 == iMagicWord ||
|
else if (AI_MDL_MAGIC_NUMBER_BE_GS4 == iMagicWord ||
|
||||||
AI_MDL_MAGIC_NUMBER_LE_GS4 == iMagicWord)
|
AI_MDL_MAGIC_NUMBER_LE_GS4 == iMagicWord)
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A4, magic word is MDL3");
|
DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A4, magic word is MDL3");
|
||||||
this->iGSFileVersion = 3;
|
iGSFileVersion = 3;
|
||||||
this->InternReadFile_3DGS_MDL345();
|
InternReadFile_3DGS_MDL345();
|
||||||
}
|
}
|
||||||
// GameStudio A5+ MDL4 format
|
// GameStudio A5+ MDL4 format
|
||||||
else if (AI_MDL_MAGIC_NUMBER_BE_GS5a == iMagicWord ||
|
else if (AI_MDL_MAGIC_NUMBER_BE_GS5a == iMagicWord ||
|
||||||
AI_MDL_MAGIC_NUMBER_LE_GS5a == iMagicWord)
|
AI_MDL_MAGIC_NUMBER_LE_GS5a == iMagicWord)
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A4, magic word is MDL4");
|
DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A4, magic word is MDL4");
|
||||||
this->iGSFileVersion = 4;
|
iGSFileVersion = 4;
|
||||||
this->InternReadFile_3DGS_MDL345();
|
InternReadFile_3DGS_MDL345();
|
||||||
}
|
}
|
||||||
// GameStudio A5+ MDL5 format
|
// GameStudio A5+ MDL5 format
|
||||||
else if (AI_MDL_MAGIC_NUMBER_BE_GS5b == iMagicWord ||
|
else if (AI_MDL_MAGIC_NUMBER_BE_GS5b == iMagicWord ||
|
||||||
AI_MDL_MAGIC_NUMBER_LE_GS5b == iMagicWord)
|
AI_MDL_MAGIC_NUMBER_LE_GS5b == iMagicWord)
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A5, magic word is MDL5");
|
DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A5, magic word is MDL5");
|
||||||
this->iGSFileVersion = 5;
|
iGSFileVersion = 5;
|
||||||
this->InternReadFile_3DGS_MDL345();
|
InternReadFile_3DGS_MDL345();
|
||||||
}
|
}
|
||||||
// GameStudio A7 MDL7 format
|
// GameStudio A7 MDL7 format
|
||||||
else if (AI_MDL_MAGIC_NUMBER_BE_GS7 == iMagicWord ||
|
else if (AI_MDL_MAGIC_NUMBER_BE_GS7 == iMagicWord ||
|
||||||
AI_MDL_MAGIC_NUMBER_LE_GS7 == iMagicWord)
|
AI_MDL_MAGIC_NUMBER_LE_GS7 == iMagicWord)
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A7, magic word is MDL7");
|
DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A7, magic word is MDL7");
|
||||||
this->iGSFileVersion = 7;
|
iGSFileVersion = 7;
|
||||||
this->InternReadFile_3DGS_MDL7();
|
InternReadFile_3DGS_MDL7();
|
||||||
}
|
}
|
||||||
// IDST/IDSQ Format (CS:S/HL², etc ...)
|
// IDST/IDSQ Format (CS:S/HL², etc ...)
|
||||||
else if (AI_MDL_MAGIC_NUMBER_BE_HL2a == iMagicWord ||
|
else if (AI_MDL_MAGIC_NUMBER_BE_HL2a == iMagicWord ||
|
||||||
|
@ -202,8 +199,8 @@ void MDLImporter::InternReadFile( const std::string& pFile,
|
||||||
AI_MDL_MAGIC_NUMBER_LE_HL2b == iMagicWord)
|
AI_MDL_MAGIC_NUMBER_LE_HL2b == iMagicWord)
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->debug("MDL subtype: CS:S\\HL², magic word is IDST/IDSQ");
|
DefaultLogger::get()->debug("MDL subtype: CS:S\\HL², magic word is IDST/IDSQ");
|
||||||
this->iGSFileVersion = 0;
|
iGSFileVersion = 0;
|
||||||
this->InternReadFile_HL2();
|
InternReadFile_HL2();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -235,7 +232,9 @@ void MDLImporter::InternReadFile( const std::string& pFile,
|
||||||
AI_DEBUG_INVALIDATE_PTR(this->pIOHandler);
|
AI_DEBUG_INVALIDATE_PTR(this->pIOHandler);
|
||||||
AI_DEBUG_INVALIDATE_PTR(this->pScene);
|
AI_DEBUG_INVALIDATE_PTR(this->pScene);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Check whether we're still inside the valid file range
|
||||||
void MDLImporter::SizeCheck(const void* szPos)
|
void MDLImporter::SizeCheck(const void* szPos)
|
||||||
{
|
{
|
||||||
if (!szPos || (const unsigned char*)szPos > this->mBuffer + this->iFileSize)
|
if (!szPos || (const unsigned char*)szPos > this->mBuffer + this->iFileSize)
|
||||||
|
@ -244,17 +243,19 @@ void MDLImporter::SizeCheck(const void* szPos)
|
||||||
"or contains invalid data.");
|
"or contains invalid data.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Just for debgging purposes
|
||||||
void MDLImporter::SizeCheck(const void* szPos, const char* szFile, unsigned int iLine)
|
void MDLImporter::SizeCheck(const void* szPos, const char* szFile, unsigned int iLine)
|
||||||
{
|
{
|
||||||
if (!szFile)return SizeCheck(szPos);
|
ai_assert(NULL != szFile);
|
||||||
if (!szPos || (const unsigned char*)szPos > this->mBuffer + this->iFileSize)
|
if (!szPos || (const unsigned char*)szPos > mBuffer + iFileSize)
|
||||||
{
|
{
|
||||||
// remove a directory if there is one
|
// remove a directory if there is one
|
||||||
const char* szFilePtr = ::strrchr(szFile,'\\');
|
const char* szFilePtr = ::strrchr(szFile,'\\');
|
||||||
if (!szFilePtr)
|
if (!szFilePtr) {
|
||||||
{
|
if(!(szFilePtr = ::strrchr(szFile,'/')))
|
||||||
if(!(szFilePtr = ::strrchr(szFile,'/')))szFilePtr = szFile;
|
szFilePtr = szFile;
|
||||||
}
|
}
|
||||||
if (szFilePtr)++szFilePtr;
|
if (szFilePtr)++szFilePtr;
|
||||||
|
|
||||||
|
@ -265,7 +266,9 @@ void MDLImporter::SizeCheck(const void* szPos, const char* szFile, unsigned int
|
||||||
throw new ImportErrorException(szBuffer);
|
throw new ImportErrorException(szBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Validate a quake file header
|
||||||
void MDLImporter::ValidateHeader_Quake1(const MDL::Header* pcHeader)
|
void MDLImporter::ValidateHeader_Quake1(const MDL::Header* pcHeader)
|
||||||
{
|
{
|
||||||
// some values may not be NULL
|
// some values may not be NULL
|
||||||
|
@ -320,16 +323,14 @@ void FlipQuakeHeader(BE_NCONST MDL::Header* pcHeader)
|
||||||
AI_SWAP4( pcHeader->skinheight);
|
AI_SWAP4( pcHeader->skinheight);
|
||||||
AI_SWAP4( pcHeader->skinwidth);
|
AI_SWAP4( pcHeader->skinwidth);
|
||||||
AI_SWAP4( pcHeader->synctype);
|
AI_SWAP4( pcHeader->synctype);
|
||||||
|
|
||||||
// ByteSwap::Swap4(& pcHeader->skin);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Read a Quake 1 file
|
||||||
void MDLImporter::InternReadFile_Quake1( )
|
void MDLImporter::InternReadFile_Quake1( )
|
||||||
{
|
{
|
||||||
ai_assert(NULL != pScene);
|
ai_assert(NULL != pScene);
|
||||||
|
|
||||||
BE_NCONST MDL::Header *pcHeader = (BE_NCONST MDL::Header*)this->mBuffer;
|
BE_NCONST MDL::Header *pcHeader = (BE_NCONST MDL::Header*)this->mBuffer;
|
||||||
|
|
||||||
#ifdef AI_BUILD_BIG_ENDIAN
|
#ifdef AI_BUILD_BIG_ENDIAN
|
||||||
|
@ -402,13 +403,10 @@ void MDLImporter::InternReadFile_Quake1( )
|
||||||
BE_NCONST MDL::GroupFrame* pcFrames2 = (BE_NCONST MDL::GroupFrame*)pcFrames;
|
BE_NCONST MDL::GroupFrame* pcFrames2 = (BE_NCONST MDL::GroupFrame*)pcFrames;
|
||||||
pcFirstFrame = (BE_NCONST MDL::SimpleFrame*)(&pcFrames2->time + pcFrames->type);
|
pcFirstFrame = (BE_NCONST MDL::SimpleFrame*)(&pcFrames2->time + pcFrames->type);
|
||||||
}
|
}
|
||||||
BE_NCONST MDL::Vertex* pcVertices = (BE_NCONST MDL::Vertex*) ((pcFirstFrame->name) +
|
BE_NCONST MDL::Vertex* pcVertices = (BE_NCONST MDL::Vertex*) ((pcFirstFrame->name) + sizeof(pcFirstFrame->name));
|
||||||
sizeof(pcFirstFrame->name));
|
|
||||||
|
|
||||||
VALIDATE_FILE_SIZE((const unsigned char*)(pcVertices + pcHeader->num_verts));
|
VALIDATE_FILE_SIZE((const unsigned char*)(pcVertices + pcHeader->num_verts));
|
||||||
|
|
||||||
#ifdef AI_BUILD_BIG_ENDIAN
|
#ifdef AI_BUILD_BIG_ENDIAN
|
||||||
|
|
||||||
for (int i = 0; i<pcHeader->num_verts;++i)
|
for (int i = 0; i<pcHeader->num_verts;++i)
|
||||||
{
|
{
|
||||||
AI_SWAP4( pcTexCoords[i].onseam );
|
AI_SWAP4( pcTexCoords[i].onseam );
|
||||||
|
@ -423,12 +421,10 @@ void MDLImporter::InternReadFile_Quake1( )
|
||||||
AI_SWAP4( pcTriangles[i].vertex[1]);
|
AI_SWAP4( pcTriangles[i].vertex[1]);
|
||||||
AI_SWAP4( pcTriangles[i].vertex[2]);
|
AI_SWAP4( pcTriangles[i].vertex[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// setup materials
|
// setup materials
|
||||||
this->SetupMaterialProperties_3DGS_MDL5_Quake1();
|
SetupMaterialProperties_3DGS_MDL5_Quake1();
|
||||||
|
|
||||||
// allocate enough storage to hold all vertices and triangles
|
// allocate enough storage to hold all vertices and triangles
|
||||||
aiMesh* pcMesh = new aiMesh();
|
aiMesh* pcMesh = new aiMesh();
|
||||||
|
@ -509,10 +505,11 @@ void MDLImporter::InternReadFile_Quake1( )
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Setup material properties for Quake and older GameStudio files
|
||||||
void MDLImporter::SetupMaterialProperties_3DGS_MDL5_Quake1( )
|
void MDLImporter::SetupMaterialProperties_3DGS_MDL5_Quake1( )
|
||||||
{
|
{
|
||||||
// get a pointer to the file header
|
|
||||||
const MDL::Header* const pcHeader = (const MDL::Header*)this->mBuffer;
|
const MDL::Header* const pcHeader = (const MDL::Header*)this->mBuffer;
|
||||||
|
|
||||||
// allocate ONE material
|
// allocate ONE material
|
||||||
|
@ -520,14 +517,13 @@ void MDLImporter::SetupMaterialProperties_3DGS_MDL5_Quake1( )
|
||||||
pScene->mMaterials[0] = new MaterialHelper();
|
pScene->mMaterials[0] = new MaterialHelper();
|
||||||
pScene->mNumMaterials = 1;
|
pScene->mNumMaterials = 1;
|
||||||
|
|
||||||
// setup the material properties
|
// setup the material's properties
|
||||||
const int iMode = (int)aiShadingMode_Gouraud;
|
const int iMode = (int)aiShadingMode_Gouraud;
|
||||||
MaterialHelper* const pcHelper = (MaterialHelper*)pScene->mMaterials[0];
|
MaterialHelper* const pcHelper = (MaterialHelper*)pScene->mMaterials[0];
|
||||||
pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
|
pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
|
||||||
|
|
||||||
aiColor4D clr;
|
aiColor4D clr;
|
||||||
if (0 != pcHeader->num_skins && pScene->mNumTextures)
|
if (0 != pcHeader->num_skins && pScene->mNumTextures) {
|
||||||
{
|
|
||||||
// can we replace the texture with a single color?
|
// can we replace the texture with a single color?
|
||||||
clr = this->ReplaceTextureWithColor(pScene->mTextures[0]);
|
clr = this->ReplaceTextureWithColor(pScene->mTextures[0]);
|
||||||
if (is_not_qnan(clr.r))
|
if (is_not_qnan(clr.r))
|
||||||
|
@ -553,7 +549,9 @@ void MDLImporter::SetupMaterialProperties_3DGS_MDL5_Quake1( )
|
||||||
clr.b *= 0.05f;clr.a = 1.0f;
|
clr.b *= 0.05f;clr.a = 1.0f;
|
||||||
pcHelper->AddProperty<aiColor4D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
|
pcHelper->AddProperty<aiColor4D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Read a MDL 3,4,5 file
|
||||||
void MDLImporter::InternReadFile_3DGS_MDL345( )
|
void MDLImporter::InternReadFile_3DGS_MDL345( )
|
||||||
{
|
{
|
||||||
ai_assert(NULL != pScene);
|
ai_assert(NULL != pScene);
|
||||||
|
@ -563,28 +561,26 @@ void MDLImporter::InternReadFile_3DGS_MDL345( )
|
||||||
#ifdef AI_BUILD_BIG_ENDIAN
|
#ifdef AI_BUILD_BIG_ENDIAN
|
||||||
FlipQuakeHeader(pcHeader);
|
FlipQuakeHeader(pcHeader);
|
||||||
#endif
|
#endif
|
||||||
this->ValidateHeader_Quake1(pcHeader);
|
ValidateHeader_Quake1(pcHeader);
|
||||||
|
|
||||||
// current cursor position in the file
|
// current cursor position in the file
|
||||||
const unsigned char* szCurrent = (const unsigned char*)(pcHeader+1);
|
const unsigned char* szCurrent = (const unsigned char*)(pcHeader+1);
|
||||||
|
|
||||||
// need to read all textures
|
// need to read all textures
|
||||||
for (unsigned int i = 0; i < (unsigned int)pcHeader->num_skins;++i)
|
for (unsigned int i = 0; i < (unsigned int)pcHeader->num_skins;++i) {
|
||||||
{
|
|
||||||
BE_NCONST MDL::Skin* pcSkin;
|
BE_NCONST MDL::Skin* pcSkin;
|
||||||
pcSkin = (BE_NCONST MDL::Skin*)szCurrent;
|
pcSkin = (BE_NCONST MDL::Skin*)szCurrent;
|
||||||
AI_SWAP4( pcSkin->group);
|
AI_SWAP4( pcSkin->group);
|
||||||
// create one output image
|
// create one output image
|
||||||
unsigned int iSkip = i ? 0xffffffff : 0;
|
unsigned int iSkip = i ? 0xffffffff : 0;
|
||||||
if (5 <= this->iGSFileVersion)
|
if (5 <= iGSFileVersion)
|
||||||
{
|
{
|
||||||
// MDL5 format could contain MIPmaps
|
// MDL5 format could contain MIPmaps
|
||||||
this->CreateTexture_3DGS_MDL5((unsigned char*)pcSkin + sizeof(uint32_t),
|
CreateTexture_3DGS_MDL5((unsigned char*)pcSkin + sizeof(uint32_t),
|
||||||
pcSkin->group,&iSkip);
|
pcSkin->group,&iSkip);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
CreateTexture_3DGS_MDL4((unsigned char*)pcSkin + sizeof(uint32_t),
|
||||||
this->CreateTexture_3DGS_MDL4((unsigned char*)pcSkin + sizeof(uint32_t),
|
|
||||||
pcSkin->group,&iSkip);
|
pcSkin->group,&iSkip);
|
||||||
}
|
}
|
||||||
// need to skip one image
|
// need to skip one image
|
||||||
|
@ -624,7 +620,7 @@ void MDLImporter::InternReadFile_3DGS_MDL345( )
|
||||||
VALIDATE_FILE_SIZE(szCurrent);
|
VALIDATE_FILE_SIZE(szCurrent);
|
||||||
|
|
||||||
// setup materials
|
// setup materials
|
||||||
this->SetupMaterialProperties_3DGS_MDL5_Quake1();
|
SetupMaterialProperties_3DGS_MDL5_Quake1();
|
||||||
|
|
||||||
// allocate enough storage to hold all vertices and triangles
|
// allocate enough storage to hold all vertices and triangles
|
||||||
aiMesh* pcMesh = new aiMesh();
|
aiMesh* pcMesh = new aiMesh();
|
||||||
|
@ -659,15 +655,12 @@ void MDLImporter::InternReadFile_3DGS_MDL345( )
|
||||||
AI_SWAP4(pcFrames->type);
|
AI_SWAP4(pcFrames->type);
|
||||||
|
|
||||||
// byte packed vertices
|
// byte packed vertices
|
||||||
// BIG TODO: these two snippets are nearly totally identical ...
|
// FIXME: these two snippets are nearly totally identical ...
|
||||||
// ***********************************************************************
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
if (0 == pcFrames->type || 3 >= this->iGSFileVersion)
|
if (0 == pcFrames->type || 3 >= this->iGSFileVersion)
|
||||||
{
|
{
|
||||||
const MDL::SimpleFrame* pcFirstFrame = (const MDL::SimpleFrame*)(szCurrent + sizeof(uint32_t));
|
const MDL::SimpleFrame* pcFirstFrame = (const MDL::SimpleFrame*)(szCurrent + sizeof(uint32_t));
|
||||||
|
const MDL::Vertex* pcVertices = (const MDL::Vertex*) ((pcFirstFrame->name) + sizeof(pcFirstFrame->name));
|
||||||
// get a pointer to the vertices
|
|
||||||
const MDL::Vertex* pcVertices = (const MDL::Vertex*) ((pcFirstFrame->name)
|
|
||||||
+ sizeof(pcFirstFrame->name));
|
|
||||||
|
|
||||||
VALIDATE_FILE_SIZE(pcVertices + pcHeader->num_verts);
|
VALIDATE_FILE_SIZE(pcVertices + pcHeader->num_verts);
|
||||||
|
|
||||||
|
@ -705,9 +698,8 @@ void MDLImporter::InternReadFile_3DGS_MDL345( )
|
||||||
pcMesh->mNormals[iCurrent].y *= -1.0f;
|
pcMesh->mNormals[iCurrent].y *= -1.0f;
|
||||||
|
|
||||||
// read texture coordinates
|
// read texture coordinates
|
||||||
if (pcHeader->synctype)
|
if (pcHeader->synctype) {
|
||||||
{
|
ImportUVCoordinate_3DGS_MDL345(pcMesh->mTextureCoords[0][iCurrent],
|
||||||
this->ImportUVCoordinate_3DGS_MDL345(pcMesh->mTextureCoords[0][iCurrent],
|
|
||||||
pcTexCoords,pcTriangles->index_uv[c]);
|
pcTexCoords,pcTriangles->index_uv[c]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -719,7 +711,7 @@ void MDLImporter::InternReadFile_3DGS_MDL345( )
|
||||||
|
|
||||||
}
|
}
|
||||||
// short packed vertices
|
// short packed vertices
|
||||||
// ***********************************************************************
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// now get a pointer to the first frame in the file
|
// now get a pointer to the first frame in the file
|
||||||
|
@ -765,9 +757,8 @@ void MDLImporter::InternReadFile_3DGS_MDL345( )
|
||||||
pcMesh->mNormals[iCurrent].y *= -1.0f;
|
pcMesh->mNormals[iCurrent].y *= -1.0f;
|
||||||
|
|
||||||
// read texture coordinates
|
// read texture coordinates
|
||||||
if (pcHeader->synctype)
|
if (pcHeader->synctype) {
|
||||||
{
|
ImportUVCoordinate_3DGS_MDL345(pcMesh->mTextureCoords[0][iCurrent],
|
||||||
this->ImportUVCoordinate_3DGS_MDL345(pcMesh->mTextureCoords[0][iCurrent],
|
|
||||||
pcTexCoords,pcTriangles->index_uv[c]);
|
pcTexCoords,pcTriangles->index_uv[c]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -784,14 +775,15 @@ void MDLImporter::InternReadFile_3DGS_MDL345( )
|
||||||
this->CalculateUVCoordinates_MDL5();
|
this->CalculateUVCoordinates_MDL5();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Get a single UV coordinate for Quake and older GameStudio files
|
||||||
void MDLImporter::ImportUVCoordinate_3DGS_MDL345(
|
void MDLImporter::ImportUVCoordinate_3DGS_MDL345(
|
||||||
aiVector3D& vOut,
|
aiVector3D& vOut,
|
||||||
const MDL::TexCoord_MDL3* pcSrc,
|
const MDL::TexCoord_MDL3* pcSrc,
|
||||||
unsigned int iIndex)
|
unsigned int iIndex)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != pcSrc);
|
ai_assert(NULL != pcSrc);
|
||||||
|
|
||||||
const MDL::Header* const pcHeader = (const MDL::Header*)this->mBuffer;
|
const MDL::Header* const pcHeader = (const MDL::Header*)this->mBuffer;
|
||||||
|
|
||||||
// validate UV indices
|
// validate UV indices
|
||||||
|
@ -805,8 +797,7 @@ void MDLImporter::ImportUVCoordinate_3DGS_MDL345(
|
||||||
float t = (float)pcSrc[iIndex].v;
|
float t = (float)pcSrc[iIndex].v;
|
||||||
|
|
||||||
// Scale s and t to range from 0.0 to 1.0
|
// Scale s and t to range from 0.0 to 1.0
|
||||||
if (0x5 != this->iGSFileVersion)
|
if (0x5 != this->iGSFileVersion) {
|
||||||
{
|
|
||||||
s = (s + 0.5f) / pcHeader->skinwidth;
|
s = (s + 0.5f) / pcHeader->skinwidth;
|
||||||
t = 1.0f-(t + 0.5f) / pcHeader->skinheight;
|
t = 1.0f-(t + 0.5f) / pcHeader->skinheight;
|
||||||
}
|
}
|
||||||
|
@ -815,7 +806,9 @@ void MDLImporter::ImportUVCoordinate_3DGS_MDL345(
|
||||||
vOut.y = t;
|
vOut.y = t;
|
||||||
vOut.z = 0.0f;
|
vOut.z = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Compute UV coordinates for a MDL5 file
|
||||||
void MDLImporter::CalculateUVCoordinates_MDL5()
|
void MDLImporter::CalculateUVCoordinates_MDL5()
|
||||||
{
|
{
|
||||||
const MDL::Header* const pcHeader = (const MDL::Header*)this->mBuffer;
|
const MDL::Header* const pcHeader = (const MDL::Header*)this->mBuffer;
|
||||||
|
@ -850,14 +843,12 @@ void MDLImporter::CalculateUVCoordinates_MDL5()
|
||||||
iHeight = pcTex->mHeight;
|
iHeight = pcTex->mHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (1 != iWidth || 1 != iHeight)
|
if (1 != iWidth || 1 != iHeight) {
|
||||||
{
|
|
||||||
const float fWidth = (float)iWidth;
|
const float fWidth = (float)iWidth;
|
||||||
const float fHeight = (float)iHeight;
|
const float fHeight = (float)iHeight;
|
||||||
aiMesh* pcMesh = this->pScene->mMeshes[0];
|
aiMesh* pcMesh = this->pScene->mMeshes[0];
|
||||||
for (unsigned int i = 0; i < pcMesh->mNumVertices;++i)
|
for (unsigned int i = 0; i < pcMesh->mNumVertices;++i)
|
||||||
{
|
{
|
||||||
// width and height can't be 0 here
|
|
||||||
pcMesh->mTextureCoords[0][i].x /= fWidth;
|
pcMesh->mTextureCoords[0][i].x /= fWidth;
|
||||||
pcMesh->mTextureCoords[0][i].y /= fHeight;
|
pcMesh->mTextureCoords[0][i].y /= fHeight;
|
||||||
pcMesh->mTextureCoords[0][i].y = 1.0f - pcMesh->mTextureCoords[0][i].y; // DX to OGL
|
pcMesh->mTextureCoords[0][i].y = 1.0f - pcMesh->mTextureCoords[0][i].y; // DX to OGL
|
||||||
|
@ -865,39 +856,35 @@ void MDLImporter::CalculateUVCoordinates_MDL5()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Validate the header of a MDL7 file
|
||||||
void MDLImporter::ValidateHeader_3DGS_MDL7(const MDL::Header_MDL7* pcHeader)
|
void MDLImporter::ValidateHeader_3DGS_MDL7(const MDL::Header_MDL7* pcHeader)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != pcHeader);
|
ai_assert(NULL != pcHeader);
|
||||||
|
|
||||||
if (sizeof(MDL::ColorValue_MDL7) != pcHeader->colorvalue_stc_size)
|
// There are some fixed sizes ...
|
||||||
{
|
if (sizeof(MDL::ColorValue_MDL7) != pcHeader->colorvalue_stc_size) {
|
||||||
throw new ImportErrorException(
|
throw new ImportErrorException(
|
||||||
"[3DGS MDL7] sizeof(MDL::ColorValue_MDL7) != pcHeader->colorvalue_stc_size"
|
"[3DGS MDL7] sizeof(MDL::ColorValue_MDL7) != pcHeader->colorvalue_stc_size");
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (sizeof(MDL::TexCoord_MDL7) != pcHeader->skinpoint_stc_size)
|
if (sizeof(MDL::TexCoord_MDL7) != pcHeader->skinpoint_stc_size) {
|
||||||
{
|
|
||||||
throw new ImportErrorException(
|
throw new ImportErrorException(
|
||||||
"[3DGS MDL7] sizeof(MDL::TexCoord_MDL7) != pcHeader->skinpoint_stc_size"
|
"[3DGS MDL7] sizeof(MDL::TexCoord_MDL7) != pcHeader->skinpoint_stc_size");
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (sizeof(MDL::Skin_MDL7) != pcHeader->skin_stc_size)
|
if (sizeof(MDL::Skin_MDL7) != pcHeader->skin_stc_size) {
|
||||||
{
|
|
||||||
throw new ImportErrorException(
|
throw new ImportErrorException(
|
||||||
"sizeof(MDL::Skin_MDL7) != pcHeader->skin_stc_size"
|
"sizeof(MDL::Skin_MDL7) != pcHeader->skin_stc_size");
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if there are no groups ... how should we load such a file?
|
// if there are no groups ... how should we load such a file?
|
||||||
if(!pcHeader->groups_num)
|
if(!pcHeader->groups_num) {
|
||||||
{
|
|
||||||
// LOG
|
|
||||||
throw new ImportErrorException( "[3DGS MDL7] No frames found");
|
throw new ImportErrorException( "[3DGS MDL7] No frames found");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// resolve bone animation matrices
|
||||||
void MDLImporter::CalcAbsBoneMatrices_3DGS_MDL7(MDL::IntBone_MDL7** apcOutBones)
|
void MDLImporter::CalcAbsBoneMatrices_3DGS_MDL7(MDL::IntBone_MDL7** apcOutBones)
|
||||||
{
|
{
|
||||||
const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
|
const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
|
||||||
|
@ -923,8 +910,9 @@ void MDLImporter::CalcAbsBoneMatrices_3DGS_MDL7(MDL::IntBone_MDL7** apcOutBones)
|
||||||
|
|
||||||
if (iParent == pcBone->parent_index)
|
if (iParent == pcBone->parent_index)
|
||||||
{
|
{
|
||||||
// extract from MDL7 readme ...
|
// MDL7 readme
|
||||||
/************************************************************
|
////////////////////////////////////////////////////////////////
|
||||||
|
/*
|
||||||
The animation matrix is then calculated the following way:
|
The animation matrix is then calculated the following way:
|
||||||
|
|
||||||
vector3 bPos = <absolute bone position>
|
vector3 bPos = <absolute bone position>
|
||||||
|
@ -939,7 +927,8 @@ void MDLImporter::CalcAbsBoneMatrices_3DGS_MDL7(MDL::IntBone_MDL7** apcOutBones)
|
||||||
|
|
||||||
laM = sm1 * laM;
|
laM = sm1 * laM;
|
||||||
laM = laM * sm2;
|
laM = laM * sm2;
|
||||||
*************************************************************/
|
*/
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
MDL::IntBone_MDL7* const pcOutBone = apcOutBones[iBone];
|
MDL::IntBone_MDL7* const pcOutBone = apcOutBones[iBone];
|
||||||
|
|
||||||
|
@ -967,14 +956,12 @@ void MDLImporter::CalcAbsBoneMatrices_3DGS_MDL7(MDL::IntBone_MDL7** apcOutBones)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// make sure we won't run over the buffer's end if there is no
|
// Make sure we won't run over the buffer's end if there is no
|
||||||
// terminal 0 character (however the documentation says there
|
// terminal 0 character (however the documentation says there
|
||||||
// should be one)
|
// should be one)
|
||||||
uint32_t iMaxLen = pcHeader->bone_stc_size-16;
|
uint32_t iMaxLen = pcHeader->bone_stc_size-16;
|
||||||
for (uint32_t qq = 0; qq < iMaxLen;++qq)
|
for (uint32_t qq = 0; qq < iMaxLen;++qq) {
|
||||||
{
|
if (!pcBone->name[qq]) {
|
||||||
if (!pcBone->name[qq])
|
|
||||||
{
|
|
||||||
iMaxLen = qq;
|
iMaxLen = qq;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -990,7 +977,9 @@ void MDLImporter::CalcAbsBoneMatrices_3DGS_MDL7(MDL::IntBone_MDL7** apcOutBones)
|
||||||
++iParent;
|
++iParent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// read bones from a MDL7 file
|
||||||
MDL::IntBone_MDL7** MDLImporter::LoadBones_3DGS_MDL7()
|
MDL::IntBone_MDL7** MDLImporter::LoadBones_3DGS_MDL7()
|
||||||
{
|
{
|
||||||
const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
|
const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
|
||||||
|
@ -1010,12 +999,14 @@ MDL::IntBone_MDL7** MDLImporter::LoadBones_3DGS_MDL7()
|
||||||
apcBonesOut[crank] = new MDL::IntBone_MDL7();
|
apcBonesOut[crank] = new MDL::IntBone_MDL7();
|
||||||
|
|
||||||
// and calculate absolute bone offset matrices ...
|
// and calculate absolute bone offset matrices ...
|
||||||
this->CalcAbsBoneMatrices_3DGS_MDL7(apcBonesOut);
|
CalcAbsBoneMatrices_3DGS_MDL7(apcBonesOut);
|
||||||
return apcBonesOut;
|
return apcBonesOut;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// read faces from a MDL7 file
|
||||||
void MDLImporter::ReadFaces_3DGS_MDL7(
|
void MDLImporter::ReadFaces_3DGS_MDL7(
|
||||||
const MDL::IntGroupInfo_MDL7& groupInfo,
|
const MDL::IntGroupInfo_MDL7& groupInfo,
|
||||||
MDL::IntGroupData_MDL7& groupData)
|
MDL::IntGroupData_MDL7& groupData)
|
||||||
|
@ -1038,8 +1029,7 @@ void MDLImporter::ReadFaces_3DGS_MDL7(
|
||||||
unsigned int iIndex = pcGroupTris->v_index[c];
|
unsigned int iIndex = pcGroupTris->v_index[c];
|
||||||
if(iIndex > (unsigned int)groupInfo.pcGroup->numverts)
|
if(iIndex > (unsigned int)groupInfo.pcGroup->numverts)
|
||||||
{
|
{
|
||||||
// (we might need to read this section a second time - to process
|
// (we might need to read this section a second time - to process frame vertices correctly)
|
||||||
// frame vertices correctly)
|
|
||||||
const_cast<MDL::Triangle_MDL7*>(pcGroupTris)->v_index[c] = iIndex = groupInfo.pcGroup->numverts-1;
|
const_cast<MDL::Triangle_MDL7*>(pcGroupTris)->v_index[c] = iIndex = groupInfo.pcGroup->numverts-1;
|
||||||
DefaultLogger::get()->warn("Index overflow in MDL7 vertex list");
|
DefaultLogger::get()->warn("Index overflow in MDL7 vertex list");
|
||||||
}
|
}
|
||||||
|
@ -1078,7 +1068,6 @@ void MDLImporter::ReadFaces_3DGS_MDL7(
|
||||||
vNormal.y *= -1.0f;
|
vNormal.y *= -1.0f;
|
||||||
}
|
}
|
||||||
// validate and process the first uv coordinate set
|
// validate and process the first uv coordinate set
|
||||||
// *************************************************************
|
|
||||||
if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV)
|
if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV)
|
||||||
{
|
{
|
||||||
if (groupInfo.pcGroup->num_stpts)
|
if (groupInfo.pcGroup->num_stpts)
|
||||||
|
@ -1108,7 +1097,6 @@ void MDLImporter::ReadFaces_3DGS_MDL7(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// validate and process the second uv coordinate set
|
// validate and process the second uv coordinate set
|
||||||
// *************************************************************
|
|
||||||
if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_TWO_UV)
|
if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_TWO_UV)
|
||||||
{
|
{
|
||||||
if (groupInfo.pcGroup->num_stpts)
|
if (groupInfo.pcGroup->num_stpts)
|
||||||
|
@ -1150,7 +1138,9 @@ void MDLImporter::ReadFaces_3DGS_MDL7(
|
||||||
pcHeader->triangle_stc_size);
|
pcHeader->triangle_stc_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// handle frames in a MDL7 file
|
||||||
bool MDLImporter::ProcessFrames_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInfo,
|
bool MDLImporter::ProcessFrames_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInfo,
|
||||||
MDL::IntGroupData_MDL7& groupData,
|
MDL::IntGroupData_MDL7& groupData,
|
||||||
MDL::IntSharedData_MDL7& shared,
|
MDL::IntSharedData_MDL7& shared,
|
||||||
|
@ -1159,7 +1149,7 @@ bool MDLImporter::ProcessFrames_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInf
|
||||||
{
|
{
|
||||||
ai_assert(NULL != szCurrent && NULL != szCurrentOut);
|
ai_assert(NULL != szCurrent && NULL != szCurrentOut);
|
||||||
|
|
||||||
const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
|
const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7*)mBuffer;
|
||||||
|
|
||||||
// if we have no bones we can simply skip all frames,
|
// if we have no bones we can simply skip all frames,
|
||||||
// otherwise we'll need to process them.
|
// otherwise we'll need to process them.
|
||||||
|
@ -1175,8 +1165,7 @@ bool MDLImporter::ProcessFrames_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInf
|
||||||
frame.pcFrame->vertices_count * pcHeader->framevertex_stc_size +
|
frame.pcFrame->vertices_count * pcHeader->framevertex_stc_size +
|
||||||
frame.pcFrame->transmatrix_count * pcHeader->bonetrans_stc_size;
|
frame.pcFrame->transmatrix_count * pcHeader->bonetrans_stc_size;
|
||||||
|
|
||||||
if (((const char*)szCurrent - (const char*)pcHeader) + iAdd > (unsigned int)pcHeader->data_size)
|
if (((const char*)szCurrent - (const char*)pcHeader) + iAdd > (unsigned int)pcHeader->data_size) {
|
||||||
{
|
|
||||||
DefaultLogger::get()->warn("Index overflow in frame area. "
|
DefaultLogger::get()->warn("Index overflow in frame area. "
|
||||||
"Ignoring all frames and all further mesh groups, too.");
|
"Ignoring all frames and all further mesh groups, too.");
|
||||||
|
|
||||||
|
@ -1255,23 +1244,24 @@ bool MDLImporter::ProcessFrames_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// parse bone trafo matrix keys (only if there are bones ...)
|
// parse bone trafo matrix keys (only if there are bones ...)
|
||||||
if (shared.apcOutBones)this->ParseBoneTrafoKeys_3DGS_MDL7(groupInfo,frame,shared);
|
if (shared.apcOutBones)ParseBoneTrafoKeys_3DGS_MDL7(groupInfo,frame,shared);
|
||||||
szCurrent += iAdd;
|
szCurrent += iAdd;
|
||||||
}
|
}
|
||||||
*szCurrentOut = szCurrent;
|
*szCurrentOut = szCurrent;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Sort faces by material, handle multiple UVs correctly
|
||||||
void MDLImporter::SortByMaterials_3DGS_MDL7(
|
void MDLImporter::SortByMaterials_3DGS_MDL7(
|
||||||
const MDL::IntGroupInfo_MDL7& groupInfo,
|
const MDL::IntGroupInfo_MDL7& groupInfo,
|
||||||
MDL::IntGroupData_MDL7& groupData,
|
MDL::IntGroupData_MDL7& groupData,
|
||||||
MDL::IntSplittedGroupData_MDL7& splittedGroupData)
|
MDL::IntSplittedGroupData_MDL7& splittedGroupData)
|
||||||
{
|
{
|
||||||
const unsigned int iNumMaterials = (unsigned int)splittedGroupData.shared.pcMats.size();
|
const unsigned int iNumMaterials = (unsigned int)splittedGroupData.shared.pcMats.size();
|
||||||
|
|
||||||
// if we don't need a second set of texture coordinates there is no reason to keep it in memory ...
|
|
||||||
if (!groupData.bNeed2UV)
|
if (!groupData.bNeed2UV)
|
||||||
{
|
{
|
||||||
|
// if we don't need a second set of texture coordinates there is no reason to keep it in memory ...
|
||||||
groupData.vTextureCoords2.clear();
|
groupData.vTextureCoords2.clear();
|
||||||
|
|
||||||
// allocate the array
|
// allocate the array
|
||||||
|
@ -1304,9 +1294,8 @@ void MDLImporter::SortByMaterials_3DGS_MDL7(
|
||||||
std::vector<MDL::IntMaterial_MDL7> avMats;
|
std::vector<MDL::IntMaterial_MDL7> avMats;
|
||||||
avMats.reserve(iNumMaterials*2);
|
avMats.reserve(iNumMaterials*2);
|
||||||
|
|
||||||
std::vector<std::vector<unsigned int>* > aiTempSplit;
|
// fixme: why on the heap?
|
||||||
aiTempSplit.reserve(iNumMaterials*2);
|
std::vector<std::vector<unsigned int>* > aiTempSplit(iNumMaterials*2);
|
||||||
|
|
||||||
for (unsigned int m = 0; m < iNumMaterials;++m)
|
for (unsigned int m = 0; m < iNumMaterials;++m)
|
||||||
aiTempSplit[m] = new std::vector<unsigned int>();
|
aiTempSplit[m] = new std::vector<unsigned int>();
|
||||||
|
|
||||||
|
@ -1358,7 +1347,7 @@ void MDLImporter::SortByMaterials_3DGS_MDL7(
|
||||||
sHelper.pcMat = new MaterialHelper();
|
sHelper.pcMat = new MaterialHelper();
|
||||||
sHelper.iOldMatIndices[0] = iMatIndex;
|
sHelper.iOldMatIndices[0] = iMatIndex;
|
||||||
sHelper.iOldMatIndices[1] = iMatIndex2;
|
sHelper.iOldMatIndices[1] = iMatIndex2;
|
||||||
this->JoinSkins_3DGS_MDL7(splittedGroupData.shared.pcMats[iMatIndex],
|
JoinSkins_3DGS_MDL7(splittedGroupData.shared.pcMats[iMatIndex],
|
||||||
splittedGroupData.shared.pcMats[iMatIndex2],sHelper.pcMat);
|
splittedGroupData.shared.pcMats[iMatIndex2],sHelper.pcMat);
|
||||||
|
|
||||||
// and add it to the list
|
// and add it to the list
|
||||||
|
@ -1367,9 +1356,8 @@ void MDLImporter::SortByMaterials_3DGS_MDL7(
|
||||||
}
|
}
|
||||||
// adjust the size of the file array
|
// adjust the size of the file array
|
||||||
if (iNum == aiTempSplit.size())
|
if (iNum == aiTempSplit.size())
|
||||||
{
|
|
||||||
aiTempSplit.push_back(new std::vector<unsigned int>());
|
aiTempSplit.push_back(new std::vector<unsigned int>());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
aiTempSplit[iNum]->push_back(iFace);
|
aiTempSplit[iNum]->push_back(iFace);
|
||||||
}
|
}
|
||||||
|
@ -1395,7 +1383,9 @@ void MDLImporter::SortByMaterials_3DGS_MDL7(
|
||||||
splittedGroupData.aiSplit[m] = aiTempSplit[m];
|
splittedGroupData.aiSplit[m] = aiTempSplit[m];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Read a MDL7 file
|
||||||
void MDLImporter::InternReadFile_3DGS_MDL7( )
|
void MDLImporter::InternReadFile_3DGS_MDL7( )
|
||||||
{
|
{
|
||||||
ai_assert(NULL != pScene);
|
ai_assert(NULL != pScene);
|
||||||
|
@ -1462,8 +1452,7 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
|
||||||
if (1 != groupInfo.pcGroup->typ)
|
if (1 != groupInfo.pcGroup->typ)
|
||||||
{
|
{
|
||||||
// Not a triangle-based mesh
|
// Not a triangle-based mesh
|
||||||
DefaultLogger::get()->warn("[3DGS MDL7] Mesh group is not basing on"
|
DefaultLogger::get()->warn("[3DGS MDL7] Not a triangle mesh group. Continuing happily");
|
||||||
"triangles. Continuing happily");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// store the name of the group
|
// store the name of the group
|
||||||
|
@ -1544,8 +1533,7 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
|
||||||
if (sharedData.apcOutBones)groupData.aiBones.resize(iNumVertices,0xffffffff);
|
if (sharedData.apcOutBones)groupData.aiBones.resize(iNumVertices,0xffffffff);
|
||||||
|
|
||||||
// it is also possible that there are 0 UV coordinate sets
|
// it is also possible that there are 0 UV coordinate sets
|
||||||
if (groupInfo.pcGroup->num_stpts)
|
if (groupInfo.pcGroup->num_stpts){
|
||||||
{
|
|
||||||
groupData.vTextureCoords1.resize(iNumVertices,aiVector3D());
|
groupData.vTextureCoords1.resize(iNumVertices,aiVector3D());
|
||||||
|
|
||||||
// check whether the triangle data structure is large enough
|
// check whether the triangle data structure is large enough
|
||||||
|
@ -1559,14 +1547,13 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
|
||||||
groupData.pcFaces = new MDL::IntFace_MDL7[groupInfo.pcGroup->numtris];
|
groupData.pcFaces = new MDL::IntFace_MDL7[groupInfo.pcGroup->numtris];
|
||||||
|
|
||||||
// read all faces into the preallocated arrays
|
// read all faces into the preallocated arrays
|
||||||
this->ReadFaces_3DGS_MDL7(groupInfo, groupData);
|
ReadFaces_3DGS_MDL7(groupInfo, groupData);
|
||||||
|
|
||||||
// sort by materials
|
// sort by materials
|
||||||
this->SortByMaterials_3DGS_MDL7(groupInfo, groupData,
|
SortByMaterials_3DGS_MDL7(groupInfo, groupData,
|
||||||
splittedGroupData);
|
splittedGroupData);
|
||||||
|
|
||||||
for (unsigned int qq = 0; qq < sharedData.pcMats.size();++qq)
|
for (unsigned int qq = 0; qq < sharedData.pcMats.size();++qq) {
|
||||||
{
|
|
||||||
if (!splittedGroupData.aiSplit[qq]->empty())
|
if (!splittedGroupData.aiSplit[qq]->empty())
|
||||||
sharedData.abNeedMaterials[qq] = true;
|
sharedData.abNeedMaterials[qq] = true;
|
||||||
}
|
}
|
||||||
|
@ -1575,19 +1562,18 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
|
||||||
"vertices or faces. It will be skipped.");
|
"vertices or faces. It will be skipped.");
|
||||||
|
|
||||||
// process all frames and generate output meshes
|
// process all frames and generate output meshes
|
||||||
this->ProcessFrames_3DGS_MDL7(groupInfo,groupData, sharedData,szCurrent,&szCurrent);
|
ProcessFrames_3DGS_MDL7(groupInfo,groupData, sharedData,szCurrent,&szCurrent);
|
||||||
this->GenerateOutputMeshes_3DGS_MDL7(groupData,splittedGroupData);
|
GenerateOutputMeshes_3DGS_MDL7(groupData,splittedGroupData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate a nodegraph and subnodes for each group
|
// generate a nodegraph and subnodes for each group
|
||||||
this->pScene->mRootNode = new aiNode();
|
pScene->mRootNode = new aiNode();
|
||||||
|
|
||||||
// now we need to build a final mesh list
|
// now we need to build a final mesh list
|
||||||
for (uint32_t i = 0; i < pcHeader->groups_num;++i)
|
for (uint32_t i = 0; i < pcHeader->groups_num;++i)
|
||||||
{
|
pScene->mNumMeshes += (unsigned int)avOutList[i].size();
|
||||||
this->pScene->mNumMeshes += (unsigned int)avOutList[i].size();
|
|
||||||
}
|
this->pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
|
||||||
this->pScene->mMeshes = new aiMesh*[this->pScene->mNumMeshes];
|
|
||||||
{
|
{
|
||||||
unsigned int p = 0,q = 0;
|
unsigned int p = 0,q = 0;
|
||||||
for (uint32_t i = 0; i < pcHeader->groups_num;++i)
|
for (uint32_t i = 0; i < pcHeader->groups_num;++i)
|
||||||
|
@ -1596,17 +1582,16 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
|
||||||
{
|
{
|
||||||
this->pScene->mMeshes[p++] = avOutList[i][a];
|
this->pScene->mMeshes[p++] = avOutList[i][a];
|
||||||
}
|
}
|
||||||
if (!avOutList[i].empty())++this->pScene->mRootNode->mNumChildren;
|
if (!avOutList[i].empty())++pScene->mRootNode->mNumChildren;
|
||||||
}
|
}
|
||||||
// we will later need an extra node to serve as parent for all bones
|
// we will later need an extra node to serve as parent for all bones
|
||||||
if (sharedData.apcOutBones)++this->pScene->mRootNode->mNumChildren;
|
if (sharedData.apcOutBones)++pScene->mRootNode->mNumChildren;
|
||||||
this->pScene->mRootNode->mChildren = new aiNode*[this->pScene->mRootNode->mNumChildren];
|
this->pScene->mRootNode->mChildren = new aiNode*[pScene->mRootNode->mNumChildren];
|
||||||
p = 0;
|
p = 0;
|
||||||
for (uint32_t i = 0; i < pcHeader->groups_num;++i)
|
for (uint32_t i = 0; i < pcHeader->groups_num;++i) {
|
||||||
{
|
|
||||||
if (avOutList[i].empty())continue;
|
if (avOutList[i].empty())continue;
|
||||||
|
|
||||||
aiNode* const pcNode = this->pScene->mRootNode->mChildren[p] = new aiNode();
|
aiNode* const pcNode = pScene->mRootNode->mChildren[p] = new aiNode();
|
||||||
pcNode->mNumMeshes = (unsigned int)avOutList[i].size();
|
pcNode->mNumMeshes = (unsigned int)avOutList[i].size();
|
||||||
pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
|
pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
|
||||||
pcNode->mParent = this->pScene->mRootNode;
|
pcNode->mParent = this->pScene->mRootNode;
|
||||||
|
@ -1616,7 +1601,8 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
|
||||||
|
|
||||||
// setup the name of the node
|
// setup the name of the node
|
||||||
char* const szBuffer = &aszGroupNameBuffer[i*AI_MDL7_MAX_GROUPNAMESIZE];
|
char* const szBuffer = &aszGroupNameBuffer[i*AI_MDL7_MAX_GROUPNAMESIZE];
|
||||||
if ('\0' == *szBuffer)pcNode->mName.length = ::sprintf(szBuffer,"Group_%i",p);
|
if ('\0' == *szBuffer)
|
||||||
|
pcNode->mName.length = ::sprintf(szBuffer,"Group_%i",p);
|
||||||
else pcNode->mName.length = ::strlen(szBuffer);
|
else pcNode->mName.length = ::strlen(szBuffer);
|
||||||
::strcpy(pcNode->mName.data,szBuffer);
|
::strcpy(pcNode->mName.data,szBuffer);
|
||||||
++p;
|
++p;
|
||||||
|
@ -1624,15 +1610,15 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
|
||||||
}
|
}
|
||||||
|
|
||||||
// if there is only one root node with a single child we can optimize it a bit ...
|
// if there is only one root node with a single child we can optimize it a bit ...
|
||||||
if (1 == this->pScene->mRootNode->mNumChildren && !sharedData.apcOutBones)
|
if (1 == pScene->mRootNode->mNumChildren && !sharedData.apcOutBones)
|
||||||
{
|
{
|
||||||
aiNode* pcOldRoot = this->pScene->mRootNode;
|
aiNode* pcOldRoot = this->pScene->mRootNode;
|
||||||
this->pScene->mRootNode = pcOldRoot->mChildren[0];
|
pScene->mRootNode = pcOldRoot->mChildren[0];
|
||||||
pcOldRoot->mChildren[0] = NULL;
|
pcOldRoot->mChildren[0] = NULL;
|
||||||
delete pcOldRoot;
|
delete pcOldRoot;
|
||||||
this->pScene->mRootNode->mParent = NULL;
|
pScene->mRootNode->mParent = NULL;
|
||||||
}
|
}
|
||||||
else this->pScene->mRootNode->mName.Set("<mesh_root>");
|
else pScene->mRootNode->mName.Set("<mesh_root>");
|
||||||
|
|
||||||
delete[] avOutList;
|
delete[] avOutList;
|
||||||
delete[] aszGroupNameBuffer;
|
delete[] aszGroupNameBuffer;
|
||||||
|
@ -1640,75 +1626,75 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
|
||||||
AI_DEBUG_INVALIDATE_PTR(aszGroupNameBuffer);
|
AI_DEBUG_INVALIDATE_PTR(aszGroupNameBuffer);
|
||||||
|
|
||||||
// build a final material list.
|
// build a final material list.
|
||||||
this->CopyMaterials_3DGS_MDL7(sharedData);
|
CopyMaterials_3DGS_MDL7(sharedData);
|
||||||
this->HandleMaterialReferences_3DGS_MDL7();
|
HandleMaterialReferences_3DGS_MDL7();
|
||||||
|
|
||||||
// generate output bone animations and add all bones to the scenegraph
|
// generate output bone animations and add all bones to the scenegraph
|
||||||
if (sharedData.apcOutBones)
|
if (sharedData.apcOutBones)
|
||||||
{
|
{
|
||||||
// this step adds empty dummy bones to the nodegraph
|
// this step adds empty dummy bones to the nodegraph
|
||||||
// insert another dummy node to avoid name conflicts
|
// insert another dummy node to avoid name conflicts
|
||||||
aiNode* const pc = this->pScene->mRootNode->mChildren[
|
aiNode* const pc = pScene->mRootNode->mChildren[pScene->mRootNode->mNumChildren-1] = new aiNode();
|
||||||
this->pScene->mRootNode->mNumChildren-1] = new aiNode();
|
|
||||||
|
|
||||||
pc->mName.Set("<skeleton_root>");
|
pc->mName.Set("<skeleton_root>");
|
||||||
|
|
||||||
// add bones to the nodegraph
|
// add bones to the nodegraph
|
||||||
this->AddBonesToNodeGraph_3DGS_MDL7((const Assimp::MDL::IntBone_MDL7 **)
|
AddBonesToNodeGraph_3DGS_MDL7((const Assimp::MDL::IntBone_MDL7 **)
|
||||||
sharedData.apcOutBones,pc,0xffff);
|
sharedData.apcOutBones,pc,0xffff);
|
||||||
|
|
||||||
// this steps build a valid output animation
|
// this steps build a valid output animation
|
||||||
this->BuildOutputAnims_3DGS_MDL7((const Assimp::MDL::IntBone_MDL7 **)
|
BuildOutputAnims_3DGS_MDL7((const Assimp::MDL::IntBone_MDL7 **)
|
||||||
sharedData.apcOutBones);
|
sharedData.apcOutBones);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void MDLImporter::CopyMaterials_3DGS_MDL7(MDL::IntSharedData_MDL7 &shared)
|
void MDLImporter::CopyMaterials_3DGS_MDL7(MDL::IntSharedData_MDL7 &shared)
|
||||||
{
|
{
|
||||||
this->pScene->mNumMaterials = (unsigned int)shared.pcMats.size();
|
pScene->mNumMaterials = (unsigned int)shared.pcMats.size();
|
||||||
this->pScene->mMaterials = new aiMaterial*[this->pScene->mNumMaterials];
|
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
|
||||||
for (unsigned int i = 0; i < this->pScene->mNumMaterials;++i)
|
for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
|
||||||
this->pScene->mMaterials[i] = shared.pcMats[i];
|
pScene->mMaterials[i] = shared.pcMats[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void MDLImporter::HandleMaterialReferences_3DGS_MDL7()
|
void MDLImporter::HandleMaterialReferences_3DGS_MDL7()
|
||||||
{
|
{
|
||||||
// search for referrer materials
|
// search for referrer materials
|
||||||
for (unsigned int i = 0; i < this->pScene->mNumMaterials;++i)
|
for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
|
||||||
{
|
{
|
||||||
int iIndex = 0;
|
int iIndex = 0;
|
||||||
if (AI_SUCCESS == aiGetMaterialInteger(this->pScene->mMaterials[i],
|
if (AI_SUCCESS == aiGetMaterialInteger(pScene->mMaterials[i],
|
||||||
AI_MDL7_REFERRER_MATERIAL, &iIndex) )
|
AI_MDL7_REFERRER_MATERIAL, &iIndex) )
|
||||||
{
|
{
|
||||||
for (unsigned int a = 0; a < this->pScene->mNumMeshes;++a)
|
for (unsigned int a = 0; a < pScene->mNumMeshes;++a)
|
||||||
{
|
{
|
||||||
aiMesh* const pcMesh = this->pScene->mMeshes[a];
|
aiMesh* const pcMesh = pScene->mMeshes[a];
|
||||||
if (i == pcMesh->mMaterialIndex)
|
if (i == pcMesh->mMaterialIndex)
|
||||||
pcMesh->mMaterialIndex = iIndex;
|
pcMesh->mMaterialIndex = iIndex;
|
||||||
}
|
}
|
||||||
// collapse the rest of the array
|
// collapse the rest of the array
|
||||||
delete this->pScene->mMaterials[i];
|
delete pScene->mMaterials[i];
|
||||||
for (unsigned int pp = i; pp < this->pScene->mNumMaterials-1;++pp)
|
for (unsigned int pp = i; pp < pScene->mNumMaterials-1;++pp)
|
||||||
{
|
{
|
||||||
this->pScene->mMaterials[pp] = this->pScene->mMaterials[pp+1];
|
this->pScene->mMaterials[pp] = pScene->mMaterials[pp+1];
|
||||||
for (unsigned int a = 0; a < this->pScene->mNumMeshes;++a)
|
for (unsigned int a = 0; a < pScene->mNumMeshes;++a)
|
||||||
{
|
{
|
||||||
aiMesh* const pcMesh = this->pScene->mMeshes[a];
|
aiMesh* const pcMesh = pScene->mMeshes[a];
|
||||||
if (pcMesh->mMaterialIndex > i)--pcMesh->mMaterialIndex;
|
if (pcMesh->mMaterialIndex > i)--pcMesh->mMaterialIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
--this->pScene->mNumMaterials;
|
--pScene->mNumMaterials;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Read bone transformation keys
|
||||||
void MDLImporter::ParseBoneTrafoKeys_3DGS_MDL7(
|
void MDLImporter::ParseBoneTrafoKeys_3DGS_MDL7(
|
||||||
const MDL::IntGroupInfo_MDL7& groupInfo,
|
const MDL::IntGroupInfo_MDL7& groupInfo,
|
||||||
IntFrameInfo_MDL7& frame,
|
IntFrameInfo_MDL7& frame,
|
||||||
MDL::IntSharedData_MDL7& shared)
|
MDL::IntSharedData_MDL7& shared)
|
||||||
{
|
{
|
||||||
|
|
||||||
// get a pointer to the header ...
|
|
||||||
const MDL::Header_MDL7* const pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
|
const MDL::Header_MDL7* const pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
|
||||||
|
|
||||||
// only the first group contains bone animation keys
|
// only the first group contains bone animation keys
|
||||||
|
@ -1724,14 +1710,12 @@ void MDLImporter::ParseBoneTrafoKeys_3DGS_MDL7(
|
||||||
// read all transformation matrices
|
// read all transformation matrices
|
||||||
for (unsigned int iTrafo = 0; iTrafo < frame.pcFrame->transmatrix_count;++iTrafo)
|
for (unsigned int iTrafo = 0; iTrafo < frame.pcFrame->transmatrix_count;++iTrafo)
|
||||||
{
|
{
|
||||||
if(pcBoneTransforms->bone_index >= pcHeader->bones_num)
|
if(pcBoneTransforms->bone_index >= pcHeader->bones_num) {
|
||||||
{
|
|
||||||
DefaultLogger::get()->warn("Index overflow in frame area. "
|
DefaultLogger::get()->warn("Index overflow in frame area. "
|
||||||
"Unable to parse this bone transformation");
|
"Unable to parse this bone transformation");
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
AddAnimationBoneTrafoKey_3DGS_MDL7(frame.iIndex,
|
||||||
this->AddAnimationBoneTrafoKey_3DGS_MDL7(frame.iIndex,
|
|
||||||
pcBoneTransforms,shared.apcOutBones);
|
pcBoneTransforms,shared.apcOutBones);
|
||||||
}
|
}
|
||||||
pcBoneTransforms = (const MDL::BoneTransform_MDL7*)(
|
pcBoneTransforms = (const MDL::BoneTransform_MDL7*)(
|
||||||
|
@ -1745,7 +1729,9 @@ void MDLImporter::ParseBoneTrafoKeys_3DGS_MDL7(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Attach bones to the output nodegraph
|
||||||
void MDLImporter::AddBonesToNodeGraph_3DGS_MDL7(const MDL::IntBone_MDL7** apcBones,
|
void MDLImporter::AddBonesToNodeGraph_3DGS_MDL7(const MDL::IntBone_MDL7** apcBones,
|
||||||
aiNode* pcParent,uint16_t iParentIndex)
|
aiNode* pcParent,uint16_t iParentIndex)
|
||||||
{
|
{
|
||||||
|
@ -1773,14 +1759,14 @@ void MDLImporter::AddBonesToNodeGraph_3DGS_MDL7(const MDL::IntBone_MDL7** apcBon
|
||||||
this->AddBonesToNodeGraph_3DGS_MDL7(apcBones,pcNode,(uint16_t)i);
|
this->AddBonesToNodeGraph_3DGS_MDL7(apcBones,pcNode,(uint16_t)i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Build output animations
|
||||||
void MDLImporter::BuildOutputAnims_3DGS_MDL7(
|
void MDLImporter::BuildOutputAnims_3DGS_MDL7(
|
||||||
const MDL::IntBone_MDL7** apcBonesOut)
|
const MDL::IntBone_MDL7** apcBonesOut)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != apcBonesOut);
|
ai_assert(NULL != apcBonesOut);
|
||||||
|
const MDL::Header_MDL7* const pcHeader = (const MDL::Header_MDL7*)mBuffer;
|
||||||
// get a pointer to the header ...
|
|
||||||
const MDL::Header_MDL7* const pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
|
|
||||||
|
|
||||||
// one animation ...
|
// one animation ...
|
||||||
aiAnimation* pcAnim = new aiAnimation();
|
aiAnimation* pcAnim = new aiAnimation();
|
||||||
|
@ -1831,12 +1817,13 @@ void MDLImporter::BuildOutputAnims_3DGS_MDL7(
|
||||||
}
|
}
|
||||||
|
|
||||||
// store the output animation
|
// store the output animation
|
||||||
this->pScene->mNumAnimations = 1;
|
pScene->mNumAnimations = 1;
|
||||||
this->pScene->mAnimations = new aiAnimation*[1];
|
pScene->mAnimations = new aiAnimation*[1];
|
||||||
this->pScene->mAnimations[0] = pcAnim;
|
pScene->mAnimations[0] = pcAnim;
|
||||||
}
|
}
|
||||||
else delete pcAnim;
|
else delete pcAnim;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void MDLImporter::AddAnimationBoneTrafoKey_3DGS_MDL7(unsigned int iTrafo,
|
void MDLImporter::AddAnimationBoneTrafoKey_3DGS_MDL7(unsigned int iTrafo,
|
||||||
const MDL::BoneTransform_MDL7* pcBoneTransforms,
|
const MDL::BoneTransform_MDL7* pcBoneTransforms,
|
||||||
|
@ -1880,7 +1867,9 @@ void MDLImporter::AddAnimationBoneTrafoKey_3DGS_MDL7(unsigned int iTrafo,
|
||||||
pcBoneOut->pkeyScalings.push_back ( vScaling );
|
pcBoneOut->pkeyScalings.push_back ( vScaling );
|
||||||
pcBoneOut->pkeyRotations.push_back ( qRotation );
|
pcBoneOut->pkeyRotations.push_back ( qRotation );
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Construct output meshes
|
||||||
void MDLImporter::GenerateOutputMeshes_3DGS_MDL7(
|
void MDLImporter::GenerateOutputMeshes_3DGS_MDL7(
|
||||||
MDL::IntGroupData_MDL7& groupData,
|
MDL::IntGroupData_MDL7& groupData,
|
||||||
MDL::IntSplittedGroupData_MDL7& splittedGroupData)
|
MDL::IntSplittedGroupData_MDL7& splittedGroupData)
|
||||||
|
@ -2015,7 +2004,9 @@ void MDLImporter::GenerateOutputMeshes_3DGS_MDL7(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Join to materials
|
||||||
void MDLImporter::JoinSkins_3DGS_MDL7(
|
void MDLImporter::JoinSkins_3DGS_MDL7(
|
||||||
MaterialHelper* pcMat1,
|
MaterialHelper* pcMat1,
|
||||||
MaterialHelper* pcMat2,
|
MaterialHelper* pcMat2,
|
||||||
|
@ -2041,7 +2032,9 @@ void MDLImporter::JoinSkins_3DGS_MDL7(
|
||||||
pcMatOut->AddProperty(&sString,AI_MATKEY_TEXTURE_DIFFUSE(1));
|
pcMatOut->AddProperty(&sString,AI_MATKEY_TEXTURE_DIFFUSE(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Read a half-life 2 MDL
|
||||||
void MDLImporter::InternReadFile_HL2( )
|
void MDLImporter::InternReadFile_HL2( )
|
||||||
{
|
{
|
||||||
//const MDL::Header_HL2* pcHeader = (const MDL::Header_HL2*)this->mBuffer;
|
//const MDL::Header_HL2* pcHeader = (const MDL::Header_HL2*)this->mBuffer;
|
||||||
|
|
|
@ -39,17 +39,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
//!
|
/** @file MDLLoader.h
|
||||||
//! @file Definition of MDL importer class
|
* @brief Declaration of the loader for MDL files
|
||||||
//!
|
*/
|
||||||
|
|
||||||
#ifndef AI_MDLLOADER_H_INCLUDED
|
#ifndef AI_MDLLOADER_H_INCLUDED
|
||||||
#define AI_MDLLOADER_H_INCLUDED
|
#define AI_MDLLOADER_H_INCLUDED
|
||||||
|
|
||||||
#include "BaseImporter.h"
|
#include "BaseImporter.h"
|
||||||
#include "../include/aiTypes.h"
|
|
||||||
#include "../include/aiTexture.h"
|
|
||||||
#include "../include/aiMaterial.h"
|
|
||||||
|
|
||||||
struct aiNode;
|
struct aiNode;
|
||||||
#include "MDLFileData.h"
|
#include "MDLFileData.h"
|
||||||
|
@ -60,13 +57,28 @@ class MaterialHelper;
|
||||||
|
|
||||||
using namespace MDL;
|
using namespace MDL;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
#if (!defined VALIDATE_FILE_SIZE)
|
// Include file/line information in debug builds
|
||||||
# define VALIDATE_FILE_SIZE(msg) this->SizeCheck(msg,__FILE__,__LINE__)
|
#ifdef ASSIMP_BUILD_DEBUG
|
||||||
|
# define VALIDATE_FILE_SIZE(msg) SizeCheck(msg,__FILE__,__LINE__)
|
||||||
|
#else
|
||||||
|
# define VALIDATE_FILE_SIZE(msg) SizeCheck(msg)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
/** Used to load MDL files
|
/** @brief Class to load MDL files.
|
||||||
|
*
|
||||||
|
* Several subformats exist:
|
||||||
|
* <ul>
|
||||||
|
* <li>Quake I</li>
|
||||||
|
* <li>3D Game Studio MDL3, MDL4</li>
|
||||||
|
* <li>3D Game Studio MDL5</li>
|
||||||
|
* <li>3D Game Studio MDL7</li>
|
||||||
|
* <li>Halflife 2</li>
|
||||||
|
* </ul>
|
||||||
|
* These formats are partially identical and it would be possible to load
|
||||||
|
* them all with a single 1000-line function-beast. However, it has been
|
||||||
|
* splitted to several code paths to make the code easier to read and maintain.
|
||||||
*/
|
*/
|
||||||
class MDLImporter : public BaseImporter
|
class MDLImporter : public BaseImporter
|
||||||
{
|
{
|
||||||
|
@ -101,10 +113,7 @@ protected:
|
||||||
/** Called by Importer::GetExtensionList() for each loaded importer.
|
/** Called by Importer::GetExtensionList() for each loaded importer.
|
||||||
* See BaseImporter::GetExtensionList() for details
|
* See BaseImporter::GetExtensionList() for details
|
||||||
*/
|
*/
|
||||||
void GetExtensionList(std::string& append)
|
void GetExtensionList(std::string& append);
|
||||||
{
|
|
||||||
append.append("*.mdl");
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Imports the given file into the given scene structure.
|
/** Imports the given file into the given scene structure.
|
||||||
|
@ -135,11 +144,6 @@ protected:
|
||||||
*/
|
*/
|
||||||
void InternReadFile_HL2( );
|
void InternReadFile_HL2( );
|
||||||
|
|
||||||
|
|
||||||
// *******************************************************************
|
|
||||||
// Debugging/validation functions
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Check whether a given position is inside the valid range
|
/** Check whether a given position is inside the valid range
|
||||||
* Throw a new ImportErrorException if it is not
|
* Throw a new ImportErrorException if it is not
|
||||||
|
@ -164,10 +168,6 @@ protected:
|
||||||
void ValidateHeader_Quake1(const MDL::Header* pcHeader);
|
void ValidateHeader_Quake1(const MDL::Header* pcHeader);
|
||||||
|
|
||||||
|
|
||||||
// *******************************************************************
|
|
||||||
// Material import
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Try to load a palette from the current directory (colormap.lmp)
|
/** Try to load a palette from the current directory (colormap.lmp)
|
||||||
* If it is not found the default palette of Quake1 is returned
|
* If it is not found the default palette of Quake1 is returned
|
||||||
|
@ -195,6 +195,7 @@ protected:
|
||||||
unsigned int iType,
|
unsigned int iType,
|
||||||
unsigned int* piSkip);
|
unsigned int* piSkip);
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Used to load textures from MDL5
|
/** Used to load textures from MDL5
|
||||||
* \param szData Input data
|
* \param szData Input data
|
||||||
|
@ -218,16 +219,13 @@ protected:
|
||||||
aiColor4D ReplaceTextureWithColor(const aiTexture* pcTexture);
|
aiColor4D ReplaceTextureWithColor(const aiTexture* pcTexture);
|
||||||
|
|
||||||
|
|
||||||
// *******************************************************************
|
|
||||||
// Quake1, MDL 3,4,5 import
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Converts the absolute texture coordinates in MDL5 files to
|
/** Converts the absolute texture coordinates in MDL5 files to
|
||||||
* relative in a range between 0 and 1
|
* relative in a range between 0 and 1
|
||||||
*/
|
*/
|
||||||
void CalculateUVCoordinates_MDL5();
|
void CalculateUVCoordinates_MDL5();
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Read an UV coordinate from the file. If the file format is not
|
/** Read an UV coordinate from the file. If the file format is not
|
||||||
* MDL5, the function calculates relative texture coordinates
|
* MDL5, the function calculates relative texture coordinates
|
||||||
|
@ -248,9 +246,6 @@ protected:
|
||||||
void SetupMaterialProperties_3DGS_MDL5_Quake1( );
|
void SetupMaterialProperties_3DGS_MDL5_Quake1( );
|
||||||
|
|
||||||
|
|
||||||
// *******************************************************************
|
|
||||||
// MDL7 import
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Parse a skin lump in a MDL7/HMP7 file with all of its features
|
/** 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
|
* variant 1: Current cursor position is the beginning of the skin header
|
||||||
|
|
|
@ -168,7 +168,7 @@ void MDLImporter::CreateTexture_3DGS_MDL4(const unsigned char* szData,
|
||||||
{
|
{
|
||||||
ai_assert(NULL != piSkip);
|
ai_assert(NULL != piSkip);
|
||||||
|
|
||||||
const MDL::Header *pcHeader = (const MDL::Header*)this->mBuffer; //the endianess is allready corrected in the InternReadFile_3DGS_MDL345 function
|
const MDL::Header *pcHeader = (const MDL::Header*)mBuffer; //the endianess is allready corrected in the InternReadFile_3DGS_MDL345 function
|
||||||
|
|
||||||
if (iType == 1 || iType > 3)
|
if (iType == 1 || iType > 3)
|
||||||
{
|
{
|
||||||
|
@ -184,7 +184,7 @@ void MDLImporter::CreateTexture_3DGS_MDL4(const unsigned char* szData,
|
||||||
pcNew->mHeight = pcHeader->skinheight;
|
pcNew->mHeight = pcHeader->skinheight;
|
||||||
|
|
||||||
if (bNoRead)pcNew->pcData = (aiTexel*)0xffffffff;
|
if (bNoRead)pcNew->pcData = (aiTexel*)0xffffffff;
|
||||||
this->ParseTextureColorData(szData,iType,piSkip,pcNew);
|
ParseTextureColorData(szData,iType,piSkip,pcNew);
|
||||||
|
|
||||||
// store the texture
|
// store the texture
|
||||||
if (!bNoRead)
|
if (!bNoRead)
|
||||||
|
|
|
@ -61,7 +61,38 @@ extern "C" {
|
||||||
* writes the target point as a subnode of the camera's main node,
|
* writes the target point as a subnode of the camera's main node,
|
||||||
* called "<camName>.Target". However, this is just additional information
|
* called "<camName>.Target". However, this is just additional information
|
||||||
* then, the transformation tracks of the camera main node make the
|
* then, the transformation tracks of the camera main node make the
|
||||||
* camera already point in the right direction.
|
* camera already look in the right direction.
|
||||||
|
* <br>
|
||||||
|
* An important aspect is that the camera itself is also part of the
|
||||||
|
* scenegraph. This means, any values such as the look-at vector are not
|
||||||
|
* *absolute*, they're <b>relative</b> to the coordinate system defined
|
||||||
|
* by the node which corresponds to the camera. This allows for camera
|
||||||
|
* animations. For static cameras parameters like the 'look-at' or 'up' vectors
|
||||||
|
* are usually specified directly in aiCamera, but beware, they could also
|
||||||
|
* be encoded in the node transformation. The following (pseudo)code sample
|
||||||
|
* shows how to do it:
|
||||||
|
* @code
|
||||||
|
* // Get the camera matrix for a camera at a specific time
|
||||||
|
* // if the node hierarchy for the camera does not contain
|
||||||
|
* // at least one animated node this is a static computation
|
||||||
|
* get-camera-matrix (node sceneRoot, camera cam) : matrix
|
||||||
|
* {
|
||||||
|
* node cnd = find-node-for-camera(cam)
|
||||||
|
* matrix cmt = identity()
|
||||||
|
*
|
||||||
|
* // as usual - get the absolute camera transformation for this frame
|
||||||
|
* for each node nd in hierarchy from sceneRoot to cnd
|
||||||
|
* matrix cur
|
||||||
|
* if (is-animated(nd))
|
||||||
|
* cur = eval-animation(nd)
|
||||||
|
* else cur = nd->mTransformation;
|
||||||
|
* cmt = mult-matrices( cmt, cur )
|
||||||
|
* end for
|
||||||
|
*
|
||||||
|
* // now multiply with the camera's own local transform
|
||||||
|
* cam = mult-matrices (cam, get-camera-matrix(cmt) )
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
struct aiCamera
|
struct aiCamera
|
||||||
|
@ -149,6 +180,38 @@ struct aiCamera
|
||||||
, mAspect (0.f)
|
, mAspect (0.f)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
/** @brief Get a *right-handed* camera matrix from me
|
||||||
|
* @param out Camera matrix to be filled
|
||||||
|
*/
|
||||||
|
void GetCameraMatrix (aiMatrix4x4& out) const
|
||||||
|
{
|
||||||
|
/** todo: test ... should work, but i'm not absolutely sure */
|
||||||
|
|
||||||
|
/** We don't know whether these vectors are already normalized ...*/
|
||||||
|
aiVector3D zaxis = mLookAt; zaxis.Normalize();
|
||||||
|
aiVector3D yaxis = mUp; yaxis.Normalize();
|
||||||
|
aiVector3D xaxis = mUp^mLookAt; xaxis.Normalize();
|
||||||
|
|
||||||
|
out.a3 = -(xaxis * mPosition);
|
||||||
|
out.b3 = -(yaxis * mPosition);
|
||||||
|
out.c3 = -(zaxis * mPosition);
|
||||||
|
|
||||||
|
out.a1 = xaxis.x;
|
||||||
|
out.a2 = xaxis.y;
|
||||||
|
out.a3 = xaxis.z;
|
||||||
|
|
||||||
|
out.b1 = yaxis.x;
|
||||||
|
out.b2 = yaxis.y;
|
||||||
|
out.b3 = yaxis.z;
|
||||||
|
|
||||||
|
out.c1 = zaxis.x;
|
||||||
|
out.c2 = zaxis.y;
|
||||||
|
out.c3 = zaxis.z;
|
||||||
|
|
||||||
|
out.d1 = out.d2 = out.d3 = 0.f;
|
||||||
|
out.d4 = 1.f;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue