D:/Zythum/DinoKod/mdlMaxExport/MDLMaxExporter.cpp

00001 //---------------------------------------------------------------------------------------------
00002 //      This file is a part of "DinoKod".
00003 //      Copyright © 2003 Dino Productions. All Rights Reserved.
00004 //      
00005 //      File                    : MDLMaxExporter.cpp
00006 //      Author                  : Sebastien LEIX        sebastien.leix@wanadoo.fr
00007 //      Date                    : 02/01/2003
00008 //      Modification    :
00009 //
00010 //---------------------------------------------------------------------------------------------
00011 #include "resource.h"
00012 #include "mdlMaxExporter.h"
00013 #include "Common/Console.h"
00014 #include "Common/Vertex.h"
00015 #include "Model/MdlLoader.h"
00016 #include "Model/MdlMesh.h"
00017 
00018 #include <modstack.h>
00019 #include <iskin.h>
00020 //#include <simpmod.h>
00021 
00022 //#define CLUSTOSM_CLASS_ID                     0x25215824
00023 
00024 #define PLUGIN_NAME     "3Dino MODEL Exporter"
00025 
00026 int                     g_ControlsInit = FALSE;
00027 HINSTANCE       g_hInstance = NULL;
00028 HWND            g_hWnd = NULL;
00029 
00030 //---------------------------------------------------------------------------------------------
00031 BOOL WINAPI DllMain( HINSTANCE hinstDLL, ULONG fdwReason, LPVOID lpvReserved ) 
00032 { 
00033         g_hInstance = hinstDLL;
00034         // Hang on to this DLL's instance handle.
00035         if( !g_ControlsInit )
00036         {
00037                 g_ControlsInit = TRUE;
00038 
00039                 // Initialize MAX's custom controls
00040                 InitCustomControls( hinstDLL );
00041 
00042                 // Initialize Win95 controls
00043                 InitCommonControls();
00044         }
00045 
00046         return TRUE;
00047 }
00048 
00049 //---------------------------------------------------------------------------------------------
00050 __declspec( dllexport ) int LibNumberClasses()
00051 {
00052         return 1;
00053 }
00054 
00055 //---------------------------------------------------------------------------------------------
00056 __declspec( dllexport ) ClassDesc* LibClassDesc( int i )
00057 {
00058         switch( i )
00059         {
00060         case 0:
00061                 return (ClassDesc*)&MdlExporterClassDesc;
00062         default:
00063                 return 0;
00064         }
00065 }
00066 
00067 //---------------------------------------------------------------------------------------------
00068 __declspec( dllexport ) const TCHAR* LibDescription()
00069 {
00070         return _T( PLUGIN_NAME );
00071 }
00072 
00073 //---------------------------------------------------------------------------------------------
00074 extern "C" __declspec( dllexport ) ULONG LibVersion()
00075 {
00076         return VERSION_3DSMAX;
00077 }
00078 
00079 //---------------------------------------------------------------------------------------------
00080 //---------------------------------------------------------------------------------------------
00081 //---------------------------------------------------------------------------------------------
00082 KMdlExporter::KMdlExporter()
00083 : SceneExport()
00084 {
00085 #if _DEBUG
00086         g_Console.Create( "MdlExporter", true, g_hInstance );
00087 #endif _DEBUG
00088 }
00089 
00090 //---------------------------------------------------------------------------------------------
00091 KMdlExporter::~KMdlExporter()
00092 {
00093 #if _DEBUG
00094         g_Console.Close();
00095 #endif _DEBUG
00096 }
00097 
00098 //---------------------------------------------------------------------------------------------
00099 void KMdlExporter::ShowAbout( HWND hWnd )
00100 {
00101 }
00102 
00103 //---------------------------------------------------------------------------------------------
00104 int KMdlExporter::DoExport( const TCHAR *pName, ExpInterface *pExtInterface, Interface *pInterface, BOOL bSuppressPrompts, DWORD Options )
00105 {
00106 //      s32             AnimStart;
00107 //      s32             AnimEnd;
00108 //      s32             AnimStep;
00109         KMdlLoader      Loader;
00110 
00111         g_hWnd = pInterface->GetMAXHWnd();
00112 
00113         g_Console << "===============================================================" << KENDL;
00114         g_Console << "Prompt options... " << (char*)pName << "..." << KENDL;
00115 
00116         if( !bSuppressPrompts )
00117         {
00118 /*              if( !DialogBoxParam( g_hInstance, MAKEINTRESOURCE(IDD_DIALOG_EXPORT), pInterface->GetMAXHWnd(), ExportDlgProc, (LPARAM)this ) )
00119                 {
00120                         g_Console << "Canceled." << KENDL;
00121                         return 1;
00122                 }*/
00123         }
00124 
00125         g_Console << "Exporting " << (char*)pName << "..." << KENDL;
00126 
00127         // Exporte les materiaux
00128         if( !ExportMaterials( Loader, pInterface->GetSceneMtls() ) )
00129                 return 1;
00130 
00131         Interval interval = pInterface->GetAnimRange();
00132 
00133         m_TickStart     = interval.Start();
00134         m_TickEnd       = interval.End();
00135         m_TickStep      = /*GetFrameRate() * */GetTicksPerFrame();
00136 
00137         // Frame Interval
00138         Loader.SetStartFrame( m_TickStart / GetTicksPerFrame() );
00139         Loader.SetEndFrame( m_TickEnd / GetTicksPerFrame() );
00140         g_Console << "Frames " << Loader.GetStartFrame() << " to " << Loader.GetEndFrame() << KENDL;
00141         
00142         // Exporte les nodes
00143 //      ResetXFormAll( pInterface, pInterface->GetRootNode(), 0 );
00144         if( !ExportNode( Loader, NULL, pInterface->GetRootNode(), (Options & SCENE_EXPORT_SELECTED) ? TRUE : FALSE, 0 ) )
00145                 return 1;
00146 
00147         // Sauve le fichier
00148         Loader.SaveMDL( (char*)pName );
00149 
00150         g_Console << "Done." << KENDL;
00151 
00152         char    pText[256];
00153         sprintf( pText, "File [%s] successfully exported!", pName );
00154         MessageBox( g_hWnd, pText, "MDL Export", MB_OK );
00155 
00156         return 1;
00157 }
00158 
00159 //---------------------------------------------------------------------------------------------
00160 INT_PTR CALLBACK KMdlExporter::ExportDlgProc( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam )
00161 {
00162         KMdlExporter* pExporter = (KMdlExporter*)(u64)GetWindowLongPtr( hWnd, GWLP_USERDATA ); 
00163 
00164         switch( Msg )
00165         {
00166         case WM_INITDIALOG:
00167                 break;
00168         case WM_COMMAND:
00169                 switch( LOWORD( wParam ) )
00170                 {
00171                 case IDOK:
00172                         EndDialog( hWnd, 1 );
00173                         break;
00174                 case IDCANCEL:
00175                         EndDialog( hWnd, 0 );
00176                         break;
00177                 }
00178                 break;
00179                 default:
00180                         return FALSE;
00181         }
00182 
00183         return TRUE;
00184 }
00185 
00186 //---------------------------------------------------------------------------------------------
00187 bool KMdlExporter::ExportMaterials( KMdlLoader& Loader, MtlBaseLib* pMtlBaseLib )
00188 {
00189         if( !pMtlBaseLib )
00190         {
00191                 MessageBox( g_hWnd, "No material set.\nYou need one material!", "MDL Export Error", MB_OK | MB_ICONSTOP );
00192                 return false;
00193         }
00194 /*
00195         MtlBase*        pMtl;
00196         for( int i = 0; i < pMtlBaseLib->Count(); i ++ )
00197         {
00198                 pMtl = (*pMtlBaseLib)[i];
00199 
00200                 // Ajoute le materiel
00201                 Loader.AddTexture( (char*)pMtl->GetName() );
00202                 g_Console << "Shader " << i << " : " << (char*)pMtl->GetName() << KENDL;
00203         }*/
00204         if( pMtlBaseLib->Count() != 1 )
00205         {
00206                 char    pText[256];
00207                 sprintf( pText, "%i material(s) detected.\nYou need only 1 material!", pMtlBaseLib->Count() );
00208                 MessageBox( g_hWnd, pText, "MDL Export Error", MB_OK | MB_ICONWARNING );
00209 //              return false;
00210         }
00211 
00212         if( pMtlBaseLib->Count() == 0 )
00213         {
00214                 // Cree un material par defaut
00215                 Loader.AddShader( "Error" );
00216                 g_Console << "No material detected, a default shader added." << KENDL;
00217                 return true;
00218         }
00219 
00220         Mtl*    pMtl;
00221         
00222         pMtl = (Mtl*)(*pMtlBaseLib)[0];
00223 
00224         int NumMat = pMtl->NumSubMtls();
00225 
00226         if( NumMat < 1 )
00227         {
00228                 char    pText[256];
00229                 sprintf( pText, "0 sub-material detected.\nYou need a least one sub-material!" );
00230                 MessageBox( g_hWnd, pText, "MDL Export Error", MB_OK | MB_ICONWARNING );
00231 
00232                 // Cree un material par defaut
00233                 Loader.AddShader( "Error" );
00234                 g_Console << "No material detected, a default shader added." << KENDL;
00235                 return true;
00236         }
00237 
00238 
00239         for( int mat = 0; mat < NumMat; mat ++ )
00240         {
00241                 Mtl* pSubMat = pMtl->GetSubMtl( mat );
00242 
00243                 if( pSubMat )
00244                 {
00245                         // Ajoute le materiel
00246                         Loader.AddShader( (char*)pSubMat->GetName() );
00247                         g_Console << "Shader " << mat << " : " << (char*)pSubMat->GetName() << KENDL;
00248                 }
00249         }
00250 
00251 
00252         return true;
00253 }
00254 
00255 //---------------------------------------------------------------------------------------------
00256 bool KMdlExporter::ExportNode( KMdlLoader& Loader, KMdlMesh* pMesh, INode* pNode, bool bSelected, TimeValue Time )
00257 {
00258         KMdlMesh*       pCurrentMesh = pMesh;
00259 
00260         g_Console << "Node Name : " << pNode->GetName() << KENDL;
00261 
00262         if( !bSelected || pNode->Selected() )
00263         {
00264                 // Exporte la node
00265                 ObjectState     ObjState = pNode->EvalWorldState( Time );
00266                 if( ObjState.obj )
00267                 {
00268                         switch( ObjState.obj->SuperClassID() )
00269                         {
00270                         case GEOMOBJECT_CLASS_ID:
00271                                 {
00272                                         KMdlMesh*       pNodeMesh = ExportTriObject( Loader, pNode, Time );
00273                                         if( pNodeMesh )
00274                                         {
00275                                                 // Ajoute le mesh au modele
00276                                                 Loader.AddMesh( pNodeMesh );
00277                                                 pCurrentMesh = pNodeMesh;
00278                                         }
00279                                         break;
00280                                 }
00281 
00282                         case HELPER_CLASS_ID:
00283                                 {
00284                                         KMdlMesh*       pNodeMesh = ExportHelpers( Loader, pNode, Time );
00285                                         if( pNodeMesh )
00286                                         {
00287                                                 // Ajoute le mesh au modele
00288                                                 Loader.AddMesh( pNodeMesh );
00289                                                 pCurrentMesh = pNodeMesh;
00290                                         }
00291                                         break;
00292                                 }
00293 
00294 /*                      case CAMERA_CLASS_ID:
00295                                 break;
00296                         case LIGHT_CLASS_ID:
00297                                 break;
00298                         case SHAPE_CLASS_ID:
00299                                 break;
00300                         case HELPER_CLASS_ID:
00301                                 {
00302                                         ExportHelper( pNode, Time );                            
00303                                 }
00304                                 break;*/
00305                         default:
00306                                 KError::Warning( NULL, "Unknown object type, skipping node [%s]", pNode->GetName() );
00307                                 return true;
00308                         }
00309                 }
00310         }
00311 
00312         // Exporte les fils
00313         for( int i = 0; i < pNode->NumberOfChildren(); i ++ )
00314         {
00315                 if( !ExportNode( Loader, pCurrentMesh, pNode->GetChildNode( i ), bSelected, Time ) )
00316                         return false;
00317         }
00318 
00319         return true;
00320 }
00321 
00322 //---------------------------------------------------------------------------------------------
00323 KMdlMesh* KMdlExporter::ExportTriObject( KMdlLoader& Loader, INode* pNode, TimeValue Time )
00324 {
00325         TriObject*      pTriObject;
00326         Object*         pObject;
00327         
00328         pObject = pNode->EvalWorldState( Time ).obj;
00329 
00330         //
00331         //      TriObject
00332         //
00333 //      if( pObject->ClassID() != Class_ID( TRIOBJ_CLASS_ID, 0 ) )
00334 //      {
00335 //              KError::Warning( NULL, "Unknown geomobject type, skipping node [%s]", pNode->GetName() );
00336 //              return NULL;
00337 //      }
00338         
00339 //      EDITTRIOBJ_CLASS_ID
00340 
00341 
00342         if( !pObject->CanConvertToType( Class_ID( TRIOBJ_CLASS_ID, 0 ) ) )
00343         {
00344                 char    pText[256];
00345                 sprintf( pText, "Error : Cannot convert node [%s] to TriObject", pNode->GetName() );
00346 //              MessageBox( g_hWnd, pText, "MDL Export Error", MB_OK | MB_ICONSTOP );
00347                 g_Console << pText << KENDL;
00348                 return NULL;
00349         }
00350 
00351         pTriObject = (TriObject*)pObject->ConvertToType( Time, Class_ID( TRIOBJ_CLASS_ID, 0) );
00352         if( !pTriObject )
00353         {
00354                 char    pText[256];
00355                 sprintf( pText, "Error : Cannot convert node [%s] to TriObject", pNode->GetName() );
00356 //              MessageBox( g_hWnd, pText, "MDL Export Error", MB_OK | MB_ICONSTOP );
00357                 g_Console << pText << KENDL;
00358                 return NULL;
00359         }
00360 
00361         // Creation du mesh
00362         KMdlMesh*               pMdlMesh        = new KMdlMesh();
00363 
00364         //
00365         //      Skin
00366         //
00367         ISkin*                          pSkin = NULL;
00368         ISkinContextData*       pSkinData = NULL;
00369         Object*                         pObjectRef = pNode->GetObjectRef();
00370 
00371         if( pObjectRef )
00372         {
00373                 if( pObjectRef->SuperClassID() == GEN_DERIVOB_CLASS_ID )
00374                 {
00375                         IDerivedObject*         pDerivedObject = (IDerivedObject*)pObjectRef;
00376 
00377                         // Recherche le modifier I_SKIN
00378                         for( int Mod = 0; Mod < pDerivedObject->NumModifiers(); Mod ++ )
00379                         {
00380                                 Modifier*       pModifier = pDerivedObject->GetModifier( Mod );
00381 
00382                                 pSkin = (ISkin*)pModifier->GetInterface(I_SKIN);
00383                                 if( pSkin )
00384                                 {
00385                                         pSkinData = pSkin->GetContextInterface( pNode );
00386                                         if( pSkinData )
00387                                         {
00388                                                 // Skin trouvé
00389                                                 g_Console << "Mesh Skinning :" << KENDL;
00390 
00391                                                 int     NumBones = pSkin->GetNumBones();
00392                                                 
00393                                                 // Le vertex shader code l'indice du bone sur un u8, donc de 0 à 255
00394                                                 if( NumBones > 254 )
00395                                                 {
00396                                                         KError::Warning( NULL, "Too much bones for object [%s]\nBones : %i Maximum allowed : 254", pNode->GetName(), NumBones );
00397                                                 }
00398 
00399                                                 g_Console << "Bones : " << NumBones << KENDL;
00400                                                 
00401                                                 KMdlBone*       pMdlBone;
00402                                                 for( int Bone = 0; Bone < NumBones; Bone ++ )
00403                                                 {
00404                                                         INode*  pBone = pSkin->GetBone( Bone );
00405                                                         Matrix3 BoneMatrix = pBone->GetNodeTM( Time );
00406                                                         Point3  r;
00407 /*                                              
00408                                                         g_Console << "Bone : " << pBone->GetName() << KENDL;
00409                                                         r = BoneMatrix.GetRow( 0 );
00410                                                         g_Console << r.x << "   " << r.y << "   " << r.z << "   " << 0.0f << KENDL;
00411                                                         r = BoneMatrix.GetRow( 1 );
00412                                                         g_Console << r.x << "   " << r.y << "   " << r.z << "   " << 0.0f << KENDL;
00413                                                         r = BoneMatrix.GetRow( 2 );
00414                                                         g_Console << r.x << "   " << r.y << "   " << r.z << "   " << 0.0f << KENDL;
00415                                                         r = BoneMatrix.GetRow( 3 );
00416                                                         g_Console << r.x << "   " << r.y << "   " << r.z << "   " << 1.0f << KENDL;
00417 */
00418                                                         // Ajoute le bone
00419                                                         pMdlBone = new KMdlBone();
00420                                                         pMdlBone->m_Name = pBone->GetName();
00421                                                         pMdlMesh->AddpBone( pMdlBone );
00422                                                 }
00423                                                 break;
00424                                         }
00425                                 }
00426                         }
00427                 }
00428                 
00429         }
00430 
00431         Mesh*                   pMesh           = &pTriObject->GetMesh();
00432         int                             NumFaces        = pMesh->getNumFaces();
00433         int                             Face;
00434 
00435         // Génération des normals
00436         pMesh->buildNormals();
00437 
00438         // Verifie qu'il y est les coordonnées de textures
00439         bool    bHasUV = pMesh->tVerts ? true : false;
00440 
00441         if( !bHasUV )
00442         {
00443 //              char    pText[256];
00444 //              sprintf( pText, "Object [%s] need texture coordinate.", pNode->GetName() );
00445 //              MessageBox( g_hWnd, pText, "MDL Export Error", MB_OK | MB_ICONSTOP );
00446 //              return NULL;
00447                 KError::Warning( NULL, "Object [%s] has not texture coordinate.", pNode->GetName() );
00448         }
00449 
00450         // Type
00451         if( pObject->ClassID() == BONE_OBJ_CLASSID )
00452         {
00453                 pMdlMesh->m_Type = KMMT_BONE;
00454                 g_Console << "Type : BONE" << KENDL;
00455         }
00456         else
00457         {
00458                 pMdlMesh->m_Type = KMMT_MESH;
00459                 g_Console << "Type : MESH" << KENDL;
00460         }
00461 
00462         // Nom
00463         pMdlMesh->m_Name                = KStr( pNode->GetName() );
00464         pMdlMesh->m_FatherName  = ( pNode->GetParentNode()->IsRootNode() ) ? KStr( "" ) : KStr( pNode->GetParentNode()->GetName() );
00465 
00466         // Matrice de transformation animée
00467         ExportMatrices( pMdlMesh, pNode );
00468 /*      
00469         //
00470         // Matrice de transformation animée
00471         //
00472         KMatrix* pLastMatrix = NULL;
00473 
00474         g_Console << "Frame : ";
00475         for( TimeValue CurrentTime = m_TickStart; CurrentTime < m_TickEnd; CurrentTime += m_TickStep )
00476         {
00477                 Matrix3 NodeMatrix              = pNode->GetNodeTM( CurrentTime );
00478                 Matrix3 ParentMatrix    = pNode->GetParentTM( CurrentTime );
00479                 Matrix3 LocalMatrix;
00480 
00481                 LocalMatrix = NodeMatrix * Inverse( ParentMatrix );
00482 
00483                 Point3  r;
00484                 KMatrix Matrix;
00485 
00486                 r = LocalMatrix.GetRow( 0 );
00487                 Matrix._11 = r.x;       Matrix._12 = r.y;       Matrix._13 = r.z;       Matrix._14 = 0.0f;
00488                 r = LocalMatrix.GetRow( 1 );
00489                 Matrix._21 = r.x;       Matrix._22 = r.y;       Matrix._23 = r.z;       Matrix._24 = 0.0f;
00490                 r = LocalMatrix.GetRow( 2 );
00491                 Matrix._31 = r.x;       Matrix._32 = r.y;       Matrix._33 = r.z;       Matrix._34 = 0.0f;
00492                 r = LocalMatrix.GetRow( 3 );
00493                 Matrix._41 = r.x;       Matrix._42 = r.y;       Matrix._43 = r.z;       Matrix._44 = 1.0f;
00494 
00495                 // Ajoute la matrice si elle est diferente de la clé précédente
00496                 if( pLastMatrix && ((*pLastMatrix) == Matrix ) )
00497                         continue;
00498 
00499                 KMdlFrameMatrix*        pFrameMatrix = new KMdlFrameMatrix();
00500                 pFrameMatrix->m_FrameId = CurrentTime / GetTicksPerFrame();
00501                 pFrameMatrix->m_Matrix  = Matrix;
00502                 pMdlMesh->m_FrameMatrix.Add( pFrameMatrix );
00503 
00504                 pLastMatrix = &pFrameMatrix->m_Matrix;
00505 
00506                 g_Console << pFrameMatrix->m_FrameId << " ";
00507         }
00508         g_Console << KENDL;
00509 */
00510         //
00511         // Calcul et alloue le nombre de primitives
00512         //
00513         MtlID                   Mtl;
00514         bool                    bAlready;
00515         for( Face = 0; Face < NumFaces; Face ++ )
00516         {
00517                 Mtl = pMesh->getFaceMtlIndex( Face );
00518 
00519                 // Max utilise un modulo pour recupere le id de materiau
00520                 Mtl %= Loader.GetnTextures();
00521 
00522                 // Regarde s'il est deja dans la liste
00523                 bAlready = false;
00524                 for( int m = 0; m < (int)pMdlMesh->GetnPrimitives(); m ++ )
00525                 {
00526                         // Oui, on l'a déja
00527                         if( pMdlMesh->GetpPrimitive( m )->m_ShaderId == Mtl )
00528                         {
00529                                 // Ajoute 1 face de plus
00530                                 pMdlMesh->GetpPrimitive( m )->m_nIndices += 3;
00531                                 bAlready = true;
00532                                 break;
00533                         }
00534                 }
00535                 // Non, on l'ajoute
00536                 if( !bAlready )
00537                 {
00538                         KMdlPrimitive*  pPrimitive = new KMdlPrimitive();
00539                         pPrimitive->m_ShaderId = Mtl;
00540                         pPrimitive->m_nIndices += 3;
00541                         pMdlMesh->AddpPrimitive( pPrimitive );
00542                 }
00543         }
00544 
00545         // DUMP
00546         for( int m = 0; m < (int)pMdlMesh->GetnPrimitives(); m ++ )
00547         {
00548                 g_Console << "Shader " << pMdlMesh->GetpPrimitive( m )->m_ShaderId << " : " << pMdlMesh->GetpPrimitive( m )->m_nIndices / 3 << " Faces." << KENDL;
00549         }
00550 
00551 
00552         //
00553         //      Index/Vertex
00554         //
00555         // Aloue les index et vertex
00556         for( int p = 0; p < (int)pMdlMesh->GetnPrimitives(); p ++ )
00557         {
00558                 // Alloue le maximum possible, de toute facon on s'en fou, au reload l'allocation se fera au plus juste
00559                 pMdlMesh->GetpPrimitive( p )->m_nIndices = 0;
00560                 pMdlMesh->GetpPrimitive( p )->m_pIndices = new u16[NumFaces*3];
00561                 
00562                 KMdlFrameVertex*        pFrameVertex = new KMdlFrameVertex();
00563                 pFrameVertex->m_FrameId         = 0;
00564                 pFrameVertex->m_nVertices       = 0;
00565                 pFrameVertex->m_pVertices       = new KMdlVertex[NumFaces*3];
00566                 pMdlMesh->GetpPrimitive( p )->m_FrameVertices.Add( pFrameVertex );
00567                 pMdlMesh->GetpPrimitive( p )->m_nFrames ++;
00568         }
00569 
00570 
00571 
00572         int                     v2;
00573         KMdlVertex      Vertex;
00574         int                     VtxID[3] = { 0, 2, 1 };
00575         int                     Index[3];
00576 
00577         for( Face = 0; Face < NumFaces; Face ++ )
00578         {
00579                 // Recherche la primitive qui correspond a ce material
00580                 Mtl = pMesh->getFaceMtlIndex( Face );
00581 
00582                 // Max utilise un modulo pour recupere le id du material
00583                 Mtl %= Loader.GetnTextures();
00584 
00585                 for( int m = 0; m < (int)pMdlMesh->GetnPrimitives(); m ++ )
00586                 {
00587                         KMdlPrimitive*          pPrimitive              = pMdlMesh->GetpPrimitive( m );
00588                         KMdlFrameVertex*        pFrameVertex    = pPrimitive->m_FrameVertices[0];
00589 
00590                         if( pPrimitive->m_ShaderId == Mtl )
00591                         {
00592                                 // Ajoute les vertex
00593                                 for( int j = 0; j < 3; j ++ )
00594                                 {
00595                                         int     i = VtxID[j];
00596 
00597                                         // Vertex id
00598                                         v2 = pMesh->faces[Face].v[i];
00599 
00600                                         // Position
00601                                         Vertex.m_Position.x     = pMesh->verts[v2].x;
00602                                         Vertex.m_Position.y     = pMesh->verts[v2].y;
00603                                         Vertex.m_Position.z     = pMesh->verts[v2].z;
00604                                         
00605                                         // Normal
00606                                         Point3  Normal = GetVertexNormal( pMesh, Face, pMesh->getRVertPtr( v2 ) );
00607                                         Vertex.m_Normal.x       = Normal.x;
00608                                         Vertex.m_Normal.y       = Normal.y;
00609                                         Vertex.m_Normal.z       = Normal.z;
00610 
00611                                         // Blending Weights/Indices
00612                                         for( int BoneId = 0; BoneId < KBVERTEX_NUNBLENDWEIGHT; BoneId++ )
00613                                         {
00614                                                 Vertex.m_Weight[BoneId]         = 255;
00615                                                 Vertex.m_Indices[BoneId]        = 0; // 20 = pas de bone
00616                                         }
00617 
00618                                         if( pSkinData )
00619                                         {
00620                                                 int NumBones = pSkinData->GetNumAssignedBones( v2 );
00621                                                 if( NumBones > KBVERTEX_NUNBLENDWEIGHT )
00622                                                 {
00623                                                         KError::Error( NULL, "Too mush assigned bones for this vertex\nVertex %i of object : %s\nNumber assigned for this vertex: %i\nNumber maximum allowed by vertex %i", v2, pNode->GetName(), NumBones, KBVERTEX_NUNBLENDWEIGHT );
00624                                                         return NULL;
00625                                                 }
00626                                                 
00627                                                 for( int BoneId = 0; BoneId < NumBones; BoneId++ )
00628                                                 {
00629                                                         Vertex.m_Weight[BoneId]         = (u8)(pSkinData->GetBoneWeight( v2, BoneId ) * 255.0f);
00630                                                         Vertex.m_Indices[BoneId]        = (u8)pSkinData->GetAssignedBone( v2, BoneId ) + 1;
00631                                                 }
00632                                         }
00633 
00634 
00635                                         // Texture coordonnées
00636                                         if( bHasUV )
00637                                         {
00638                                                 Vertex.m_TU     = pMesh->tVerts[pMesh->tvFace[Face].t[i]].x;
00639                                                 Vertex.m_TV     = -pMesh->tVerts[pMesh->tvFace[Face].t[i]].y;
00640                                         }
00641                                         else
00642                                         {
00643                                                 Vertex.m_TU     = 0.0;
00644                                                 Vertex.m_TV     = 0.0;
00645                                         }
00646 
00647                                         // Recherche si le vertex n'est pas deja dans la liste
00648                                         int     vidx = -1;
00649                                         for( int vv = 0; vv < pFrameVertex->m_nVertices; vv ++ )
00650                                         {
00651                                                 if( pFrameVertex->m_pVertices[vv] == Vertex )
00652                                                 {
00653                                                         // Le vertex existe deja dans la liste, on recupere l'index
00654                                                         vidx = vv;
00655                                                         break;
00656                                                 }
00657                                         }
00658 
00659                                         if( vidx == -1 )
00660                                         {
00661                                                 // Nouveau vertex, ajoute le vertex
00662                                                 pFrameVertex->m_pVertices[pFrameVertex->m_nVertices] = Vertex;
00663                                                 // Recupere l'index
00664                                                 Index[j] = pFrameVertex->m_nVertices;
00665                                                 // et oui, y'a 2 compteurs... :(
00666                                                 pFrameVertex->m_nVertices ++;
00667                                                 pPrimitive->m_nVertices ++;
00668                                         }
00669                                         else
00670                                         {
00671                                                 // Un vertex similaire existe deja
00672                                                 Index[j] = vidx;
00673                                         }
00674                                 }
00675 
00676                                 // Ajoute les index
00677                                 // vertex 0
00678                                 pPrimitive->m_pIndices[pPrimitive->m_nIndices + 0] = Index[0];//pPrimitive->m_nIndices + 0;
00679                                 // vertex 1
00680                                 pPrimitive->m_pIndices[pPrimitive->m_nIndices + 1] = Index[1];//pPrimitive->m_nIndices + 1;
00681                                 // vertex 2
00682                                 pPrimitive->m_pIndices[pPrimitive->m_nIndices + 2] = Index[2];//pPrimitive->m_nIndices + 2;
00683                                 pPrimitive->m_nIndices += 3;
00684                         }
00685                 }
00686         }       
00687 
00688         return pMdlMesh;
00689 }
00690 
00691 //---------------------------------------------------------------------------------------------
00692 KMdlMesh* KMdlExporter::ExportHelpers( KMdlLoader& Loader, INode* pNode, TimeValue Time )
00693 {
00694         KMdlMesh*       pMdlMesh = new KMdlMesh();
00695 
00696         // Nom
00697         pMdlMesh->m_Name                = KStr( pNode->GetName() );
00698         pMdlMesh->m_FatherName  = ( pNode->GetParentNode()->IsRootNode() ) ? KStr( "" ) : KStr( pNode->GetParentNode()->GetName() );
00699 
00700         // Type
00701         pMdlMesh->m_Type                = KMMT_DUMMY;
00702 
00703         // Matrice de transformation animée
00704         ExportMatrices( pMdlMesh, pNode );
00705 
00706         return pMdlMesh;
00707 }
00708 
00709 //---------------------------------------------------------------------------------------------
00710 Point3 KMdlExporter::GetVertexNormal(Mesh* mesh, int faceNo, RVertex* rv)
00711 {
00712         Face* f = &mesh->faces[faceNo];
00713         DWORD smGroup = f->smGroup;
00714         int numNormals;
00715         Point3 vertexNormal;
00716         
00717         // Is normal specified
00718         // SPCIFIED is not currently used, but may be used in future versions.
00719         if (rv->rFlags & SPECIFIED_NORMAL) {
00720                 vertexNormal = rv->rn.getNormal();
00721         }
00722         // If normal is not specified it's only available if the face belongs
00723         // to a smoothing group
00724         else if ((numNormals = rv->rFlags & NORCT_MASK) && smGroup) {
00725                 // If there is only one vertex is found in the rn member.
00726                 if (numNormals == 1) {
00727                         vertexNormal = rv->rn.getNormal();
00728                 }
00729                 else {
00730                         // If two or more vertices are there you need to step through them
00731                         // and find the vertex with the same smoothing group as the current face.
00732                         // You will find multiple normals in the ern member.
00733                         for (int i = 0; i < numNormals; i++) {
00734                                 if (rv->ern[i].getSmGroup() & smGroup) {
00735                                         vertexNormal = rv->ern[i].getNormal();
00736                                 }
00737                         }
00738                 }
00739         }
00740         else {
00741                 // Get the normal from the Face if no smoothing groups are there
00742                 vertexNormal = mesh->getFaceNormal(faceNo);
00743         }
00744         
00745         return vertexNormal;
00746 }
00747 
00748 //---------------------------------------------------------------------------------------------
00749 KMdlMesh* KMdlExporter::ExportBoneObject( KMdlLoader& Loader, INode* pNode, TimeValue Time )
00750 {
00751 //      TriObject*      pTriObject;
00752 //      Object*         pObject;
00753         
00754 //      pObject = pNode->EvalWorldState( Time ).obj;
00755 
00756         //
00757         //      Bone
00758         //
00759 /*      if( pObject->ClassID() == BONE_OBJ_CLASSID )
00760         {*/
00761                 g_Console << "BONE_OBJ_CLASSID" << KENDL;
00762                 Matrix3 m = pNode->GetNodeTM( Time );
00763                 Point3  r;
00764         
00765                 r = m.GetRow( 0 );
00766                 g_Console << r.x << "   " << r.y << "   " << r.z << "   " << 0.0f << KENDL;
00767                 r = m.GetRow( 1 );
00768                 g_Console << r.x << "   " << r.y << "   " << r.z << "   " << 0.0f << KENDL;
00769                 r = m.GetRow( 2 );
00770                 g_Console << r.x << "   " << r.y << "   " << r.z << "   " << 0.0f << KENDL;
00771                 r = m.GetRow( 3 );
00772                 g_Console << r.x << "   " << r.y << "   " << r.z << "   " << 1.0f << KENDL;
00773 /*              
00774                 return NULL;
00775         }*/
00776 
00777         return NULL;
00778 }
00779 
00780 //---------------------------------------------------------------------------------------------
00781 void KMdlExporter::ExportMatrices( KMdlMesh* pMdlMesh, INode* pNode )
00782 {
00783         //
00784         // Matrice de transformation animée
00785         //
00786         KMatrix* pLastMatrix = NULL;
00787 
00788         g_Console << "Frame : ";
00789         for( TimeValue CurrentTime = m_TickStart; CurrentTime < m_TickEnd; CurrentTime += m_TickStep )
00790         {
00791 //              Matrix3 ResetMatrix             = ResetXForm( pNode, CurrentTime );
00792                 Matrix3 NodeMatrix              = pNode->GetObjectTM( CurrentTime );//pNode->GetNodeTM( CurrentTime );
00793 //              Matrix3 ParentMatrix    = pNode->GetParentTM( CurrentTime );
00794                 Matrix3 ParentMatrix;
00795                 ParentMatrix.IdentityMatrix();
00796                 if( pNode->GetParentNode() )
00797                         ParentMatrix = pNode->GetParentNode()->GetObjectTM( CurrentTime );
00798                 Matrix3 LocalMatrix;
00799 
00800                 LocalMatrix = NodeMatrix * Inverse( ParentMatrix );
00801 //              LocalMatrix = ResetXForm( pNode, CurrentTime );
00802 //              LocalMatrix.IdentityMatrix();
00803 
00804                 Point3  r;
00805                 KMatrix Matrix;
00806 
00807                 r = LocalMatrix.GetRow( 0 );
00808                 Matrix._11 = r.x;       Matrix._12 = r.y;       Matrix._13 = r.z;       Matrix._14 = 0.0f;
00809                 r = LocalMatrix.GetRow( 1 );
00810                 Matrix._21 = r.x;       Matrix._22 = r.y;       Matrix._23 = r.z;       Matrix._24 = 0.0f;
00811                 r = LocalMatrix.GetRow( 2 );
00812                 Matrix._31 = r.x;       Matrix._32 = r.y;       Matrix._33 = r.z;       Matrix._34 = 0.0f;
00813                 r = LocalMatrix.GetRow( 3 );
00814                 Matrix._41 = r.x;       Matrix._42 = r.y;       Matrix._43 = r.z;       Matrix._44 = 1.0f;
00815 
00816                 // Ajoute la matrice si elle est diferente de la clé précédente
00817                 if( pLastMatrix && ((*pLastMatrix) == Matrix ) )
00818                         continue;
00819 /*
00820                 g_Console << "Matrix : " << pNode->GetName() << KENDL;
00821                 r = LocalMatrix.GetRow( 0 );
00822                 g_Console << r.x << "   " << r.y << "   " << r.z << "   " << 0.0f << KENDL;
00823                 r = LocalMatrix.GetRow( 1 );
00824                 g_Console << r.x << "   " << r.y << "   " << r.z << "   " << 0.0f << KENDL;
00825                 r = LocalMatrix.GetRow( 2 );
00826                 g_Console << r.x << "   " << r.y << "   " << r.z << "   " << 0.0f << KENDL;
00827                 r = LocalMatrix.GetRow( 3 );
00828                 g_Console << r.x << "   " << r.y << "   " << r.z << "   " << 1.0f << KENDL;
00829 */
00830                 KMdlFrameMatrix*        pFrameMatrix = new KMdlFrameMatrix();
00831                 pFrameMatrix->m_FrameId = CurrentTime / GetTicksPerFrame();
00832                 pFrameMatrix->m_Matrix  = Matrix;
00833                 pMdlMesh->AddpFrameMatrix( pFrameMatrix );
00834 
00835                 pLastMatrix = &pFrameMatrix->m_Matrix;
00836 
00837                 g_Console << pFrameMatrix->m_FrameId << " ";
00838         }
00839         g_Console << KENDL;
00840 }
00841 /*
00842 //---------------------------------------------------------------------------------------------
00843 void KMdlExporter::ResetXFormAll( Interface* pInterface, INode* pNode, TimeValue Time )
00844 {
00845         ResetXForm( pInterface, pNode, Time );
00846 
00847         // Exporte les fils
00848         for( int i = 0; i < pNode->NumberOfChildren(); i ++ )
00849                 ResetXFormAll( pInterface, pNode->GetChildNode( i ), Time );
00850 }
00851 
00852 //---------------------------------------------------------------------------------------------
00853 Matrix3 KMdlExporter::ResetXForm( Interface* pInterface, INode* pNode, TimeValue Time )
00854 {
00855         Matrix3 ntm, ptm, rtm(1), piv(1), tm;
00856 
00857         // Get Parent and Node TMs
00858         ntm = pNode->GetNodeTM( Time );
00859         ptm = pNode->GetParentTM( Time );
00860 
00861         // Compute the relative TM
00862         ntm = ntm * Inverse( ptm );
00863 
00864         // The reset TM only inherits position
00865         rtm.SetTrans( ntm.GetTrans() );
00866 
00867         // Set the node TM to the reset TM  
00868         tm = rtm*ptm;
00869         pNode->SetNodeTM( Time, tm );
00870 
00871         // Compute the pivot TM
00872         piv.SetTrans( pNode->GetObjOffsetPos() );
00873         PreRotateMatrix( piv, pNode->GetObjOffsetRot() );
00874         ApplyScaling( piv, pNode->GetObjOffsetScale() );
00875 
00876         // Reset the offset to 0
00877         pNode->SetObjOffsetPos( Point3(0,0,0) );
00878         pNode->SetObjOffsetRot( IdentQuat() );
00879         pNode->SetObjOffsetScale( ScaleValue( Point3( 1,1,1 ) ) );
00880 
00881         // Take the position out of the matrix since 
00882         // we don't reset position
00883         ntm.NoTrans();
00884 
00885         // Apply the offset to the TM
00886         ntm = piv * ntm;
00887 
00888         // Apply a derived object to the node's object
00889         Object *obj = pNode->GetObjectRef();
00890         IDerivedObject *dobj = CreateDerivedObject(obj);
00891 
00892         // Create an XForm mod
00893         SimpleMod *mod = (SimpleMod*)pInterface->CreateInstance(
00894         OSM_CLASS_ID,
00895         Class_ID(CLUSTOSM_CLASS_ID,0));
00896 
00897         // Apply the transformation to the mod.
00898         SetXFormPacket pckt(ntm);
00899         mod->tmControl->SetValue( Time,&pckt);
00900 
00901         // Add the modifier to the derived object.
00902         ModContext* mc = new ModContext(new Matrix3(1), NULL, NULL); 
00903         dobj->AddModifier(mod, mc);
00904 
00905         // Replace the node's object
00906         pNode->SetObjectRef(dobj);
00907 
00908         return ntm;
00909 }*/

Generated on Sun Mar 25 20:02:13 2007 for Zythum Project by  doxygen 1.5.1-p1