57
57
// ------------------------------------------------------------------------------------------------
58
58
// Ugly stuff ... nevermind
59
#define _AI_MDL7_ACCESS(_data, _index, _limit, _type) \
59
#define _AI_MDL7_ACCESS(_data, _index, _limit, _type) \
60
60
(*((const _type*)(((const char*)_data) + _index * _limit)))
62
#define _AI_MDL7_ACCESS_PTR(_data, _index, _limit, _type) \
62
#define _AI_MDL7_ACCESS_PTR(_data, _index, _limit, _type) \
63
63
((BE_NCONST _type*)(((const char*)_data) + _index * _limit))
65
#define _AI_MDL7_ACCESS_VERT(_data, _index, _limit) \
65
#define _AI_MDL7_ACCESS_VERT(_data, _index, _limit) \
66
66
_AI_MDL7_ACCESS(_data,_index,_limit,MDL::Vertex_MDL7)
68
68
// ------------------------------------------------------------------------------------------------
107
107
// AI_CONFIG_IMPORT_MDL_KEYFRAME option overrides the
108
108
// AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
109
if (0xffffffff == configFrameID) {
109
if(0xffffffff == configFrameID) {
110
110
configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
131
131
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
133
133
// Check whether we can read from the file
134
if ( file.get() == NULL) {
134
if( file.get() == NULL) {
135
135
throw DeadlyImportError( "Failed to open MDL file " + pFile + ".");
138
138
// This should work for all other types of MDL files, too ...
139
139
// the quake header is one of the smallest, afaik
140
140
iFileSize = (unsigned int)file->FileSize();
141
if ( iFileSize < sizeof(MDL::Header)) {
141
if( iFileSize < sizeof(MDL::Header)) {
142
142
throw DeadlyImportError( "MDL File is too small.");
156
156
// Determine the file subtype and call the appropriate member function
158
158
// Original Quake1 format
159
if (AI_MDL_MAGIC_NUMBER_BE == iMagicWord || AI_MDL_MAGIC_NUMBER_LE == iMagicWord) {
159
if (AI_MDL_MAGIC_NUMBER_BE == iMagicWord || AI_MDL_MAGIC_NUMBER_LE == iMagicWord) {
160
160
DefaultLogger::get()->debug("MDL subtype: Quake 1, magic word is IDPO");
161
161
iGSFileVersion = 0;
162
162
InternReadFile_Quake1();
164
164
// GameStudio A<old> MDL2 format - used by some test models that come with 3DGS
165
else if (AI_MDL_MAGIC_NUMBER_BE_GS3 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS3 == iMagicWord) {
165
else if (AI_MDL_MAGIC_NUMBER_BE_GS3 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS3 == iMagicWord) {
166
166
DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A2, magic word is MDL2");
167
167
iGSFileVersion = 2;
168
168
InternReadFile_Quake1();
170
170
// GameStudio A4 MDL3 format
171
else if (AI_MDL_MAGIC_NUMBER_BE_GS4 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS4 == iMagicWord) {
171
else if (AI_MDL_MAGIC_NUMBER_BE_GS4 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS4 == iMagicWord) {
172
172
DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A4, magic word is MDL3");
173
173
iGSFileVersion = 3;
174
174
InternReadFile_3DGS_MDL345();
176
176
// GameStudio A5+ MDL4 format
177
else if (AI_MDL_MAGIC_NUMBER_BE_GS5a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS5a == iMagicWord) {
177
else if (AI_MDL_MAGIC_NUMBER_BE_GS5a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS5a == iMagicWord) {
178
178
DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A4, magic word is MDL4");
179
179
iGSFileVersion = 4;
180
180
InternReadFile_3DGS_MDL345();
182
182
// GameStudio A5+ MDL5 format
183
else if (AI_MDL_MAGIC_NUMBER_BE_GS5b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS5b == iMagicWord) {
183
else if (AI_MDL_MAGIC_NUMBER_BE_GS5b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS5b == iMagicWord) {
184
184
DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A5, magic word is MDL5");
185
185
iGSFileVersion = 5;
186
186
InternReadFile_3DGS_MDL345();
188
188
// GameStudio A7 MDL7 format
189
else if (AI_MDL_MAGIC_NUMBER_BE_GS7 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS7 == iMagicWord) {
189
else if (AI_MDL_MAGIC_NUMBER_BE_GS7 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS7 == iMagicWord) {
190
190
DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A7, magic word is MDL7");
191
191
iGSFileVersion = 7;
192
192
InternReadFile_3DGS_MDL7();
194
// IDST/IDSQ Format (CS:S/HL, etc ...)
194
// IDST/IDSQ Format (CS:S/HL�, etc ...)
195
195
else if (AI_MDL_MAGIC_NUMBER_BE_HL2a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2a == iMagicWord ||
196
196
AI_MDL_MAGIC_NUMBER_BE_HL2b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2b == iMagicWord)
236
236
// remove a directory if there is one
237
237
const char* szFilePtr = ::strrchr(szFile,'\\');
239
if (!(szFilePtr = ::strrchr(szFile,'/')))
239
if(!(szFilePtr = ::strrchr(szFile,'/')))
240
240
szFilePtr = szFile;
242
242
if (szFilePtr)++szFilePtr;
279
279
if (!this->iGSFileVersion && pcHeader->version != AI_MDL_VERSION)
280
280
DefaultLogger::get()->warn("Quake 1 MDL model has an unknown version: AI_MDL_VERSION (=6) is "
281
281
"the expected file format version");
282
if (pcHeader->num_skins && (!pcHeader->skinwidth || !pcHeader->skinheight))
282
if(pcHeader->num_skins && (!pcHeader->skinwidth || !pcHeader->skinheight))
283
283
DefaultLogger::get()->warn("Skin width or height are 0");
469
469
float t = (float)pcTexCoords[iIndex].t;
471
471
// translate texture coordinates
472
if (0 == pcTriangles->facesfront && 0 != pcTexCoords[iIndex].onseam) {
472
if (0 == pcTriangles->facesfront && 0 != pcTexCoords[iIndex].onseam) {
473
473
s += pcHeader->skinwidth * 0.5f;
503
503
pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
506
if (0 != pcHeader->num_skins && pScene->mNumTextures) {
506
if (0 != pcHeader->num_skins && pScene->mNumTextures) {
507
507
// can we replace the texture with a single color?
508
508
clr = this->ReplaceTextureWithColor(pScene->mTextures[0]);
509
if (is_not_qnan(clr.r)) {
509
if (is_not_qnan(clr.r)) {
510
510
delete pScene->mTextures[0];
511
511
delete[] pScene->mTextures;
513
513
pScene->mTextures = NULL;
514
514
pScene->mNumTextures = 0;
517
517
clr.b = clr.a = clr.g = clr.r = 1.0f;
518
518
aiString szString;
519
519
::memcpy(szString.data,AI_MAKE_EMBEDDED_TEXNAME(0),3);
547
547
const unsigned char* szCurrent = (const unsigned char*)(pcHeader+1);
549
549
// need to read all textures
550
for (unsigned int i = 0; i < (unsigned int)pcHeader->num_skins;++i) {
550
for (unsigned int i = 0; i < (unsigned int)pcHeader->num_skins;++i) {
551
551
BE_NCONST MDL::Skin* pcSkin;
552
552
pcSkin = (BE_NCONST MDL::Skin*)szCurrent;
553
553
AI_SWAP4( pcSkin->group);
580
580
#ifdef AI_BUILD_BIG_ENDIAN
582
for (int i = 0; i<pcHeader->synctype;++i) {
582
for (int i = 0; i<pcHeader->synctype;++i) {
583
583
AI_SWAP2( pcTexCoords[i].u );
584
584
AI_SWAP2( pcTexCoords[i].v );
587
for (int i = 0; i<pcHeader->num_tris;++i) {
587
for (int i = 0; i<pcHeader->num_tris;++i) {
588
588
AI_SWAP2( pcTriangles[i].index_xyz[0]);
589
589
AI_SWAP2( pcTriangles[i].index_xyz[1]);
590
590
AI_SWAP2( pcTriangles[i].index_xyz[2]);
622
622
pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices];
623
623
pcMesh->mNormals = new aiVector3D[pcMesh->mNumVertices];
625
if (pcHeader->synctype) {
625
if (pcHeader->synctype) {
626
626
pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
627
627
pcMesh->mNumUVComponents[0] = 2;
634
634
// byte packed vertices
635
635
// FIXME: these two snippets below are almost identical ... join them?
636
636
/////////////////////////////////////////////////////////////////////////////////////
637
if (0 == pcFrames->type || 3 >= this->iGSFileVersion) {
637
if (0 == pcFrames->type || 3 >= this->iGSFileVersion) {
639
639
const MDL::SimpleFrame* pcFirstFrame = (const MDL::SimpleFrame*)(szCurrent + sizeof(uint32_t));
640
640
const MDL::Vertex* pcVertices = (const MDL::Vertex*) ((pcFirstFrame->name) + sizeof(pcFirstFrame->name));
644
644
// now iterate through all triangles
645
645
unsigned int iCurrent = 0;
646
for (unsigned int i = 0; i < (unsigned int) pcHeader->num_tris;++i) {
646
for (unsigned int i = 0; i < (unsigned int) pcHeader->num_tris;++i) {
647
647
pcMesh->mFaces[i].mIndices = new unsigned int[3];
648
648
pcMesh->mFaces[i].mNumIndices = 3;
650
650
unsigned int iTemp = iCurrent;
651
for (unsigned int c = 0; c < 3;++c,++iCurrent) {
651
for (unsigned int c = 0; c < 3;++c,++iCurrent) {
653
653
unsigned int iIndex = pcTriangles->index_xyz[c];
654
if (iIndex >= (unsigned int)pcHeader->num_verts) {
654
if (iIndex >= (unsigned int)pcHeader->num_verts) {
655
655
iIndex = pcHeader->num_verts-1;
656
656
DefaultLogger::get()->warn("Index overflow in MDLn vertex list");
672
672
// pcMesh->mNormals[iCurrent].y *= -1.0f;
674
674
// read texture coordinates
675
if (pcHeader->synctype) {
675
if (pcHeader->synctype) {
676
676
ImportUVCoordinate_3DGS_MDL345(pcMesh->mTextureCoords[0][iCurrent],
677
677
pcTexCoords,pcTriangles->index_uv[c]);
699
699
// now iterate through all triangles
700
700
unsigned int iCurrent = 0;
701
for (unsigned int i = 0; i < (unsigned int) pcHeader->num_tris;++i) {
701
for (unsigned int i = 0; i < (unsigned int) pcHeader->num_tris;++i) {
702
702
pcMesh->mFaces[i].mIndices = new unsigned int[3];
703
703
pcMesh->mFaces[i].mNumIndices = 3;
705
705
unsigned int iTemp = iCurrent;
706
for (unsigned int c = 0; c < 3;++c,++iCurrent) {
706
for (unsigned int c = 0; c < 3;++c,++iCurrent) {
708
708
unsigned int iIndex = pcTriangles->index_xyz[c];
709
if (iIndex >= (unsigned int)pcHeader->num_verts) {
709
if (iIndex >= (unsigned int)pcHeader->num_verts) {
710
710
iIndex = pcHeader->num_verts-1;
711
711
DefaultLogger::get()->warn("Index overflow in MDLn vertex list");
727
727
// pcMesh->mNormals[iCurrent].y *= -1.0f;
729
729
// read texture coordinates
730
if (pcHeader->synctype) {
730
if (pcHeader->synctype) {
731
731
ImportUVCoordinate_3DGS_MDL345(pcMesh->mTextureCoords[0][iCurrent],
732
732
pcTexCoords,pcTriangles->index_uv[c]);
757
757
const MDL::Header* const pcHeader = (const MDL::Header*)this->mBuffer;
759
759
// validate UV indices
760
if (iIndex >= (unsigned int) pcHeader->synctype) {
760
if (iIndex >= (unsigned int) pcHeader->synctype) {
761
761
iIndex = pcHeader->synctype-1;
762
762
DefaultLogger::get()->warn("Index overflow in MDLn UV coord list");
766
766
float t = (float)pcSrc[iIndex].v;
768
768
// Scale s and t to range from 0.0 to 1.0
769
if (0x5 != iGSFileVersion) {
769
if (0x5 != iGSFileVersion) {
770
770
s = (s + 0.5f) / pcHeader->skinwidth;
771
771
t = 1.0f-(t + 0.5f) / pcHeader->skinheight;
781
781
void MDLImporter::CalculateUVCoordinates_MDL5()
783
783
const MDL::Header* const pcHeader = (const MDL::Header*)this->mBuffer;
784
if (pcHeader->num_skins && this->pScene->mNumTextures) {
784
if (pcHeader->num_skins && this->pScene->mNumTextures) {
785
785
const aiTexture* pcTex = this->pScene->mTextures[0];
787
787
// if the file is loaded in DDS format: get the size of the
788
788
// texture from the header of the DDS file
789
789
// skip three DWORDs and read first height, then the width
790
790
unsigned int iWidth, iHeight;
791
if (!pcTex->mHeight) {
791
if (!pcTex->mHeight) {
792
792
const uint32_t* piPtr = (uint32_t*)pcTex->pcData;
808
808
iWidth = pcTex->mWidth;
809
809
iHeight = pcTex->mHeight;
812
if (1 != iWidth || 1 != iHeight) {
812
if (1 != iWidth || 1 != iHeight) {
813
813
const float fWidth = (float)iWidth;
814
814
const float fHeight = (float)iHeight;
815
815
aiMesh* pcMesh = this->pScene->mMeshes[0];
830
830
ai_assert(NULL != pcHeader);
832
832
// There are some fixed sizes ...
833
if (sizeof(MDL::ColorValue_MDL7) != pcHeader->colorvalue_stc_size) {
833
if (sizeof(MDL::ColorValue_MDL7) != pcHeader->colorvalue_stc_size) {
834
834
throw DeadlyImportError(
835
835
"[3DGS MDL7] sizeof(MDL::ColorValue_MDL7) != pcHeader->colorvalue_stc_size");
837
if (sizeof(MDL::TexCoord_MDL7) != pcHeader->skinpoint_stc_size) {
837
if (sizeof(MDL::TexCoord_MDL7) != pcHeader->skinpoint_stc_size) {
838
838
throw DeadlyImportError(
839
839
"[3DGS MDL7] sizeof(MDL::TexCoord_MDL7) != pcHeader->skinpoint_stc_size");
841
if (sizeof(MDL::Skin_MDL7) != pcHeader->skin_stc_size) {
841
if (sizeof(MDL::Skin_MDL7) != pcHeader->skin_stc_size) {
842
842
throw DeadlyImportError(
843
843
"sizeof(MDL::Skin_MDL7) != pcHeader->skin_stc_size");
846
846
// if there are no groups ... how should we load such a file?
847
if (!pcHeader->groups_num) {
847
if(!pcHeader->groups_num) {
848
848
throw DeadlyImportError( "[3DGS MDL7] No frames found");
862
862
// index (0) and so on until we can't find a new node.
863
863
uint16_t iParent = 0xffff;
864
864
uint32_t iIterations = 0;
865
while (iIterations++ < pcHeader->bones_num) {
866
for (uint32_t iBone = 0; iBone < pcHeader->bones_num;++iBone) {
865
while (iIterations++ < pcHeader->bones_num) {
866
for (uint32_t iBone = 0; iBone < pcHeader->bones_num;++iBone) {
867
867
BE_NCONST MDL::Bone_MDL7* pcBone = _AI_MDL7_ACCESS_PTR(pcBones,iBone,
868
868
pcHeader->bone_stc_size,MDL::Bone_MDL7);
898
898
// store the parent index of the bone
899
899
pcOutBone->iParent = pcBone->parent_index;
900
if (0xffff != iParent) {
900
if (0xffff != iParent) {
901
901
const MDL::IntBone_MDL7* pcParentBone = apcOutBones[iParent];
902
902
pcOutBone->mOffsetMatrix.a4 = -pcParentBone->vPosition.x;
903
903
pcOutBone->mOffsetMatrix.b4 = -pcParentBone->vPosition.y;
910
910
pcOutBone->mOffsetMatrix.b4 -= pcBone->y;
911
911
pcOutBone->mOffsetMatrix.c4 -= pcBone->z;
913
if (AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_NOT_THERE == pcHeader->bone_stc_size) {
913
if (AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_NOT_THERE == pcHeader->bone_stc_size) {
914
914
// no real name for our poor bone is specified :-(
915
915
pcOutBone->mName.length = ::sprintf(pcOutBone->mName.data,
916
916
"UnnamedBone_%i",iBone);
919
919
// Make sure we won't run over the buffer's end if there is no
920
920
// terminal 0 character (however the documentation says there
921
921
// should be one)
922
922
uint32_t iMaxLen = pcHeader->bone_stc_size-16;
923
for (uint32_t qq = 0; qq < iMaxLen;++qq) {
924
if (!pcBone->name[qq]) {
923
for (uint32_t qq = 0; qq < iMaxLen;++qq) {
924
if (!pcBone->name[qq]) {
943
943
MDL::IntBone_MDL7** MDLImporter::LoadBones_3DGS_MDL7()
945
945
const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
946
if (pcHeader->bones_num) {
946
if (pcHeader->bones_num) {
947
947
// validate the size of the bone data structure in the file
948
948
if (AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_20_CHARS != pcHeader->bone_stc_size &&
949
949
AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_32_CHARS != pcHeader->bone_stc_size &&
975
975
// iterate through all triangles and build valid display lists
976
976
unsigned int iOutIndex = 0;
977
for (unsigned int iTriangle = 0; iTriangle < (unsigned int)groupInfo.pcGroup->numtris; ++iTriangle) {
977
for (unsigned int iTriangle = 0; iTriangle < (unsigned int)groupInfo.pcGroup->numtris; ++iTriangle) {
978
978
AI_SWAP2(pcGroupTris->v_index[0]);
979
979
AI_SWAP2(pcGroupTris->v_index[1]);
980
980
AI_SWAP2(pcGroupTris->v_index[2]);
982
982
// iterate through all indices of the current triangle
983
for (unsigned int c = 0; c < 3;++c,++iOutIndex) {
983
for (unsigned int c = 0; c < 3;++c,++iOutIndex) {
985
985
// validate the vertex index
986
986
unsigned int iIndex = pcGroupTris->v_index[c];
987
if (iIndex > (unsigned int)groupInfo.pcGroup->numverts) {
987
if(iIndex > (unsigned int)groupInfo.pcGroup->numverts) {
988
988
// (we might need to read this section a second time - to process frame vertices correctly)
989
989
const_cast<MDL::Triangle_MDL7*>(pcGroupTris)->v_index[c] = iIndex = groupInfo.pcGroup->numverts-1;
990
990
DefaultLogger::get()->warn("Index overflow in MDL7 vertex list");
1007
1007
// now read the normal vector
1008
if (AI_MDL7_FRAMEVERTEX030305_STCSIZE <= pcHeader->mainvertex_stc_size) {
1008
if (AI_MDL7_FRAMEVERTEX030305_STCSIZE <= pcHeader->mainvertex_stc_size) {
1009
1009
// read the full normal vector
1010
1010
aiVector3D& vNormal = groupData.vNormals[ iOutIndex ];
1011
1011
vNormal.x = _AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts,iIndex,pcHeader->mainvertex_stc_size) .norm[0];
1015
1015
vNormal.z = _AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts,iIndex,pcHeader->mainvertex_stc_size) .norm[2];
1016
1016
AI_SWAP4(vNormal.z);
1018
else if (AI_MDL7_FRAMEVERTEX120503_STCSIZE <= pcHeader->mainvertex_stc_size) {
1018
else if (AI_MDL7_FRAMEVERTEX120503_STCSIZE <= pcHeader->mainvertex_stc_size) {
1019
1019
// read the normal vector from Quake2's smart table
1020
1020
aiVector3D& vNormal = groupData.vNormals[ iOutIndex ];
1021
1021
MD2::LookupNormalIndex(_AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts,iIndex,
1022
1022
pcHeader->mainvertex_stc_size) .norm162index,vNormal);
1024
1024
// validate and process the first uv coordinate set
1025
if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV) {
1025
if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV) {
1027
if (groupInfo.pcGroup->num_stpts) {
1027
if (groupInfo.pcGroup->num_stpts) {
1028
1028
AI_SWAP2(pcGroupTris->skinsets[0].st_index[0]);
1029
1029
AI_SWAP2(pcGroupTris->skinsets[0].st_index[1]);
1030
1030
AI_SWAP2(pcGroupTris->skinsets[0].st_index[2]);
1032
1032
iIndex = pcGroupTris->skinsets[0].st_index[c];
1033
if (iIndex > (unsigned int)groupInfo.pcGroup->num_stpts) {
1033
if(iIndex > (unsigned int)groupInfo.pcGroup->num_stpts) {
1034
1034
iIndex = groupInfo.pcGroup->num_stpts-1;
1035
1035
DefaultLogger::get()->warn("Index overflow in MDL7 UV coordinate list (#1)");
1050
1050
// validate and process the second uv coordinate set
1051
if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_TWO_UV) {
1051
if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_TWO_UV) {
1053
if (groupInfo.pcGroup->num_stpts) {
1053
if (groupInfo.pcGroup->num_stpts) {
1054
1054
AI_SWAP2(pcGroupTris->skinsets[1].st_index[0]);
1055
1055
AI_SWAP2(pcGroupTris->skinsets[1].st_index[1]);
1056
1056
AI_SWAP2(pcGroupTris->skinsets[1].st_index[2]);
1057
1057
AI_SWAP4(pcGroupTris->skinsets[1].material);
1059
1059
iIndex = pcGroupTris->skinsets[1].st_index[c];
1060
if (iIndex > (unsigned int)groupInfo.pcGroup->num_stpts) {
1060
if(iIndex > (unsigned int)groupInfo.pcGroup->num_stpts) {
1061
1061
iIndex = groupInfo.pcGroup->num_stpts-1;
1062
1062
DefaultLogger::get()->warn("Index overflow in MDL7 UV coordinate list (#2)");
1101
1101
// if we have no bones we can simply skip all frames,
1102
1102
// otherwise we'll need to process them.
1103
1103
// FIX: If we need another frame than the first we must apply frame vertex replacements ...
1104
for (unsigned int iFrame = 0; iFrame < (unsigned int)groupInfo.pcGroup->numframes;++iFrame) {
1104
for(unsigned int iFrame = 0; iFrame < (unsigned int)groupInfo.pcGroup->numframes;++iFrame) {
1105
1105
MDL::IntFrameInfo_MDL7 frame ((BE_NCONST MDL::Frame_MDL7*)szCurrent,iFrame);
1107
1107
AI_SWAP4(frame.pcFrame->vertices_count);
1111
1111
frame.pcFrame->vertices_count * pcHeader->framevertex_stc_size +
1112
1112
frame.pcFrame->transmatrix_count * pcHeader->bonetrans_stc_size;
1114
if (((const char*)szCurrent - (const char*)pcHeader) + iAdd > (unsigned int)pcHeader->data_size) {
1114
if (((const char*)szCurrent - (const char*)pcHeader) + iAdd > (unsigned int)pcHeader->data_size) {
1115
1115
DefaultLogger::get()->warn("Index overflow in frame area. "
1116
1116
"Ignoring all frames and all further mesh groups, too.");
1123
1123
// our output frame?
1124
if (configFrameID == iFrame) {
1124
if (configFrameID == iFrame) {
1125
1125
BE_NCONST MDL::Vertex_MDL7* pcFrameVertices = (BE_NCONST MDL::Vertex_MDL7*)(szCurrent+pcHeader->frame_stc_size);
1127
for (unsigned int qq = 0; qq < frame.pcFrame->vertices_count;++qq) {
1127
for (unsigned int qq = 0; qq < frame.pcFrame->vertices_count;++qq) {
1128
1128
// I assume this are simple replacements for normal vertices, the bone index serving
1129
1129
// as the index of the vertex to be replaced.
1130
1130
uint16_t iIndex = _AI_MDL7_ACCESS(pcFrameVertices,qq,pcHeader->framevertex_stc_size,MDL::Vertex_MDL7).vertindex;
1131
1131
AI_SWAP2(iIndex);
1132
if (iIndex >= groupInfo.pcGroup->numverts) {
1132
if (iIndex >= groupInfo.pcGroup->numverts) {
1133
1133
DefaultLogger::get()->warn("Invalid vertex index in frame vertex section");
1144
1144
AI_SWAP4(vPosition.z);
1146
1146
// now read the normal vector
1147
if (AI_MDL7_FRAMEVERTEX030305_STCSIZE <= pcHeader->mainvertex_stc_size) {
1147
if (AI_MDL7_FRAMEVERTEX030305_STCSIZE <= pcHeader->mainvertex_stc_size) {
1148
1148
// read the full normal vector
1149
1149
vNormal.x = _AI_MDL7_ACCESS_VERT(pcFrameVertices,qq,pcHeader->framevertex_stc_size) .norm[0];
1150
1150
AI_SWAP4(vNormal.x);
1153
1153
vNormal.z = _AI_MDL7_ACCESS_VERT(pcFrameVertices,qq,pcHeader->framevertex_stc_size) .norm[2];
1154
1154
AI_SWAP4(vNormal.z);
1156
else if (AI_MDL7_FRAMEVERTEX120503_STCSIZE <= pcHeader->mainvertex_stc_size) {
1156
else if (AI_MDL7_FRAMEVERTEX120503_STCSIZE <= pcHeader->mainvertex_stc_size) {
1157
1157
// read the normal vector from Quake2's smart table
1158
1158
MD2::LookupNormalIndex(_AI_MDL7_ACCESS_VERT(pcFrameVertices,qq,
1159
1159
pcHeader->framevertex_stc_size) .norm162index,vNormal);
1162
1162
// FIXME: O(n^2) at the moment ...
1163
1163
BE_NCONST MDL::Triangle_MDL7* pcGroupTris = groupInfo.pcGroupTris;
1164
1164
unsigned int iOutIndex = 0;
1165
for (unsigned int iTriangle = 0; iTriangle < (unsigned int)groupInfo.pcGroup->numtris; ++iTriangle) {
1165
for (unsigned int iTriangle = 0; iTriangle < (unsigned int)groupInfo.pcGroup->numtris; ++iTriangle) {
1166
1166
// iterate through all indices of the current triangle
1167
for (unsigned int c = 0; c < 3;++c,++iOutIndex) {
1167
for (unsigned int c = 0; c < 3;++c,++iOutIndex) {
1168
1168
// replace the vertex with the new data
1169
1169
const unsigned int iCurIndex = pcGroupTris->v_index[c];
1170
if (iCurIndex == iIndex) {
1170
if (iCurIndex == iIndex) {
1171
1171
groupData.vPositions[iOutIndex] = vPosition;
1172
1172
groupData.vNormals[iOutIndex] = vNormal;
1196
1196
MDL::IntSplittedGroupData_MDL7& splittedGroupData)
1198
1198
const unsigned int iNumMaterials = (unsigned int)splittedGroupData.shared.pcMats.size();
1199
if (!groupData.bNeed2UV) {
1199
if (!groupData.bNeed2UV) {
1200
1200
// if we don't need a second set of texture coordinates there is no reason to keep it in memory ...
1201
1201
groupData.vTextureCoords2.clear();
1207
1207
splittedGroupData.aiSplit[m] = new std::vector<unsigned int>();
1209
1209
// iterate through all faces and sort by material
1210
for (unsigned int iFace = 0; iFace < (unsigned int)groupInfo.pcGroup->numtris;++iFace) {
1210
for (unsigned int iFace = 0; iFace < (unsigned int)groupInfo.pcGroup->numtris;++iFace) {
1212
if (groupData.pcFaces[iFace].iMatIndex[0] >= iNumMaterials) {
1212
if (groupData.pcFaces[iFace].iMatIndex[0] >= iNumMaterials) {
1213
1213
// use the last material instead
1214
1214
splittedGroupData.aiSplit[iNumMaterials-1]->push_back(iFace);
1216
1216
// sometimes MED writes -1, but normally only if there is only
1217
1217
// one skin assigned. No warning in this case
1218
if (0xFFFFFFFF != groupData.pcFaces[iFace].iMatIndex[0])
1218
if(0xFFFFFFFF != groupData.pcFaces[iFace].iMatIndex[0])
1219
1219
DefaultLogger::get()->warn("Index overflow in MDL7 material list [#0]");
1221
1221
else splittedGroupData.aiSplit[groupData.pcFaces[iFace].
1234
1234
aiTempSplit[m] = new std::vector<unsigned int>();
1236
1236
// iterate through all faces and sort by material
1237
for (unsigned int iFace = 0; iFace < (unsigned int)groupInfo.pcGroup->numtris;++iFace) {
1237
for (unsigned int iFace = 0; iFace < (unsigned int)groupInfo.pcGroup->numtris;++iFace) {
1239
1239
unsigned int iMatIndex = groupData.pcFaces[iFace].iMatIndex[0];
1240
if (iMatIndex >= iNumMaterials) {
1240
if (iMatIndex >= iNumMaterials) {
1241
1241
// sometimes MED writes -1, but normally only if there is only
1242
1242
// one skin assigned. No warning in this case
1243
if (0xffffffff != iMatIndex)
1243
if(0xffffffff != iMatIndex)
1244
1244
DefaultLogger::get()->warn("Index overflow in MDL7 material list [#1]");
1245
1245
iMatIndex = iNumMaterials-1;
1247
1247
unsigned int iMatIndex2 = groupData.pcFaces[iFace].iMatIndex[1];
1249
1249
unsigned int iNum = iMatIndex;
1250
if (0xffffffff != iMatIndex2 && iMatIndex != iMatIndex2) {
1251
if (iMatIndex2 >= iNumMaterials) {
1250
if (0xffffffff != iMatIndex2 && iMatIndex != iMatIndex2) {
1251
if (iMatIndex2 >= iNumMaterials) {
1252
1252
// sometimes MED writes -1, but normally only if there is only
1253
1253
// one skin assigned. No warning in this case
1254
1254
DefaultLogger::get()->warn("Index overflow in MDL7 material list [#2]");
1260
1260
bool bFound = false;
1261
1261
for (std::vector<MDL::IntMaterial_MDL7>::iterator i = avMats.begin();i != avMats.end();++i,++iNum){
1262
if ((*i).iOldMatIndices[0] == iMatIndex && (*i).iOldMatIndices[1] == iMatIndex2) {
1262
if ((*i).iOldMatIndices[0] == iMatIndex && (*i).iOldMatIndices[1] == iMatIndex2) {
1263
1263
// reuse this material
1269
1269
// build a new material ...
1270
1270
MDL::IntMaterial_MDL7 sHelper;
1271
1271
sHelper.pcMat = new MaterialHelper();
1289
1289
// now add the newly created materials to the old list
1290
if (0 == groupInfo.iIndex) {
1290
if (0 == groupInfo.iIndex) {
1291
1291
splittedGroupData.shared.pcMats.resize(avMats.size());
1292
1292
for (unsigned int o = 0; o < avMats.size();++o)
1293
1293
splittedGroupData.shared.pcMats[o] = avMats[o].pcMat;
1296
1296
// This might result in redundant materials ...
1297
1297
splittedGroupData.shared.pcMats.resize(iNumMaterials + avMats.size());
1298
1298
for (unsigned int o = iNumMaterials; o < avMats.size();++o)
1357
1357
char* aszGroupNameBuffer = new char[AI_MDL7_MAX_GROUPNAMESIZE*pcHeader->groups_num];
1359
1359
// read all groups
1360
for (unsigned int iGroup = 0; iGroup < (unsigned int)pcHeader->groups_num;++iGroup) {
1360
for (unsigned int iGroup = 0; iGroup < (unsigned int)pcHeader->groups_num;++iGroup) {
1361
1361
MDL::IntGroupInfo_MDL7 groupInfo((BE_NCONST MDL::Group_MDL7*)szCurrent,iGroup);
1362
1362
szCurrent = (const unsigned char*)(groupInfo.pcGroup+1);
1370
1370
AI_SWAP4(groupInfo.pcGroup->numverts);
1371
1371
AI_SWAP4(groupInfo.pcGroup->numframes);
1373
if (1 != groupInfo.pcGroup->typ) {
1373
if (1 != groupInfo.pcGroup->typ) {
1374
1374
// Not a triangle-based mesh
1375
1375
DefaultLogger::get()->warn("[3DGS MDL7] Not a triangle mesh group. Continuing happily");
1388
1388
sharedData.abNeedMaterials.resize(sharedData.abNeedMaterials.size() +
1389
1389
groupInfo.pcGroup->numskins,false);
1391
for (unsigned int iSkin = 0; iSkin < (unsigned int)groupInfo.pcGroup->numskins;++iSkin) {
1391
for (unsigned int iSkin = 0; iSkin < (unsigned int)groupInfo.pcGroup->numskins;++iSkin) {
1392
1392
ParseSkinLump_3DGS_MDL7(szCurrent,&szCurrent,sharedData.pcMats);
1394
1394
// if we have absolutely no skin loaded we need to generate a default material
1395
if (sharedData.pcMats.empty()) {
1395
if (sharedData.pcMats.empty()) {
1396
1396
const int iMode = (int)aiShadingMode_Gouraud;
1397
1397
sharedData.pcMats.push_back(new MaterialHelper());
1398
1398
MaterialHelper* pcHelper = (MaterialHelper*)sharedData.pcMats[0];
1416
1416
// now get a pointer to all texture coords in the group
1417
1417
groupInfo.pcGroupUVs = (BE_NCONST MDL::TexCoord_MDL7*)szCurrent;
1418
for (int i = 0; i < groupInfo.pcGroup->num_stpts; ++i){
1418
for(int i = 0; i < groupInfo.pcGroup->num_stpts; ++i){
1419
1419
AI_SWAP4(groupInfo.pcGroupUVs[i].u);
1420
1420
AI_SWAP4(groupInfo.pcGroupUVs[i].v);
1428
1428
// now get a pointer to all vertices in the group
1429
1429
groupInfo.pcGroupVerts = (BE_NCONST MDL::Vertex_MDL7*)szCurrent;
1430
for (int i = 0; i < groupInfo.pcGroup->numverts; ++i){
1430
for(int i = 0; i < groupInfo.pcGroup->numverts; ++i){
1431
1431
AI_SWAP4(groupInfo.pcGroupVerts[i].x);
1432
1432
AI_SWAP4(groupInfo.pcGroupVerts[i].y);
1433
1433
AI_SWAP4(groupInfo.pcGroupVerts[i].z);
1456
1456
// check whether the triangle data structure is large enough
1457
1457
// to contain a second UV coodinate set
1458
if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_TWO_UV) {
1458
if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_TWO_UV) {
1459
1459
groupData.vTextureCoords2.resize(iNumVertices,aiVector3D());
1460
1460
groupData.bNeed2UV = true;
1469
1469
SortByMaterials_3DGS_MDL7(groupInfo, groupData,
1470
1470
splittedGroupData);
1472
for (unsigned int qq = 0; qq < sharedData.pcMats.size();++qq) {
1472
for (unsigned int qq = 0; qq < sharedData.pcMats.size();++qq) {
1473
1473
if (!splittedGroupData.aiSplit[qq]->empty())
1474
1474
sharedData.abNeedMaterials[qq] = true;
1489
1489
for (uint32_t i = 0; i < pcHeader->groups_num;++i)
1490
1490
pScene->mNumMeshes += (unsigned int)avOutList[i].size();
1492
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]; {
1492
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]; {
1493
1493
unsigned int p = 0,q = 0;
1494
for (uint32_t i = 0; i < pcHeader->groups_num;++i) {
1495
for (unsigned int a = 0; a < avOutList[i].size();++a) {
1494
for (uint32_t i = 0; i < pcHeader->groups_num;++i) {
1495
for (unsigned int a = 0; a < avOutList[i].size();++a) {
1496
1496
pScene->mMeshes[p++] = avOutList[i][a];
1498
1498
if (!avOutList[i].empty())++pScene->mRootNode->mNumChildren;
1501
1501
if (sharedData.apcOutBones)++pScene->mRootNode->mNumChildren;
1502
1502
this->pScene->mRootNode->mChildren = new aiNode*[pScene->mRootNode->mNumChildren];
1504
for (uint32_t i = 0; i < pcHeader->groups_num;++i) {
1504
for (uint32_t i = 0; i < pcHeader->groups_num;++i) {
1505
1505
if (avOutList[i].empty())continue;
1507
1507
aiNode* const pcNode = pScene->mRootNode->mChildren[p] = new aiNode();
1525
1525
// if there is only one root node with a single child we can optimize it a bit ...
1526
if (1 == pScene->mRootNode->mNumChildren && !sharedData.apcOutBones) {
1526
if (1 == pScene->mRootNode->mNumChildren && !sharedData.apcOutBones) {
1527
1527
aiNode* pcOldRoot = this->pScene->mRootNode;
1528
1528
pScene->mRootNode = pcOldRoot->mChildren[0];
1529
1529
pcOldRoot->mChildren[0] = NULL;
1542
1542
HandleMaterialReferences_3DGS_MDL7();
1544
1544
// generate output bone animations and add all bones to the scenegraph
1545
if (sharedData.apcOutBones) {
1545
if (sharedData.apcOutBones) {
1546
1546
// this step adds empty dummy bones to the nodegraph
1547
1547
// insert another dummy node to avoid name conflicts
1548
1548
aiNode* const pc = pScene->mRootNode->mChildren[pScene->mRootNode->mNumChildren-1] = new aiNode();
1575
1575
void MDLImporter::HandleMaterialReferences_3DGS_MDL7()
1577
1577
// search for referrer materials
1578
for (unsigned int i = 0; i < pScene->mNumMaterials;++i) {
1578
for (unsigned int i = 0; i < pScene->mNumMaterials;++i) {
1579
1579
int iIndex = 0;
1580
if (AI_SUCCESS == aiGetMaterialInteger(pScene->mMaterials[i],AI_MDL7_REFERRER_MATERIAL, &iIndex) ) {
1581
for (unsigned int a = 0; a < pScene->mNumMeshes;++a) {
1580
if (AI_SUCCESS == aiGetMaterialInteger(pScene->mMaterials[i],AI_MDL7_REFERRER_MATERIAL, &iIndex) ) {
1581
for (unsigned int a = 0; a < pScene->mNumMeshes;++a) {
1582
1582
aiMesh* const pcMesh = pScene->mMeshes[a];
1583
1583
if (i == pcMesh->mMaterialIndex) {
1584
1584
pcMesh->mMaterialIndex = iIndex;
1587
1587
// collapse the rest of the array
1588
1588
delete pScene->mMaterials[i];
1589
for (unsigned int pp = i; pp < pScene->mNumMaterials-1;++pp) {
1589
for (unsigned int pp = i; pp < pScene->mNumMaterials-1;++pp) {
1591
1591
pScene->mMaterials[pp] = pScene->mMaterials[pp+1];
1592
for (unsigned int a = 0; a < pScene->mNumMeshes;++a) {
1592
for (unsigned int a = 0; a < pScene->mNumMeshes;++a) {
1593
1593
aiMesh* const pcMesh = pScene->mMeshes[a];
1594
1594
if (pcMesh->mMaterialIndex > i)--pcMesh->mMaterialIndex;
1609
1609
const MDL::Header_MDL7* const pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
1611
1611
// only the first group contains bone animation keys
1612
if (frame.pcFrame->transmatrix_count) {
1613
if (!groupInfo.iIndex) {
1612
if (frame.pcFrame->transmatrix_count) {
1613
if (!groupInfo.iIndex) {
1614
1614
// skip all frames vertices. We can't support them
1615
1615
const MDL::BoneTransform_MDL7* pcBoneTransforms = (const MDL::BoneTransform_MDL7*)
1616
1616
(((const char*)frame.pcFrame) + pcHeader->frame_stc_size +
1617
1617
frame.pcFrame->vertices_count * pcHeader->framevertex_stc_size);
1619
1619
// read all transformation matrices
1620
for (unsigned int iTrafo = 0; iTrafo < frame.pcFrame->transmatrix_count;++iTrafo) {
1621
if (pcBoneTransforms->bone_index >= pcHeader->bones_num) {
1620
for (unsigned int iTrafo = 0; iTrafo < frame.pcFrame->transmatrix_count;++iTrafo) {
1621
if(pcBoneTransforms->bone_index >= pcHeader->bones_num) {
1622
1622
DefaultLogger::get()->warn("Index overflow in frame area. "
1623
1623
"Unable to parse this bone transformation");
1626
1626
AddAnimationBoneTrafoKey_3DGS_MDL7(frame.iIndex,
1627
1627
pcBoneTransforms,shared.apcOutBones);
1647
1647
const MDL::Header_MDL7* const pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
1649
1649
const MDL::IntBone_MDL7** apcBones2 = apcBones;
1650
for (uint32_t i = 0; i < pcHeader->bones_num;++i) {
1650
for (uint32_t i = 0; i < pcHeader->bones_num;++i) {
1652
1652
const MDL::IntBone_MDL7* const pcBone = *apcBones2++;
1653
1653
if (pcBone->iParent == iParentIndex) {
1657
1657
pcParent->mChildren = new aiNode*[pcParent->mNumChildren];
1658
1658
unsigned int qq = 0;
1659
for (uint32_t i = 0; i < pcHeader->bones_num;++i) {
1659
for (uint32_t i = 0; i < pcHeader->bones_num;++i) {
1661
1661
const MDL::IntBone_MDL7* const pcBone = *apcBones++;
1662
1662
if (pcBone->iParent != iParentIndex)continue;
1679
1679
// one animation ...
1680
1680
aiAnimation* pcAnim = new aiAnimation();
1681
for (uint32_t i = 0; i < pcHeader->bones_num;++i) {
1682
if (!apcBonesOut[i]->pkeyPositions.empty()) {
1681
for (uint32_t i = 0; i < pcHeader->bones_num;++i) {
1682
if (!apcBonesOut[i]->pkeyPositions.empty()) {
1684
1684
// get the last frame ... (needn't be equal to pcHeader->frames_num)
1685
for (size_t qq = 0; qq < apcBonesOut[i]->pkeyPositions.size();++qq) {
1685
for (size_t qq = 0; qq < apcBonesOut[i]->pkeyPositions.size();++qq) {
1686
1686
pcAnim->mDuration = std::max(pcAnim->mDuration, (double)
1687
1687
apcBonesOut[i]->pkeyPositions[qq].mTime);
1689
1689
++pcAnim->mNumChannels;
1692
if (pcAnim->mDuration) {
1692
if (pcAnim->mDuration) {
1693
1693
pcAnim->mChannels = new aiNodeAnim*[pcAnim->mNumChannels];
1695
1695
unsigned int iCnt = 0;
1696
for (uint32_t i = 0; i < pcHeader->bones_num;++i) {
1697
if (!apcBonesOut[i]->pkeyPositions.empty()) {
1696
for (uint32_t i = 0; i < pcHeader->bones_num;++i) {
1697
if (!apcBonesOut[i]->pkeyPositions.empty()) {
1698
1698
const MDL::IntBone_MDL7* const intBone = apcBonesOut[i];
1700
1700
aiNodeAnim* const pcNodeAnim = pcAnim->mChannels[iCnt++] = new aiNodeAnim();
1710
1710
pcNodeAnim->mRotationKeys = new aiQuatKey[pcNodeAnim->mNumPositionKeys];
1712
1712
// copy all keys
1713
for (unsigned int qq = 0; qq < pcNodeAnim->mNumPositionKeys;++qq) {
1713
for (unsigned int qq = 0; qq < pcNodeAnim->mNumPositionKeys;++qq) {
1714
1714
pcNodeAnim->mPositionKeys[qq] = intBone->pkeyPositions[qq];
1715
1715
pcNodeAnim->mScalingKeys[qq] = intBone->pkeyScalings[qq];
1716
1716
pcNodeAnim->mRotationKeys[qq] = intBone->pkeyRotations[qq];
1765
1765
// add the keys to the bone
1766
1766
MDL::IntBone_MDL7* const pcBoneOut = apcBonesOut[pcBoneTransforms->bone_index];
1767
pcBoneOut->pkeyPositions.push_back ( vPosition );
1768
pcBoneOut->pkeyScalings.push_back ( vScaling );
1769
pcBoneOut->pkeyRotations.push_back ( qRotation );
1767
pcBoneOut->pkeyPositions.push_back ( vPosition );
1768
pcBoneOut->pkeyScalings.push_back ( vScaling );
1769
pcBoneOut->pkeyRotations.push_back ( qRotation );
1772
1772
// ------------------------------------------------------------------------------------------------
1781
1781
const MDL::Header_MDL7* const pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
1782
1782
const unsigned int iNumOutBones = pcHeader->bones_num;
1784
for (std::vector<MaterialHelper*>::size_type i = 0; i < shared.pcMats.size();++i) {
1785
if (!splittedGroupData.aiSplit[i]->empty()) {
1784
for (std::vector<MaterialHelper*>::size_type i = 0; i < shared.pcMats.size();++i) {
1785
if (!splittedGroupData.aiSplit[i]->empty()) {
1787
1787
// allocate the output mesh
1788
1788
aiMesh* pcMesh = new aiMesh();
1798
1798
pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices];
1799
1799
pcMesh->mNormals = new aiVector3D[pcMesh->mNumVertices];
1801
if (!groupData.vTextureCoords1.empty()) {
1801
if (!groupData.vTextureCoords1.empty()) {
1802
1802
pcMesh->mNumUVComponents[0] = 2;
1803
1803
pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
1804
if (!groupData.vTextureCoords2.empty()) {
1804
if (!groupData.vTextureCoords2.empty()) {
1805
1805
pcMesh->mNumUVComponents[1] = 2;
1806
1806
pcMesh->mTextureCoords[1] = new aiVector3D[pcMesh->mNumVertices];
1810
1810
// iterate through all faces and build an unique set of vertices
1811
1811
unsigned int iCurrent = 0;
1812
for (unsigned int iFace = 0; iFace < pcMesh->mNumFaces;++iFace) {
1812
for (unsigned int iFace = 0; iFace < pcMesh->mNumFaces;++iFace) {
1813
1813
pcMesh->mFaces[iFace].mNumIndices = 3;
1814
1814
pcMesh->mFaces[iFace].mIndices = new unsigned int[3];
1817
1817
const MDL::IntFace_MDL7& oldFace = groupData.pcFaces[iSrcFace];
1819
1819
// iterate through all face indices
1820
for (unsigned int c = 0; c < 3;++c) {
1820
for (unsigned int c = 0; c < 3;++c) {
1821
1821
const uint32_t iIndex = oldFace.mIndices[c];
1822
1822
pcMesh->mVertices[iCurrent] = groupData.vPositions[iIndex];
1823
1823
pcMesh->mNormals[iCurrent] = groupData.vNormals[iIndex];
1825
if (!groupData.vTextureCoords1.empty()) {
1825
if (!groupData.vTextureCoords1.empty()) {
1827
1827
pcMesh->mTextureCoords[0][iCurrent] = groupData.vTextureCoords1[iIndex];
1828
if (!groupData.vTextureCoords2.empty()) {
1828
if (!groupData.vTextureCoords2.empty()) {
1829
1829
pcMesh->mTextureCoords[1][iCurrent] = groupData.vTextureCoords2[iIndex];
1836
1836
// if we have bones in the mesh we'll need to generate
1837
1837
// proper vertex weights for them
1838
if (!groupData.aiBones.empty()) {
1838
if (!groupData.aiBones.empty()) {
1839
1839
std::vector<std::vector<unsigned int> > aaiVWeightList;
1840
1840
aaiVWeightList.resize(iNumOutBones);
1842
1842
int iCurrent = 0;
1843
for (unsigned int iFace = 0; iFace < pcMesh->mNumFaces;++iFace) {
1843
for (unsigned int iFace = 0; iFace < pcMesh->mNumFaces;++iFace) {
1844
1844
unsigned int iSrcFace = splittedGroupData.aiSplit[i]->operator[](iFace);
1845
1845
const MDL::IntFace_MDL7& oldFace = groupData.pcFaces[iSrcFace];
1847
1847
// iterate through all face indices
1848
for (unsigned int c = 0; c < 3;++c) {
1848
for (unsigned int c = 0; c < 3;++c) {
1849
1849
unsigned int iBone = groupData.aiBones[ oldFace.mIndices[c] ];
1850
if (0xffffffff != iBone) {
1851
if (iBone >= iNumOutBones) {
1850
if (0xffffffff != iBone) {
1851
if (iBone >= iNumOutBones) {
1852
1852
DefaultLogger::get()->error("Bone index overflow. "
1853
1853
"The bone index of a vertex exceeds the allowed range. ");
1854
1854
iBone = iNumOutBones-1;
1880
1880
pcBone->mNumWeights = (unsigned int)(*k).size();
1881
1881
pcBone->mWeights = new aiVertexWeight[pcBone->mNumWeights];
1883
for (unsigned int weight = 0; weight < pcBone->mNumWeights;++weight) {
1883
for (unsigned int weight = 0; weight < pcBone->mNumWeights;++weight) {
1884
1884
pcBone->mWeights[weight].mVertexId = (*k)[weight];
1885
1885
pcBone->mWeights[weight].mWeight = 1.0f;
1911
1911
// then extract the diffuse texture from the second skin,
1912
1912
// setup 1 as UV source and we have it
1913
1913
aiString sString;
1914
if (AI_SUCCESS == aiGetMaterialString ( pcMat2, AI_MATKEY_TEXTURE_DIFFUSE(0),&sString )) {
1914
if(AI_SUCCESS == aiGetMaterialString ( pcMat2, AI_MATKEY_TEXTURE_DIFFUSE(0),&sString )) {
1916
1916
pcMatOut->AddProperty<int>(&iVal,1,AI_MATKEY_UVWSRC_DIFFUSE(1));
1917
1917
pcMatOut->AddProperty(&sString,AI_MATKEY_TEXTURE_DIFFUSE(1));