~neon/qt/quick3d

« back to all changes in this revision

Viewing changes to 3rdparty/assimp/code/MDLLoader.cpp

  • Committer: Qt by Nokia
  • Author(s): Sergey Dubitskiy
  • Date: 2012-01-24 23:46:01 UTC
  • Revision ID: git-v1:4f3b9edab3b59b6ea150d65c5357f50174cbdd73
Upgrade to AssImp library v2.0.863.

Also includes a new example.

Task-number: QTBUG-22194.

Change-Id: I8870edadff58f8103e3645574b635a3b83ce1d98
Reviewed-by: Danny Pope <daniel.pope@nokia.com>

Show diffs side-by-side

added added

removed removed

Lines of Context:
56
56
 
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)))
61
61
 
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))
64
64
 
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)
67
67
 
68
68
// ------------------------------------------------------------------------------------------------
106
106
    // The
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);
111
111
    }
112
112
 
131
131
    boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
132
132
 
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 + ".");
136
136
    }
137
137
 
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.");
143
143
    }
144
144
 
156
156
    // Determine the file subtype and call the appropriate member function
157
157
 
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();
163
163
    }
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();
169
169
    }
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();
175
175
    }
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();
181
181
    }
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();
187
187
    }
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();
193
193
    }
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)
197
197
    {
199
199
        iGSFileVersion = 0;
200
200
        InternReadFile_HL2();
201
201
    }
202
 
    else {
 
202
    else    {
203
203
        // print the magic word to the log file
204
204
        throw DeadlyImportError( "Unknown MDL subformat " + pFile +
205
205
            ". Magic word (" + std::string((char*)&iMagicWord,4) + ") is not known");
235
235
    {
236
236
        // remove a directory if there is one
237
237
        const char* szFilePtr = ::strrchr(szFile,'\\');
238
 
        if (!szFilePtr) {
239
 
            if (!(szFilePtr = ::strrchr(szFile,'/')))
 
238
        if (!szFilePtr)    {
 
239
            if(!(szFilePtr = ::strrchr(szFile,'/')))
240
240
                szFilePtr = szFile;
241
241
        }
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");
284
284
    }
285
285
}
469
469
            float t = (float)pcTexCoords[iIndex].t;
470
470
 
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;
474
474
            }
475
475
 
503
503
    pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
504
504
 
505
505
    aiColor4D clr;
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;
512
512
 
513
513
            pScene->mTextures = NULL;
514
514
            pScene->mNumTextures = 0;
515
515
        }
516
 
        else {
 
516
        else    {
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);
548
548
 
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);
559
559
            CreateTexture_3DGS_MDL5((unsigned char*)pcSkin + sizeof(uint32_t),
560
560
                pcSkin->group,&iSkip);
561
561
        }
562
 
        else {
 
562
        else    {
563
563
            CreateTexture_3DGS_MDL4((unsigned char*)pcSkin + sizeof(uint32_t),
564
564
                pcSkin->group,&iSkip);
565
565
        }
579
579
 
580
580
#ifdef AI_BUILD_BIG_ENDIAN
581
581
 
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 );
585
585
    }
586
586
 
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];
624
624
 
625
 
    if (pcHeader->synctype) {
 
625
    if (pcHeader->synctype)    {
626
626
        pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
627
627
        pcMesh->mNumUVComponents[0] = 2;
628
628
    }
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)    {
638
638
 
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));
643
643
 
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;
649
649
 
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)    {
652
652
                // read vertices
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");
657
657
                }
672
672
                // pcMesh->mNormals[iCurrent].y *= -1.0f;
673
673
 
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]);
678
678
                }
686
686
    }
687
687
    // short packed vertices
688
688
    /////////////////////////////////////////////////////////////////////////////////////
689
 
    else {
 
689
    else    {
690
690
        // now get a pointer to the first frame in the file
691
691
        const MDL::SimpleFrame_MDLn_SP* pcFirstFrame = (const MDL::SimpleFrame_MDLn_SP*) (szCurrent + sizeof(uint32_t));
692
692
 
698
698
 
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;
704
704
 
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)    {
707
707
                // read vertices
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");
712
712
                }
727
727
                // pcMesh->mNormals[iCurrent].y *= -1.0f;
728
728
 
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]);
733
733
                }
757
757
    const MDL::Header* const pcHeader = (const MDL::Header*)this->mBuffer;
