611 lines
27 KiB
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;
|
|
}
|
|
|
|
|