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>
-
- // Includes D3D
- #define D3D_OVERLOADS
- #include <ddraw.h>
- #include <d3d.h>
-
- // Includes utilitaires D3D
- #include "d3dmath.h"
- #include "d3dutil.h"
- #include "D3DEnum.h"
-
- #include <d3dx.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"
-
- //************************************* C O M M U N S ***********************
- void vDeleteObjects(void)
- {
- // RAZ points
- for (int iVert = 0 ; iVert < XDC_NUMPT ; iVert++)
- {
- Vertices[iVert].bEnabled = FALSE;
- Vertices[iVert].bHidden = FALSE;
- Vertices[iVert].bSelected = FALSE;
- Vertices[iVert].bSmooth = FALSE;
- Vertices[iVert].iDepend = 0;
- }
- iVertFirstAvailable = 0;
- iVertLastUsed = -1;
-
- // RAZ arêtes
- for (int iEdge = 0 ; iEdge < XDC_NUMEDGE ; iEdge++)
- {
- Edges[iEdge].bEnabled = FALSE;
- Edges[iEdge].bHidden = FALSE;
- }
- iEdgeFirstAvailable = 0;
- iEdgeLastUsed = -1;
-
- // RAZ lampes
- for (int iLamp = 0 ; iLamp < XDC_NUMLAMP ; iLamp++)
- if (Lampes[iLamp].bEnabled) bDeleteLamp(iLamp);
-
- iLampFirstAvailable = 0;
- iLampLastUsed = -1;
-
- // RAZ facettes
- for (int iTriangle = 0 ; iTriangle < XDC_NUMTRI ; iTriangle++)
- {
- Triangles[iTriangle].bEnabled = FALSE;
- Triangles[iTriangle].bHidden = FALSE;
- }
- iTriaFirstAvailable = 0;
- iTriaLastUsed = -1;
-
- // RAZ matériaux
- for (int iMtrl = 0 ; iMtrl < XDC_NUMMTRL ; iMtrl++)
- {
- Materials[iMtrl].bEnabled = FALSE;
- Materials[iMtrl].bTextured = FALSE;
- }
- iMtrlFirstAvailable = 0;
- iMtrlLastUsed = -1;
-
- iFastMaterial("Blanc", 255, 255, 255);
- iFastMaterial("Noir", 0, 0, 0);
- iFastMaterial("Rouge", 255, 0, 0);
- iFastMaterial("Vert", 0, 255, 0);
- iFastMaterial("Bleu", 0, 0, 255);
-
- #ifndef _AMIGA_
- // RAZ Objets D3D
- vDeleteD3DObjects();
- #endif
- }
-
- //************************************** M A T E R I A L S *************************
- BOOL bSameMaterial(D3DMATERIAL7 *hMtrl1, D3DMATERIAL7 *hMtrl2)
- {
- double fDist =
- fabs(hMtrl2 -> ambient.a - hMtrl1 -> ambient.a) +
- fabs(hMtrl2 -> ambient.r - hMtrl1 -> ambient.r) +
- fabs(hMtrl2 -> ambient.g - hMtrl1 -> ambient.g) +
- fabs(hMtrl2 -> ambient.b - hMtrl1 -> ambient.b) +
-
- fabs(hMtrl2 -> diffuse.a - hMtrl1 -> diffuse.a) +
- fabs(hMtrl2 -> diffuse.r - hMtrl1 -> diffuse.r) +
- fabs(hMtrl2 -> diffuse.g - hMtrl1 -> diffuse.g) +
- fabs(hMtrl2 -> diffuse.b - hMtrl1 -> diffuse.b) +
-
- fabs(hMtrl2 -> specular.a - hMtrl1 -> specular.a) +
- fabs(hMtrl2 -> specular.r - hMtrl1 -> specular.r) +
- fabs(hMtrl2 -> specular.g - hMtrl1 -> specular.g) +
- fabs(hMtrl2 -> specular.b - hMtrl1 -> specular.b) +
- fabs(hMtrl2 -> power - hMtrl1 -> power);
-
- return (fDist < 0.1);
- }
-
- int iFindMaterial(D3DMATERIAL7 *hMtrl, int iPrevious)
- {
- int iCnt;
- float fTolerance = (float) fabs(fXmax - fXmin) / XDC_ZONE;
-
- // Rechercher le matériau
- for (iCnt = max(iPrevious + 1, 0) ;
- (iCnt <= iMtrlLastUsed)
- && (!( (Materials[iCnt].bEnabled == TRUE)
- && (!bSameMaterial(hMtrl, &(Materials[iCnt].mtrl)))
- ))
- ;
- iCnt++) ;
-
- // Si matériau trouvé alors renvoyer son indice
- if (iCnt <= iMtrlLastUsed)
- return(iCnt);
-
- // Sinon renvoyer -1
- return -1;
- }
-
- BOOL bTextureMaterial(int iMtrl, char *sTexName)
- {
- if (iMtrl > iMtrlLastUsed) return FALSE;
- if (!Materials[iMtrl].bEnabled) return FALSE;
-
- if (sTexName) // Il faudrait sans doute uploader la texture...
- {
- strcpy(Materials[iMtrl].sTexName, sTexName);
- Materials[iMtrl].hTexture = NULL;
- Materials[iMtrl].bTextured = TRUE;
- }
- else // Il faudrait sans doute releaser la texture...
- Materials[iMtrl].bTextured = FALSE;
-
- return TRUE;
- }
-
- int iFastMaterial(char *sName, unsigned char bRouge, unsigned char bVert, unsigned char bBleu)
- {
- D3DMATERIAL7 Mtrl, *pMtrl = &Mtrl;
- ZeroMemory(pMtrl, sizeof(D3DMATERIAL7));
- pMtrl -> ambient.a = 0.8f;
- pMtrl -> ambient.r = (float) bRouge / 256.f / 6.f;
- pMtrl -> ambient.g = (float) bVert / 256.f / 6.f;
- pMtrl -> ambient.b = (float) bBleu / 256.f / 6.f;
-
- pMtrl -> diffuse.a = 0.8f;
- pMtrl -> diffuse.r = (float) bRouge / 256.f;
- pMtrl -> diffuse.g = (float) bVert / 256.f;
- pMtrl -> diffuse.b = (float) bBleu / 256.f;
-
- pMtrl -> specular.a = 0.8f;
- pMtrl -> specular.r = 1.f;
- pMtrl -> specular.g = 1.f;
- pMtrl -> specular.b = 1.f;
- pMtrl -> power = 1.f;
-
- return iMakeMaterial(pMtrl, sName, XDC_ALLOWSAME);
- }
-
- int iMakeMaterial(D3DMATERIAL7 *hMtrl, char *sName, BOOL bSame)
- {
- int iCnt;
-
- // Rechercher le premier index libre
- for (iCnt = bSame ? 0 : iMtrlFirstAvailable ;
- (iCnt <= iMtrlLastUsed)
- && ( ((!bSame) && (Materials[iCnt].bEnabled == TRUE))
- || ((bSame) && (!( (Materials[iCnt].bEnabled == TRUE)
- && (bSameMaterial(hMtrl, &(Materials[iCnt].mtrl)))
- ) ) )
- ) ;
- iCnt++) ;
-
- // Si limite tableau atteinte alors renvoyer erreur
- if (iCnt >= XDC_NUMMTRL)
- {
- vTrace("*** E0016 : Plus de slots matériaux libres");
- return -1;
- }
-
- // Si matériau trouvé dans tableau alors le renvoyer
- if (bSame)
- {
- if ((iCnt < XDC_NUMMTRL) && (Materials[iCnt].bEnabled == TRUE)
- && (bSameMaterial(hMtrl, &(Materials[iCnt].mtrl))))
- return(iCnt);
- else
- return(iMakeMaterial(hMtrl, sName, XDC_FORCENEW));
- }
-
- // Créer un nouveau point
- Materials[iCnt].mtrl = *hMtrl;
- if (sName) strcpy(Materials[iCnt].sName, sName); else strcpy(Materials[iCnt].sName, "[unnamed]");
- Materials[iCnt].bEnabled =TRUE;
-
- while (Materials[iMtrlFirstAvailable].bEnabled == TRUE) iMtrlFirstAvailable++;
- if (iMtrlLastUsed < iCnt) iMtrlLastUsed = iCnt;
-
- return iCnt;
- }
-
-
- BOOL bDeleteMaterial(int iMtrl)
- {
- // Si le material n'est pas enabled alors ne rien faire
- if (Materials[iMtrl].bEnabled == FALSE) return FALSE;
-
- // Disabler le point
- Materials[iMtrl].bEnabled = FALSE;
-
- // Mettre à jour les indices globaux du tableau des vertices
- if (iMtrl == iMtrlLastUsed) while ((iMtrlLastUsed > -1) && (!Materials[--iMtrlLastUsed].bEnabled)) ;
- if (iMtrl < iMtrlFirstAvailable) iMtrlFirstAvailable = iMtrl;
-
- return TRUE;
- }
-
- //************************************** V E R T E X *************************
- int iFindVertex(D3DVECTOR p, int iPrevious)
- {
- int iCnt;
- float fTolerance = (float) fabs(fXmax - fXmin) / XDC_ZONE;
-
- // Rechercher le point
- for (iCnt = max(iPrevious + 1, 0) ;
- (iCnt <= iVertLastUsed)
- && (!( (Vertices[iCnt].bEnabled == TRUE)
- && (Vertices[iCnt].bHidden == FALSE)
- && (fabs(Vertices[iCnt].vPoint.x - p.x) < fTolerance)
- && (fabs(Vertices[iCnt].vPoint.y - p.y) < fTolerance)
- && (fabs(Vertices[iCnt].vPoint.z - p.z) < fTolerance)
- ))
- ;
- iCnt++) ;
-
- // Si point trouvé alors renvoyer son indice
- if (iCnt <= iVertLastUsed)
- return(iCnt);
-
- // Sinon renvoyer -1
- return -1;
- }
-
- int iMakeVertex(D3DVECTOR p, BOOL bSame)
- {
- int iCnt;
-
- // Rechercher le premier index libre
- for (iCnt = bSame ? 0 : iVertFirstAvailable ;
- (iCnt <= iVertLastUsed)
- && ( ((!bSame) && (Vertices[iCnt].bEnabled == TRUE))
- || ((bSame) && (!((Vertices[iCnt].bEnabled == TRUE) && (Vertices[iCnt].bHidden == FALSE) && (Magnitude(Vertices[iCnt].vPoint - p) < 10.f * g_EPSILON))))
- ) ;
- iCnt++) ;
-
- // Si limite tableau atteinte alors renvoyer erreur
- if (iCnt >= XDC_NUMPT)
- {
- vTrace("*** E0016 : Plus de slots vertex libres");
- return -1;
- }
-
- // Si point trouvé dans tableau alors le renvoyer
- if (bSame)
- {
- if ((iCnt < XDC_NUMPT) && (Vertices[iCnt].bEnabled == TRUE) && (Vertices[iCnt].bHidden == FALSE) && (Magnitude(Vertices[iCnt].vPoint - p) < 10.f * g_EPSILON))
- return(iCnt);
- else
- return(iMakeVertex(p, XDC_FORCENEW));
- }
-
- // Créer un nouveau point
- Vertices[iCnt].vPoint = p;
- Vertices[iCnt].bSelected = FALSE;
- Vertices[iCnt].bHidden = FALSE;
- Vertices[iCnt].bEnabled =TRUE;
-
- while (Vertices[iVertFirstAvailable].bEnabled == TRUE) iVertFirstAvailable++;
- if (iVertLastUsed < iCnt) iVertLastUsed = iCnt;
-
- return iCnt;
- }
-
- BOOL bVertInEdge(int iVert, int iEdge)
- {
- if ( (Edges[iEdge].iSommets[0] == iVert)
- || (Edges[iEdge].iSommets[1] == iVert)
- )
- return TRUE;
- else
- return FALSE;
- }
-
- BOOL bVertInTriangle(int iVert, int iTriangle)
- {
- if ( (Triangles[iTriangle].iSommets[0] == iVert)
- || (Triangles[iTriangle].iSommets[1] == iVert)
- || (Triangles[iTriangle].iSommets[2] == iVert)
- )
- return TRUE;
- else
- return FALSE;
- }
-
- int iEdgesPerVert(int iVert)
- {
- int iCnt, jCnt = 0;
-
- for (iCnt = 0 ; iCnt <= iVertLastUsed ; iCnt++)
- if (bVertInEdge(iVert, iCnt))
- jCnt++;
-
- return jCnt;
- }
-
- int iTrianglesPerVert(int iVert)
- {
- int iCnt, jCnt = 0;
-
- for (iCnt = 0 ; iCnt <= iVertLastUsed ; iCnt++)
- if (bVertInTriangle(iVert, iCnt))
- jCnt++;
-
- return jCnt;
- }
-
- BOOL bDeleteVertex(int iVert)
- {
- int iCnt;
-
- // Si le point n'est pas enabled alors ne rien faire
- if (Vertices[iVert].bEnabled == FALSE) return FALSE;
-
- // Disabler le point
- Vertices[iVert].bEnabled = FALSE;
-
- // Mettre à jour les indices globaux du tableau des vertices
- if (iVert == iVertLastUsed) while ((iVertLastUsed > -1) && (!Vertices[--iVertLastUsed].bEnabled)) ;
- if (iVert < iVertFirstAvailable) iVertFirstAvailable = iVert;
-
- // Supprimer toutes les arêtes desquelles le sommet supprimé est une extrêmité
- for (iCnt = 0 ; iCnt <= iEdgeLastUsed ; iCnt++)
- if (bVertInEdge(iVert, iCnt))
- bDeleteEdge(iCnt);
-
- // Pour tout triangle duquel le sommet supprimé est un sommet, transformer le triangle en une arête entre les 2 sommets restants
- for (iCnt = 0 ; iCnt <= iTriaLastUsed ; iCnt++)
- if (bVertInTriangle(iVert, iCnt))
- {
- /*
- if (Triangles[iCnt].iSommets[0] == iVert) iMakeEdge(Triangles[iCnt].iSommets[1], Triangles[iCnt].iSommets[2]);
- if (Triangles[iCnt].iSommets[1] == iVert) iMakeEdge(Triangles[iCnt].iSommets[0], Triangles[iCnt].iSommets[2]);
- if (Triangles[iCnt].iSommets[2] == iVert) iMakeEdge(Triangles[iCnt].iSommets[0], Triangles[iCnt].iSommets[1]);
- */
- bDeleteTriangle(iCnt);
- }
-
- return TRUE;
- }
-
- #ifndef _AMIGA_
- BOOL bSmoothNorm(int iVertex)
- {
- if (Vertices[iVertex].bEnabled == FALSE) return FALSE;
- if (Vertices[iVertex].bSmooth == FALSE) return FALSE;
- if (Vertices[iVertex].iDepend == 0) return FALSE;
-
- D3DVECTOR vn = D3DVECTOR(0.f, 0.f, 0.f);
-
- for (int iTriangle = 0 ; iTriangle <= iTriaLastUsed ; iTriangle++)
- {
- if (Triangles[iTriangle].bEnabled == FALSE) continue;
- if (!bVertInTriangle(iVertex, iTriangle)) continue;
-
- D3DVECTOR vc;
- /*
- short iS0 = Triangles [iTriangle].iSommets[0],
- iS1 = Triangles [iTriangle].iSommets[1],
- iS2 = Triangles [iTriangle].iSommets[2];
-
- D3DVECTOR
- v01 = Vertices[iS1].vPoint - Vertices[iS0].vPoint,
- v02 = Vertices[iS2].vPoint - Vertices[iS0].vPoint,
- v12 = Vertices[iS2].vPoint - Vertices[iS1].vPoint,
- vn0, vn1, vn2;
-
- vn0 = Normalize(CrossProduct(v01, v02));
- vn1 = Normalize(CrossProduct(v01, v12));
- vn2 = Normalize(CrossProduct(v02, v12));
-
- */
- for (int iCnt = 0 ; iCnt < 3 ; iCnt++)
- if (iVertex == Triangles [iTriangle].iSommets[iCnt])
- vc = D3DVECTOR(
- Triangles [iTriangle].pSommets[iCnt].nx,
- Triangles [iTriangle].pSommets[iCnt].ny,
- Triangles [iTriangle].pSommets[iCnt].nz);
-
- /*
- if (iVertex == iS0) vc = vn0;
- if (iVertex == iS1) vc = vn1;
- if (iVertex == iS2) vc = vn2;
-
- float fdp = DotProduct(vn, vc);
-
- if (fdp >= 0)
- */
- vn += vc;
- /*
- else
- vn -= vc;
- */
- }
-
- Vertices[iVertex].vNormal = Normalize(vn);
-
- return TRUE;
- }
- #endif
-
- BOOL bIsVertexSelected(int iVertex)
- {
- return
- Vertices[iVertex].bEnabled && Vertices[iVertex].bSelected;
- }
-
- //************************************** L A M P E S *************************
- int iFindLamp(D3DVECTOR p, int iPrevious)
- {
- int iCnt;
- float fTolerance = (float) fabs(fXmax - fXmin) / XDC_ZONE;
-
- // Rechercher la lampe
- for (iCnt = max(iPrevious + 1, 0) ;
- (iCnt <= iLampLastUsed)
- && (!( (Lampes[iCnt].bEnabled == TRUE)
- && (fabs(Lampes[iCnt].lLamp.dvPosition.x - p.x) < fTolerance)
- && (fabs(Lampes[iCnt].lLamp.dvPosition.y - p.y) < fTolerance)
- && (fabs(Lampes[iCnt].lLamp.dvPosition.z - p.z) < fTolerance)
- ))
- ;
- iCnt++) ;
-
- // Si point trouvé alors renvoyer son indice
- if (iCnt <= iLampLastUsed)
- return(iCnt);
-
- // Sinon renvoyer -1
- return -1;
- }
-
- int iMakeLamp(
- D3DLIGHTTYPE dltType, /* Type of light source */
- D3DCOLORVALUE dcvDiffuse, /* Diffuse color of light */
- D3DCOLORVALUE dcvSpecular, /* Specular color of light */
- D3DCOLORVALUE dcvAmbient, /* Ambient color of light */
- D3DVECTOR dvPosition, /* Position in world space */
- D3DVECTOR dvDirection, /* Direction in world space */
- D3DVALUE dvRange, /* Cutoff range */
- D3DVALUE dvFalloff, /* Falloff */
- D3DVALUE dvAttenuation0, /* Constant attenuation */
- D3DVALUE dvAttenuation1, /* Linear attenuation */
- D3DVALUE dvAttenuation2, /* Quadratic attenuation */
- D3DVALUE dvTheta, /* Inner angle of spotlight cone */
- D3DVALUE dvPhi /* Outer angle of spotlight cone */
- )
- {
- int iCnt;
-
- // Rechercher le premier index libre
- for (iCnt = iLampFirstAvailable ;
- (iCnt <= iLampLastUsed)
- && (Lampes[iCnt].bEnabled == TRUE) ;
- iCnt++) ;
-
- // Si limite tableau atteinte alors renvoyer erreur
- if (iCnt >= XDC_NUMLAMP)
- {
- vTrace("*** E0017 : Plus de slots vertex libres");
- return -1;
- }
-
- // Créer une nouvelle lampe
- ZeroMemory(&Lampes[iCnt].lLamp, sizeof(D3DLIGHT7));
- Lampes[iCnt].bEnabled = TRUE;
- Lampes[iCnt].bSelected = FALSE;
- Lampes[iCnt].bLit = TRUE;
- Lampes[iCnt].lLamp.dltType = dltType; // D3DLIGHT_POINT ou D3DLIGHT_DIRECTIONAL ou D3DLIGHT_SPOT
- Lampes[iCnt].lLamp.dcvDiffuse = dcvDiffuse;
- Lampes[iCnt].lLamp.dcvSpecular = dcvSpecular;
- Lampes[iCnt].lLamp.dcvAmbient = dcvAmbient;
- Lampes[iCnt].lLamp.dvPosition = dvPosition;
- Lampes[iCnt].lLamp.dvDirection = dvDirection;
- Lampes[iCnt].lLamp.dvRange = dvRange;
- Lampes[iCnt].lLamp.dvFalloff = dvFalloff;
- Lampes[iCnt].lLamp.dvAttenuation0 = dvAttenuation0;
- Lampes[iCnt].lLamp.dvAttenuation1 = dvAttenuation1;
- Lampes[iCnt].lLamp.dvAttenuation2 = dvAttenuation2;
- Lampes[iCnt].lLamp.dvTheta = dvTheta;
- Lampes[iCnt].lLamp.dvPhi = dvPhi;
-
- #ifndef NO3D
- lpd3dDevice->SetLight(iCnt, &Lampes[iCnt].lLamp);
- lpd3dDevice->LightEnable(iCnt, Lampes[iCnt].bLit);
- #endif
-
- while (Lampes[iLampFirstAvailable].bEnabled == TRUE) iLampFirstAvailable++;
- if (iLampLastUsed < iCnt) iLampLastUsed = iCnt;
-
- return iCnt;
- }
-
- BOOL bUpdateLamp(int iLamp)
- {
- // Si la lampe n'est pas enabled alors ne rien faire
- if (Lampes[iLamp].bEnabled == FALSE) return FALSE;
-
- #ifndef NO3D
- lpd3dDevice->SetLight(iLamp, &Lampes[iLamp].lLamp);
- lpd3dDevice->LightEnable(iLamp, Lampes[iLamp].bLit);
- #endif
-
- return TRUE;
- }
-
- BOOL bDeleteLamp(int iLamp)
- {
- // Si la lampe n'est pas enabled alors ne rien faire
- if (Lampes[iLamp].bEnabled == FALSE) return FALSE;
-
- // Disabler la lampe
- #ifndef NO3D
- lpd3dDevice->LightEnable(iLamp, FALSE);
- #endif
- Lampes[iLamp].bEnabled = FALSE;
- Lampes[iLamp].bLit = FALSE;
-
- // Mettre à jour les indices globaux du tableau des lampes
- if (iLamp == iLampLastUsed) while ((iLampLastUsed > -1) && (!Lampes[--iLampLastUsed].bEnabled)) ;
- if (iLamp < iLampFirstAvailable) iLampFirstAvailable = iLamp;
-
- return TRUE;
- }
-
- //************************************** E D G E S ***************************
- int iFindEdge(int i1, int i2)
- {
- int iCnt;
-
- for (iCnt = 0 ; iCnt <= iEdgeLastUsed ; iCnt++)
- if ( ((Edges[iCnt].iSommets[0] == i1) || (Edges[iCnt].iSommets[1] == i1))
- && ((Edges[iCnt].iSommets[0] == i2) || (Edges[iCnt].iSommets[1] == i2))
- )
- return iCnt;
-
- return -1;
- }
-
- int iMakeEdge(int i1, int i2)
- {
- int iCnt;
-
- // Rechercher un slot d'arête libre
- for (iCnt = iEdgeFirstAvailable ; (iCnt <= iEdgeLastUsed) && (Edges [iCnt].bEnabled == TRUE) ; iCnt++);
-
- // Si pas trouvé alors fail
- if (iCnt >= XDC_NUMEDGE)
- {
- vTrace("*** E0018 : Plus de slots arêtes libres");
- return -1;
- }
-
- // Créer l'arête
- Edges [iCnt].iSommets[0] = i1;
- Edges [iCnt].iSommets[1] = i2;
-
- Edges[iCnt].bEnabled = TRUE;
- Edges[iCnt].bHidden = FALSE;
-
- while (Edges[iEdgeFirstAvailable].bEnabled == TRUE) iEdgeFirstAvailable++;
- if (iEdgeLastUsed < iCnt) iEdgeLastUsed = iCnt;
-
- return iCnt;
- }
-
- BOOL bDeleteEdge(int iEdge)
- {
- // Si l'arête n'est pas enabled alors ne rien faire
- if (Edges[iEdge].bEnabled == FALSE) return FALSE;
-
- // Disabler l'arête
- Edges[iEdge].bEnabled = FALSE;
-
- // Mettre à jour les indices globaux du tableau des arêtes
- if (iEdge == iEdgeLastUsed) while ((iEdgeLastUsed > -1) && !(Edges[--iEdgeLastUsed].bEnabled)) ;
- if (iEdge < iEdgeFirstAvailable) iEdgeFirstAvailable = iEdge;
-
- return TRUE;
- }
-
- BOOL bIsEdgeSelected(int iEdge)
- {
- return
- Edges[iEdge].bEnabled &&
- bIsVertexSelected(Edges[iEdge].iSommets[0]) &&
- bIsVertexSelected(Edges[iEdge].iSommets[1]);
- }
-
- BOOL bIsEdgePartiallySelected(int iEdge)
- {
- return
- Edges[iEdge].bEnabled &&
- (bIsVertexSelected(Edges[iEdge].iSommets[0]) ||
- bIsVertexSelected(Edges[iEdge].iSommets[1]));
- }
-
- //************************************** T R I A N G L E S *******************
- int iFindTriangle(int i1, int i2, int i3)
- {
- int iCnt;
-
- for (iCnt = 0 ; iCnt <= iTriaLastUsed ; iCnt++)
- if ( ((Triangles[iCnt].iSommets[0] == i1) || (Triangles[iCnt].iSommets[1] == i1) || (Triangles[iCnt].iSommets[2] == i1))
- && ((Triangles[iCnt].iSommets[0] == i2) || (Triangles[iCnt].iSommets[1] == i2) || (Triangles[iCnt].iSommets[2] == i2))
- && ((Triangles[iCnt].iSommets[0] == i3) || (Triangles[iCnt].iSommets[1] == i3) || (Triangles[iCnt].iSommets[2] == i3))
- )
- return iCnt;
-
- return -1;
- }
-
- BOOL bSetUV(int iTriangle, int u0, int v0, int u1, int v1, int u2, int v2)
- {
- if (iTriangle > iTriaLastUsed) return FALSE;
- if (!Triangles[iTriangle].bEnabled) return FALSE;
-
- Triangles[iTriangle].u[0] = u0;
- Triangles[iTriangle].u[1] = u1;
- Triangles[iTriangle].u[2] = u2;
- Triangles[iTriangle].v[0] = v0;
- Triangles[iTriangle].v[1] = v1;
- Triangles[iTriangle].v[2] = v2;
-
- return TRUE;
- }
-
- int iMakeTriangle(int i1, int i2, int i3, int iMtrl)
- {
- int iCnt;
-
- // Rechercher un slot de triangle libre
- for (iCnt = iTriaFirstAvailable ; (iCnt <= iTriaLastUsed) && (Triangles [iCnt].bEnabled == TRUE) ; iCnt++);
-
- // Si pas trouvé alors fail
- if (iCnt >= XDC_NUMTRI)
- {
- vTrace("*** E0019 : Plus de slots triangles libres");
- return -1;
- }
-
- // Créer le triangle
- Triangles [iCnt].iSommets[0] = i1;
- Triangles [iCnt].iSommets[1] = i2;
- Triangles [iCnt].iSommets[2] = i3;
-
- // Incrémenter le compteur de triangles des sommets
- Vertices[Triangles [iCnt].iSommets[0]].iDepend++;
- Vertices[Triangles [iCnt].iSommets[1]].iDepend++;
- Vertices[Triangles [iCnt].iSommets[2]].iDepend++;
-
- // Affecter couleur et aspect
- Triangles[iCnt].iMtrl = iMtrl;
- Triangles[iCnt].bEnabled = TRUE;
- Triangles[iCnt].bHidden = FALSE;
-
- #ifndef _AMIGA_
- // Mettre à jour les coordonnées du triangle D3D correspondant
- bUpdateD3DTri(iCnt);
- #endif
-
- while (Triangles[iTriaFirstAvailable].bEnabled == TRUE) iTriaFirstAvailable++;
- if (iTriaLastUsed < iCnt) iTriaLastUsed = iCnt;
-
- return iCnt;
- }
-
- BOOL bDeleteTriangle(int iTriangle)
- {
- // Si le triangle n'est pas enabled alors ne rien faire
- if (Triangles[iTriangle].bEnabled == FALSE) return FALSE;
-
- // Disabler le triangle
- Triangles[iTriangle].bEnabled = FALSE;
-
- // Mettre à jour les indices globaux du tableau des triangles
- if (iTriangle == iTriaLastUsed) while ((iTriaLastUsed > -1) && (!Triangles[--iTriaLastUsed].bEnabled)) ;
- if (iTriangle < iTriaFirstAvailable) iTriaFirstAvailable = iTriangle;
-
- // Décrémenter le compteur de triangles des sommets
- Vertices[Triangles [iTriangle].iSommets[0]].iDepend--;
- Vertices[Triangles [iTriangle].iSommets[1]].iDepend--;
- Vertices[Triangles [iTriangle].iSommets[2]].iDepend--;
-
- return TRUE;
- }
-
- #ifndef _AMIGA_
- BOOL bUpdateD3DTri(int iCnt)
- {
- if (Triangles[iCnt].bEnabled == FALSE) return FALSE;
-
- short iS0 = Triangles [iCnt].iSommets[0],
- iS1 = Triangles [iCnt].iSommets[1],
- iS2 = Triangles [iCnt].iSommets[2];
-
- D3DVECTOR
- v01 = Vertices[iS1].vPoint - Vertices[iS0].vPoint,
- v02 = Vertices[iS2].vPoint - Vertices[iS0].vPoint,
- v12 = Vertices[iS2].vPoint - Vertices[iS1].vPoint,
- vn0, vn1, vn2,
- v1, v2, vp2, v3, v4;
-
- D3DMATRIX p;
-
- // Calculer la normale au point 0 : v3
- v1 = Normalize(v01);
- v2 = Normalize(v02);
- v3 = Normalize(CrossProduct(v01, v02));
-
- // On fait un repère orthonormal avec v3 et v1 (qui sont orthonormés) et leur produit vectoriel
- vp2 = Normalize(CrossProduct(v3, v1));
-
- // On fait la matrice de changement de repère
- D3DUtil_SetIdentityMatrix(p);
- p._11 = v1.x;
- p._21 = v1.y;
- p._31 = v1.z;
- p._12 = vp2.x;
- p._22 = vp2.y;
- p._32 = vp2.z;
- p._13 = v3.x;
- p._23 = v3.y;
- p._33 = v3.z;
-
- // on calcule l'image de z dans le nouveau repère : v4
- D3DMath_VectorMatrixMultiply(v4, D3DVECTOR(0.f, 0.f, 1.f), p);
-
- // On vérifie que v4 est dans le même sens que z, ce qui nous dit si le triangle est CW ou CCW
- float fSign = DotProduct(D3DVECTOR(0.f, 0.f, 1.f), v4);
-
- // On calcule les vecteurs normaux
- if (Vertices[iS0].bSmooth) { bSmoothNorm(iS0); vn0 = Vertices[iS0].vNormal; }
- else vn0 = Normalize(CrossProduct(v01, v02));
-
- if (Vertices[iS1].bSmooth) { bSmoothNorm(iS1); vn1 = Vertices[iS1].vNormal; }
- else vn1 = Normalize(CrossProduct(v01, v12));
-
- if (Vertices[iS2].bSmooth) { bSmoothNorm(iS2); vn2 = Vertices[iS2].vNormal; }
- else vn2 = Normalize(CrossProduct(v02, v12));
-
- // Créer les 2 triangles D3D (CW, CCW) en ordonnant les sommets pour avoir les CCW en 1er
- if (fSign >= 0)
- {
- Triangles [iCnt].pSommets[0] = D3DVERTEX(Vertices[iS0].vPoint, vn0, 0, 0);
- Triangles [iCnt].pSommets[1] = D3DVERTEX(Vertices[iS1].vPoint, vn1, 0, 0);
- Triangles [iCnt].pSommets[2] = D3DVERTEX(Vertices[iS2].vPoint, vn2, 0, 0);
- Triangles [iCnt].pSommets[3] = D3DVERTEX(Vertices[iS0].vPoint, -vn0, 0, 0);
- Triangles [iCnt].pSommets[4] = D3DVERTEX(Vertices[iS2].vPoint, -vn2, 0, 0);
- Triangles [iCnt].pSommets[5] = D3DVERTEX(Vertices[iS1].vPoint, -vn1, 0, 0);
- }
- else
- {
- Triangles [iCnt].pSommets[0] = D3DVERTEX(Vertices[iS0].vPoint, -vn0, 0, 0);
- Triangles [iCnt].pSommets[1] = D3DVERTEX(Vertices[iS2].vPoint, -vn2, 0, 0);
- Triangles [iCnt].pSommets[2] = D3DVERTEX(Vertices[iS1].vPoint, -vn1, 0, 0);
- Triangles [iCnt].pSommets[3] = D3DVERTEX(Vertices[iS0].vPoint, vn0, 0, 0);
- Triangles [iCnt].pSommets[4] = D3DVERTEX(Vertices[iS1].vPoint, vn1, 0, 0);
- Triangles [iCnt].pSommets[5] = D3DVERTEX(Vertices[iS2].vPoint, vn2, 0, 0);
- }
-
- return TRUE;
- }
- #endif
-
- BOOL bSubdivideTriangle(int iTriangle)
- {
- int iNewV[3], iNewT[4];
-
- if (Triangles[iTriangle].bEnabled == FALSE) return(FALSE);
-
- if (-1 == (iNewV[0] = iMakeVertex(
- (Vertices[Triangles[iTriangle].iSommets[0]].vPoint +
- Vertices[Triangles[iTriangle].iSommets[1]].vPoint
- ) / 2.f, XDC_ALLOWSAME))) return FALSE;
-
- if (-1 == (iNewV[1] = iMakeVertex(
- (Vertices[Triangles[iTriangle].iSommets[1]].vPoint +
- Vertices[Triangles[iTriangle].iSommets[2]].vPoint
- ) / 2.f, XDC_ALLOWSAME))) return FALSE;
-
- if (-1 == (iNewV[2] = iMakeVertex(
- (Vertices[Triangles[iTriangle].iSommets[2]].vPoint +
- Vertices[Triangles[iTriangle].iSommets[0]].vPoint
- ) / 2.f, XDC_ALLOWSAME))) return FALSE;
-
- if (-1 == (iNewT[0] = iMakeTriangle(iNewV[0], iNewV[1], iNewV[2], Triangles[iTriangle].iMtrl))) return FALSE;
- if (-1 == (iNewT[1] = iMakeTriangle(iNewV[0], iNewV[1], Triangles[iTriangle].iSommets[1], Triangles[iTriangle].iMtrl))) return FALSE;
- if (-1 == (iNewT[2] = iMakeTriangle(iNewV[1], iNewV[2], Triangles[iTriangle].iSommets[2], Triangles[iTriangle].iMtrl))) return FALSE;
- if (-1 == (iNewT[3] = iMakeTriangle(iNewV[0], iNewV[2], Triangles[iTriangle].iSommets[0], Triangles[iTriangle].iMtrl))) return FALSE;
-
- Vertices[iNewV[0]].bSelected =
- Vertices[iNewV[1]].bSelected =
- Vertices[iNewV[2]].bSelected = Vertices[Triangles[iTriangle].iSommets[0]].bSelected;
-
- return bDeleteTriangle(iTriangle);
- }
-
- BOOL bIsTriangleSelected(int iTriangle)
- {
- return
- Triangles[iTriangle].bEnabled &&
- bIsVertexSelected(Triangles[iTriangle].iSommets[0]) &&
- bIsVertexSelected(Triangles[iTriangle].iSommets[1]) &&
- bIsVertexSelected(Triangles[iTriangle].iSommets[2]);
- }
-
- BOOL bIsTrianglePartiallySelected(int iTriangle)
- {
- return
- Triangles[iTriangle].bEnabled &&
- (bIsVertexSelected(Triangles[iTriangle].iSommets[0]) ||
- bIsVertexSelected(Triangles[iTriangle].iSommets[1]) ||
- bIsVertexSelected(Triangles[iTriangle].iSommets[2]));
- }
-
- //********************************************** O U T I L S *************************
- // Propager de façon **non** récursive la dé/sélection d'un vertex aux vertices connexes (à travers edges ou triangles)
- void vPropagateSelection(void)
- {
- register BOOL bReste;
-
- bReste = TRUE;
- while (bReste)
- {
- bReste = FALSE;
-
- for (register int iEdge = 0 ; iEdge <= iEdgeLastUsed ; iEdge++)
- if (bIsEdgePartiallySelected(iEdge) && !bIsEdgeSelected(iEdge))
- bReste =
- Vertices[Edges[iEdge].iSommets[0]].bSelected =
- Vertices[Edges[iEdge].iSommets[1]].bSelected = TRUE;
- }
-
- bReste = TRUE;
- while (bReste)
- {
- bReste = FALSE;
-
- for (register int iTria = 0 ; iTria <= iTriaLastUsed ; iTria++)
- if (bIsTrianglePartiallySelected(iTria) && !bIsTriangleSelected(iTria))
- bReste =
- Vertices[Triangles[iTria].iSommets[0]].bSelected =
- Vertices[Triangles[iTria].iSommets[1]].bSelected =
- Vertices[Triangles[iTria].iSommets[2]].bSelected = TRUE;
- }
- }
-
- // Cloner la sélection
- BOOL bCloneSelection(D3DVECTOR vShift, BOOL bCloneMode)
- {
- int iCnt, jCnt, iNumSelected, *iIndex;
-
- // Compter les points sélectionnés
- iNumSelected = 0;
- for (iCnt = 0 ; iCnt <= iVertLastUsed ; iCnt++)
- if (bIsVertexSelected(iCnt)) iNumSelected++;
-
- if (!iNumSelected) return FALSE;
-
- // Allouer la table de correspondance ancien / nouvel index
- iIndex = (int *) malloc(iNumSelected * 2 * sizeof(int));
-
- // Cloner les points sélectionnés en conservant la table de correspondance ancien / nouveau
- // et en décalant les nouveaux de vShift
- jCnt = 0;
- for (iCnt = 0 ; iCnt <= iVertLastUsed ; iCnt++)
- {
- D3DVECTOR vVect = Vertices[iCnt].vPoint + vShift;
-
- if (!bIsVertexSelected(iCnt)) continue;
-
- // Remplir la table de correspondance ancien / nouveau
- iIndex[jCnt] = iCnt;
- iIndex[jCnt + 1] = iMakeVertex(vVect, XDC_FORCENEW);
- jCnt += 2;
- }
-
- // Cloner les arêtes éventuelles entre les anciens points
- for (iCnt = 0 ; iCnt <= iEdgeLastUsed ; iCnt++)
- {
- if (Edges[iCnt].bEnabled == FALSE) continue;
-
- int iOVert1 = Edges[iCnt].iSommets[0],
- iOVert2 = Edges[iCnt].iSommets[1],
- iCVert1 = -1,
- iCVert2 = -1;
-
- // Vérifier que les deux sommets originaux de l'arête sont sélectionnés
- if (bIsVertexSelected(iOVert1) && bIsVertexSelected(iOVert2))
- {
- // Alors il faut créer une nouvelle arête avec les sommets clonés
- for (jCnt = 0 ; jCnt < iNumSelected ; jCnt++)
- {
- if (iIndex[jCnt * 2] == iOVert1) iCVert1 = iIndex[jCnt * 2 + 1];
- if (iIndex[jCnt * 2] == iOVert2) iCVert2 = iIndex[jCnt * 2 + 1];
- }
- if ((iCVert1 != -1) && (iCVert2 != -1))
- {
- iMakeEdge(iCVert1, iCVert2);
-
- // Si le mode de clonage est avec extrusion, créer les triangles de l'élévation
- if (bCloneMode == XDC_MODE_EXTRUDE)
- {
- iMakeTriangle(iOVert1, iCVert1, iCVert2, 0);
- iMakeTriangle(iOVert1, iOVert2, iCVert2, 0);
- }
- }
- }
- }
-
- // Cloner les triangles éventuels entre les différents points
- for (iCnt = 0 ; iCnt <= iTriaLastUsed ; iCnt++)
- {
- if (Triangles[iCnt].bEnabled == FALSE) continue;
-
- int iOVert1 = Triangles[iCnt].iSommets[0],
- iOVert2 = Triangles[iCnt].iSommets[1],
- iOVert3 = Triangles[iCnt].iSommets[2],
- iCVert1 = -1,
- iCVert2 = -1,
- iCVert3 = -1;
-
- // Vérifier que les trois sommets originaux du triangle sont sélectionnés
- if (bIsVertexSelected(iOVert1) && bIsVertexSelected(iOVert2) && bIsVertexSelected(iOVert3))
- {
- // Alors il faut créer un nouveau triangle avec les sommets clonés
- for (jCnt = 0 ; jCnt < iNumSelected ; jCnt++)
- {
- if (iIndex[jCnt * 2] == iOVert1) iCVert1 = iIndex[jCnt * 2 + 1];
- if (iIndex[jCnt * 2] == iOVert2) iCVert2 = iIndex[jCnt * 2 + 1];
- if (iIndex[jCnt * 2] == iOVert3) iCVert3 = iIndex[jCnt * 2 + 1];
- }
- if ((iCVert1 != -1) && (iCVert2 != -1) && (iCVert3 != -1))
- {
- iMakeTriangle(iCVert1, iCVert2, iCVert3, Triangles[iCnt].iMtrl);
-
- // Si le mode de clonage est avec extrusion, créer les triangles de l'élévation
- if (bCloneMode == XDC_MODE_EXTRUDE)
- {
- iMakeTriangle(iOVert1, iCVert1, iCVert2, Triangles[iCnt].iMtrl);
- iMakeTriangle(iOVert1, iOVert2, iCVert2, Triangles[iCnt].iMtrl);
- iMakeTriangle(iOVert2, iCVert2, iCVert3, Triangles[iCnt].iMtrl);
- iMakeTriangle(iOVert2, iOVert3, iCVert3, Triangles[iCnt].iMtrl);
- iMakeTriangle(iOVert1, iCVert1, iCVert3, Triangles[iCnt].iMtrl);
- iMakeTriangle(iOVert1, iOVert3, iCVert3, Triangles[iCnt].iMtrl);
- }
- }
- }
- }
-
- // Inverser la sélection (sélectionner les nouveaux points)
- for (iCnt = 0 ; iCnt < iNumSelected ; iCnt++)
- {
- Vertices[iIndex[iCnt * 2 ]].bSelected = FALSE;
- Vertices[iIndex[iCnt * 2 + 1]].bSelected = TRUE;
- }
-
- // Libérer la table de correspondance
- free(iIndex);
-
- return TRUE;
- }
-
- // Cacher les éléments de la sélection
- void vHideSelection(void)
- {
- int iVert, iCnt;
-
- for (iVert = 0 ; iVert <= iVertLastUsed ; iVert++)
- {
- if (bIsVertexSelected(iVert))
- {
- Vertices[iVert].bHidden = TRUE;
- Vertices[iVert].bSelected = FALSE;
-
- for (iCnt = 0 ; iCnt <= iEdgeLastUsed ; iCnt++)
- {
- if (Edges[iCnt].bEnabled == FALSE) continue;
-
- if (bVertInEdge(iVert, iCnt))
- Edges[iCnt].bHidden = TRUE;
- }
- for (iCnt = 0 ; iCnt <= iTriaLastUsed ; iCnt++)
- {
- if (Triangles[iCnt].bEnabled == FALSE) continue;
-
- if (bVertInTriangle(iVert, iCnt))
- Triangles[iCnt].bHidden = TRUE;
- }
- }
- }
- }
-
- // Rendre visibles les éléments cachés
- void vRevealHidden(void)
- {
- int iCnt;
-
- for (iCnt = 0 ; iCnt <= iVertLastUsed ; iCnt++)
- {
- if (Vertices[iCnt].bEnabled == FALSE) continue;
-
- Vertices[iCnt].bHidden = FALSE;
- }
-
- for (iCnt = 0 ; iCnt <= iEdgeLastUsed ; iCnt++)
- {
- if (Edges[iCnt].bEnabled == FALSE) continue;
-
- Edges[iCnt].bHidden = FALSE;
- }
-
- for (iCnt = 0 ; iCnt <= iTriaLastUsed ; iCnt++)
- {
- if (Triangles[iCnt].bEnabled == FALSE) continue;
-
- Triangles[iCnt].bHidden = FALSE;
- }
- }
-
- // Déterminer le barycentre de la sélection
- D3DVECTOR vCenter(void)
- {
- D3DVECTOR dVect = D3DVECTOR(0.f, 0.f, 0.f);
- int jCnt = 0;
-
- for (int iVert = 0 ; iVert <= iVertLastUsed ; iVert++)
- if (bIsVertexSelected(iVert))
- {
- // Mémoriser les coordonnées avant modification
- Vertices[iVert].vPointBack = Vertices[iVert].vPoint;
-
- // Compter les points
- jCnt++;
-
- // Additionner les coordonnées du point à celles du barycentre
- dVect.x += Vertices[iVert].vPoint.x;
- dVect.y += Vertices[iVert].vPoint.y;
- dVect.z += Vertices[iVert].vPoint.z;
- }
-
- if (!jCnt)
- {
- vTrace("*** E0022 : Pas de sélection");
- return dVect;
- }
-
- // Moyenner la somme des points
- dVect.x /= jCnt;
- dVect.y /= jCnt;
- dVect.z /= jCnt;
-
- return dVect;
- }
-
- // Garbage collektor !-)
- void vCollect(void)
- {
- int iShift, iVert, iMtrl, *iMapTo;
-
- // Réindexer les arêtes
- iShift = 0;
-
- for (int iEdge = 0 ; iEdge <= iEdgeLastUsed ; iEdge++)
- {
- if (Edges[iEdge].bEnabled == FALSE)
- {
- while (Edges[iEdge + iShift].bEnabled == FALSE)
- {
- iShift++;
- iEdgeLastUsed--;
- }
- }
- if (iShift)
- {
- Edges[iEdge] = Edges[iEdge + iShift];
- Edges[iEdge + iShift].bEnabled = FALSE;
- }
- }
-
- iEdgeFirstAvailable = iEdgeLastUsed + 1;
-
- // Réindexer les triangles
- iShift = 0;
-
- for (int iTria = 0 ; iTria <= iTriaLastUsed ; iTria++)
- {
- if (Triangles[iTria].bEnabled == FALSE)
- {
- while (Triangles[iTria + iShift].bEnabled == FALSE)
- {
- iShift++;
- iTriaLastUsed--;
- }
- }
- if (iShift)
- {
- Triangles[iTria] = Triangles[iTria + iShift];
- Triangles[iTria + iShift].bEnabled = FALSE;
- }
- }
-
- iTriaFirstAvailable = iTriaLastUsed + 1;
-
- // Compter les sommets inutilisés pour ne faire la suite que s'il y en a
- iShift = 0;
-
- for (iVert = 0 ; iVert <= iVertLastUsed ; iVert++)
- if (Vertices[iVert].bEnabled == FALSE)
- iShift++;
-
- if (!iShift)
- goto _DoneVert;
-
- // Allouer la table de mapping
- if (!(iMapTo = (int *) malloc((iVertLastUsed + 1) * sizeof(int))))
- {
- vTrace("*** E0032 : erreur malloc table mapping GC");
- return;
- }
-
- // Préinitialiser la table de mapping
- for (iShift = 0 ; iShift <= iVertLastUsed ; iShift++)
- iMapTo[iShift] = iShift;
-
- // Réindexer les sommets
- iShift = 0;
-
- for (iVert = 0 ; iVert <= iVertLastUsed ; iVert++)
- {
- if (Vertices[iVert].bEnabled == FALSE)
- {
- while (Vertices[iVert + iShift].bEnabled == FALSE)
- {
- iShift++;
- iVertLastUsed--;
- }
- }
-
- if (iShift)
- {
- Vertices[iVert] = Vertices[iVert + iShift];
- Vertices[iVert + iShift].bEnabled = Vertices[iVert + iShift].bSelected = FALSE;
- iMapTo[iVert + iShift] = iVert;
- }
- }
-
- iVertFirstAvailable = iVertLastUsed + 1;
-
- // Réindexer les sommets dans les arêtes
- for(iShift = 0 ; iShift <= iEdgeLastUsed ; iShift++)
- {
- Edges[iShift].iSommets[0] = iMapTo[Edges[iShift].iSommets[0]];
- Edges[iShift].iSommets[1] = iMapTo[Edges[iShift].iSommets[1]];
- }
-
- // Réindexer les sommets dans les triangles
- for(iShift = 0 ; iShift <= iTriaLastUsed ; iShift++)
- {
- Triangles[iShift].iSommets[0] = iMapTo[Triangles[iShift].iSommets[0]];
- Triangles[iShift].iSommets[1] = iMapTo[Triangles[iShift].iSommets[1]];
- Triangles[iShift].iSommets[2] = iMapTo[Triangles[iShift].iSommets[2]];
- }
-
- // Libérer la table
- free(iMapTo);
-
- _DoneVert:
-
- // Compter les matériaux inutilisés pour ne faire la suite que s'il y en a
- iShift = 0;
-
- for (iMtrl = 0 ; iMtrl <= iMtrlLastUsed ; iMtrl++)
- if (Materials[iMtrl].bEnabled == FALSE)
- iShift++;
-
- if (!iShift)
- return;
-
- // Allouer la table de mapping
- if (!(iMapTo = (int *) malloc((iMtrlLastUsed + 1) * sizeof(int))))
- {
- vTrace("*** E0032 : erreur malloc table mapping GC");
- return;
- }
-
- // Préinitialiser la table de mapping
- for (iShift = 0 ; iShift <= iMtrlLastUsed ; iShift++)
- iMapTo[iShift] = iShift;
-
- // Réindexer les matériaux
- iShift = 0;
-
- for (iMtrl = 0 ; iMtrl <= iMtrlLastUsed ; iMtrl++)
- {
- if (Materials[iMtrl].bEnabled == FALSE)
- {
- while (Materials[iMtrl + iShift].bEnabled == FALSE)
- {
- iShift++;
- iMtrlLastUsed--;
- }
- }
-
- if (iShift)
- {
- Materials[iMtrl] = Materials[iMtrl + iShift];
- Materials[iMtrl + iShift].bEnabled = FALSE;
- iMapTo[iMtrl + iShift] = iMtrl;
- }
- }
-
- iMtrlFirstAvailable = iMtrlLastUsed + 1;
-
- // Réindexer les matériaux dans les triangles
- for(iShift = 0 ; iShift <= iTriaLastUsed ; iShift++)
- Triangles[iShift].iMtrl = iMapTo[Triangles[iShift].iMtrl];
-
- // Libérer la table
- free(iMapTo);
- }
-