758
758
 
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");
763
763
    }
766
766
    float t = (float)pcSrc[iIndex].v;
767
767
 
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;
772
772
    }
781
781
void MDLImporter::CalculateUVCoordinates_MDL5()
782
782
{
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];
786
786
 
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;
793
793
 
794
794
            piPtr += 3;
804
804
                iHeight = 1;
805
805
            }
806
806
        }
807
 
        else {
 
807
        else    {
808
808
            iWidth  = pcTex->mWidth;
809
809
            iHeight = pcTex->mHeight;
810
810
        }
811
811
 
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);
831
831
 
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");
836
836
    }
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");
840
840
    }
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");
844
844
    }
845
845
 
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");
849
849
    }
850
850
}
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);
869
869
 
872
872
            AI_SWAP4(pcBone->y);
873
873
            AI_SWAP4(pcBone->z);
874
874
 
875
 
            if (iParent == pcBone->parent_index) {
 
875
            if (iParent == pcBone->parent_index)    {
876
876
                // MDL7 readme
877
877
                ////////////////////////////////////////////////////////////////
878
878
                /*
897
897
 
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;
912
912
 
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);
917
917
                }
918
 
                else {
 
918
                else    {
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])    {
925
925
                            iMaxLen = qq;
926
926
                            break;
927
927
                        }
943
943
MDL::IntBone_MDL7** MDLImporter::LoadBones_3DGS_MDL7()
944
944
{
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 &&
974
974
 
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]);
981
981
 
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)    {
984
984
 
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");
1005
1005
            }
1006
1006
 
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);
1017
1017
            }
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);
1023
1023
            }
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)    {
1026
1026
 
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]);
1031
1031
 
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)");
1036
1036
                    }
1048
1048
                }
1049
1049
            }
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)    {
1052
1052
 
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);
1058
1058
 
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)");
1063
1063
                    }
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);
1106
1106
 
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;
1113
1113
 
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.");
1117
1117
 
1121
1121
            return false;
1122
1122
        }
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);
1126
1126
 
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");
1134
1134
                    continue;
1135
1135
                }
1144
1144
                AI_SWAP4(vPosition.z);
1145
1145
 
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);
1155
1155
                }
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;
1173
1173
                        }
1196
1196
    MDL::IntSplittedGroupData_MDL7& splittedGroupData)
1197
1197
{
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();
1202
1202
 
1207
1207
            splittedGroupData.aiSplit[m] = new std::vector<unsigned int>();
1208
1208
 
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)    {
1211
1211
            // check range
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);
1215
1215
 
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]");
1220
1220
            }
1221
1221
            else splittedGroupData.aiSplit[groupData.pcFaces[iFace].
1234
1234
            aiTempSplit[m] = new std::vector<unsigned int>();
1235
1235
 
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)    {
1238
1238
            // check range
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;
1246
1246
            }
1247
1247
            unsigned int iMatIndex2 = groupData.pcFaces[iFace].iMatIndex[1];
1248
1248
 
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]");
1259
1259
                iNum = 0;
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
1264
1264
                        bFound = true;
1265
1265
                        break;
1266
1266
                    }
1267
1267
                }
1268
 
                if (!bFound) {
 
1268
                if (!bFound)    {
1269
1269
                    //  build a new material ...
1270
1270
                    MDL::IntMaterial_MDL7 sHelper;
1271
1271
                    sHelper.pcMat = new MaterialHelper();
1287
1287
        }
1288
1288
 
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;
1294
1294
        }
1295
 
        else {
 
1295
        else    {
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];
1358
1358
 
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);
1363
1363
 
1370
1370
        AI_SWAP4(groupInfo.pcGroup->numverts);
1371
1371
        AI_SWAP4(groupInfo.pcGroup->numframes);
1372
1372
 
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");
1376
1376
        }
1388
1388
        sharedData.abNeedMaterials.resize(sharedData.abNeedMaterials.size() +
1389
1389
            groupInfo.pcGroup->numskins,false);
1390
1390
 
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);
1393
1393
        }
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];
1415
1415
 
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);
1421
1421
        }
1427
1427
 
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);
1455
1455
 
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;
1461
1461
                }
1469
1469
            SortByMaterials_3DGS_MDL7(groupInfo, groupData,
1470
1470
                splittedGroupData);
1471
1471
 
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;
1475
1475
            }
1489
1489
    for (uint32_t i = 0; i < pcHeader->groups_num;++i)
1490
1490
        pScene->mNumMeshes += (unsigned int)avOutList[i].size();
1491
1491
 
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];
1497
1497
            }
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];
1503
1503
        p = 0;
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;
1506
1506
 
1507
1507
            aiNode* const pcNode = pScene->mRootNode->mChildren[p] = new aiNode();
1523
1523
    }
1524
1524
 
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();
1543
1543
 
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()
1576
1576
{
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;
1586
1586
            }
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)    {
1590
1590
 
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;
1595
1595
                }
1609
1609
    const MDL::Header_MDL7* const pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
1610
1610
 
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);
1618
1618
 
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");
1624
1624
                }
1625
 
                else {
 
1625
                else    {
1626
1626
                    AddAnimationBoneTrafoKey_3DGS_MDL7(frame.iIndex,
1627
1627
                        pcBoneTransforms,shared.apcOutBones);
1628
1628
                }
1630
1630
                    (const char*)pcBoneTransforms + pcHeader->bonetrans_stc_size);
1631
1631
            }
1632
1632
        }
1633
 
        else {
 
1633
        else    {
1634
1634
            DefaultLogger::get()->warn("Ignoring animation keyframes in groups != 0");
1635
1635
        }
1636
1636
    }
1647
1647
    const MDL::Header_MDL7* const pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
1648
1648
 
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)    {
1651
1651
 
1652
1652
        const MDL::IntBone_MDL7* const pcBone = *apcBones2++;
1653
1653
        if (pcBone->iParent == iParentIndex) {
1656
1656
    }
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)    {
1660
1660
 
1661
1661
        const MDL::IntBone_MDL7* const pcBone = *apcBones++;
1662
1662
        if (pcBone->iParent != iParentIndex)continue;
1678
1678
 
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())    {
1683
1683
 
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);
1688
1688
            }
1689
1689
            ++pcAnim->mNumChannels;
1690
1690
        }
1691
1691
    }
1692
 
    if (pcAnim->mDuration) {
 
1692
    if (pcAnim->mDuration)    {
1693
1693
        pcAnim->mChannels = new aiNodeAnim*[pcAnim->mNumChannels];
1694
1694
 
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];
1699
1699
 
1700
1700
                aiNodeAnim* const pcNodeAnim = pcAnim->mChannels[iCnt++] = new aiNodeAnim();
1710
1710
                pcNodeAnim->mRotationKeys = new aiQuatKey[pcNodeAnim->mNumPositionKeys];
1711
1711
 
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];
1764
1764
 
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 );
1770
1770
}
1771
1771
 
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;
1783
1783
 
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())    {
1786
1786
 
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];
1800
1800
 
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];
1807
1807
                }
1809
1809
 
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];
1815
1815
 
1817
1817
                const MDL::IntFace_MDL7& oldFace = groupData.pcFaces[iSrcFace];
1818
1818
 
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];
1824
1824
 
1825
 
                    if (!groupData.vTextureCoords1.empty()) {
 
1825
                    if (!groupData.vTextureCoords1.empty())    {
1826
1826
 
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];
1830
1830
                        }
1831
1831
                    }
1835
1835
 
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);
1841
1841
 
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];
1846
1846
 
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;
1859
1859
                    }
1860
1860
                }
1861
1861
                // now check which bones are required ...
1862
 
                for (std::vector<std::vector<unsigned int> >::const_iterator k =  aaiVWeightList.begin();k != aaiVWeightList.end();++k) {
 
1862
                for (std::vector<std::vector<unsigned int> >::const_iterator k =  aaiVWeightList.begin();k != aaiVWeightList.end();++k)    {
1863
1863
                    if (!(*k).empty()) {
1864
1864
                        ++pcMesh->mNumBones;
1865
1865
                    }
1880
1880
                    pcBone->mNumWeights = (unsigned int)(*k).size();
1881
1881
                    pcBone->mWeights = new aiVertexWeight[pcBone->mNumWeights];
1882
1882
 
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;
1886
1886
                    }
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 ))    {
1915
1915
        iVal = 1;
1916
1916
        pcMatOut->AddProperty<int>(&iVal,1,AI_MATKEY_UVWSRC_DIFFUSE(1));
1917
1917
        pcMatOut->AddProperty(&sString,AI_MATKEY_TEXTURE_DIFFUSE(1));