home *** CD-ROM | disk | FTP | other *** search
- #define STRICT
-
- // Includes standard Windows
- #include <windows.h>
- #include <windowsx.h>
- #include <time.h>
- #include <stdlib.h>
- #include <malloc.h>
- #include <memory.h>
- #include <stdio.h>
- #include <math.h>
- #include <io.h>
-
- // Includes D3D
- #define D3D_OVERLOADS
- #include <ddraw.h>
- #include <d3d.h>
- #include <d3dx.h>
-
- // Includes utilitaires D3D
- #include "d3dmath.h"
- #include "d3dutil.h"
- #include "D3DEnum.h"
-
- // Ids Resources
- #include "resource.h"
-
- // Constantes
- #include "const.h"
-
- // Types
- #include "types.h"
-
- // Variables globales projet
- #include "vars.h"
-
- // Prototypes fonctions autres modules
- #include "proto.h"
-
- // Macros
- #include "macros.h"
-
- void vLoadSculpt(void)
- {
- evertex *saVertices = NULL;
- eface *saFaces = NULL;
- elamp *saLamps = NULL;
- world saWorld;
- int *iVertIndexMap = NULL, *iLampIndexMap = NULL;
- observer saObserver;
- BOOL bObs = FALSE;
- int iNumVertex = 0, iNumFace = 0, iNumLamps = 0;
- char cBuffer[13];
- long iX, iY;
- float fEnvXmin = 2000000000., fEnvXmax = -2000000000., fEnvSize;
- float fEnvYmin = 2000000000., fEnvYmax = -2000000000.;
- float fEnvZmin = 2000000000., fEnvZmax = -2000000000.;
- DWORD dwNBytesRead;
- static TCHAR sFileName[512];
-
- #ifndef _AMIGA_
- HANDLE hFile;
- static TCHAR sInitialDir[512] = "";
- TCHAR sCurrentName[512] = "*.scene";
- OFSTRUCT ReOpenBuff;
- // Récupérer le directory courant
- GetCurrentDirectory(sizeof(sInitialDir), sInitialDir);
-
- // Préparer une structure OPENFILENAME
- OPENFILENAME sOFName = { sizeof(OPENFILENAME), NULL, NULL,
- "Fichiers Scènes (*.scene)\0*.scene\0\0",
- NULL, 0, 1, sCurrentName, 512, sFileName, 512,
- sInitialDir, "Ouvrir un fichier scène", OFN_FILEMUSTEXIST, 0, 1,
- ".scene", 0, NULL, NULL };
-
- // Choisir un fichier
- if(!GetOpenFileName(&sOFName))
- return;
-
- // Stocker le nom du directory pour le prochain appel
- strcpy(sInitialDir, sCurrentName);
- strstr(sInitialDir, sFileName)[0] = '\0';
-
- // Ouvrir le fichier en lecture
- if ((HANDLE) HFILE_ERROR == (hFile = (HANDLE) OpenFile(sFileName, &ReOpenBuff, OF_READ)))
- return;
- #else
- FILE* hFile;
-
- strcpy(sFileName, "#?.scene");
-
- if (!FSelect("Ouvrir...", sFileName))
- return;
-
- hFile = fopen(sFileName, "r");
- if (!hFile)
- {
- vTrace("Pb ouverture fichier %s", sFileName);
- return;
- }
- #endif // _AMIGA_
-
- vTrace("*** Fichier scène ouvert : %s", sFileName);
-
- // Vérifier la structure d'entête Sculpt 3D
- #ifndef _AMIGA_
- ReadFile(hFile, cBuffer, 12, &dwNBytesRead, NULL);
- #else
- dwNBytesRead = fread(cBuffer, 1, 12, hFile);
- #endif
- if (strncmp((char *) cBuffer, "FORM", 4) || strncmp((char *) cBuffer + 8, "SC3D", 4))
- {
- vTrace("*** E0024 : En-tête fichier scène incorrect");
- goto _Fin;
- }
-
- // Parcourir le fichier en décodant les chunks au fur et à mesure
- #ifndef _AMIGA_
- while ((ReadFile(hFile, cBuffer, 4, &dwNBytesRead, NULL)) && (dwNBytesRead == 4))
- #else
- while (4 == (dwNBytesRead = fread(cBuffer, 1, 4, hFile)))
- #endif
- {
- vTrace("Chunk : %4s", cBuffer);
-
- if (!strncmp((char *) cBuffer, "VERT", 4)) // Sommets
- {
- // Charger le nombre de vertex
- #ifndef _AMIGA_
- ReadFile(hFile, &iX, 4, &dwNBytesRead, NULL);
- #else
- dwNBytesRead = fread(&iX, 1, 4, hFile);
- #endif
- iNumVertex = swapl(iX) / sizeof(evertex);
- vTrace("Nombre de sommets : %ld", iNumVertex);
-
- // Allouer une structure temporaire pour les vertex Sculpt, avec leurs coordonnées INT
- saVertices = (evertex *) malloc(iNumVertex * sizeof(evertex));
- if (!saVertices)
- {
- vTrace("*** E0025 : Erreur malloc saVertices");
- goto _Fin;
- }
-
- // Allouer une structure d'index pour les vertex
- // (les vertex sont lus dans l'ordre dans le fichier, mais la fonction
- // iMakeVertex les range comme elle peut dans le tableau global de vertex,
- // donc pour réindexer les triangles et normaliser les coordonnées lues
- // il faut conserver la trace des permutations)
- iVertIndexMap = (int *) malloc(iNumVertex * sizeof(int));
- if (!iVertIndexMap)
- {
- vTrace("*** E0026 : Erreur malloc iVertIndexMap");
- goto _Fin;
- }
-
- // Lire la structure de vertex sculpt du fichier dans la structure allouée ci-dessus
- #ifndef _AMIGA_
- ReadFile(hFile, saVertices, iNumVertex * sizeof(evertex), &dwNBytesRead, NULL);
- #else
- dwNBytesRead = fread(saVertices, 1, iNumVertex * sizeof(evertex), hFile);
- #endif
- // Pour chaque vertex sculpt (coordonnées INT),
- // - convertir les coordonnées en float
- // - créer un vecteur temporaire et y copier les coordonnées converties en float
- // - demander à la fonction iMakeVertex de stocker le point défini par le vecteur temporaire
- // - mémoriser dans la table d'index où la fonction iMakeVertex a rangé le point
- for (int iVertex = 0 ; iVertex < iNumVertex ; iVertex++)
- {
- iX = saVertices[iVertex].pos[0] = swapl(saVertices[iVertex].pos[0]);
- if (fEnvXmin > (float) iX) fEnvXmin = (float) iX; if (fEnvXmax < (float) iX) fEnvXmax = (float) iX;
-
- iX = saVertices[iVertex].pos[1] = swapl(saVertices[iVertex].pos[1]);
- if (fEnvYmin > (float) iX) fEnvYmin = (float) iX; if (fEnvYmax < (float) iX) fEnvYmax = (float) iX;
-
- iX = saVertices[iVertex].pos[2] = swapl(saVertices[iVertex].pos[2]);
- if (fEnvZmin > (float) iX) fEnvZmin = (float) iX; if (fEnvZmax < (float) iX) fEnvZmax = (float) iX;
-
- iVertIndexMap[iVertex] = iMakeVertex(
- D3DVECTOR(
- (float) saVertices[iVertex].pos[0],
- (float) saVertices[iVertex].pos[1],
- (float) saVertices[iVertex].pos[2]),
- XDC_FORCENEW);
- }
- continue;
- }
-
- if (!strncmp((char *) cBuffer, "LAMP", 4)) // Sommets
- {
- // Charger le nombre de lampes
- #ifndef _AMIGA_
- ReadFile(hFile, &iX, 4, &dwNBytesRead, NULL);
- #else
- dwNBytesRead = fread(&iX, 1, 4, hFile);
- #endif
- iNumLamps = swapl(iX) / sizeof(elamp);
- vTrace("Nombre de lampes : %ld", iNumLamps);
-
- // Allouer une structure temporaire pour les vertex Sculpt, avec leurs coordonnées INT
- saLamps = (elamp *) malloc(iNumLamps * sizeof(elamp));
- if (!saLamps)
- {
- vTrace("*** E0027 : Erreur malloc saLamps");
- goto _Fin;
- }
-
- // Allouer une structure d'index pour les lampes
- // (les vertex sont lus dans l'ordre dans le fichier, mais la fonction
- // iMakeLamp les range comme elle peut dans le tableau global de lampes,
- // donc pour normaliser les coordonnées des lampes il faut conserver la trace des rangements)
- iLampIndexMap = (int *) malloc(iNumLamps * sizeof(int));
- if (!iLampIndexMap)
- {
- vTrace("*** E0028 : Erreur malloc iLampIndexMap");
- goto _Fin;
- }
-
- // Lire la structure de vertex sculpt du fichier dans la structure allouée ci-dessus
- #ifndef _AMIGA_
- ReadFile(hFile, saLamps, iNumLamps * sizeof(elamp), &dwNBytesRead, NULL);
- #else
- dwNBytesRead = fread(saLamps, 1, iNumLamps * sizeof(elamp), hFile);
- #endif
- // Pour chaque lampe sculpt (coordonnées INT),
- // - convertir les coordonnées en float
- // - créer un vecteur temporaire et y copier les coordonnées converties en float
- // - demander à la fonction iMakeLamp de stocker le point défini par le vecteur temporaire
- // - mémoriser dans la table d'index où la fonction iMakeLamp a rangé le point
- for (int iLamp = 0 ; iLamp < iNumLamps ; iLamp++)
- {
- saLamps[iLamp].pos[0] = swapl(saLamps[iLamp].pos[0]);
- saLamps[iLamp].pos[1] = swapl(saLamps[iLamp].pos[1]);
- saLamps[iLamp].pos[2] = swapl(saLamps[iLamp].pos[2]);
-
- saLamps[iLamp].brightness = swapl(saLamps[iLamp].brightness);
-
- D3DCOLORVALUE dcvDiffuse = {saLamps[iLamp].color[0]/256.f, saLamps[iLamp].color[1]/256.f, saLamps[iLamp].color[2]/256.f, 0.f};
- D3DCOLORVALUE dcvSpecular = {saLamps[iLamp].color[0]/256.f, saLamps[iLamp].color[1]/256.f, saLamps[iLamp].color[2]/256.f, 0.f};
- D3DCOLORVALUE dcvAmbient = {saLamps[iLamp].color[0]/256.f, saLamps[iLamp].color[1]/256.f, saLamps[iLamp].color[2]/256.f, 0.f};
-
- iLampIndexMap[iLamp] = iMakeLamp(
- D3DLIGHT_POINT,
- dcvDiffuse,
- dcvSpecular,
- dcvAmbient,
- D3DVECTOR((float) saLamps[iLamp].pos[0], (float) saLamps[iLamp].pos[1], (float) saLamps[iLamp].pos[2]),
- D3DVECTOR(0.f, 0.f, 0.f),
- D3DLIGHT_RANGE_MAX,
- 0.f,
- 0.f,
- 0.5f,
- 0.f,
- 0.f,
- 0.f);
- }
- continue;
- }
-
- if (!strncmp((char *) cBuffer, "FACE", 4))
- {
- // Charger le nombre de faces
- #ifndef _AMIGA_
- ReadFile(hFile, &iX, 4, &dwNBytesRead, NULL);
- #else
- dwNBytesRead = fread(&iX, 1, 4, hFile);
- #endif
- iNumFace = swapl(iX) / sizeof(eface);
- vTrace("Nombre de faces : %ld", iNumFace);
-
- // Allouer une structure temporaire pour ranger les faces Sculpt 3D
- saFaces = (eface *) malloc(iNumFace * sizeof(eface));
- if (!saFaces)
- {
- vTrace("*** E0029 : Erreur malloc saFaces");
- goto _Fin;
- }
-
- // Lire les faces Sculpt du fichier
- #ifndef _AMIGA_
- ReadFile(hFile, saFaces, iNumFace * sizeof(eface), &dwNBytesRead, NULL);
- #else
- dwNBytesRead = fread(saFaces, 1, iNumFace * sizeof(eface), hFile);
- #endif
- // Pour chaque face : créer un triangle avec les sommets (index mappés)
- for (int iFace = 0 ; iFace < iNumFace ; iFace++)
- {
- saFaces[iFace].evertexi[0] = swapl(saFaces[iFace].evertexi[0]);
- saFaces[iFace].evertexi[1] = swapl(saFaces[iFace].evertexi[1]);
- saFaces[iFace].evertexi[2] = swapl(saFaces[iFace].evertexi[2]);
-
- iMakeTriangle(iVertIndexMap[saFaces[iFace].evertexi[0]],
- iVertIndexMap[saFaces[iFace].evertexi[1]],
- iVertIndexMap[saFaces[iFace].evertexi[2]],
- iFastMaterial(NULL, saFaces[iFace].color[0], saFaces[iFace].color[1], saFaces[iFace].color[2]));
- }
- continue;
- }
-
- if (!strncmp((char *) cBuffer, "OBSV", 4))
- {
- bObs = TRUE;
-
- // Sauter la taille du chunk
- #ifndef _AMIGA_
- ReadFile(hFile, &iX, sizeof(iX), &dwNBytesRead, NULL);
- #else
- dwNBytesRead = fread(&iX, 1, 4, hFile);
- #endif
- // Charger la structure observer
- #ifndef _AMIGA_
- ReadFile(hFile, &saObserver, sizeof(saObserver), &dwNBytesRead, NULL);
- #else
- dwNBytesRead = fread(&saObserver, 1, sizeof(saObserver), hFile);
- #endif
- // Mettre à jour les coordonnées de l'observateur et de la cible
- saObserver.robspos[0] = swapl(saObserver.robspos[0]);
- saObserver.robspos[1] = swapl(saObserver.robspos[1]);
- saObserver.robspos[2] = swapl(saObserver.robspos[2]);
-
- saObserver.rtarget[0] = swapl(saObserver.rtarget[0]);
- saObserver.rtarget[1] = swapl(saObserver.rtarget[1]);
- saObserver.rtarget[2] = swapl(saObserver.rtarget[2]);
-
- continue;
- }
-
- if (!strncmp((char *) cBuffer, "WRLD", 4))
- {
- bObs = TRUE;
-
- // Sauter la taille du chunk
- #ifndef _AMIGA_
- ReadFile(hFile, &iX, sizeof(iX), &dwNBytesRead, NULL);
- #else
- dwNBytesRead = fread(&iX, 1, 4, hFile);
- #endif
- // Charger la structure observer
- #ifndef _AMIGA_
- ReadFile(hFile, &saWorld, sizeof(saWorld), &dwNBytesRead, NULL);
- #else
- dwNBytesRead = fread(&saWorld, 1, sizeof(saWorld), hFile);
- #endif
- // Mettre à jour l'éclairage ambiant et la couleur du fond
- cAmbient = saWorld.backbright[0] + (saWorld.backbright[1] << 8) + (saWorld.backbright[2] << 16);
- cBack = saWorld.skycol1[0] + (saWorld.skycol1[1] << 8) + (saWorld.skycol1[2] << 16);
-
- continue;
- }
-
- // Chunk non traité.
- #ifndef _AMIGA_
- ReadFile(hFile, &iX, 4, &dwNBytesRead, NULL);
- #else
- dwNBytesRead = fread(&iX, 1, 4, hFile);
- #endif
-
- vTrace("Skip %d octets", iY = swapl(iX));
- #ifndef _AMIGA_
- SetFilePointer(hFile, iY, NULL, FILE_CURRENT);
- #else
- fseek(hFile, iY, SEEK_CUR);
- #endif
- }
-
- _Fin:
-
- // Fermer le fichier
- #ifndef _AMIGA_
- CloseHandle(hFile);
- #else
- fclose(hFile);
- #endif
-
- // Calculer la plus grande dimension de la scène
- fEnvSize = fEnvXmax - fEnvXmin;
- if (fEnvYmax - fEnvYmin > fEnvSize) fEnvSize = fEnvYmax - fEnvYmin;
- if (fEnvZmax - fEnvZmin > fEnvSize) fEnvSize = fEnvZmax - fEnvZmin;
-
- // Normaliser les coordonnées de tous les points lus
- for (int iVertex = 0 ; iVertex < iNumVertex ; iVertex++)
- {
- Vertices[iVertIndexMap[iVertex]].vPoint.x = ((Vertices[iVertIndexMap[iVertex]].vPoint.x - fEnvXmin - (fEnvXmax - fEnvXmin) / 2.f) * 8.f / fEnvSize);
- Vertices[iVertIndexMap[iVertex]].vPoint.y = ((Vertices[iVertIndexMap[iVertex]].vPoint.y - fEnvYmin - (fEnvYmax - fEnvYmin) / 2.f) * 8.f / fEnvSize);
- Vertices[iVertIndexMap[iVertex]].vPoint.z = ((Vertices[iVertIndexMap[iVertex]].vPoint.z - fEnvZmin - (fEnvZmax - fEnvZmin) / 2.f) * 8.f / fEnvSize);
- }
-
- // Normaliser les coordonnées de toutes les lampes
- for (int iLamp = 0 ; iLamp < iNumLamps ; iLamp++)
- {
- Lampes[iLampIndexMap[iLamp]].lLamp.dvPosition.x = ((Lampes[iLampIndexMap[iLamp]].lLamp.dvPosition.x - fEnvXmin - (fEnvXmax - fEnvXmin) / 2.f) * 8.f / fEnvSize);
- Lampes[iLampIndexMap[iLamp]].lLamp.dvPosition.y = ((Lampes[iLampIndexMap[iLamp]].lLamp.dvPosition.y - fEnvYmin - (fEnvYmax - fEnvYmin) / 2.f) * 8.f / fEnvSize);
- Lampes[iLampIndexMap[iLamp]].lLamp.dvPosition.z = ((Lampes[iLampIndexMap[iLamp]].lLamp.dvPosition.z - fEnvZmin - (fEnvZmax - fEnvZmin) / 2.f) * 8.f / fEnvSize);
- bUpdateLamp(iLampIndexMap[iLamp]);
- }
-
- #ifndef _AMIGA_
- // Forcer le recalcul des sommets de chaque triangle (car on a changé les points)
- for (int iTriangle = 0 ; iTriangle <= iTriaLastUsed ; iTriangle++)
- bUpdateD3DTri(iTriangle);
- #endif
-
- // Si on a lu les coordonnées de l'observateur et de la target alors les positionner
- if (bObs)
- {
- Observer.x = ((float) saObserver.robspos[0] - fEnvXmin - (fEnvXmax - fEnvXmin) / 2.f) * 8.f / fEnvSize;
- Observer.y = ((float) saObserver.robspos[1] - fEnvYmin - (fEnvYmax - fEnvYmin) / 2.f) * 8.f / fEnvSize;
- Observer.z = ((float) saObserver.robspos[2] - fEnvZmin - (fEnvZmax - fEnvZmin) / 2.f) * 8.f / fEnvSize;
- Target.x = ((float) saObserver.rtarget[0] - fEnvXmin - (fEnvXmax - fEnvXmin) / 2.f) * 8.f / fEnvSize;
- Target.y = ((float) saObserver.rtarget[1] - fEnvYmin - (fEnvYmax - fEnvYmin) / 2.f) * 8.f / fEnvSize;
- Target.z = ((float) saObserver.rtarget[2] - fEnvZmin - (fEnvZmax - fEnvZmin) / 2.f) * 8.f / fEnvSize;
- D3DUtil_SetViewMatrix(matView,
- Observer, // From
- Target, // To
- D3DVECTOR(0.f, 0.f, 0.f));
- }
-
- // Libérer les allocations mémoire
- if (saFaces) { free(saFaces); saFaces = NULL; }
- if (saVertices) { free(saVertices); saVertices = NULL; }
- if (iVertIndexMap) { free(iVertIndexMap); iVertIndexMap = NULL; }
- if (iLampIndexMap) { free(iLampIndexMap); iLampIndexMap = NULL; }
- }
-
- void vSaveSculpt(void)
- {
- }
-
-