D:/Zythum/DinoKod/mapMaxExport/MAPMaxExporter.cpp

00001 //---------------------------------------------------------------------------------------------
00002 //      This file is a part of "DinoKod".
00003 //      Copyright © 2003 Dino Productions. All Rights Reserved.
00004 //      
00005 //      File                    : MAPMaxExporter.cpp
00006 //      Author                  : Sebastien LEIX        sebastien.leix@wanadoo.fr
00007 //      Date                    : 04/01/2003
00008 //      Modification    :
00009 //
00010 //---------------------------------------------------------------------------------------------
00011 #include "resource.h"
00012 #include "mapMaxExporter.h"
00013 #include "Common/Console.h"
00014 #include "Common/Vertex.h"
00015 
00016 #define PLUGIN_NAME     "3Dino MAP Exporter"
00017 
00018 int                     g_ControlsInit = FALSE;
00019 HINSTANCE       g_hInstance = NULL;
00020 HWND            g_hWnd = NULL;
00021 
00022 //---------------------------------------------------------------------------------------------
00023 BOOL WINAPI DllMain( HINSTANCE hinstDLL, ULONG fdwReason, LPVOID lpvReserved ) 
00024 { 
00025         g_hInstance = hinstDLL;
00026         // Hang on to this DLL's instance handle.
00027         if( !g_ControlsInit )
00028         {
00029                 g_ControlsInit = TRUE;
00030 
00031                 // Initialize MAX's custom controls
00032                 InitCustomControls( hinstDLL );
00033 
00034                 // Initialize Win95 controls
00035                 InitCommonControls();
00036         }
00037 
00038         return TRUE;
00039 }
00040 
00041 //---------------------------------------------------------------------------------------------
00042 __declspec( dllexport ) int LibNumberClasses()
00043 {
00044         return 1;
00045 }
00046 
00047 //---------------------------------------------------------------------------------------------
00048 __declspec( dllexport ) ClassDesc* LibClassDesc( int i )
00049 {
00050         switch( i )
00051         {
00052         case 0:
00053                 return (ClassDesc*)&MapExporterClassDesc;
00054         default:
00055                 return 0;
00056         }
00057 }
00058 
00059 //---------------------------------------------------------------------------------------------
00060 __declspec( dllexport ) const TCHAR* LibDescription()
00061 {
00062         return _T( PLUGIN_NAME );
00063 }
00064 
00065 //---------------------------------------------------------------------------------------------
00066 extern "C" __declspec( dllexport ) ULONG LibVersion()
00067 {
00068         return VERSION_3DSMAX;
00069 }
00070 
00071 //---------------------------------------------------------------------------------------------
00072 //---------------------------------------------------------------------------------------------
00073 //---------------------------------------------------------------------------------------------
00074 KMapExporter::KMapExporter()
00075 : SceneExport()
00076 {
00077 #if _DEBUG
00078         g_Console.Create( "MapExporter" );
00079 #endif _DEBUG
00080 }
00081 
00082 //---------------------------------------------------------------------------------------------
00083 KMapExporter::~KMapExporter()
00084 {
00085 #if _DEBUG
00086         g_Console.Close();
00087 #endif _DEBUG
00088 }
00089 
00090 //---------------------------------------------------------------------------------------------
00091 void KMapExporter::ShowAbout( HWND hWnd )
00092 {
00093 }
00094 
00095 //---------------------------------------------------------------------------------------------
00096 int KMapExporter::DoExport( const TCHAR *pName, ExpInterface *pExtInterface, Interface *pInterface, BOOL bSuppressPrompts, DWORD Options )
00097 {
00098 //      s32             AnimStart;
00099 //      s32             AnimEnd;
00100 //      s32             AnimStep;
00101 //      KMapLoader      Loader;
00102 
00103         g_hWnd = pInterface->GetMAXHWnd();
00104 
00105         g_Console << "===============================================================" << KENDL;
00106         g_Console << "Prompt options... " << (char*)pName << "..." << KENDL;
00107 
00108         if( !bSuppressPrompts )
00109         {
00110 /*              if( !DialogBoxParam( g_hInstance, MAKEINTRESOURCE(IDD_DIALOG_EXPORT), pInterface->GetMAXHWnd(), ExportDlgProc, (LPARAM)this ) )
00111                 {
00112                         g_Console << "Canceled." << KENDL;
00113                         return 1;
00114                 }*/
00115         }
00116 
00117         g_Console << "Exporting " << (char*)pName << "..." << KENDL;
00118 /*
00119         // Exporte les materiaux
00120         if( !ExportMaterials( Loader, pInterface->GetSceneMtls() ) )
00121                 return 1;
00122 
00123         // Exporte les nodes
00124         if( !ExportNode( Loader, NULL, pInterface->GetRootNode(), (Options & SCENE_EXPORT_SELECTED) ? TRUE : FALSE, 0 ) )
00125                 return 1;
00126 
00127         // Sauve le fichier
00128         Loader.SaveMAP( (char*)pName );
00129 */
00130         g_Console << "Done." << KENDL;
00131 
00132         char    pText[256];
00133         sprintf( pText, "File [%s] successfully exported!", pName );
00134         MessageBox( g_hWnd, pText, "MAP Export", MB_OK );
00135 
00136         return 1;
00137 }
00138 
00139 //---------------------------------------------------------------------------------------------
00140 INT_PTR CALLBACK KMapExporter::ExportDlgProc( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam )
00141 {
00142         KMapExporter *pExporter = (KMapExporter*)GetWindowLongPtr( hWnd, GWLP_USERDATA ); 
00143 
00144         switch( Msg )
00145         {
00146         case WM_INITDIALOG:
00147                 break;
00148         case WM_COMMAND:
00149                 switch( LOWORD( wParam ) )
00150                 {
00151                 case IDOK:
00152                         EndDialog( hWnd, 1 );
00153                         break;
00154                 case IDCANCEL:
00155                         EndDialog( hWnd, 0 );
00156                         break;
00157                 }
00158                 break;
00159                 default:
00160                         return FALSE;
00161         }
00162 
00163         return TRUE;
00164 }
00165 /*
00166 //---------------------------------------------------------------------------------------------
00167 bool KMapExporter::ExportMaterials( KMapLoader& Loader, MtlBaseLib* pMtlBaseLib )
00168 {
00169         if( !pMtlBaseLib )
00170         {
00171                 MessageBox( g_hWnd, "No material set.\nYou need one material!", "MAP Export Error", MB_OK | MB_ICONSTOP );
00172                 return false;
00173         }
00174 
00175         if( pMtlBaseLib->Count() != 1 )
00176         {
00177                 char    pText[256];
00178                 sprintf( pText, "%i material(s) detected.\nYou need only one material!", pMtlBaseLib->Count() );
00179                 MessageBox( g_hWnd, pText, "MAP Export Error", MB_OK | MB_ICONSTOP );
00180                 return false;
00181         }
00182 
00183         Mtl*    pMtl;
00184         
00185         pMtl = (Mtl*)(*pMtlBaseLib)[0];
00186 
00187         int NumMat = pMtl->NumSubMtls();
00188 
00189         if( NumMat < 1 )
00190         {
00191                 char    pText[256];
00192                 sprintf( pText, "0 sub-material detected.\nYou need a least one sub-material!" );
00193                 MessageBox( g_hWnd, pText, "MAP Export Error", MB_OK | MB_ICONSTOP );
00194                 return false;
00195         }
00196 
00197 
00198         for( int mat = 0; mat <  NumMat; mat ++ )
00199         {
00200                 Mtl* pSubMat = pMtl->GetSubMtl( mat );
00201 
00202                 // Ajoute le materiel
00203                 Loader.AddTexture( (char*)pSubMat->GetName() );
00204                 g_Console << "Shader " << mat << " : " << (char*)pSubMat->GetName() << KENDL;
00205         }
00206 
00207         return true;
00208 }
00209 
00210 //---------------------------------------------------------------------------------------------
00211 bool KMapExporter::ExportNode( KMapLoader& Loader, KMapMesh* pMesh, INode* pNode, bool bSelected, TimeValue Time )
00212 {
00213         KMapMesh*       pCurrentMesh = pMesh;
00214 
00215         g_Console << "Node Name : " << pNode->GetName() << KENDL;
00216 
00217         if( !bSelected || pNode->Selected() )
00218         {
00219                 // Exporte la node
00220                 ObjectState     ObjState = pNode->EvalWorldState( Time );
00221                 if( ObjState.obj )
00222                 {
00223                         switch( ObjState.obj->SuperClassID() )
00224                         {
00225                         case GEOMOBJECT_CLASS_ID:
00226                                 {
00227                                         KMapMesh*       pNodeMesh = ExportGeomObject( Loader, pNode, Time );
00228                                         if( pNodeMesh )
00229                                         {
00230                                                 // Ajoute le mesh au modele
00231                                                 Loader.AddMesh( pNodeMesh );
00232                                         }
00233                                         else
00234                                                 return false;
00235                                         pCurrentMesh = pNodeMesh;
00236                                 }
00237                                 break;
00238                         case CAMERA_CLASS_ID:
00239                                 break;
00240                         case LIGHT_CLASS_ID:
00241                                 break;
00242                         case SHAPE_CLASS_ID:
00243                                 break;
00244                         case HELPER_CLASS_ID:
00245                                 break;
00246                         }
00247                 }
00248         }
00249 
00250         // Exporte les fils
00251         for( int i = 0; i < pNode->NumberOfChildren(); i ++ )
00252         {
00253                 if( !ExportNode( Loader, pCurrentMesh, pNode->GetChildNode( i ), bSelected, Time ) )
00254                         return false;
00255         }
00256 
00257         return true;
00258 }
00259 
00260 //---------------------------------------------------------------------------------------------
00261 KMapMesh* KMapExporter::ExportGeomObject( KMapLoader& Loader, INode* pNode, TimeValue Time )
00262 {
00263         TriObject*      pTriObject;
00264         Object*         pObject;
00265         
00266         pObject = pNode->EvalWorldState( Time ).obj;
00267 
00268         if( !pObject->CanConvertToType( Class_ID( TRIOBJ_CLASS_ID, 0 ) ) )
00269         {
00270                 char    pText[256];
00271                 sprintf( pText, "Cannot convert node [%] to TriObject", pNode->GetName() );
00272                 MessageBox( g_hWnd, pText, "MAP Export Error", MB_OK | MB_ICONSTOP );
00273                 return NULL;
00274         }
00275 
00276         pTriObject = (TriObject*)pObject->ConvertToType( Time, Class_ID( TRIOBJ_CLASS_ID, 0) );
00277         if( !pTriObject )
00278         {
00279                 char    pText[256];
00280                 sprintf( pText, "Cannot convert node [%] to TriObject", pNode->GetName() );
00281                 MessageBox( g_hWnd, pText, "MAP Export Error", MB_OK | MB_ICONSTOP );
00282                 return NULL;
00283         }
00284 
00285         KMapMesh*               pMapMesh        = new KMapMesh();
00286         Mesh*                   pMesh           = &pTriObject->GetMesh();
00287         int                             NumFaces        = pMesh->getNumFaces();
00288         int                             Face;
00289 
00290 
00291         // Nom
00292         pMapMesh->m_Name                = KStr( pNode->GetName() );
00293         pMapMesh->m_FatherName  = ( pNode->GetParentNode()->IsRootNode() ) ? KStr( "" ) : KStr( pNode->GetParentNode()->GetName() );
00294         
00295         //
00296         // Matrice de transformation
00297         //
00298         Matrix3 m = pNode->GetNodeTM( Time );
00299         Point3  r;
00300         KMatrix Matrix;
00301 
00302         r = m.GetRow( 0 );
00303         Matrix._11 = r.x;       Matrix._12 = r.y;       Matrix._13 = r.z;       Matrix._14 = 0.0f;
00304         r = m.GetRow( 1 );
00305         Matrix._21 = r.x;       Matrix._22 = r.y;       Matrix._23 = r.z;       Matrix._24 = 0.0f;
00306         r = m.GetRow( 2 );
00307         Matrix._31 = r.x;       Matrix._32 = r.y;       Matrix._33 = r.z;       Matrix._34 = 0.0f;
00308         r = m.GetRow( 3 );
00309         Matrix._41 = r.x;       Matrix._42 = r.y;       Matrix._43 = r.z;       Matrix._44 = 1.0f;
00310 
00311         KMapFrameMatrix*        pFrameMatrix = new KMapFrameMatrix();
00312         pFrameMatrix->m_FrameId = 0;
00313         pFrameMatrix->m_Matrix  = Matrix;
00314         pMapMesh->m_FrameMatrix.Add( pFrameMatrix );
00315         pMapMesh->m_nFrames ++;
00316 
00317 
00318 
00319         pMesh->buildNormals();
00320 
00321         if( !pMesh->tVerts )
00322         {
00323                 char    pText[256];
00324                 sprintf( pText, "Object [%s] need texture coordinate", pNode->GetName() );
00325                 MessageBox( g_hWnd, pText, "MAP Export Error", MB_OK | MB_ICONSTOP );
00326                 return NULL;
00327         }
00328 
00329         //
00330         // Calcul et alloue le nombre de primitives
00331         //
00332         MtlID                   Mtl;
00333         bool                    bAlready;
00334         for( Face = 0; Face < NumFaces; Face ++ )
00335         {
00336                 Mtl = pMesh->getFaceMtlIndex( Face );
00337 
00338                 // Max utilise un modulo pour recupere le id de materiau
00339                 Mtl %= Loader.GetnTextures();
00340 
00341                 // Regarde s'il est deja dans la liste
00342                 bAlready = false;
00343                 for( int m = 0; m < (int)pMapMesh->m_Primitives.GetSize(); m ++ )
00344                 {
00345                         // Oui, on l'a déja
00346                         if( pMapMesh->m_Primitives[m]->m_ShaderId == Mtl )
00347                         {
00348                                 // Ajoute 1 face de plus
00349                                 pMapMesh->m_Primitives[m]->m_nIndices += 3;
00350                                 bAlready = true;
00351                                 break;
00352                         }
00353                 }
00354                 // Non, on l'ajoute
00355                 if( !bAlready )
00356                 {
00357                         KMapPrimitive*  pPrimitive = new KMapPrimitive();
00358                         pPrimitive->m_ShaderId = Mtl;
00359                         pPrimitive->m_nIndices += 3;
00360                         pMapMesh->m_Primitives.Add( pPrimitive );
00361                         pMapMesh->m_nPrimitives ++;
00362                 }
00363         }
00364 
00365         // DUMP
00366         for( int m = 0; m < (int)pMapMesh->m_Primitives.GetSize(); m ++ )
00367         {
00368                 g_Console << "Shader " << pMapMesh->m_Primitives[m]->m_ShaderId << " : " << pMapMesh->m_Primitives[m]->m_nIndices / 3 << " Faces." << KENDL;
00369         }
00370 
00371 
00372         //
00373         //      Index/Vertex
00374         //
00375         // Aloue les index et vertex
00376         for( int p = 0; p < (int)pMapMesh->m_Primitives.GetSize(); p ++ )
00377         {
00378                 // Alloue le maximum possible, de toute facon on s'en fou, au reload l'allocation se fera au plus juste
00379                 pMapMesh->m_Primitives[p]->m_nIndices = 0;
00380                 pMapMesh->m_Primitives[p]->m_pIndices = new u16[NumFaces*3];
00381                 
00382                 KMapFrameVertex*        pFrameVertex = new KMapFrameVertex();
00383                 pFrameVertex->m_FrameId         = 0;
00384                 pFrameVertex->m_nVertices       = 0;
00385                 pFrameVertex->m_pVertices       = new KMapVertex[NumFaces*3];
00386                 pMapMesh->m_Primitives[p]->m_FrameVertices.Add( pFrameVertex );
00387                 pMapMesh->m_Primitives[p]->m_nFrames ++;
00388         }
00389 
00390 
00391 
00392         int                     v2;
00393         KMapVertex      Vertex;
00394         for( Face = 0; Face < NumFaces; Face ++ )
00395         {
00396                 // Recherche la primitive qui correspond a ce materiel
00397                 Mtl = pMesh->getFaceMtlIndex( Face );
00398 
00399                 // Max utilise un modulo pour recupere le id de materiau
00400                 Mtl %= Loader.GetnTextures();
00401 
00402                 for( int m = 0; m < (int)pMapMesh->m_Primitives.GetSize(); m ++ )
00403                 {
00404                         KMapPrimitive*          pPrimitive              = pMapMesh->m_Primitives[m];
00405                         KMapFrameVertex*        pFrameVertex    = pPrimitive->m_FrameVertices[0];
00406 
00407                         if( pPrimitive->m_ShaderId == Mtl )
00408                         {
00409                                 // Ajoute les vertex
00410                                 for( int i = 0; i < 3; i ++ )
00411                                 {
00412                                         // Vertex id
00413                                         v2 = pMesh->faces[Face].v[i];
00414 
00415                                         // Position
00416                                         Vertex.Position.x       = pMesh->verts[v2].x;
00417                                         Vertex.Position.y       = pMesh->verts[v2].y;
00418                                         Vertex.Position.z       = pMesh->verts[v2].z;
00419                                         
00420                                         // Normal
00421                                         Point3  Normal = GetVertexNormal( pMesh, Face, pMesh->getRVertPtr( v2 ) );
00422                                         Vertex.Normal.x         = Normal.x;
00423                                         Vertex.Normal.y         = Normal.y;
00424                                         Vertex.Normal.z         = Normal.z;
00425 
00426                                         // Texture coordonnées
00427                                         Vertex.tu1                      = pMesh->tVerts[pMesh->tvFace[Face].t[i]].x;
00428                                         Vertex.tv1                      = pMesh->tVerts[pMesh->tvFace[Face].t[i]].y;
00429                                         Vertex.tu2                      = 0.0;
00430                                         Vertex.tv2                      = 0.0;
00431 
00432                                         // Ajoute le vertex
00433                                         pFrameVertex->m_pVertices[pFrameVertex->m_nVertices] = Vertex;
00434                                         pFrameVertex->m_nVertices ++;
00435                                         pPrimitive->m_nVertices ++;
00436                                 }
00437 
00438                                 // Ajoute les index
00439                                 // vertex 0
00440                                 pPrimitive->m_pIndices[pPrimitive->m_nIndices + 0] = pPrimitive->m_nIndices + 0;
00441                                 // vertex 1
00442                                 pPrimitive->m_pIndices[pPrimitive->m_nIndices + 1] = pPrimitive->m_nIndices + 1;
00443                                 // vertex 2
00444                                 pPrimitive->m_pIndices[pPrimitive->m_nIndices + 2] = pPrimitive->m_nIndices + 2;
00445                                 pPrimitive->m_nIndices += 3;
00446                         }
00447                 }
00448         }       
00449 
00450         return pMapMesh;
00451 }
00452 
00453 //---------------------------------------------------------------------------------------------
00454 Point3 KMapExporter::GetVertexNormal(Mesh* mesh, int faceNo, RVertex* rv)
00455 {
00456         Face* f = &mesh->faces[faceNo];
00457         DWORD smGroup = f->smGroup;
00458         int numNormals;
00459         Point3 vertexNormal;
00460         
00461         // Is normal specified
00462         // SPCIFIED is not currently used, but may be used in future versions.
00463         if (rv->rFlags & SPECIFIED_NORMAL) {
00464                 vertexNormal = rv->rn.getNormal();
00465         }
00466         // If normal is not specified it's only available if the face belongs
00467         // to a smoothing group
00468         else if ((numNormals = rv->rFlags & NORCT_MASK) && smGroup) {
00469                 // If there is only one vertex is found in the rn member.
00470                 if (numNormals == 1) {
00471                         vertexNormal = rv->rn.getNormal();
00472                 }
00473                 else {
00474                         // If two or more vertices are there you need to step through them
00475                         // and find the vertex with the same smoothing group as the current face.
00476                         // You will find multiple normals in the ern member.
00477                         for (int i = 0; i < numNormals; i++) {
00478                                 if (rv->ern[i].getSmGroup() & smGroup) {
00479                                         vertexNormal = rv->ern[i].getNormal();
00480                                 }
00481                         }
00482                 }
00483         }
00484         else {
00485                 // Get the normal from the Face if no smoothing groups are there
00486                 vertexNormal = mesh->getFaceNormal(faceNo);
00487         }
00488         
00489         return vertexNormal;
00490 }
00491 */

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