home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Graphics / sKulpt / skulpt-src / File-Sculpt.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-30  |  14.6 KB  |  429 lines

  1. #define STRICT
  2.  
  3. // Includes standard Windows
  4. #include <windows.h>
  5. #include <windowsx.h>
  6. #include <time.h>
  7. #include <stdlib.h>
  8. #include <malloc.h>
  9. #include <memory.h>
  10. #include <stdio.h>
  11. #include <math.h>
  12. #include <io.h>
  13.  
  14. // Includes D3D
  15. #define  D3D_OVERLOADS
  16. #include <ddraw.h>
  17. #include <d3d.h>
  18. #include <d3dx.h>
  19.  
  20. // Includes utilitaires D3D
  21. #include "d3dmath.h"
  22. #include "d3dutil.h"
  23. #include "D3DEnum.h"
  24.  
  25. // Ids Resources
  26. #include "resource.h"
  27.  
  28. // Constantes
  29. #include "const.h"
  30.  
  31. // Types
  32. #include "types.h"
  33.  
  34. // Variables globales projet
  35. #include "vars.h"
  36.  
  37. // Prototypes fonctions autres modules
  38. #include "proto.h"
  39.  
  40. // Macros
  41. #include "macros.h"
  42.  
  43. void vLoadSculpt(void)
  44. {
  45.     evertex *saVertices = NULL;
  46.     eface *saFaces = NULL;
  47.     elamp *saLamps = NULL;
  48.     world saWorld;
  49.     int *iVertIndexMap = NULL, *iLampIndexMap = NULL;
  50.     observer saObserver;
  51.     BOOL bObs = FALSE;
  52.     int iNumVertex = 0, iNumFace = 0, iNumLamps = 0;
  53.     char cBuffer[13];
  54.     long iX, iY;
  55.     float fEnvXmin = 2000000000., fEnvXmax = -2000000000., fEnvSize;
  56.     float fEnvYmin = 2000000000., fEnvYmax = -2000000000.;
  57.     float fEnvZmin = 2000000000., fEnvZmax = -2000000000.;
  58.     DWORD dwNBytesRead;
  59.     static TCHAR sFileName[512];
  60.  
  61. #ifndef _AMIGA_
  62.     HANDLE hFile;
  63.     static TCHAR sInitialDir[512] = "";
  64.     TCHAR sCurrentName[512] = "*.scene";
  65.     OFSTRUCT ReOpenBuff;
  66.     // Récupérer le directory courant
  67.     GetCurrentDirectory(sizeof(sInitialDir), sInitialDir);
  68.  
  69.     // Préparer une structure OPENFILENAME
  70.     OPENFILENAME sOFName = { sizeof(OPENFILENAME), NULL, NULL,
  71.                          "Fichiers Scènes (*.scene)\0*.scene\0\0",
  72.                          NULL, 0, 1, sCurrentName, 512, sFileName, 512,
  73.                          sInitialDir, "Ouvrir un fichier scène", OFN_FILEMUSTEXIST, 0, 1,
  74.                          ".scene", 0, NULL, NULL };
  75.  
  76.     // Choisir un fichier
  77.     if(!GetOpenFileName(&sOFName))
  78.         return;
  79.  
  80.     // Stocker le nom du directory pour le prochain appel
  81.     strcpy(sInitialDir, sCurrentName);
  82.     strstr(sInitialDir, sFileName)[0] = '\0';
  83.  
  84.     // Ouvrir le fichier en lecture
  85.     if ((HANDLE) HFILE_ERROR == (hFile = (HANDLE) OpenFile(sFileName, &ReOpenBuff, OF_READ)))
  86.         return;
  87. #else
  88.     FILE* hFile;
  89.  
  90.     strcpy(sFileName, "#?.scene");
  91.  
  92.     if (!FSelect("Ouvrir...", sFileName))
  93.         return;
  94.  
  95.    hFile = fopen(sFileName, "r");
  96.     if (!hFile)
  97.     {
  98.         vTrace("Pb ouverture fichier %s", sFileName);
  99.         return;
  100.     }
  101. #endif // _AMIGA_
  102.  
  103.     vTrace("*** Fichier scène ouvert : %s", sFileName);
  104.  
  105.     // Vérifier la structure d'entête Sculpt 3D
  106. #ifndef _AMIGA_
  107.     ReadFile(hFile, cBuffer, 12, &dwNBytesRead, NULL);
  108. #else
  109.     dwNBytesRead = fread(cBuffer, 1, 12, hFile);
  110. #endif
  111.     if (strncmp((char *) cBuffer, "FORM", 4) || strncmp((char *) cBuffer + 8, "SC3D", 4))
  112.     {
  113.         vTrace("*** E0024 : En-tête fichier scène incorrect");
  114.         goto _Fin;
  115.     }
  116.  
  117.     // Parcourir le fichier en décodant les chunks au fur et à mesure
  118. #ifndef _AMIGA_
  119.     while ((ReadFile(hFile, cBuffer, 4, &dwNBytesRead, NULL)) && (dwNBytesRead == 4))
  120. #else
  121.     while (4 == (dwNBytesRead = fread(cBuffer, 1, 4, hFile)))
  122. #endif
  123.     {
  124.         vTrace("Chunk : %4s", cBuffer);
  125.  
  126.         if (!strncmp((char *) cBuffer, "VERT", 4))    // Sommets
  127.         {
  128.             // Charger le nombre de vertex
  129. #ifndef _AMIGA_
  130.             ReadFile(hFile, &iX, 4, &dwNBytesRead, NULL);
  131. #else
  132.             dwNBytesRead = fread(&iX, 1, 4, hFile);
  133. #endif
  134.             iNumVertex = swapl(iX) / sizeof(evertex);
  135.             vTrace("Nombre de sommets : %ld", iNumVertex);
  136.  
  137.             // Allouer une structure temporaire pour les vertex Sculpt, avec leurs coordonnées INT
  138.             saVertices = (evertex *) malloc(iNumVertex * sizeof(evertex));
  139.             if (!saVertices)
  140.             {
  141.                 vTrace("*** E0025 : Erreur malloc saVertices");
  142.                 goto _Fin;
  143.             }
  144.  
  145.             // Allouer une structure d'index pour les vertex
  146.             // (les vertex sont lus dans l'ordre dans le fichier, mais la fonction
  147.             // iMakeVertex les range comme elle peut dans le tableau global de vertex,
  148.             // donc pour réindexer les triangles et normaliser les coordonnées lues
  149.             // il faut conserver la trace des permutations)
  150.             iVertIndexMap = (int *) malloc(iNumVertex * sizeof(int));
  151.             if (!iVertIndexMap)
  152.             {
  153.                 vTrace("*** E0026 : Erreur malloc iVertIndexMap");
  154.                 goto _Fin;
  155.             }
  156.  
  157.             // Lire la structure de vertex sculpt du fichier dans la structure allouée ci-dessus
  158. #ifndef _AMIGA_
  159.             ReadFile(hFile, saVertices, iNumVertex * sizeof(evertex), &dwNBytesRead, NULL);
  160. #else
  161.             dwNBytesRead = fread(saVertices, 1, iNumVertex * sizeof(evertex), hFile);
  162. #endif
  163.             // Pour chaque vertex sculpt (coordonnées INT),
  164.             // - convertir les coordonnées en float
  165.             // - créer un vecteur temporaire et y copier les coordonnées converties en float
  166.             // - demander à la fonction iMakeVertex de stocker le point défini par le vecteur temporaire
  167.             // - mémoriser dans la table d'index où la fonction iMakeVertex a rangé le point
  168.             for (int iVertex = 0 ; iVertex < iNumVertex ; iVertex++)
  169.             {
  170.                 iX = saVertices[iVertex].pos[0] = swapl(saVertices[iVertex].pos[0]);
  171.                 if (fEnvXmin > (float) iX) fEnvXmin = (float) iX; if (fEnvXmax < (float) iX) fEnvXmax = (float) iX;
  172.                 
  173.                 iX = saVertices[iVertex].pos[1] = swapl(saVertices[iVertex].pos[1]);
  174.                 if (fEnvYmin > (float) iX) fEnvYmin = (float) iX; if (fEnvYmax < (float) iX) fEnvYmax = (float) iX;
  175.                 
  176.                 iX = saVertices[iVertex].pos[2] = swapl(saVertices[iVertex].pos[2]);
  177.                 if (fEnvZmin > (float) iX) fEnvZmin = (float) iX; if (fEnvZmax < (float) iX) fEnvZmax = (float) iX;
  178.                 
  179.                 iVertIndexMap[iVertex] = iMakeVertex(
  180.                     D3DVECTOR(
  181.                         (float) saVertices[iVertex].pos[0],
  182.                         (float) saVertices[iVertex].pos[1],
  183.                         (float) saVertices[iVertex].pos[2]),
  184.                     XDC_FORCENEW);
  185.             }
  186.             continue;
  187.         }
  188.  
  189.         if (!strncmp((char *) cBuffer, "LAMP", 4))    // Sommets
  190.         {
  191.             // Charger le nombre de lampes
  192. #ifndef _AMIGA_
  193.             ReadFile(hFile, &iX, 4, &dwNBytesRead, NULL);
  194. #else
  195.             dwNBytesRead = fread(&iX, 1, 4, hFile);
  196. #endif
  197.             iNumLamps = swapl(iX) / sizeof(elamp);
  198.             vTrace("Nombre de lampes : %ld", iNumLamps);
  199.  
  200.             // Allouer une structure temporaire pour les vertex Sculpt, avec leurs coordonnées INT
  201.             saLamps = (elamp *) malloc(iNumLamps * sizeof(elamp));
  202.             if (!saLamps)
  203.             {
  204.                 vTrace("*** E0027 : Erreur malloc saLamps");
  205.                 goto _Fin;
  206.             }
  207.  
  208.             // Allouer une structure d'index pour les lampes
  209.             // (les vertex sont lus dans l'ordre dans le fichier, mais la fonction
  210.             // iMakeLamp les range comme elle peut dans le tableau global de lampes,
  211.             // donc pour normaliser les coordonnées des lampes il faut conserver la trace des rangements)
  212.             iLampIndexMap = (int *) malloc(iNumLamps * sizeof(int));
  213.             if (!iLampIndexMap)
  214.             {
  215.                 vTrace("*** E0028 : Erreur malloc iLampIndexMap");
  216.                 goto _Fin;
  217.             }
  218.  
  219.             // Lire la structure de vertex sculpt du fichier dans la structure allouée ci-dessus
  220. #ifndef _AMIGA_
  221.             ReadFile(hFile, saLamps, iNumLamps * sizeof(elamp), &dwNBytesRead, NULL);
  222. #else
  223.             dwNBytesRead = fread(saLamps, 1, iNumLamps * sizeof(elamp), hFile);
  224. #endif
  225.             // Pour chaque lampe sculpt (coordonnées INT),
  226.             // - convertir les coordonnées en float
  227.             // - créer un vecteur temporaire et y copier les coordonnées converties en float
  228.             // - demander à la fonction iMakeLamp de stocker le point défini par le vecteur temporaire
  229.             // - mémoriser dans la table d'index où la fonction iMakeLamp a rangé le point
  230.             for (int iLamp = 0 ; iLamp < iNumLamps ; iLamp++)
  231.             {
  232.                 saLamps[iLamp].pos[0] = swapl(saLamps[iLamp].pos[0]);
  233.                 saLamps[iLamp].pos[1] = swapl(saLamps[iLamp].pos[1]);
  234.                 saLamps[iLamp].pos[2] = swapl(saLamps[iLamp].pos[2]);
  235.                 
  236.                 saLamps[iLamp].brightness = swapl(saLamps[iLamp].brightness);
  237.                 
  238.                 D3DCOLORVALUE   dcvDiffuse    = {saLamps[iLamp].color[0]/256.f, saLamps[iLamp].color[1]/256.f, saLamps[iLamp].color[2]/256.f, 0.f};
  239.                 D3DCOLORVALUE   dcvSpecular    = {saLamps[iLamp].color[0]/256.f, saLamps[iLamp].color[1]/256.f, saLamps[iLamp].color[2]/256.f, 0.f};
  240.                 D3DCOLORVALUE   dcvAmbient    = {saLamps[iLamp].color[0]/256.f, saLamps[iLamp].color[1]/256.f, saLamps[iLamp].color[2]/256.f, 0.f};
  241.  
  242.                 iLampIndexMap[iLamp] = iMakeLamp(
  243.                         D3DLIGHT_POINT,
  244.                         dcvDiffuse,
  245.                         dcvSpecular,
  246.                         dcvAmbient,
  247.                         D3DVECTOR((float) saLamps[iLamp].pos[0], (float) saLamps[iLamp].pos[1], (float) saLamps[iLamp].pos[2]),
  248.                         D3DVECTOR(0.f, 0.f, 0.f),
  249.                         D3DLIGHT_RANGE_MAX,
  250.                         0.f,
  251.                         0.f,
  252.                         0.5f,
  253.                         0.f,
  254.                         0.f,
  255.                         0.f);
  256.             }
  257.             continue;
  258.         }
  259.  
  260.         if (!strncmp((char *) cBuffer, "FACE", 4))
  261.         {
  262.             // Charger le nombre de faces
  263. #ifndef _AMIGA_
  264.             ReadFile(hFile, &iX, 4, &dwNBytesRead, NULL);
  265. #else
  266.             dwNBytesRead = fread(&iX, 1, 4, hFile);
  267. #endif
  268.             iNumFace = swapl(iX) / sizeof(eface);
  269.             vTrace("Nombre de faces : %ld", iNumFace);
  270.  
  271.             // Allouer une structure temporaire pour ranger les faces Sculpt 3D
  272.             saFaces = (eface *) malloc(iNumFace * sizeof(eface));    
  273.             if (!saFaces)
  274.             {
  275.                 vTrace("*** E0029 : Erreur malloc saFaces");
  276.                 goto _Fin;
  277.             }
  278.  
  279.             // Lire les faces Sculpt du fichier
  280. #ifndef _AMIGA_
  281.             ReadFile(hFile, saFaces, iNumFace * sizeof(eface), &dwNBytesRead, NULL);
  282. #else
  283.             dwNBytesRead = fread(saFaces, 1, iNumFace * sizeof(eface), hFile);
  284. #endif
  285.             // Pour chaque face : créer un triangle avec les sommets (index mappés)
  286.             for (int iFace = 0 ; iFace < iNumFace ; iFace++)
  287.             {
  288.                 saFaces[iFace].evertexi[0] = swapl(saFaces[iFace].evertexi[0]);
  289.                 saFaces[iFace].evertexi[1] = swapl(saFaces[iFace].evertexi[1]);
  290.                 saFaces[iFace].evertexi[2] = swapl(saFaces[iFace].evertexi[2]);
  291.  
  292.                 iMakeTriangle(iVertIndexMap[saFaces[iFace].evertexi[0]],
  293.                           iVertIndexMap[saFaces[iFace].evertexi[1]],
  294.                           iVertIndexMap[saFaces[iFace].evertexi[2]],
  295.                           iFastMaterial(NULL, saFaces[iFace].color[0], saFaces[iFace].color[1], saFaces[iFace].color[2]));
  296.             }
  297.             continue;
  298.         }
  299.  
  300.         if (!strncmp((char *) cBuffer, "OBSV", 4))
  301.         {
  302.             bObs = TRUE;
  303.  
  304.             // Sauter la taille du chunk
  305. #ifndef _AMIGA_
  306.             ReadFile(hFile, &iX, sizeof(iX), &dwNBytesRead, NULL);
  307. #else
  308.             dwNBytesRead = fread(&iX, 1, 4, hFile);
  309. #endif
  310.             // Charger la structure observer
  311. #ifndef _AMIGA_
  312.             ReadFile(hFile, &saObserver, sizeof(saObserver), &dwNBytesRead, NULL);
  313. #else
  314.             dwNBytesRead = fread(&saObserver, 1, sizeof(saObserver), hFile);
  315. #endif
  316.             // Mettre à jour les coordonnées de l'observateur et de la cible
  317.             saObserver.robspos[0] = swapl(saObserver.robspos[0]);
  318.             saObserver.robspos[1] = swapl(saObserver.robspos[1]);
  319.             saObserver.robspos[2] = swapl(saObserver.robspos[2]);
  320.  
  321.             saObserver.rtarget[0] = swapl(saObserver.rtarget[0]);
  322.             saObserver.rtarget[1] = swapl(saObserver.rtarget[1]);
  323.             saObserver.rtarget[2] = swapl(saObserver.rtarget[2]);
  324.  
  325.             continue;
  326.         }
  327.  
  328.         if (!strncmp((char *) cBuffer, "WRLD", 4))
  329.         {
  330.             bObs = TRUE;
  331.  
  332.             // Sauter la taille du chunk
  333. #ifndef _AMIGA_
  334.             ReadFile(hFile, &iX, sizeof(iX), &dwNBytesRead, NULL);
  335. #else
  336.             dwNBytesRead = fread(&iX, 1, 4, hFile);
  337. #endif
  338.             // Charger la structure observer
  339. #ifndef _AMIGA_
  340.             ReadFile(hFile, &saWorld, sizeof(saWorld), &dwNBytesRead, NULL);
  341. #else
  342.             dwNBytesRead = fread(&saWorld, 1, sizeof(saWorld), hFile);
  343. #endif
  344.             // Mettre à jour l'éclairage ambiant et la couleur du fond
  345.             cAmbient = saWorld.backbright[0] + (saWorld.backbright[1] << 8) + (saWorld.backbright[2] << 16);
  346.             cBack = saWorld.skycol1[0] + (saWorld.skycol1[1] << 8) + (saWorld.skycol1[2] << 16);
  347.  
  348.             continue;
  349.         }
  350.  
  351.         // Chunk non traité.
  352. #ifndef _AMIGA_
  353.         ReadFile(hFile, &iX, 4, &dwNBytesRead, NULL);
  354. #else
  355.         dwNBytesRead = fread(&iX, 1, 4, hFile);
  356. #endif
  357.  
  358.         vTrace("Skip %d octets", iY = swapl(iX));
  359. #ifndef _AMIGA_
  360.         SetFilePointer(hFile, iY, NULL, FILE_CURRENT);
  361. #else
  362.         fseek(hFile, iY, SEEK_CUR);
  363. #endif
  364.     }
  365.  
  366. _Fin:
  367.  
  368.     // Fermer le fichier
  369. #ifndef _AMIGA_
  370.     CloseHandle(hFile);
  371. #else
  372.     fclose(hFile);
  373. #endif
  374.  
  375.     // Calculer la plus grande dimension de la scène
  376.     fEnvSize = fEnvXmax - fEnvXmin;
  377.     if (fEnvYmax - fEnvYmin > fEnvSize) fEnvSize = fEnvYmax - fEnvYmin;
  378.     if (fEnvZmax - fEnvZmin > fEnvSize)    fEnvSize = fEnvZmax - fEnvZmin;
  379.  
  380.     // Normaliser les coordonnées de tous les points lus
  381.     for (int iVertex = 0 ; iVertex < iNumVertex ; iVertex++)
  382.     {
  383.         Vertices[iVertIndexMap[iVertex]].vPoint.x = ((Vertices[iVertIndexMap[iVertex]].vPoint.x - fEnvXmin - (fEnvXmax - fEnvXmin) / 2.f) * 8.f / fEnvSize);
  384.         Vertices[iVertIndexMap[iVertex]].vPoint.y = ((Vertices[iVertIndexMap[iVertex]].vPoint.y - fEnvYmin - (fEnvYmax - fEnvYmin) / 2.f) * 8.f / fEnvSize);
  385.         Vertices[iVertIndexMap[iVertex]].vPoint.z = ((Vertices[iVertIndexMap[iVertex]].vPoint.z - fEnvZmin - (fEnvZmax - fEnvZmin) / 2.f) * 8.f / fEnvSize);
  386.     }
  387.  
  388.     // Normaliser les coordonnées de toutes les lampes
  389.     for (int iLamp = 0 ; iLamp < iNumLamps ; iLamp++)
  390.     {
  391.         Lampes[iLampIndexMap[iLamp]].lLamp.dvPosition.x = ((Lampes[iLampIndexMap[iLamp]].lLamp.dvPosition.x - fEnvXmin - (fEnvXmax - fEnvXmin) / 2.f) * 8.f / fEnvSize);
  392.         Lampes[iLampIndexMap[iLamp]].lLamp.dvPosition.y = ((Lampes[iLampIndexMap[iLamp]].lLamp.dvPosition.y - fEnvYmin - (fEnvYmax - fEnvYmin) / 2.f) * 8.f / fEnvSize);
  393.         Lampes[iLampIndexMap[iLamp]].lLamp.dvPosition.z = ((Lampes[iLampIndexMap[iLamp]].lLamp.dvPosition.z - fEnvZmin - (fEnvZmax - fEnvZmin) / 2.f) * 8.f / fEnvSize);
  394.         bUpdateLamp(iLampIndexMap[iLamp]);
  395.     }
  396.  
  397. #ifndef _AMIGA_
  398.     // Forcer le recalcul des sommets de chaque triangle (car on a changé les points)
  399.     for (int iTriangle = 0 ; iTriangle <= iTriaLastUsed ; iTriangle++)
  400.         bUpdateD3DTri(iTriangle);
  401. #endif
  402.  
  403.     // Si on a lu les coordonnées de l'observateur et de la target alors les positionner
  404.     if (bObs)
  405.     {
  406.         Observer.x = ((float) saObserver.robspos[0] - fEnvXmin - (fEnvXmax - fEnvXmin) / 2.f) * 8.f / fEnvSize;
  407.         Observer.y = ((float) saObserver.robspos[1] - fEnvYmin - (fEnvYmax - fEnvYmin) / 2.f) * 8.f / fEnvSize;
  408.         Observer.z = ((float) saObserver.robspos[2] - fEnvZmin - (fEnvZmax - fEnvZmin) / 2.f) * 8.f / fEnvSize;
  409.         Target.x = ((float) saObserver.rtarget[0] - fEnvXmin - (fEnvXmax - fEnvXmin) / 2.f) * 8.f / fEnvSize;
  410.         Target.y = ((float) saObserver.rtarget[1] - fEnvYmin - (fEnvYmax - fEnvYmin) / 2.f) * 8.f / fEnvSize;
  411.         Target.z = ((float) saObserver.rtarget[2] - fEnvZmin - (fEnvZmax - fEnvZmin) / 2.f) * 8.f / fEnvSize;
  412.         D3DUtil_SetViewMatrix(matView,
  413.               Observer,    // From
  414.               Target,    // To
  415.               D3DVECTOR(0.f, 0.f, 0.f));
  416.     }
  417.  
  418.     // Libérer les allocations mémoire
  419.     if (saFaces) { free(saFaces); saFaces = NULL; }
  420.     if (saVertices) { free(saVertices); saVertices = NULL; }
  421.     if (iVertIndexMap) { free(iVertIndexMap); iVertIndexMap = NULL; }
  422.     if (iLampIndexMap) { free(iLampIndexMap); iLampIndexMap = NULL; }
  423. }
  424.  
  425. void vSaveSculpt(void)
  426. {
  427. }
  428.  
  429.