/*========================================================================= * * 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; istMinPoint, 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; ixNbElements; 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; jxNbFaces; 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; jxNbFaces; 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; id_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; kxNbPoints; 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; ixNbPoints; 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; lxNbPoints; 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; kxNbPoints; 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; ixNbPoints; 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; kxNbPoints; 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; xIndexxNbElements; xIndex++) { if ( p_stObj->d_xListOfElementsTypes[xIndex] == MLT_C_xElementIndexedTriangles ) { p_stLocalElement = ((MLT_tdstElementIndexedTriangles *)p_stObj->d_stListOfElements[xIndex]); for (i=0; ixNbFaces; 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; ixNbFaces; 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; }