reman3/Rayman_X/cpa/Appli/Max23Dos/src/Altimaps.c

936 lines
33 KiB
C

/*=========================================================================
*
* Altimap.h - Altimap functions
*
* Version 1.0
* Revision date
*
*=======================================================================*/
#include "Altimaps.h"
#include "sprobj.h"
#include "SpoSave.h"
//--------------------------------------------------------------------
/****************************************************************************
* Description: Test if an element is altimap or not
*
* Parameters: p_fX : elements to test
* p_iEqualX : returns the equal elements
* p_stGeometric : geometric object
* k : returns number of equal elements
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
BOOL MLT_bIsAltimap(float **p_fX, int **p_iEqualX, MLT_tdstGeometricObject *p_stGeometric, int *k)
{
int i=0;
BOOL bTrue;
float x1;
(*p_iEqualX)[0]=1;
*k=0;
// get the elements from the array with x coordinates which
// are closed till a limit fLimit with the first element of the sorted array
// continue with completing the arrays with equal elements
while (i<=p_stGeometric->xNbPoints)
{
x1=(*p_fX)[i];
// when all the values are equal, get that number
while ( (*p_fX)[i+1] == x1)
{
i++;
(*p_iEqualX)[*k]++;
}
i++;
(*k)++;
(*p_iEqualX)[(*k)]=1;
}
bTrue=TRUE;
//test if the number of equal elements is exactly the same for all the pars
for (i=0;i<*k-2; i++)
if ((*p_iEqualX)[i]!=(*p_iEqualX)[i+1])
bTrue = FALSE;
return bTrue;
}
/****************************************************************************
* Description: complete the structure of the altimap element
*
* Parameters: p_stGeometric : geometric object
* p_stAltimap : altimap element
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vCompleteAltimapStructure(MLT_tdstGeometricObject *p_stGeometric, MLT_tdstElementAltimap* p_stAltimap)
{
MLT_tdstElementIndexedTriangles *p_stGeom, *p_stGeomNext;
MLT_tdstTripledIndex *d_stVertexIndexes;
BOOL bIsAltimap, bIsFirstTriangle;
float *d_fX, *d_fY;
int m, i, k, j, l, iNew, iIndexSquare;
int *d_iInd, *d_iXIndex, *d_iXIndexFinal, *d_iEqualX;
int iLin, iCol;
int iFirst;
int iLast;
//allocate the intermediare vectors for vertexes
d_fX = (float *)malloc(p_stGeometric->xNbPoints*sizeof(float));
if (d_fX==NULL) //test if it could be allocated
{
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
return ;
}
d_fY = (float *)malloc(p_stGeometric->xNbPoints*sizeof(float));
//test if it could be allocated
if (d_fY==NULL)
{
free(d_fX);
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
return ;
}
p_stAltimap->d_stPointNormals = (MTH3D_tdstVector *)malloc(sizeof(MTH3D_tdstVector)*p_stGeometric->xNbPoints);
//test if it could be allocated
if (p_stAltimap->d_stPointNormals==NULL)
{
free(d_fX);
free(d_fY);
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
return ;
}
p_stAltimap->d_xHeight = (MTH_tdxReal *)malloc(sizeof(MTH_tdxReal)*p_stGeometric->xNbPoints);
//test if it could be allocated
if (p_stAltimap->d_xHeight==NULL)
{
free(d_fX);
free(d_fY);
free(p_stAltimap->d_stPointNormals);
free(p_stAltimap);
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
return ;
}
d_iXIndex = (int *)malloc(p_stGeometric->xNbPoints*sizeof(int));
//test if it could be allocated
if (d_iXIndex==NULL)
{
free(d_fX);
free(d_fY);
MLT_vFree(p_stAltimap);
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
return ;
}
//determine the number of faces and the number of UVs for the element altimap
p_stGeom = (MLT_tdstElementIndexedTriangles*)(p_stGeometric->d_stListOfElements[0]);
p_stAltimap->xNbElementUV=0;
p_stAltimap->xNbFaces = 0;
for(i=0; i<p_stGeometric->xNbElements; i++)
{ p_stGeom = (MLT_tdstElementIndexedTriangles*)(p_stGeometric->d_stListOfElements[i]);
//get the number of Faces and maximum number of elementUV for the altimap
p_stAltimap->xNbFaces += p_stGeom->xNbFaces;
p_stAltimap->xNbElementUV += p_stGeom->xNbElementUV;
}
d_stVertexIndexes = (MLT_tdstTripledIndex *)malloc((p_stAltimap->xNbFaces)*sizeof(MLT_tdstTripledIndex));
if (d_stVertexIndexes==NULL)//test if it could be allocated
{
free(d_fX);
free(d_fY);
MLT_vFree(p_stAltimap);
free(d_iXIndex);
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
return ;
}
//get the initial values for the X, Y coordinates, the height, and the normals in X, Y, Z
for (i=0; i< p_stGeometric->xNbPoints; i++)
{ d_fX[i] = p_stGeometric->d_stListOfPoints[i].xX;
d_fY[i] = p_stGeometric->d_stListOfPoints[i].xY;
p_stAltimap->d_xHeight[i] = p_stGeometric->d_stListOfPoints[i].xZ;
MTH3D_M_vSetVectorElements(&p_stAltimap->d_stPointNormals[i],
p_stGeometric->d_stListOfPointsNormals[i].xX,
p_stGeometric->d_stListOfPointsNormals[i].xY,
p_stGeometric->d_stListOfPointsNormals[i].xZ);
d_iXIndex[i] = i;
}
//get also the indexes of the vertexes which creates a face
k=0;
for(j=0; j<p_stGeometric->xNbElements; j++)
{ p_stGeom = (MLT_tdstElementIndexedTriangles*)(p_stGeometric->d_stListOfElements[j]);
for (i=0; i<p_stGeom->xNbFaces; i++)
{ d_stVertexIndexes[k+i].a3_xIndex[0] = p_stGeom->d_stListOfFacesTripled[i].a3_xIndex[0];
d_stVertexIndexes[k+i].a3_xIndex[1] = p_stGeom->d_stListOfFacesTripled[i].a3_xIndex[1];
d_stVertexIndexes[k+i].a3_xIndex[2] = p_stGeom->d_stListOfFacesTripled[i].a3_xIndex[2];
}
k += p_stGeom->xNbFaces;
}
//sort the array with x coordinates
MLT_vBubbleSort(&d_fX, &d_iXIndex, p_stGeometric->xNbPoints);
//update all the vectors (y, z and normalx, normaly, normalz vor the vertexes after the sorted x array
MLT_vExchange(&d_fY, d_iXIndex, p_stGeometric->xNbPoints);
MLT_vExchange(&p_stAltimap->d_xHeight, d_iXIndex, p_stGeometric->xNbPoints);
MLT_vExchangeNormals(&p_stAltimap->d_stPointNormals, d_iXIndex, p_stGeometric->xNbPoints);
MLT_vExchangeIndexes(&d_stVertexIndexes, d_iXIndex, p_stAltimap->xNbFaces, p_stGeometric->xNbPoints);
d_iEqualX= (int *)malloc(1000*sizeof(int));
if (d_iEqualX==NULL)//test if it could be allocated
{
MLT_vFreeAlloc(d_fX, d_fY, d_stVertexIndexes);
MLT_vFree(p_stAltimap);
free(d_iXIndex);
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
return ;
}
if (bIsAltimap=MLT_bIsAltimap(&d_fX, &d_iEqualX, p_stGeometric, &k)) //if the object is an altimap
{ for (i=0; i< p_stGeometric->xNbPoints; i++)
d_iXIndex[i] = i;
MLT_vBubbleSort(&d_fY, &d_iXIndex, p_stGeometric->xNbPoints); //sort the array with the y coordinates
//update all the vectors (x, z and normalx, normaly, normalz vor the vertexes after the sorted x array
MLT_vExchange(&d_fX, d_iXIndex, p_stGeometric->xNbPoints);
MLT_vExchange(&p_stAltimap->d_xHeight, d_iXIndex, p_stGeometric->xNbPoints);
MLT_vExchangeNormals(&p_stAltimap->d_stPointNormals, d_iXIndex, p_stGeometric->xNbPoints);
MLT_vExchangeIndexes(&d_stVertexIndexes, d_iXIndex, p_stAltimap->xNbFaces, p_stGeometric->xNbPoints);
iFirst = 0;
iLast = k-2;
//sort the array of X coordinates between the indexes: 0:k-2,k-1:...
for (i=0; i< p_stGeometric->xNbPoints; i++)
d_iXIndex[i] = i;
while (iLast<p_stGeometric->xNbPoints-1)
{
MLT_vFinalSort(&d_fX, &d_iXIndex, iFirst, iLast);
iFirst += k-1;
iLast += k-1;
}
MLT_vExchange(&d_fY, d_iXIndex, p_stGeometric->xNbPoints);
MLT_vExchange(&p_stAltimap->d_xHeight, d_iXIndex, p_stGeometric->xNbPoints);
MLT_vExchangeNormals(&p_stAltimap->d_stPointNormals, d_iXIndex, p_stGeometric->xNbPoints);
MLT_vExchangeIndexes(&d_stVertexIndexes, d_iXIndex, p_stAltimap->xNbFaces, p_stGeometric->xNbPoints);
}
free(d_iXIndex);
//if it was not an altimap return, after deallocated all
if (!bIsAltimap)
{
MLT_vFreeAlloc(d_fX, d_fY, d_stVertexIndexes);
if (d_iEqualX) free(d_iEqualX);
MLT_vFree(p_stAltimap);
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
return;
}
//set the components of the altimap
//set the origin
MTH3D_M_vSetVectorElements(&p_stAltimap->stOrigin, d_fX[0], d_fY[0], p_stAltimap->d_xHeight[0]);
//set the square pattern
p_stAltimap->xDeltaX = (d_fX[k-2]-d_fX[0])/(k-2);
p_stAltimap->xDeltaY = (d_fY[p_stGeometric->xNbPoints-k+1]-d_fY[0])/(d_iEqualX[0]-1); //d_fY[p_stGeometric->xNbPoints/d_iEqualX[0]]-d_fY[0];
p_stAltimap->xWidth = k-2;
p_stAltimap->xDepth = d_iEqualX[0]-1;
free(d_iEqualX);
//see if the values are good in a precision of fLimit=0.001
bIsAltimap=TRUE;
for (i=0; i<p_stGeometric->xNbPoints; i++)
{
//get the column and line for the index i
iCol = i % ( p_stAltimap->xWidth+1);
iLin = (i-iCol)/(p_stAltimap->xWidth+1);
//if the data is in the precision, arange the values, if not is not an altimap
if (fabs(d_fX[i]-d_fX[0]-iCol*p_stAltimap->xDeltaX)<=g_fLimit1)
d_fX[i] = d_fX[0]+iCol*p_stAltimap->xDeltaX;
else
bIsAltimap=FALSE;
if (fabs(d_fY[i]-d_fY[0]-iLin*p_stAltimap->xDeltaY)<=g_fLimit1)
d_fY[i] = d_fY[0]+iLin*p_stAltimap->xDeltaY;
else
bIsAltimap=FALSE;
}
//if it was not an altimap return, after deallocated all
if (!bIsAltimap)
{
MLT_vFreeAlloc(d_fX, d_fY, d_stVertexIndexes);
MLT_vFree(p_stAltimap);
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
return;
}
//set the number of squares and vertexes
p_stAltimap->xNbSquares = p_stAltimap->xWidth*p_stAltimap->xDepth; //k-2;
p_stAltimap->xNbVertexes = p_stGeometric->xNbPoints;
p_stAltimap->d_stSquare = (MLT_tdstAltimapSquare *)malloc(sizeof(MLT_tdstAltimapSquare)*p_stAltimap->xNbSquares);
//alloc all the structure needed by the altimap
//test if it could be allocated
if (p_stAltimap->d_stSquare==NULL)
{
MLT_vFree(p_stAltimap);
MLT_vFreeAlloc(d_fX, d_fY, d_stVertexIndexes);
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
return ;
}
p_stAltimap->d_stFaceNormals = (MTH3D_tdstVector *)malloc(sizeof(MTH3D_tdstVector)*p_stAltimap->xNbFaces);
//test if it could be allocated
if (p_stAltimap->d_stFaceNormals==NULL)
{
free(p_stAltimap->d_stSquare);
MLT_vFree(p_stAltimap);
MLT_vFreeAlloc(d_fX, d_fY, d_stVertexIndexes);
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
return ;
}
p_stAltimap->d_hFMD = (MLT_tdxHandleOfFMD *)malloc(sizeof(MLT_tdxHandleOfFMD)*p_stAltimap->xNbFaces);
//test if it could be allocated
if (p_stAltimap->d_hFMD==NULL)
{
free(p_stAltimap->d_stSquare);
free(p_stAltimap->d_stFaceNormals);
MLT_vFree(p_stAltimap);
MLT_vFreeAlloc(d_fX, d_fY, d_stVertexIndexes);
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
return ;
}
for (i=0; i<p_stAltimap->xNbFaces; i++)
{ p_stAltimap->d_hFMD[i] = (MLT_tdstHandleOfFMD *)malloc(sizeof(MLT_tdstHandleOfFMD));
if (p_stAltimap->d_hFMD[i]==NULL)//test if it could be allocated
{
free(p_stAltimap->d_stSquare);
free(p_stAltimap->d_stFaceNormals);
free(p_stAltimap->d_hFMD);
MLT_vFree(p_stAltimap);
MLT_vFreeAlloc(d_fX, d_fY, d_stVertexIndexes);
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
return ;
}
}
p_stAltimap->d_stUVValues = (ACP_tdst2DUVValues *)malloc(sizeof(ACP_tdst2DUVValues)*p_stAltimap->xNbElementUV);
if (p_stAltimap->d_stUVValues==NULL)//test if it could be allocated
{
free(p_stAltimap->d_stSquare);
free(p_stAltimap->d_stFaceNormals);
for (i=0; i<p_stAltimap->xNbFaces; i++)
free(p_stAltimap->d_hFMD[i]);
free(p_stAltimap->d_hFMD);
MLT_vFree(p_stAltimap);
MLT_vFreeAlloc(d_fX, d_fY, d_stVertexIndexes);
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
return ;
}
//set the types, number of faces and the index of the first triangle for every square
for (i=0;i<p_stAltimap->xNbSquares;i++)
{ p_stAltimap->d_stSquare[i].ucType = 0;
p_stAltimap->d_stSquare[i].sNbFacesForSquare = 0;
p_stAltimap->d_stSquare[i].xFaceIndex = -1;
}
d_iXIndex = (int *)malloc(2*p_stAltimap->xNbSquares*sizeof(int));
if (d_iXIndex==NULL)
{
MLT_vFreeAltimap(p_stAltimap);
MLT_vFreeAlloc(d_fX, d_fY, d_stVertexIndexes);
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
return ;
}
d_iXIndexFinal = (int *)malloc(p_stAltimap->xNbFaces*sizeof(int));
//test if it could be allocated
if (d_iXIndexFinal==NULL)
{
MLT_vFreeAltimap(p_stAltimap);
MLT_vFreeAlloc(d_fX, d_fY, d_stVertexIndexes);
free(d_iXIndex);
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
return ;
}
for (i=0; i<2*p_stAltimap->xNbSquares; i++)
d_iXIndex[i]=-1;
//for every square get the indexes for the triangles associated with a square
for (i=0; i<p_stAltimap->xNbFaces; i++)
{ iIndexSquare = MLT_iIndexSquare(&d_stVertexIndexes[i], p_stAltimap, &bIsFirstTriangle);
if (iIndexSquare==-1)
{
if (d_iXIndex) free(d_iXIndex);
if (d_iXIndexFinal) free(d_iXIndexFinal);
MLT_vFreeAlloc(d_fX, d_fY, d_stVertexIndexes);
MLT_vFreeAltimap(p_stAltimap);
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
return;
}
if (d_iXIndex[2*iIndexSquare] == -1)
d_iXIndex[2*iIndexSquare] = i;
else
if (bIsFirstTriangle)
{ d_iXIndex[2*iIndexSquare+1] = d_iXIndex[2*iIndexSquare];
d_iXIndex[2*iIndexSquare] = i;
}
else
d_iXIndex[2*iIndexSquare+1] = i;
}
j=0;
for (i=0; i<2*p_stAltimap->xNbSquares; i++)
{ if (d_iXIndex[i] != -1)
{ d_iXIndexFinal[j] = d_iXIndex[i];
j++;
}
}
free(d_iXIndex);
//get the UVs for the altimap element
p_stGeom=(MLT_tdstElementIndexedTriangles*)(p_stGeometric->d_stListOfElements[0]);
for (i=0; i<p_stGeom->xNbElementUV; i++)
{ p_stAltimap->d_stUVValues[i].xU = p_stGeom->d_stListOfElementUV[i].xU;
p_stAltimap->d_stUVValues[i].xV = p_stGeom->d_stListOfElementUV[i].xV;
}
p_stAltimap->xNbElementUV = p_stGeom->xNbElementUV;
//get also the material for a face
for (i=0; i<p_stAltimap->xNbFaces; i++)
if (d_iXIndexFinal[i] < p_stGeom->xNbFaces)
strcpy(p_stAltimap->d_hFMD[i]->sMaterial, p_stGeom->sMaterial);
//for every element indexed triangle, of the geometric object
for (l=1; l<p_stGeometric->xNbElements; l++)
{ p_stGeomNext=(MLT_tdstElementIndexedTriangles*)(p_stGeometric->d_stListOfElements[l]);
j=p_stGeom->xNbFaces;
m=p_stGeom->xNbElementUV;
p_stGeom->d_stListOfFacesNormals=(MTH3D_tdstVector *)realloc(p_stGeom->d_stListOfFacesNormals,
(p_stGeomNext->xNbFaces+j)*sizeof(MTH3D_tdstVector));
p_stGeom->d_stListOfElementUV=(ACP_tdst2DUVValues *)realloc(p_stGeom->d_stListOfElementUV,
(p_stGeomNext->xNbElementUV+m)*sizeof(ACP_tdst2DUVValues));
p_stGeom->d_stListOfFacesTripledIndexUV=(MLT_tdstTripledIndex *)realloc(p_stGeom->d_stListOfFacesTripledIndexUV,
(p_stGeomNext->xNbFaces+j)*sizeof(MLT_tdstTripledIndex));
for (i=0; i<p_stGeomNext->xNbFaces; i++)
{ //set the normals
MTH3D_M_vSetVectorElements(&p_stGeom->d_stListOfFacesNormals[i+j], p_stGeomNext->d_stListOfFacesNormals[i].xX, p_stGeomNext->d_stListOfFacesNormals[i].xY, p_stGeomNext->d_stListOfFacesNormals[i].xZ);
for (k=0; k<3; k++)
//add or not the new UV at the list of UVs for the indexed triangle which will contain a concatanation of indexed traingles
//and set also the list with tripled indexes for them
if(!MLT_bExist(p_stAltimap->d_stUVValues, p_stGeomNext->d_stListOfElementUV[p_stGeomNext->d_stListOfFacesTripledIndexUV[i].a3_xIndex[k]], &iNew, p_stAltimap->xNbElementUV))
{ p_stGeom->d_stListOfFacesTripledIndexUV[i+j].a3_xIndex[k] = m;
p_stAltimap->xNbElementUV++;
p_stGeom->d_stListOfElementUV[m].xU=p_stGeomNext->d_stListOfElementUV[p_stGeomNext->d_stListOfFacesTripledIndexUV[i].a3_xIndex[k]].xU;
p_stGeom->d_stListOfElementUV[m].xV=p_stGeomNext->d_stListOfElementUV[p_stGeomNext->d_stListOfFacesTripledIndexUV[i].a3_xIndex[k]].xV;
p_stAltimap->d_stUVValues[m].xU=p_stGeomNext->d_stListOfElementUV[p_stGeomNext->d_stListOfFacesTripledIndexUV[i].a3_xIndex[k]].xU;
p_stAltimap->d_stUVValues[m].xV=p_stGeomNext->d_stListOfElementUV[p_stGeomNext->d_stListOfFacesTripledIndexUV[i].a3_xIndex[k]].xV;
m++;
}
else
p_stGeom->d_stListOfFacesTripledIndexUV[i+j].a3_xIndex[k] = iNew;
}
p_stGeom->xNbFaces += p_stGeomNext->xNbFaces;
p_stGeom->xNbElementUV = m;
//set the materials for the faces which are own by the processed element indexed triangle
for (k=0; k<p_stAltimap->xNbFaces; k++)
if ((d_iXIndexFinal[k] < p_stGeomNext->xNbFaces+j) &&(d_iXIndexFinal[k] >= j))
strcpy(p_stAltimap->d_hFMD[k]->sMaterial, p_stGeomNext->sMaterial);
}
d_iInd = (int *)malloc(3*sizeof(int));
//test if it could be allocated
if (d_iInd==NULL)
{
MLT_vFreeAltimap(p_stAltimap);
MLT_vFreeAlloc(d_fX, d_fY, d_stVertexIndexes);
free(d_iXIndexFinal);
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
return ;
}
for (i=0; i<p_stAltimap->xNbFaces; i++)
{
//get the normals to the faces for tthe altimap element
MTH3D_M_vSetVectorElements(&p_stAltimap->d_stFaceNormals[i],
p_stGeom->d_stListOfFacesNormals[d_iXIndexFinal[i]].xX,
p_stGeom->d_stListOfFacesNormals[d_iXIndexFinal[i]].xY,
p_stGeom->d_stListOfFacesNormals[d_iXIndexFinal[i]].xZ);
MLT_vSortIndex(&d_stVertexIndexes[d_iXIndexFinal[i]], p_stAltimap,/* d_fX, d_fY,*/ &d_iInd);
//and the UVs
for (j=0; j<3; j++)
p_stAltimap->d_hFMD[i]->stTrianglesIndexUVValues.a3_xIndex[j]=
p_stGeom->d_stListOfFacesTripledIndexUV[d_iXIndexFinal[i]].a3_xIndex[d_iInd[j]];
}
//set also the index to start for every square, for every triangle
if (p_stAltimap->d_stSquare[0].sNbFacesForSquare)
p_stAltimap->d_stSquare[0].xFaceIndex = 0;
for (i=1; i<p_stAltimap->xNbSquares; i++)
p_stAltimap->d_stSquare[i].xFaceIndex += p_stAltimap->d_stSquare[i-1].xFaceIndex + p_stAltimap->d_stSquare[i-1].sNbFacesForSquare+1;
//deallocate all it used
free(d_stVertexIndexes);
free(d_iXIndexFinal);
free(d_iInd);
free(d_fX);
free(d_fY);
}
/****************************************************************************
* Description: free some parts of the altimap
*
* Parameters: p_stAltimap : altimap element
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vFreeAltimap(MLT_tdstElementAltimap* p_stAltimap)
{
int i;
free(p_stAltimap->d_stFaceNormals);
free(p_stAltimap->d_stSquare);
for (i=0; i<p_stAltimap->xNbFaces; i++)
free(p_stAltimap->d_hFMD[i]);
free(p_stAltimap->d_hFMD);
free(p_stAltimap->d_stUVValues);
MLT_vFree(p_stAltimap);
}
/****************************************************************************
* Description: free the altimap
*
* Parameters: p_stAltimap : altimap element
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vFree(MLT_tdstElementAltimap* p_stAltimap)
{
free(p_stAltimap->d_xHeight);
free(p_stAltimap->d_stPointNormals);
free(p_stAltimap);
}
/****************************************************************************
* Description: free some allocated structures
*
* Parameters: d_fX : array of x coordinates
* d_fY : array of y coordinates
* d_stVertexIndexes : array of indexes
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vFreeAlloc(float *d_fX, float *d_fY, MLT_tdstTripledIndex *d_stVertexIndexes)
{
free(d_fX);
free(d_fY);
free(d_stVertexIndexes);
}
/****************************************************************************
* Description: sort an array using the bubble sort method
*
* Parameters: p_fX : array of cooridnates to sort
* p_iXIndex : array of indexes
* lNbPoints : nb of points in the array
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vBubbleSort (float **p_fX, int **p_iXIndex, long lNbPoints)
{
BOOL bSwapped;
float fTemp;
int i, iTemp;
// sort the array using the bubble sort method,
// and also update the p_iXIndex array using the same method
// in p_iXIndex are the indices for the modified array
do
{
bSwapped=FALSE;
for(i = 0; i < lNbPoints-1; i++)
{
if ((*p_fX)[i+1]<(*p_fX)[i])
{ if (fabs((*p_fX)[i+1]-(*p_fX)[i])<=g_fLimit1)
(*p_fX)[i+1] = (*p_fX)[i];
else
{ // perform the swap
fTemp=(*p_fX)[i];
(*p_fX)[i]=(*p_fX)[i+1];
//change the values of array to sort
(*p_fX)[i+1]=fTemp;
iTemp=(*p_iXIndex)[i];
(*p_iXIndex)[i]=(*p_iXIndex)[i+1];
//change the ordered array
(*p_iXIndex)[i+1]=iTemp;
//according to the array to sort, for saving the indexes
bSwapped = TRUE;
}
}
else
{ if (fabs((*p_fX)[i+1]-(*p_fX)[i])<=g_fLimit1)
(*p_fX)[i+1] = (*p_fX)[i];
}
}
} while (bSwapped);
}
/****************************************************************************
* Description: sort an array using the bubble sort method
*
* Parameters: p_fX : array of cooridnates to sort
* p_iXIndex : array of indexes
* iFirst : first index
* iLast : last index
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vFinalSort(float **p_fX, int **p_iXIndex, int iFirst, int iLast)
{
BOOL bSwapped;
float fTemp;
int i, iTemp;
do
{
bSwapped=FALSE;
for(i = iFirst; i < iLast-1; i++)
{
if ((*p_fX)[i+1]<(*p_fX)[i])
{ // perform the swap
fTemp=(*p_fX)[i];
(*p_fX)[i]=(*p_fX)[i+1];
//change the values of array to sort
(*p_fX)[i+1]=fTemp;
iTemp=(*p_iXIndex)[i];
(*p_iXIndex)[i]=(*p_iXIndex)[i+1];
//change the ordered array
(*p_iXIndex)[i+1]=iTemp;
//according to the array to sort, for saving the indexes
bSwapped = TRUE;
}
}
} while (bSwapped);
}
/****************************************************************************
* Description: Sort the arrays with indexes of columns and lines
*
* Parameters: p_stListOfFaces : list of faces
* p_stAltimap : altimap element
* p_iInd : array of indexes
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vSortIndex(MLT_tdstTripledIndex *p_stListOfFaces, MLT_tdstElementAltimap* p_stAltimap, int **p_iInd)
{
int i, *d_iCol, *d_iLin;
d_iCol = (int *)malloc(sizeof(int)*3);
d_iLin = (int *)malloc(sizeof(int)*3);
for (i=0; i<3; i++)
{
(*p_iInd)[i] = i;
//get the column and the line of every triangle
d_iCol[i] = p_stListOfFaces->a3_xIndex[i] % (p_stAltimap->xWidth+1);
d_iLin[i] = (p_stListOfFaces->a3_xIndex[i] -d_iCol[i]) / (p_stAltimap->xWidth+1);
}
MLT_vOrder(&d_iCol, p_iInd);
MLT_vArrangeArray(&d_iLin, *p_iInd);
MLT_vOrder(&d_iLin, p_iInd);
free(d_iCol);
free(d_iLin);
}
/****************************************************************************
* Description: Change an array according with an array of indexes
*
* Parameters: p_fX : array to change
* p_iXIndex : array of indexes
* lNbPoints : nb of points
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vExchange(float **p_fX, int *p_iXIndex, long lNbPoints)
{
int i;
float *d_fTemp;
d_fTemp = (float *)malloc(lNbPoints*sizeof(float));
//set the x, y, and z arrays with coordinates after the positions from the p_iXIndex array
for (i=0; i<lNbPoints; i++)
d_fTemp[i] = (*p_fX)[p_iXIndex[i]];
for (i=0; i<lNbPoints; i++)
(*p_fX)[i] = d_fTemp[i];
free(d_fTemp);
}
/****************************************************************************
* Description: Change the Tripled Indexes according with an given index
*
* Parameters: p_fX : array to change
* p_iXIndex : array of indexes
* lNbPoints : nb of points
* lGeomPoints : nb of points in geometry
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vExchangeIndexes(MLT_tdstTripledIndex **p_fX, int *p_iXIndex, long lNbPoints, long lGeomPoints)
{
int i=0;
MLT_tdstTripledIndex *d_stTemp;
d_stTemp = (MLT_tdstTripledIndex *)malloc(lNbPoints*sizeof(MLT_tdstTripledIndex));
//set the tripled indexes according to the indexes
for (i=0; i<lNbPoints; i++)
{
d_stTemp[i].a3_xIndex[0] = MLT_iGetIndex(p_iXIndex, (*p_fX)[i].a3_xIndex[0],lGeomPoints);
d_stTemp[i].a3_xIndex[1] = MLT_iGetIndex(p_iXIndex, (*p_fX)[i].a3_xIndex[1],lGeomPoints);
d_stTemp[i].a3_xIndex[2] = MLT_iGetIndex(p_iXIndex, (*p_fX)[i].a3_xIndex[2],lGeomPoints);
}
for (i=0; i<lNbPoints; i++)
{ (*p_fX)[i].a3_xIndex[0] = d_stTemp[i].a3_xIndex[0];
(*p_fX)[i].a3_xIndex[1] = d_stTemp[i].a3_xIndex[1];
(*p_fX)[i].a3_xIndex[2] = d_stTemp[i].a3_xIndex[2];
}
free(d_stTemp);
}
/****************************************************************************
* Description: Change the normals according with an given index
*
* Parameters: p_fX : array to change
* p_iXIndex : array of indexes
* lNbPoints : nb of points
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vExchangeNormals(MTH3D_tdstVector **p_fX, int *p_iXIndex, long lNbPoints)
{
int i;
MTH3D_tdstVector *d_stTemp;
d_stTemp = (MTH3D_tdstVector *)malloc(lNbPoints*sizeof(MTH3D_tdstVector));
//set the x, y, and z arrays with coordinates after the positions from the p_iXIndex array
for (i=0; i<lNbPoints; i++)
MTH3D_M_vSetVectorElements(&d_stTemp[i],
(*p_fX)[p_iXIndex[i]].xX,
(*p_fX)[p_iXIndex[i]].xY,
(*p_fX)[p_iXIndex[i]].xZ);
for (i=0; i<lNbPoints; i++)
MTH3D_M_vSetVectorElements(&(*p_fX)[i],
d_stTemp[i].xX,
d_stTemp[i].xY,
d_stTemp[i].xZ);
free(d_stTemp);
}
/****************************************************************************
* Description: order an array according with a given index
*
* Parameters: p_iValues : array to order
* p_iInd : array of indexes
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vOrder (int **p_iValues, int ** p_iInd)
{
BOOL bSwapped;
int i, iTemp;
do
{
bSwapped=FALSE;
for(i = 0; i < 2; i++)
{
//arrange an array with integers
if ((*p_iValues)[i+1] < (*p_iValues)[i])
{
iTemp=(*p_iValues)[i];
(*p_iValues)[i]=(*p_iValues)[i+1];
(*p_iValues)[i+1]=iTemp;
//arrange the array with indexes for showing how the first array is update
iTemp=(*p_iInd)[i];
(*p_iInd)[i]=(*p_iInd)[i+1];
(*p_iInd)[i+1]=iTemp;
bSwapped = TRUE;
}
}
} while (bSwapped);
}
/****************************************************************************
* Description: Arrange an array with integers after an array with indexes
*
* Parameters: p_iCol : array to order
* p_iInd : array of indexes
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vArrangeArray(int **p_iCol, int *p_iInd)
{
int i, iTemp[3];
for (i=0; i<3; i++)
iTemp[i] = (*p_iCol)[p_iInd[i]];
for (i=0; i<3; i++)
(*p_iCol)[i] = iTemp[i];
}
/****************************************************************************
* Description: Get the minumum value from an array
*
* Parameters: p_iValues : array to search
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
int MLT_iMin (int *p_iValues)
{
int i, iMin=p_iValues[0];
//get the minimum value of an array
for (i=1; i<3; i++)
if (p_iValues[i]<iMin)
iMin=p_iValues[i];
return iMin;
}
/****************************************************************************
* Description: Get the index of value in an array
*
* Parameters: p_iXIndex : array to search
* iValue : value to search for
* lNbPoints : number of points
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
int MLT_iGetIndex (int *p_iXIndex, int iValue, long lNbPoints)
{
int i;
for (i=0; i<lNbPoints;i++)
{
//return the index of the element which have a value equal to the searched one
if (p_iXIndex[i]==iValue)
return i;
}
return -1;
}
/****************************************************************************
* Description: Get the index of a square which contains the triangle
*
* Parameters: p_stListOfFaces : list of faces
* p_stAltimap : altimap element
* bIsFirst : flag for the search
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
int MLT_iIndexSquare(MLT_tdstTripledIndex *p_stListOfFaces, MLT_tdstElementAltimap* p_stAltimap, BOOL *bIsFirst)
{
int i, *d_iCol, *d_iLin, *d_iInd;
d_iCol = (int *)malloc(sizeof(int)*3);
d_iLin = (int *)malloc(sizeof(int)*3);
d_iInd = (int *)malloc(sizeof(int)*3);
//get the indexes of the columns and lines for the three points which forms a triangle
for (i=0; i<3; i++)
{ d_iInd[i] = i;
d_iCol[i] = p_stListOfFaces->a3_xIndex[i] % (p_stAltimap->xWidth+1);
d_iLin[i] = (p_stListOfFaces->a3_xIndex[i] -d_iCol[i]) / (p_stAltimap->xWidth+1);
}
//get the sorted array with the column indexes
MLT_vOrder(&d_iCol, &d_iInd);
MLT_vArrangeArray(&d_iLin, d_iInd);
for (i=0; i<3; i++)
d_iInd[i] = i;
MLT_vOrder(&d_iLin, &d_iInd);
MLT_vArrangeArray(&d_iCol, d_iInd);
//determine the index of the square
if (((d_iCol[0]==d_iCol[1]) || (d_iCol[2]==d_iCol[1]) || (d_iCol[0]==d_iCol[2]))&&
((d_iLin[0]==d_iLin[1]) || (d_iLin[2]==d_iLin[1]) || (d_iLin[0]==d_iLin[2])))
i=MLT_iMin(d_iLin)*p_stAltimap->xWidth + MLT_iMin(d_iCol);
else return i=-1;
//determine also the type of the square (how many triangles are in it, and how are they located in the square)
if ((d_iCol[0]==d_iCol[2])&&(d_iCol[0]==d_iCol[1]+1))
{ if (!p_stAltimap->d_stSquare[i].ucType || (p_stAltimap->d_stSquare[i].ucType==2))
p_stAltimap->d_stSquare[i].ucType += 1;
else return i=-1;
*bIsFirst = TRUE;
p_stAltimap->d_stSquare[i].sNbFacesForSquare++;
}
if ((d_iCol[0]==d_iCol[2]) && (d_iCol[0]==d_iCol[1]-1))
{ if (!p_stAltimap->d_stSquare[i].ucType || (p_stAltimap->d_stSquare[i].ucType==1))
p_stAltimap->d_stSquare[i].ucType+=2;
else return i=-1;
*bIsFirst = FALSE; //it is not the first triangle (with index 0)
p_stAltimap->d_stSquare[i].sNbFacesForSquare++;
}
if ((d_iCol[0]==d_iCol[1])&&(d_iCol[0]==d_iCol[2]-1))
{ if (!p_stAltimap->d_stSquare[i].ucType || (p_stAltimap->d_stSquare[i].ucType==8))
p_stAltimap->d_stSquare[i].ucType+=4;
else return i=-1;
*bIsFirst = TRUE;
p_stAltimap->d_stSquare[i].sNbFacesForSquare++;
}
if ((d_iCol[0]==d_iCol[1]-1) && (d_iCol[1]==d_iCol[2]))
{ if (!p_stAltimap->d_stSquare[i].ucType || (p_stAltimap->d_stSquare[i].ucType==4))
p_stAltimap->d_stSquare[i].ucType+=8;
else return i=-1;
*bIsFirst = FALSE;//it is not the first triangle (with index 0)
p_stAltimap->d_stSquare[i].sNbFacesForSquare++;
}
free(d_iCol);
free(d_iLin);
free(d_iInd);
return i;
}
/****************************************************************************
* Description: Test if an UV exist in the array of UVs
*
* Parameters: p_stUV : array to search
* stUVi : value to search for
* iNew : returns the index of the found element
* lNumber : rnb of elements
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
BOOL MLT_bExist (ACP_tdst2DUVValues *p_stUV, ACP_tdst2DUVValues stUVi, int *iNew, long lNumber)
{
int i;
for (i=0; i<lNumber; i++)
{
//if it exist return the index of it
if ((stUVi.xU == p_stUV[i].xU)&&(stUVi.xV == p_stUV[i].xV))
{ *iNew = i;
return TRUE;
}
}
return FALSE;
}