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

611 lines
27 KiB
C

/*=========================================================================
*
* Normals.c - normal functions
*
* Version 1.0
* Revision date
*
*=======================================================================*/
#include "Normals.h"
#include "defines.h"
#include "ModLib.h"
#include "Borders.h"
//--- Global statics --------------------------------------------------------
double gs_fLim=0.01;
//--------------------------------------------------------------------
/****************************************************************************
* Description: compute all the normals for all the points of the geometric objects
*
* Parameters:
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_xComputeAllNormals ( )
{
int i, j, k, l, iCurrent=0, m=0, xIndex, n=0, p=0, n1, n3;
MTH3D_tdstVector stNormalResult, *p_stVertex, *p_stLastVertex;
MLT_tdstElementIndexedTriangles *p_stLocalElement;
MLT_tdstElementFaceMapDescriptors *p_stLocalElementFMD;
// compute minmax points for each object
for (i=0; i<g_lGeometricIndex; i++) // for all the objects
{
MTH3D_M_vSetVectorElements(&g_hGeometricInFile[i]->stMinPoint, MTH_C_InfinitPlus, MTH_C_InfinitPlus, MTH_C_InfinitPlus);
MTH3D_M_vSetVectorElements(&g_hGeometricInFile[i]->stMaxPoint, MTH_C_InfinitMinus, MTH_C_InfinitMinus, MTH_C_InfinitMinus);
MLT_vComputeMinMaxPointWithMatrix(g_hGeometricInFile[i], &g_hGeometricInFile[i]->stMinPoint, &g_hGeometricInFile[i]->stMaxPoint, g_hGeometricInFile[i]->p_stMatrix);
}
//compute the face normals for all the objects
for (i=0; i<g_lGeometricIndex; i++)
{
// for all the elements
for (xIndex=0; xIndex<g_hGeometricInFile[i]->xNbElements; xIndex++)
{
// indexed triangle
if ( g_hGeometricInFile[i]->d_xListOfElementsTypes[xIndex] == MLT_C_xElementIndexedTriangles )
{
p_stLocalElement = ((MLT_tdstElementIndexedTriangles *)g_hGeometricInFile[i]->d_stListOfElements[xIndex]);
for (j=0; j<p_stLocalElement->xNbFaces; j++)
{
MLT_xComputeNormalWeightedBySurf
( &stNormalResult,
g_hGeometricInFile[i]->d_stListOfPoints + p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[0],
g_hGeometricInFile[i]->d_stListOfPoints + p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[1],
g_hGeometricInFile[i]->d_stListOfPoints + p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[2]
);
p_stLocalElement->d_stListOfFacesNormals[j] = stNormalResult;
}
}
// face map descriptor
else if (g_hGeometricInFile[i]->d_xListOfElementsTypes[xIndex] == MLT_C_xElementFaceMapDescriptors)
{
p_stLocalElementFMD = ((MLT_tdstElementFaceMapDescriptors *)g_hGeometricInFile[i]->d_stListOfElements[xIndex]);
for (j=0; j<p_stLocalElementFMD->xNbFaces; j++)
{
MLT_xComputeNormalWeightedBySurf
( &stNormalResult,
g_hGeometricInFile[i]->d_stListOfPoints + p_stLocalElementFMD->d_stListOfFacesQuadrupled[j].stFaceTripled.a3_xIndex[0],
g_hGeometricInFile[i]->d_stListOfPoints + p_stLocalElementFMD->d_stListOfFacesQuadrupled[j].stFaceTripled.a3_xIndex[1],
g_hGeometricInFile[i]->d_stListOfPoints + p_stLocalElementFMD->d_stListOfFacesQuadrupled[j].stFaceTripled.a3_xIndex[2]
);
p_stLocalElementFMD->d_stListOfFacesNormals[j] = stNormalResult;
}
}
}
}
p_stLocalElement = ((MLT_tdstElementIndexedTriangles *)g_hGeometricInFile[0]->d_stListOfElements[0]);
// for all the objects make some initialization and/or allocation
for (i=0; i<g_lGeometricIndex; i++)
{
if ( g_hGeometricInFile[i]->d_stListOfPointsNormals == NULL )
g_hGeometricInFile[i]->d_stListOfPointsNormals = (MTH3D_tdstVector *)malloc(sizeof(MTH3D_tdstVector *)*g_hGeometricInFile[i]->xNbPoints);
p_stVertex = g_hGeometricInFile[i]->d_stListOfPointsNormals;
p_stLastVertex = p_stVertex + g_hGeometricInFile[i]->xNbPoints;
for ( ; p_stVertex < p_stLastVertex ; p_stVertex ++ )
MTH3D_M_vNullVector ( p_stVertex );
for (k=0; k<g_hGeometricInFile[i]->xNbPoints; k++)
{
g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndexObj = (int *)malloc(sizeof(int)*200); //malloc(sizeof(int)*(g_lGeometricIndex-1));
g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndexPoint = (int *)malloc(200*sizeof(int));
for (m=0; m<200; m++)
{ g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndexObj[m] = -1;
g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndexPoint[m] = -1;
}
}
}
// for all the objects
for (i=0; i<g_lGeometricIndex; i++)
{
for (j=i+1; j<g_lGeometricIndex; j++)
{
// if the bounding boxes contains common points
if (MLT_bIntersBoundingBoxes(g_hGeometricInFile[i], g_hGeometricInFile[j]))
{
for (k=0; k<g_hGeometricInFile[i]->xNbPoints; k++)
{
MTH3D_tdstVector stPoint_ik;
MLT_xMulMatrixVertex(&stPoint_ik, g_hGeometricInFile[i]->p_stMatrix, &g_hGeometricInFile[i]->d_stListOfPoints[k]);
if (MLT_bPointInBoundingBox(stPoint_ik, g_hGeometricInFile[j]))
{
for (l=0; l<g_hGeometricInFile[j]->xNbPoints; l++)
{
MTH3D_tdstVector stPoint_jl;
MLT_xMulMatrixVertex(&stPoint_jl, g_hGeometricInFile[j]->p_stMatrix, &g_hGeometricInFile[j]->d_stListOfPoints[l]);
if ( (fabs(stPoint_ik.xX - stPoint_jl.xX) <= gs_fLim)
&& (fabs(stPoint_ik.xY - stPoint_jl.xY) <= gs_fLim)
&& (fabs(stPoint_ik.xZ - stPoint_jl.xZ) <= gs_fLim))
//the point k from the first object is equal with the point l of the second object
{
p=0;
if (g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndexObj)
{ while (g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndexObj[p] != -1) p++;
g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndexObj[p] = j;
g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndexPoint[p] = l;
}
p=0;
if (g_hGeometricInFile[j]->p_stFaceIndexes[l].iIndexObj)
{ while (g_hGeometricInFile[j]->p_stFaceIndexes[l].iIndexObj[p] != -1) p++;
g_hGeometricInFile[j]->p_stFaceIndexes[l].iIndexObj[p] = i;
g_hGeometricInFile[j]->p_stFaceIndexes[l].iIndexPoint[p] = k;
}
}
} // !!!!!
n = 0;
while (g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndexPoint[n] != -1)
{
m = g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndexPoint[n];
p = g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndexObj[n];
n1= 0;
while (g_hGeometricInFile[p]->p_stFaceIndexes[m].iIndexElem[n1] != -1)
{
if (g_hGeometricInFile[p]->d_xListOfElementsTypes[g_hGeometricInFile[p]->p_stFaceIndexes[m].iIndexElem[n1]] == MLT_C_xElementIndexedTriangles)
{
p_stLocalElement = ((MLT_tdstElementIndexedTriangles *)g_hGeometricInFile[p]->d_stListOfElements[g_hGeometricInFile[p]->p_stFaceIndexes[m].iIndexElem[n1]]);
MTH3D_M_vAddVector ( g_hGeometricInFile[i]->d_stListOfPointsNormals + k,
g_hGeometricInFile[i]->d_stListOfPointsNormals + k,
&p_stLocalElement->d_stListOfFacesNormals[g_hGeometricInFile[p]->p_stFaceIndexes[m].iIndex[n1]] );
MTH3D_M_vNormalizeVector ( &p_stLocalElement->d_stListOfFacesNormals[g_hGeometricInFile[p]->p_stFaceIndexes[m].iIndex[n1]],
&p_stLocalElement->d_stListOfFacesNormals[g_hGeometricInFile[p]->p_stFaceIndexes[m].iIndex[n1]]);
}
else if (g_hGeometricInFile[p]->d_xListOfElementsTypes[g_hGeometricInFile[p]->p_stFaceIndexes[m].iIndexElem[n1]] == MLT_C_xElementFaceMapDescriptors)
{
p_stLocalElementFMD = ((MLT_tdstElementFaceMapDescriptors *)g_hGeometricInFile[p]->d_stListOfElements[g_hGeometricInFile[p]->p_stFaceIndexes[m].iIndexElem[n1]]);
MTH3D_M_vAddVector ( g_hGeometricInFile[i]->d_stListOfPointsNormals + k,
g_hGeometricInFile[i]->d_stListOfPointsNormals + k,
&p_stLocalElementFMD->d_stListOfFacesNormals[g_hGeometricInFile[p]->p_stFaceIndexes[m].iIndex[n1]] );
MTH3D_M_vNormalizeVector ( &p_stLocalElementFMD->d_stListOfFacesNormals[g_hGeometricInFile[p]->p_stFaceIndexes[m].iIndex[n1]],
&p_stLocalElementFMD->d_stListOfFacesNormals[g_hGeometricInFile[p]->p_stFaceIndexes[m].iIndex[n1]]);
}
n1++;
}
n3=0;
while (g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndexElem[n3] != -1)
{
if (g_hGeometricInFile[i]->d_xListOfElementsTypes[g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndexElem[n3]] == MLT_C_xElementIndexedTriangles)
{
p_stLocalElement = ((MLT_tdstElementIndexedTriangles *)g_hGeometricInFile[i]->d_stListOfElements[g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndexElem[n3]]);
MTH3D_M_vAddVector ( g_hGeometricInFile[p]->d_stListOfPointsNormals + m,
g_hGeometricInFile[p]->d_stListOfPointsNormals + m,
&p_stLocalElement->d_stListOfFacesNormals[g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndex[n3]] );
MTH3D_M_vNormalizeVector ( &p_stLocalElement->d_stListOfFacesNormals[g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndex[n3]],
&p_stLocalElement->d_stListOfFacesNormals[g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndex[n3]]);
}
else if (g_hGeometricInFile[i]->d_xListOfElementsTypes[g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndexElem[n3]] == MLT_C_xElementFaceMapDescriptors)
{
p_stLocalElementFMD = ((MLT_tdstElementFaceMapDescriptors *)g_hGeometricInFile[i]->d_stListOfElements[g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndexElem[n3]]);
MTH3D_M_vAddVector ( g_hGeometricInFile[p]->d_stListOfPointsNormals + m,
g_hGeometricInFile[p]->d_stListOfPointsNormals + m,
&p_stLocalElementFMD->d_stListOfFacesNormals[g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndex[n3]] );
MTH3D_M_vNormalizeVector ( &p_stLocalElementFMD->d_stListOfFacesNormals[g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndex[n3]],
&p_stLocalElementFMD->d_stListOfFacesNormals[g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndex[n3]]);
}
n3++;
}
n++;
}
}
}
}
}
for (k=0; k<g_hGeometricInFile[i]->xNbPoints; k++)
{
n = 0;
while(g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndex[n] != -1)
{
if (g_hGeometricInFile[i]->d_xListOfElementsTypes[g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndexElem[n]] == MLT_C_xElementIndexedTriangles)
{
p_stLocalElement = ((MLT_tdstElementIndexedTriangles *)g_hGeometricInFile[i]->d_stListOfElements[g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndexElem[n]]);
MTH3D_M_vAddVector (g_hGeometricInFile[i]->d_stListOfPointsNormals+k,
g_hGeometricInFile[i]->d_stListOfPointsNormals+k,
&p_stLocalElement->d_stListOfFacesNormals[g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndex[n]] );
if ((p_stLocalElement->d_stListOfFacesNormals[g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndex[n]].xX == 0) &&
(p_stLocalElement->d_stListOfFacesNormals[g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndex[n]].xY == 0) &&
(p_stLocalElement->d_stListOfFacesNormals[g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndex[n]].xZ == 0))
{ p_stLocalElement->d_stListOfFacesNormals[g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndex[n]].xX = 0.00;
p_stLocalElement->d_stListOfFacesNormals[g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndex[n]].xY = 0.00;
p_stLocalElement->d_stListOfFacesNormals[g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndex[n]].xZ = -1.00;
}
else
MTH3D_M_vNormalizeVector ( &p_stLocalElement->d_stListOfFacesNormals[g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndex[n]],
&p_stLocalElement->d_stListOfFacesNormals[g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndex[n]]);
}
else if (g_hGeometricInFile[i]->d_xListOfElementsTypes[g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndexElem[n]] == MLT_C_xElementIndexedTriangles)
{
p_stLocalElementFMD = ((MLT_tdstElementFaceMapDescriptors *)g_hGeometricInFile[i]->d_stListOfElements[g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndexElem[n]]);
MTH3D_M_vAddVector (g_hGeometricInFile[i]->d_stListOfPointsNormals+k,
g_hGeometricInFile[i]->d_stListOfPointsNormals+k,
&p_stLocalElementFMD->d_stListOfFacesNormals[g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndex[n]] );
MTH3D_M_vNormalizeVector ( &p_stLocalElementFMD->d_stListOfFacesNormals[g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndex[n]],
&p_stLocalElementFMD->d_stListOfFacesNormals[g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndex[n]]);
}
n++;
}
}
p_stVertex = g_hGeometricInFile[i]->d_stListOfPointsNormals;
p_stLastVertex = p_stVertex + g_hGeometricInFile[i]->xNbPoints;
for ( ; p_stVertex < p_stLastVertex ; p_stVertex ++ )
{
if ( MTH3D_M_bIsNullVector( p_stVertex) )
MTH3D_M_vSetVectorElements ( p_stVertex, MTH_C_ZERO, MTH_C_ZERO, MTH_C_ONE)
else
MTH3D_M_vNormalizeVector ( p_stVertex, p_stVertex );
}
}
for (i=0; i<g_lGeometricIndex; i++)
{
for (k=0; k<g_hGeometricInFile[i]->xNbPoints; k++)
{
if (g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndexObj)
free(g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndexObj);
if (g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndexPoint)
free(g_hGeometricInFile[i]->p_stFaceIndexes[k].iIndexPoint);
}
free(g_hGeometricInFile[i]->p_stFaceIndexes);
}
}
/****************************************************************************
* Description: get the index of the faces for all the points of a geometric object
*
* Parameters: p_stObj : geometric object
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vIndexFace (MLT_tdstGeometricObject *p_stObj)
{
int i, xIndex, j=0, k;
MLT_tdstElementIndexedTriangles *p_stLocalElement;
MLT_tdstElementFaceMapDescriptors *p_stLocalElementFMD;
p_stObj->p_stFaceIndexes = (MLT_tdstVector *)malloc(sizeof(MLT_tdstVector) * p_stObj->xNbPoints);
for (k=0; k<p_stObj->xNbPoints; k++)
{
for (i=0; i<100; i++)
{
p_stObj->p_stFaceIndexes[k].iIndexElem[i] = -1;
p_stObj->p_stFaceIndexes[k].iIndex[i] = -1;
}
for (xIndex=0; xIndex<p_stObj->xNbElements; xIndex++)
{
if ( p_stObj->d_xListOfElementsTypes[xIndex] == MLT_C_xElementIndexedTriangles )
{
p_stLocalElement = ((MLT_tdstElementIndexedTriangles *)p_stObj->d_stListOfElements[xIndex]);
for (i=0; i<p_stLocalElement->xNbFaces; i++)
{
if ((k == p_stLocalElement->d_stListOfFacesTripled[i].a3_xIndex[0]) ||
(k == p_stLocalElement->d_stListOfFacesTripled[i].a3_xIndex[1]) ||
(k == p_stLocalElement->d_stListOfFacesTripled[i].a3_xIndex[2]))
{
p_stObj->p_stFaceIndexes[k].iIndexElem[j] = xIndex;
p_stObj->p_stFaceIndexes[k].iIndex[j] = i;
j++;
}
}
}
else if (p_stObj->d_xListOfElementsTypes[xIndex] == MLT_C_xElementFaceMapDescriptors )
{
p_stLocalElementFMD = ((MLT_tdstElementFaceMapDescriptors *)p_stObj->d_stListOfElements[xIndex]);
for (i=0; i<p_stLocalElementFMD->xNbFaces; i++)
{
if ((k == p_stLocalElementFMD->d_stListOfFacesQuadrupled[i].stFaceTripled.a3_xIndex[0]) ||
(k == p_stLocalElementFMD->d_stListOfFacesQuadrupled[i].stFaceTripled.a3_xIndex[1]) ||
(k == p_stLocalElementFMD->d_stListOfFacesQuadrupled[i].stFaceTripled.a3_xIndex[2]))
{
p_stObj->p_stFaceIndexes[k].iIndexElem[j] = xIndex;
p_stObj->p_stFaceIndexes[k].iIndex[j] = i;
j++;
}
}
}
}
j = 0;
}
}
/****************************************************************************
* Description: compute the normals for the object
*
* Parameters: p_stObj : geometric object
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_xComputeObjectNormals ( MLT_tdstGeometricObject *p_stObj )
{
MTH3D_tdstVector *p_stVertex, *p_stLastVertex, stNormalResult;
MLT_tdstTripledIndex *p_stITStart, *p_stITLast;
MLT_tdstElementIndexedTriangles *p_stLocalElement;
MLT_tdstFaceMapTriangle *p_stITStartFMD, *p_stITLastFMD;
MLT_tdstElementFaceMapDescriptors *p_stLocalElementFMD;
ACP_tdxIndex xIndex, xTriangleIndex;
#ifdef USE_ALTIMAPS
if ( p_stObj->d_xListOfElementsTypes[0] == MLT_C_xElementAltimap )
MLT_xComputeAltimapObjectNormals( p_stObj );
#endif
if ( p_stObj->xNbPoints == 0 )
return;
if ( p_stObj->d_stListOfPointsNormals == NULL )
p_stObj->d_stListOfPointsNormals = (MTH3D_tdstVector *)malloc(sizeof(MTH3D_tdstVector *)*p_stObj->xNbPoints);
p_stVertex = p_stObj->d_stListOfPointsNormals;
p_stLastVertex = p_stVertex + p_stObj->xNbPoints;
for ( ; p_stVertex < p_stLastVertex ; p_stVertex ++ )
MTH3D_M_vNullVector ( p_stVertex );
for ( xIndex = 0 ; xIndex < p_stObj->xNbElements ; xIndex ++ )
{
if ( p_stObj->d_xListOfElementsTypes[xIndex] == MLT_C_xElementIndexedTriangles )
{
p_stLocalElement = ((MLT_tdstElementIndexedTriangles *)p_stObj->d_stListOfElements[xIndex]);
p_stITStart = p_stLocalElement->d_stListOfFacesTripled;
p_stITLast = p_stITStart + p_stLocalElement->xNbFaces;
for ( xTriangleIndex = 0 ; p_stITStart < p_stITLast ; p_stITStart ++ , xTriangleIndex ++ )
{
MLT_xComputeNormalWeightedBySurf
( &stNormalResult,
p_stObj->d_stListOfPoints + p_stITStart->a3_xIndex[0],
p_stObj->d_stListOfPoints + p_stITStart->a3_xIndex[1],
p_stObj->d_stListOfPoints + p_stITStart->a3_xIndex[2]
);
p_stLocalElement->d_stListOfFacesNormals[xTriangleIndex] = stNormalResult;
if ( !MTH3D_M_bIsNullVector(&stNormalResult) )
{
MTH3D_M_vAddVector ( p_stObj->d_stListOfPointsNormals + p_stITStart->a3_xIndex[0], p_stObj->d_stListOfPointsNormals + p_stITStart->a3_xIndex[0], &stNormalResult );
MTH3D_M_vAddVector ( p_stObj->d_stListOfPointsNormals + p_stITStart->a3_xIndex[1], p_stObj->d_stListOfPointsNormals + p_stITStart->a3_xIndex[1], &stNormalResult );
MTH3D_M_vAddVector ( p_stObj->d_stListOfPointsNormals + p_stITStart->a3_xIndex[2], p_stObj->d_stListOfPointsNormals + p_stITStart->a3_xIndex[2], &stNormalResult );
MTH3D_M_vNormalizeVector ( &p_stLocalElement->d_stListOfFacesNormals[xTriangleIndex], &p_stLocalElement->d_stListOfFacesNormals[xTriangleIndex] );
}
}
}
else if ( p_stObj->d_xListOfElementsTypes[xIndex] == MLT_C_xElementFaceMapDescriptors )
{
p_stLocalElementFMD = ((MLT_tdstElementFaceMapDescriptors *)p_stObj->d_stListOfElements[xIndex]);
p_stITStartFMD = p_stLocalElementFMD->d_stListOfFacesQuadrupled;
p_stITLastFMD = p_stITStartFMD + p_stLocalElementFMD->xNbFaces;
for ( xTriangleIndex=0 ; p_stITStartFMD < p_stITLastFMD ; p_stITStartFMD ++ , xTriangleIndex ++ )
{
MLT_xComputeNormalWeightedBySurf
( &stNormalResult,
p_stObj->d_stListOfPoints + p_stITStartFMD->stFaceTripled.a3_xIndex[0],
p_stObj->d_stListOfPoints + p_stITStartFMD->stFaceTripled.a3_xIndex[1],
p_stObj->d_stListOfPoints + p_stITStartFMD->stFaceTripled.a3_xIndex[2]
);
p_stLocalElementFMD->d_stListOfFacesNormals[xTriangleIndex] = stNormalResult;
if ( !MTH3D_M_bIsNullVector( &stNormalResult ) )
{
MTH3D_M_vAddVector ( p_stObj->d_stListOfPointsNormals + p_stITStartFMD->stFaceTripled.a3_xIndex[0], p_stObj->d_stListOfPointsNormals + p_stITStartFMD->stFaceTripled.a3_xIndex[0], &stNormalResult );
MTH3D_M_vAddVector ( p_stObj->d_stListOfPointsNormals + p_stITStartFMD->stFaceTripled.a3_xIndex[1], p_stObj->d_stListOfPointsNormals + p_stITStartFMD->stFaceTripled.a3_xIndex[1], &stNormalResult );
MTH3D_M_vAddVector ( p_stObj->d_stListOfPointsNormals + p_stITStartFMD->stFaceTripled.a3_xIndex[2], p_stObj->d_stListOfPointsNormals + p_stITStartFMD->stFaceTripled.a3_xIndex[2], &stNormalResult );
MTH3D_M_vNormalizeVector ( &p_stLocalElementFMD->d_stListOfFacesNormals[xTriangleIndex], &p_stLocalElementFMD->d_stListOfFacesNormals[xTriangleIndex] );
}
}
}
}
p_stVertex = p_stObj->d_stListOfPointsNormals;
p_stLastVertex = p_stVertex + p_stObj->xNbPoints;
for ( ; p_stVertex < p_stLastVertex ; p_stVertex ++ )
{
if ( MTH3D_M_bIsNullVector( p_stVertex) )
MTH3D_M_vSetVectorElements ( p_stVertex, MTH_C_ZERO, MTH_C_ZERO, MTH_C_ONE)
else
MTH3D_M_vNormalizeVector ( p_stVertex, p_stVertex );
}
}
/****************************************************************************
* Description: compute the normals for the altimap object
*
* Parameters: p_stObj : geometric object
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
#ifdef USE_ALTIMAPS
void MLT_xComputeAltimapObjectNormals ( MLT_tdstGeometricObject *p_stObj )
{
MLT_tdstElementAltimap *p_stAltimap;
ACP_tdxIndex xI, xJ, xK, xL, xA, xB, xC, xSquareBLVertex;
MTH3D_tdstVector *d_stPoints, stOriginNoZ;
MLT_tdstAltimapSquare *stSquare;
unsigned char ucType;
p_stAltimap = (MLT_tdstElementAltimap *) p_stObj->d_stListOfElements[0];
d_stPoints = (MTH3D_tdstVector *)malloc(( p_stAltimap->xWidth+1 ) * ( p_stAltimap->xDepth+1 ) * sizeof(MTH3D_tdstVector));
MTH3D_M_vSetVectorElements( &stOriginNoZ, p_stAltimap->stOrigin.xX, p_stAltimap->stOrigin.xY, MTH_C_ZERO );
for (xJ = 0, xK = 0; xJ < p_stAltimap->xDepth+1; xJ++)
{
for(xI = 0 ; xI< p_stAltimap->xWidth+1; xI++, xK ++)
{
//--- For each Vertex, sets the coordinates in its super object axis system
MTH3D_M_vNullVector(p_stAltimap->d_stPointNormals + xK);
(d_stPoints + xK) -> xX = MTH_M_xRealToLong(xI) * p_stAltimap->xDeltaX;
(d_stPoints + xK) -> xY = MTH_M_xRealToLong(xJ) * p_stAltimap->xDeltaY;
(d_stPoints + xK) -> xZ = p_stAltimap->d_xHeight[xK];
MTH3D_M_vAddVector(d_stPoints + xK, d_stPoints + xK, &stOriginNoZ);
}
}
for(xJ = 0, xK = 0 ; xJ < p_stAltimap->xDepth ; xJ++)
{
for(xI = 0 ; xI < p_stAltimap->xWidth; xI++, xK++)
{
stSquare = (p_stAltimap->d_stSquare) + xK;
xL = stSquare->xFaceIndex;
ucType = stSquare->ucType;
xSquareBLVertex = xJ * (p_stAltimap->xWidth + 1) + xI;
while( ucType )
{
if( ucType & MLT_C_xAltiSquareTopRight )
{
xA = xSquareBLVertex + 1;
xB = xSquareBLVertex + 1 + p_stAltimap->xWidth + 1;
xC = xSquareBLVertex + p_stAltimap->xWidth + 1;
ucType &= ~MLT_C_xAltiSquareTopRight;
ucType <<= 4;
}
else if( ucType & MLT_C_xAltiSquareBottomLeft )
{
xA = xSquareBLVertex;
xB = xSquareBLVertex + 1;
xC = xSquareBLVertex + p_stAltimap->xWidth + 1;
ucType = 0;
}
else if( (ucType >> 4) & MLT_C_xAltiSquareBottomLeft )
{
xA = xSquareBLVertex;
xB = xSquareBLVertex + 1;
xC = xSquareBLVertex + p_stAltimap->xWidth + 1;
ucType = 0;
xL++;
}
else if( ucType & MLT_C_xAltiSquareTopLeft )
{
xA = xSquareBLVertex;
xB = xSquareBLVertex + 1 + p_stAltimap->xWidth + 1;
xC = xSquareBLVertex + p_stAltimap->xWidth + 1;
ucType &= ~MLT_C_xAltiSquareTopLeft;
ucType <<= 4;
}
else if( ucType & MLT_C_xAltiSquareBottomRight )
{
xA = xSquareBLVertex;
xB = xSquareBLVertex + 1;
xC = xSquareBLVertex + 1 + p_stAltimap->xWidth + 1;
ucType = 0;
}
else if( (ucType >> 4) & MLT_C_xAltiSquareBottomRight )
{
xA = xSquareBLVertex;
xB = xSquareBLVertex + 1;
xC = xSquareBLVertex + 1 + p_stAltimap->xWidth + 1;
ucType = 0;
xL++;
}
else
break;
MLT_xComputeNormalWeightedBySurf( &(p_stAltimap->d_stFaceNormals[xL]), d_stPoints + xA, d_stPoints + xB, d_stPoints + xC );
MTH3D_M_vAddVector( p_stAltimap->d_stPointNormals + xA, p_stAltimap->d_stPointNormals + xA, &(p_stAltimap->d_stFaceNormals[xL]) );
MTH3D_M_vAddVector( p_stAltimap->d_stPointNormals + xB, p_stAltimap->d_stPointNormals + xB, &(p_stAltimap->d_stFaceNormals[xL]) );
MTH3D_M_vAddVector( p_stAltimap->d_stPointNormals + xC, p_stAltimap->d_stPointNormals + xC, &(p_stAltimap->d_stFaceNormals[xL]) );
MTH3D_M_vNormalizeVector ( &(p_stAltimap->d_stFaceNormals[xL]), &(p_stAltimap->d_stFaceNormals[xL]) );
}
}
for(xJ = 0, xK = 0; xJ < p_stAltimap->xDepth+1; xJ++)
{
for(xI = 0; xI< p_stAltimap->xWidth+1; xI++, xK++)
{
if( MTH_M_bEqualZero( MTH3D_M_xNormVector( p_stAltimap->d_stPointNormals + xK ) ) )
MTH3D_M_vSetVectorElements( p_stAltimap->d_stPointNormals + xK, MTH_C_ZERO, MTH_C_ZERO, MTH_C_ONE )
else
MTH3D_M_vNormalizeVector( p_stAltimap->d_stPointNormals + xK, p_stAltimap->d_stPointNormals + xK )
}
}
free(d_stPoints);
}
return;
}
#endif //USE_ALTIMAPS
/****************************************************************************
* Description: compute normal
*
* Parameters: p_stPResult : result vector
* p_stPA : first point
* p_stPB : second point
* p_stPC : third point
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_xComputeNormalWeightedBySurf ( MTH3D_tdstVector *p_stPResult, MTH3D_tdstVector *p_stPA, MTH3D_tdstVector *p_stPB, MTH3D_tdstVector *p_stPC )
{
MTH3D_tdstVector stEdgeAB, stEdgeAC;
MTH3D_M_vSubVector ( &stEdgeAB, p_stPB, p_stPA );
MTH3D_M_vSubVector ( &stEdgeAC, p_stPC, p_stPA );
MTH3D_M_vCrossProductVectorWithoutBuffer( p_stPResult, &stEdgeAB, &stEdgeAC );
}
/****************************************************************************
* Description: test if the bounding boxes of two geometric objects have common points
*
* Parameters: p_stObj1 : first geometric object
* p_stObj2 : second geometric object
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
BOOL MLT_bIntersBoundingBoxes ( MLT_tdstGeometricObject *p_stObj1, MLT_tdstGeometricObject *p_stObj2 )
{
if ( (p_stObj2->stMinPoint.xX <= (p_stObj1->stMaxPoint.xX + gs_fLim))
&& (p_stObj2->stMaxPoint.xX >= (p_stObj1->stMinPoint.xX - gs_fLim))
&& (p_stObj2->stMinPoint.xY <= (p_stObj1->stMaxPoint.xY + gs_fLim))
&& (p_stObj2->stMaxPoint.xY >= (p_stObj1->stMinPoint.xY - gs_fLim))
&& (p_stObj2->stMinPoint.xZ <= (p_stObj1->stMaxPoint.xZ + gs_fLim))
&& (p_stObj2->stMaxPoint.xZ >= (p_stObj1->stMinPoint.xZ - gs_fLim)))
return TRUE;
return FALSE;
}
/****************************************************************************
* Description: test if the specified point is in the bounding box of the geometric object
*
* Parameters: stPoint : point to test
* p_stObj : geometric object
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
BOOL MLT_bPointInBoundingBox (MTH3D_tdstVector stPoint, MLT_tdstGeometricObject *p_stObj)
{
if ((stPoint.xX >= (p_stObj->stMinPoint.xX - gs_fLim)) && (stPoint.xX <= (p_stObj->stMaxPoint.xX + gs_fLim)) &&
(stPoint.xY >= (p_stObj->stMinPoint.xY - gs_fLim)) && (stPoint.xY <= (p_stObj->stMaxPoint.xY + gs_fLim)) &&
(stPoint.xZ >= (p_stObj->stMinPoint.xZ - gs_fLim)) && (stPoint.xZ <= (p_stObj->stMaxPoint.xZ + gs_fLim)))
return TRUE;
return FALSE;
}