reman3/Rayman_X/cpa/tempgrp/COL/Inters.c

3396 lines
114 KiB
C
Raw Blame History

/*
0 1 2 3 4 5 6 7
01234567890123456789012345678901234567890123456789012345678901234567890123456789
--------------------------------------------------------------------------------
-- Description : Low level intersection
--------------------------------------------------------------------------------
-- Creation date : 22 aug 1996 Author : FPI
--------------------------------------------------------------------------------
*/
#include "acp_base.h"
#include "MTH.h"
#include "MEC.h"
#include "GMT.h"
#include "GEO.h"
#include "GLI.h"
#include "COL/Inters.h"
#include "tmr.h"
#ifdef CODEWARRIOR
#include "COL/futil.h"
#endif
/* XB 05/05/99 : add static */
static unsigned char ucPlaneCrossingdetect(MTH3D_tdstVector *p_stVertex1,
/* End XB 05/05/99 */
MTH3D_tdstVector *p_stVect12,
MTH3D_tdstVector *p_stMinPoint,
MTH3D_tdstVector *p_stMaxPoint,
MTH_tdxReal xT,
char cFace);
/*
--------------------------------------------------------------------------------
-- Description : Trinome resolution
--------------------------------------------------------------------------------
-- Creation date : 01 oct 1996 Author : FPI
--------------------------------------------------------------------------------
*/
/* resolution d un trinome */
/* used*/
ACP_tdxIndex INT_fn_xTrinomeResolution ( MTH_tdxReal xA,
MTH_tdxReal xB,
MTH_tdxReal xC,
MTH_tdxReal *p_xT1,
MTH_tdxReal *p_xT2 )
{
MTH_tdxReal xDelta;
MTH_tdxReal xDiv;
if ( MTH_M_bDifferentZero ( xA ) )
{
xDelta = MTH_M_xTrinomeDelta ( xA, xB, xC );
if ( MTH_M_bGreaterZero ( xDelta ) )
{
xDelta = MTH_M_xSqrt ( xDelta );
xB = MTH_M_xNeg ( xB );
xDiv = MTH_M_xInv ( MTH_M_xAdd ( xA, xA ) );
*p_xT1 = MTH_M_xMul ( MTH_M_xAdd (xB, xDelta ), xDiv );
*p_xT2 = MTH_M_xMul ( MTH_M_xSub (xB, xDelta ), xDiv );
return INT_C_xTwoSolutions;
}
else
{
if ( MTH_M_bLessZero ( xDelta ) )
{
return INT_C_xNoSolution;
}
else
{
if ( MTH_M_bEqualZero ( xDelta ) )
{
*p_xT1 = MTH_M_xNeg ( MTH_M_xDiv ( xB, MTH_M_xAdd ( xA, xA ) ) );
return INT_C_xOneSolution;
}
}
}
}
else
{
if ( MTH_M_bDifferentZero ( xB ) )
{
*p_xT1 = MTH_M_xNeg ( MTH_M_xDiv ( xC, xB ) );
return INT_C_xOneSolution;
}
else
{
return INT_C_xNoSolution;
}
}
return INT_C_xNoSolution;
}
/*
--------------------------------------------------------------------------------
-- Description : Box with a box intersection test
--------------------------------------------------------------------------------
-- Creation date : 22 aug 1996 Author : FPI
--------------------------------------------------------------------------------
*/
/* teste l intersection de deux boites */
/* used*/
ACP_tdxBool INT_fn_bIntersectBoxWithBox ( MTH3D_tdstVector *p_stMinPoint1,
MTH3D_tdstVector *p_stMaxPoint1,
MTH3D_tdstVector *p_stMinPoint2,
MTH3D_tdstVector *p_stMaxPoint2 )
{
return ( MTH_M_bLessEqual ( MTH_M_xMax ( MTH3D_M_xGetXofVector ( p_stMinPoint1 ), MTH3D_M_xGetXofVector ( p_stMinPoint2 ) ),
MTH_M_xMin ( MTH3D_M_xGetXofVector ( p_stMaxPoint1 ), MTH3D_M_xGetXofVector ( p_stMaxPoint2 ) )
)
) &&
( MTH_M_bLessEqual ( MTH_M_xMax ( MTH3D_M_xGetYofVector ( p_stMinPoint1 ), MTH3D_M_xGetYofVector ( p_stMinPoint2 ) ),
MTH_M_xMin ( MTH3D_M_xGetYofVector ( p_stMaxPoint1 ), MTH3D_M_xGetYofVector ( p_stMaxPoint2 ) )
)
) &&
( MTH_M_bLessEqual ( MTH_M_xMax ( MTH3D_M_xGetZofVector ( p_stMinPoint1 ), MTH3D_M_xGetZofVector ( p_stMinPoint2 ) ),
MTH_M_xMin ( MTH3D_M_xGetZofVector ( p_stMaxPoint1 ), MTH3D_M_xGetZofVector ( p_stMaxPoint2 ) )
)
);
}
/*
--------------------------------------------------------------------------------
-- Description : Sphere with a box intersection test
--------------------------------------------------------------------------------
-- Creation date : 10 jan 1997 Author : FPI
--------------------------------------------------------------------------------
*/
/* teste l intersection d une sphere et d une boite */
/* used*/
ACP_tdxBool INT_fn_bIntersectSphereWithBox ( MTH3D_tdstVector *p_stCenter,
MTH_tdxReal xRadius,
MTH3D_tdstVector *p_stMinPoint,
MTH3D_tdstVector *p_stMaxPoint )
{
MTH_tdxReal xDist;
xDist = MTH_C_ZERO;
if ( p_stCenter->xX < p_stMinPoint->xX )
{
xDist = MTH_M_xAdd ( xDist, MTH_M_xSqr ( MTH_M_xSub ( p_stCenter->xX, p_stMinPoint->xX ) ) );
}
else
{
if ( p_stCenter->xX > p_stMaxPoint->xX )
{
xDist = MTH_M_xAdd ( xDist, MTH_M_xSqr ( MTH_M_xSub ( p_stCenter->xX, p_stMaxPoint->xX ) ) );
}
}
if ( p_stCenter->xY < p_stMinPoint->xY )
{
xDist = MTH_M_xAdd ( xDist, MTH_M_xSqr ( MTH_M_xSub ( p_stCenter->xY, p_stMinPoint->xY ) ) );
}
else
{
if ( p_stCenter->xY > p_stMaxPoint->xY )
{
xDist = MTH_M_xAdd ( xDist, MTH_M_xSqr ( MTH_M_xSub ( p_stCenter->xY, p_stMaxPoint->xY ) ) );
}
}
if ( p_stCenter->xZ < p_stMinPoint->xZ )
{
xDist = MTH_M_xAdd ( xDist, MTH_M_xSqr ( MTH_M_xSub ( p_stCenter->xZ, p_stMinPoint->xZ ) ) );
}
else
{
if ( p_stCenter->xZ > p_stMaxPoint->xZ )
{
xDist = MTH_M_xAdd ( xDist, MTH_M_xSqr ( MTH_M_xSub ( p_stCenter->xZ, p_stMaxPoint->xZ ) ) );
}
}
return xDist < MTH_M_xSqr ( xRadius );
}
/*
--------------------------------------------------------------------------------
-- Description : Sphere with a sphere intersection test
--------------------------------------------------------------------------------
-- Creation date : 18 apr 1997 Author : FPI
--------------------------------------------------------------------------------
*/
/* teste l intersection de deux spheres */
/* used*/
ACP_tdxBool INT_fn_bIntersectSphereWithSphere ( MTH3D_tdstVector *p_stCenter1,
MTH_tdxReal xRadius1,
MTH3D_tdstVector *p_stCenter2,
MTH_tdxReal xRadius2 )
{
return MTH_M_bLessEqual ( MTH3D_M_xVectorGapSqr ( p_stCenter1, p_stCenter2 ), MTH_M_xSqr ( MTH_M_xAdd ( xRadius1, xRadius2 ) ) );
}
/*
--------------------------------------------------------------------------------
-- Description : Get the position of a point with a box
--------------------------------------------------------------------------------
-- Creation date : 22 aug 1996 Author : FPI
--------------------------------------------------------------------------------
*/
/* Which of the six face-plane(s) is point P outside of? */
/* used*/
unsigned long INT_fn_ulGetPositionPointWithBox ( MTH3D_tdstVector *p_stPoint,
MTH3D_tdstVector *p_stMinPoint,
MTH3D_tdstVector *p_stMaxPoint )
{
unsigned long ulOutCode;
ulOutCode = COL_C_ulNullMask;
if ( MTH_M_bLess ( MTH3D_M_xGetXofVector ( p_stPoint ), MTH3D_M_xGetXofVector ( p_stMinPoint ) ) )
ulOutCode |= COL_C_ulXMinMask;
else if ( MTH_M_bGreater ( MTH3D_M_xGetXofVector ( p_stPoint ), MTH3D_M_xGetXofVector ( p_stMaxPoint ) ) )
ulOutCode |= COL_C_ulXMaxMask;
if ( MTH_M_bLess ( MTH3D_M_xGetYofVector ( p_stPoint ), MTH3D_M_xGetYofVector ( p_stMinPoint ) ) )
ulOutCode |= COL_C_ulYMinMask;
else if ( MTH_M_bGreater ( MTH3D_M_xGetYofVector ( p_stPoint ), MTH3D_M_xGetYofVector ( p_stMaxPoint ) ) )
ulOutCode |= COL_C_ulYMaxMask;
if ( MTH_M_bLess ( MTH3D_M_xGetZofVector ( p_stPoint ), MTH3D_M_xGetZofVector ( p_stMinPoint ) ) )
ulOutCode |= COL_C_ulZMinMask;
else if ( MTH_M_bGreater ( MTH3D_M_xGetZofVector ( p_stPoint ), MTH3D_M_xGetZofVector ( p_stMaxPoint ) ) )
ulOutCode |= COL_C_ulZMaxMask;
return ulOutCode;
}
/*
--------------------------------------------------------------------------------
-- Description : Point in XY range test
--------------------------------------------------------------------------------
-- Creation date : 06 oct 1997 Author : FPI
--------------------------------------------------------------------------------
*/
/* used*/
ACP_tdxBool INT_fn_bInXYRange ( MTH3D_tdstVector *p_stPoint,
MTH3D_tdstVector *p_stMinPoint,
MTH3D_tdstVector *p_stMaxPoint )
{
if ( MTH_M_bLess ( MTH3D_M_xGetXofVector ( p_stPoint ), MTH3D_M_xGetXofVector ( p_stMinPoint ) ) )
return FALSE;
if ( MTH_M_bGreater ( MTH3D_M_xGetXofVector ( p_stPoint ), MTH3D_M_xGetXofVector ( p_stMaxPoint ) ) )
return FALSE;
if ( MTH_M_bLess ( MTH3D_M_xGetYofVector ( p_stPoint ), MTH3D_M_xGetYofVector ( p_stMinPoint ) ) )
return FALSE;
if ( MTH_M_bGreater ( MTH3D_M_xGetYofVector ( p_stPoint ), MTH3D_M_xGetYofVector ( p_stMaxPoint ) ) )
return FALSE;
return TRUE;
}
/*
--------------------------------------------------------------------------------
-- Description : Point in YZ range test
--------------------------------------------------------------------------------
-- Creation date : 06 oct 1997 Author : FPI
--------------------------------------------------------------------------------
*/
/* used*/
ACP_tdxBool INT_fn_bInYZRange ( MTH3D_tdstVector *p_stPoint,
MTH3D_tdstVector *p_stMinPoint,
MTH3D_tdstVector *p_stMaxPoint )
{
if ( MTH_M_bLess ( MTH3D_M_xGetYofVector ( p_stPoint ), MTH3D_M_xGetYofVector ( p_stMinPoint ) ) )
return FALSE;
if ( MTH_M_bGreater ( MTH3D_M_xGetYofVector ( p_stPoint ), MTH3D_M_xGetYofVector ( p_stMaxPoint ) ) )
return FALSE;
if ( MTH_M_bLess ( MTH3D_M_xGetZofVector ( p_stPoint ), MTH3D_M_xGetZofVector ( p_stMinPoint ) ) )
return FALSE;
if ( MTH_M_bGreater ( MTH3D_M_xGetZofVector ( p_stPoint ), MTH3D_M_xGetZofVector ( p_stMaxPoint ) ) )
return FALSE;
return TRUE;
}
/*
--------------------------------------------------------------------------------
-- Description : Point in XZ range test
--------------------------------------------------------------------------------
-- Creation date : 06 oct 1997 Author : FPI
--------------------------------------------------------------------------------
*/
/* used*/
ACP_tdxBool INT_fn_bInXZRange ( MTH3D_tdstVector *p_stPoint,
MTH3D_tdstVector *p_stMinPoint,
MTH3D_tdstVector *p_stMaxPoint )
{
if ( MTH_M_bLess ( MTH3D_M_xGetXofVector ( p_stPoint ), MTH3D_M_xGetXofVector ( p_stMinPoint ) ) )
return FALSE;
if ( MTH_M_bGreater ( MTH3D_M_xGetXofVector ( p_stPoint ), MTH3D_M_xGetXofVector ( p_stMaxPoint ) ) )
return FALSE;
if ( MTH_M_bLess ( MTH3D_M_xGetZofVector ( p_stPoint ), MTH3D_M_xGetZofVector ( p_stMinPoint ) ) )
return FALSE;
if ( MTH_M_bGreater ( MTH3D_M_xGetZofVector ( p_stPoint ), MTH3D_M_xGetZofVector ( p_stMaxPoint ) ) )
return FALSE;
return TRUE;
}
/*
--------------------------------------------------------------------------------
-- Description : Point with a box intersection test
--------------------------------------------------------------------------------
-- Creation date : 22 aug 1996 Author : FPI
--------------------------------------------------------------------------------
*/
/* used*/
ACP_tdxBool INT_fn_bGetInclusionPointInBox ( MTH3D_tdstVector *p_stPoint,
MTH3D_tdstVector *p_stMinPoint,
MTH3D_tdstVector *p_stMaxPoint )
{
if ( MTH_M_bLess ( MTH3D_M_xGetXofVector ( p_stPoint ), MTH3D_M_xGetXofVector ( p_stMinPoint ) ) )
return FALSE;
if ( MTH_M_bGreater ( MTH3D_M_xGetXofVector ( p_stPoint ), MTH3D_M_xGetXofVector ( p_stMaxPoint ) ) )
return FALSE;
if ( MTH_M_bLess ( MTH3D_M_xGetYofVector ( p_stPoint ), MTH3D_M_xGetYofVector ( p_stMinPoint ) ) )
return FALSE;
if ( MTH_M_bGreater ( MTH3D_M_xGetYofVector ( p_stPoint ), MTH3D_M_xGetYofVector ( p_stMaxPoint ) ) )
return FALSE;
if ( MTH_M_bLess ( MTH3D_M_xGetZofVector ( p_stPoint ), MTH3D_M_xGetZofVector ( p_stMinPoint ) ) )
return FALSE;
if ( MTH_M_bGreater ( MTH3D_M_xGetZofVector ( p_stPoint ), MTH3D_M_xGetZofVector ( p_stMaxPoint ) ) )
return FALSE;
return TRUE;
}
/*
--------------------------------------------------------------------------------
-- Description : Get position of a point with the edge plans of a box
--------------------------------------------------------------------------------
-- Creation date : 22 aug 1996 Author : FPI
--------------------------------------------------------------------------------
*/
/* Which of the twelve edge plane(s) is point P outside of? */
/* used*/
unsigned long INT_fn_ulGetPositionPointWithEdgeBox ( MTH3D_tdstVector *p_stPoint,
MTH3D_tdstVector *p_stMinPoint,
MTH3D_tdstVector *p_stMaxPoint,
MTH3D_tdstVector *p_stDelta,
MTH3D_tdstVector *p_stNegDelta )
{
unsigned long ulOutCode;
MTH3D_tdstVector stMulDeltaPoint;
MTH3D_tdstVector stMulNegDeltaPoint;
MTH3D_tdstVector stMulDeltaMax;
MTH3D_tdstVector stMulNegDeltaMin;
ulOutCode = 0;
MTH3D_M_vScaleVector ( &stMulDeltaPoint, p_stDelta, p_stPoint );
MTH3D_M_vScaleVector ( &stMulNegDeltaPoint, p_stNegDelta, p_stPoint );
MTH3D_M_vScaleVector ( &stMulDeltaMax, p_stDelta, p_stMaxPoint );
MTH3D_M_vScaleVector ( &stMulNegDeltaMin, p_stNegDelta, p_stMinPoint );
if ( (stMulDeltaPoint.xX + stMulDeltaPoint.xY) > (stMulDeltaMax.xX + stMulDeltaMax.xY) )
ulOutCode |= 0x001;
if ( (stMulDeltaPoint.xX + stMulNegDeltaPoint.xY) > (stMulDeltaMax.xX + stMulNegDeltaMin.xY) )
ulOutCode |= 0x002;
if ( (stMulNegDeltaPoint.xX + stMulDeltaPoint.xY) > (stMulNegDeltaMin.xX + stMulDeltaMax.xY) )
ulOutCode |= 0x004;
if ( (stMulNegDeltaPoint.xX + stMulNegDeltaPoint.xY) > (stMulNegDeltaMin.xX + stMulNegDeltaMin.xY) )
ulOutCode |= 0x008;
if ( (stMulDeltaPoint.xX + stMulDeltaPoint.xZ) > (stMulDeltaMax.xX + stMulDeltaMax.xZ) )
ulOutCode |= 0x010;
if ( (stMulDeltaPoint.xX + stMulNegDeltaPoint.xZ) > (stMulDeltaMax.xX + stMulNegDeltaMin.xZ) )
ulOutCode |= 0x020;
if ( (stMulNegDeltaPoint.xX + stMulDeltaPoint.xZ) > (stMulNegDeltaMin.xX + stMulDeltaMax.xZ) )
ulOutCode |= 0x040;
if ( (stMulNegDeltaPoint.xX + stMulNegDeltaPoint.xZ) > (stMulNegDeltaMin.xX + stMulNegDeltaMin.xZ) )
ulOutCode |= 0x080;
if ( (stMulDeltaPoint.xY + stMulDeltaPoint.xZ) > (stMulDeltaMax.xY + stMulDeltaMax.xZ) )
ulOutCode |= 0x100;
if ( (stMulDeltaPoint.xY + stMulNegDeltaPoint.xZ) > (stMulDeltaMax.xY + stMulNegDeltaMin.xZ) )
ulOutCode |= 0x200;
if ( (stMulNegDeltaPoint.xY + stMulDeltaPoint.xZ) > (stMulNegDeltaMin.xY + stMulDeltaMax.xZ) )
ulOutCode |= 0x400;
if ( (stMulNegDeltaPoint.xY + stMulNegDeltaPoint.xZ) > (stMulNegDeltaMin.xY + stMulNegDeltaMin.xZ) )
ulOutCode |= 0x800;
return ulOutCode;
}
/*--------------------------------------------------------------------------------------*/
/* Name : INT_fn_bIntersectEdgeWithBoxWithHit*/
/* Author : Thierry QUERE*/
/* Date : 06/03/98*/
/* Description : */
/*--------------------------------------------------------------------------------------*/
/* used*/
ACP_tdxBool INT_fn_bIntersectEdgeWithBoxWithHit ( MTH3D_tdstVector *p_stVertex1,
MTH3D_tdstVector *p_stVertex2,
MTH3D_tdstVector *p_stVect12,
MTH3D_tdstVector *p_stMinPoint,
MTH3D_tdstVector *p_stMaxPoint,
unsigned long ulExploredPlan,
MTH3D_tdstVector * p_stHit)
{
MTH_tdxReal xT;
if ( ulExploredPlan & COL_C_ulXMinMask )
{
xT = MTH_M_xDiv ( MTH_M_xSub ( p_stMinPoint->xX, p_stVertex1->xX ), p_stVect12->xX );
p_stHit->xX = p_stMinPoint->xX;
p_stHit->xY = MTH_M_xMulAdd ( p_stVect12->xY, xT, p_stVertex1->xY );
p_stHit->xZ = MTH_M_xMulAdd ( p_stVect12->xZ, xT, p_stVertex1->xZ );
if ( INT_fn_bInYZRange ( p_stHit, p_stMinPoint, p_stMaxPoint ) )
return TRUE;
}
if ( ulExploredPlan & COL_C_ulXMaxMask )
{
xT = MTH_M_xDiv ( MTH_M_xSub ( p_stMaxPoint->xX, p_stVertex1->xX ), p_stVect12->xX );
p_stHit->xX = p_stMaxPoint->xX;
p_stHit->xY = MTH_M_xMulAdd ( p_stVect12->xY, xT, p_stVertex1->xY );
p_stHit->xZ = MTH_M_xMulAdd ( p_stVect12->xZ, xT, p_stVertex1->xZ );
if ( INT_fn_bInYZRange ( p_stHit, p_stMinPoint, p_stMaxPoint ) )
return TRUE;
}
if ( ulExploredPlan & COL_C_ulYMinMask )
{
xT = MTH_M_xDiv ( MTH_M_xSub ( p_stMinPoint->xY, p_stVertex1->xY ), p_stVect12->xY );
p_stHit->xX = MTH_M_xMulAdd ( p_stVect12->xX, xT, p_stVertex1->xX );
p_stHit->xY = p_stMinPoint->xY;
p_stHit->xZ = MTH_M_xMulAdd ( p_stVect12->xZ, xT, p_stVertex1->xZ );
if ( INT_fn_bInXZRange ( p_stHit, p_stMinPoint, p_stMaxPoint ) )
return TRUE;
}
if ( ulExploredPlan & COL_C_ulYMaxMask )
{
xT = MTH_M_xDiv ( MTH_M_xSub ( p_stMaxPoint->xY, p_stVertex1->xY ), p_stVect12->xY );
p_stHit->xX = MTH_M_xMulAdd ( p_stVect12->xX, xT, p_stVertex1->xX );
p_stHit->xY = p_stMaxPoint->xY;
p_stHit->xZ = MTH_M_xMulAdd ( p_stVect12->xZ, xT, p_stVertex1->xZ );
if ( INT_fn_bInXZRange ( p_stHit, p_stMinPoint, p_stMaxPoint ) )
return TRUE;
}
if ( ulExploredPlan & COL_C_ulZMinMask )
{
xT = MTH_M_xDiv ( MTH_M_xSub ( p_stMinPoint->xZ, p_stVertex1->xZ ), p_stVect12->xZ );
p_stHit->xX = MTH_M_xMulAdd ( p_stVect12->xX, xT, p_stVertex1->xX );
p_stHit->xY = MTH_M_xMulAdd ( p_stVect12->xY, xT, p_stVertex1->xY );
p_stHit->xZ = p_stMinPoint->xZ;
if ( INT_fn_bInXYRange ( p_stHit, p_stMinPoint, p_stMaxPoint ) )
return TRUE;
}
if ( ulExploredPlan & COL_C_ulZMaxMask )
{
xT = MTH_M_xDiv ( MTH_M_xSub ( p_stMaxPoint->xZ, p_stVertex1->xZ ), p_stVect12->xZ );
p_stHit->xX = MTH_M_xMulAdd ( p_stVect12->xX, xT, p_stVertex1->xX );
p_stHit->xY = MTH_M_xMulAdd ( p_stVect12->xY, xT, p_stVertex1->xY );
p_stHit->xZ = p_stMaxPoint->xZ;
if ( INT_fn_bInXYRange ( p_stHit, p_stMinPoint, p_stMaxPoint ) )
return TRUE;
}
return FALSE;
}
/*
--------------------------------------------------------------------------------
-- Description : Segment with box intersection test
--------------------------------------------------------------------------------
-- Creation date : 22 aug 1996 Author : FPI
--------------------------------------------------------------------------------
*/
/* used*/
ACP_tdxBool INT_fn_bIntersectSegmentWithBox ( MTH3D_tdstVector *p_stVertex1,
MTH3D_tdstVector *p_stVertex2,
MTH3D_tdstVector *p_stVect12,
MTH3D_tdstVector *p_stMinPoint,
MTH3D_tdstVector *p_stMaxPoint,
MTH_tdxReal *p_xT,
MTH3D_tdstVector *p_stHit,
MTH3D_tdstVector *p_stNormal )
{
unsigned long ulVertex1Test;
unsigned long ulVertex2Test;
unsigned long ulExploredPlan;
/* optimisation sur les demi-espaces */
ulVertex1Test = INT_fn_ulGetPositionPointWithBox ( p_stVertex1, p_stMinPoint, p_stMaxPoint );
if ( ulVertex1Test == COL_C_ulNullMask )
return FALSE;
ulVertex2Test = INT_fn_ulGetPositionPointWithBox ( p_stVertex2, p_stMinPoint, p_stMaxPoint );
if ( ulVertex1Test & ulVertex2Test )
return FALSE;
ulExploredPlan = ulVertex1Test;
if ( ulExploredPlan & COL_C_ulXMinMask )
{
*p_xT = MTH_M_xDiv ( MTH_M_xSub ( p_stMinPoint->xX, p_stVertex1->xX ), p_stVect12->xX );
p_stHit->xX = p_stMinPoint->xX;
p_stHit->xY = MTH_M_xMulAdd ( p_stVect12->xY, *p_xT, p_stVertex1->xY );
p_stHit->xZ = MTH_M_xMulAdd ( p_stVect12->xZ, *p_xT, p_stVertex1->xZ );
if ( INT_fn_bInYZRange ( p_stHit, p_stMinPoint, p_stMaxPoint ) )
{
MTH3D_M_vCopyVector ( p_stNormal, &(COL_g_a6_stBoxSidesNormal[COL_C_xXMin]) );
return TRUE;
}
}
if ( ulExploredPlan & COL_C_ulXMaxMask )
{
*p_xT = MTH_M_xDiv ( MTH_M_xSub ( p_stMaxPoint->xX, p_stVertex1->xX ), p_stVect12->xX );
p_stHit->xX = p_stMaxPoint->xX;
p_stHit->xY = MTH_M_xMulAdd ( p_stVect12->xY, *p_xT, p_stVertex1->xY );
p_stHit->xZ = MTH_M_xMulAdd ( p_stVect12->xZ, *p_xT, p_stVertex1->xZ );
if ( INT_fn_bInYZRange ( p_stHit, p_stMinPoint, p_stMaxPoint ) )
{
MTH3D_M_vCopyVector ( p_stNormal, &(COL_g_a6_stBoxSidesNormal[COL_C_xXMax]) );
return TRUE;
}
}
if ( ulExploredPlan & COL_C_ulYMinMask )
{
*p_xT = MTH_M_xDiv ( MTH_M_xSub ( p_stMinPoint->xY, p_stVertex1->xY ), p_stVect12->xY );
p_stHit->xX = MTH_M_xMulAdd ( p_stVect12->xX, *p_xT, p_stVertex1->xX );
p_stHit->xY = p_stMinPoint->xY;
p_stHit->xZ = MTH_M_xMulAdd ( p_stVect12->xZ, *p_xT, p_stVertex1->xZ );
if ( INT_fn_bInXZRange ( p_stHit, p_stMinPoint, p_stMaxPoint ) )
{
MTH3D_M_vCopyVector ( p_stNormal, &(COL_g_a6_stBoxSidesNormal[COL_C_xYMin]) );
return TRUE;
}
}
if ( ulExploredPlan & COL_C_ulYMaxMask )
{
*p_xT = MTH_M_xDiv ( MTH_M_xSub ( p_stMaxPoint->xY, p_stVertex1->xY ), p_stVect12->xY );
p_stHit->xX = MTH_M_xMulAdd ( p_stVect12->xX, *p_xT, p_stVertex1->xX );
p_stHit->xY = p_stMaxPoint->xY;
p_stHit->xZ = MTH_M_xMulAdd ( p_stVect12->xZ, *p_xT, p_stVertex1->xZ );
if ( INT_fn_bInXZRange ( p_stHit, p_stMinPoint, p_stMaxPoint ) )
{
MTH3D_M_vCopyVector ( p_stNormal, &(COL_g_a6_stBoxSidesNormal[COL_C_xYMax]) );
return TRUE;
}
}
if ( ulExploredPlan & COL_C_ulZMinMask )
{
*p_xT = MTH_M_xDiv ( MTH_M_xSub ( p_stMinPoint->xZ, p_stVertex1->xZ ), p_stVect12->xZ );
p_stHit->xX = MTH_M_xMulAdd ( p_stVect12->xX, *p_xT, p_stVertex1->xX );
p_stHit->xY = MTH_M_xMulAdd ( p_stVect12->xY, *p_xT, p_stVertex1->xY );
p_stHit->xZ = p_stMinPoint->xZ;
if ( INT_fn_bInXYRange ( p_stHit, p_stMinPoint, p_stMaxPoint ) )
{
MTH3D_M_vCopyVector ( p_stNormal, &(COL_g_a6_stBoxSidesNormal[COL_C_xZMin]) );
return TRUE;
}
}
if ( ulExploredPlan & COL_C_ulZMaxMask )
{
*p_xT = MTH_M_xDiv ( MTH_M_xSub ( p_stMaxPoint->xZ, p_stVertex1->xZ ), p_stVect12->xZ );
p_stHit->xX = MTH_M_xMulAdd ( p_stVect12->xX, *p_xT, p_stVertex1->xX );
p_stHit->xY = MTH_M_xMulAdd ( p_stVect12->xY, *p_xT, p_stVertex1->xY );
p_stHit->xZ = p_stMaxPoint->xZ;
if ( INT_fn_bInXYRange ( p_stHit, p_stMinPoint, p_stMaxPoint ) )
{
MTH3D_M_vCopyVector ( p_stNormal, &(COL_g_a6_stBoxSidesNormal[COL_C_xZMax]) );
return TRUE;
}
}
return FALSE;
}
/*
--------------------------------------------------------------------------------
-- Description : Semiaxe with box intersection test
--------------------------------------------------------------------------------
-- Creation date : 12 nov 1996 Author : FPI
--------------------------------------------------------------------------------
*/
#ifdef ACTIVE_EDITOR
/* active editor only*/
ACP_tdxBool INT_fn_bIntersectSemiAxeWithBox ( MTH3D_tdstVector *p_stVertex1,
MTH3D_tdstVector *p_stVertex2,
MTH3D_tdstVector *p_stVect12,
MTH3D_tdstVector *p_stMinPoint,
MTH3D_tdstVector *p_stMaxPoint,
ACP_tdxBool *bBack,
MTH_tdxReal *p_xT,
MTH3D_tdstVector *p_stHit,
MTH3D_tdstVector *p_stNormal )
{
unsigned long ulVertex1Test;
unsigned long ulVertex2Test;
unsigned long ulExploredPlan;
/* optimisation sur les demi-espaces */
ulVertex1Test = INT_fn_ulGetPositionPointWithBox ( p_stVertex1, p_stMinPoint, p_stMaxPoint );
ulVertex2Test = INT_fn_ulGetPositionPointWithBox ( p_stVertex2, p_stMinPoint, p_stMaxPoint );
/* intersections demi droite - cotes boite */
if ( ulVertex1Test == COL_C_ulNullMask )
{
if ( ulVertex2Test == COL_C_ulNullMask )
{
ulExploredPlan = COL_C_ulNullMask;
if ( MTH_M_bGreaterZero ( p_stVect12->xX ) )
ulExploredPlan |= COL_C_ulXMaxMask;
else
ulExploredPlan |= COL_C_ulXMinMask;
if ( MTH_M_bIsNull ( p_stVect12->xX ) )
ulExploredPlan &= ~( COL_C_ulXMinMask | COL_C_ulXMaxMask );
if ( MTH_M_bGreaterZero ( p_stVect12->xY ) )
ulExploredPlan |= COL_C_ulYMaxMask;
else
ulExploredPlan |= COL_C_ulYMinMask;
if ( MTH_M_bIsNull ( p_stVect12->xY ) )
ulExploredPlan &= ~( COL_C_ulYMinMask | COL_C_ulYMaxMask );
if ( MTH_M_bGreaterZero ( p_stVect12->xZ ) )
ulExploredPlan |= COL_C_ulZMaxMask;
else
ulExploredPlan |= COL_C_ulZMinMask;
if ( MTH_M_bIsNull ( p_stVect12->xZ ) )
ulExploredPlan &= ~( COL_C_ulZMinMask | COL_C_ulZMaxMask );
}
else
{
ulExploredPlan = ulVertex2Test;
}
}
else
{
if ( ulVertex1Test & ulVertex2Test )
{
ulExploredPlan = ulVertex1Test & ulVertex2Test;
if ( ( ulExploredPlan & COL_C_ulXMinMask ) && ( MTH_M_bLessEqualZero ( p_stVect12->xX ) ) )
ulExploredPlan &= ~COL_C_ulXMinMask;
if ( ( ulExploredPlan & COL_C_ulXMaxMask ) && ( MTH_M_bGreaterEqualZero ( p_stVect12->xX ) ) )
ulExploredPlan &= ~COL_C_ulXMaxMask;
if ( ( ulExploredPlan & COL_C_ulYMinMask ) && ( MTH_M_bLessEqualZero ( p_stVect12->xY ) ) )
ulExploredPlan &= ~COL_C_ulYMinMask;
if ( ( ulExploredPlan & COL_C_ulYMaxMask ) && ( MTH_M_bGreaterEqualZero ( p_stVect12->xY ) ) )
ulExploredPlan &= ~COL_C_ulYMaxMask;
if ( ( ulExploredPlan & COL_C_ulZMinMask ) && ( MTH_M_bLessEqualZero ( p_stVect12->xZ ) ) )
ulExploredPlan &= ~COL_C_ulZMinMask;
if ( ( ulExploredPlan & COL_C_ulZMaxMask ) && ( MTH_M_bGreaterEqualZero ( p_stVect12->xZ ) ) )
ulExploredPlan &= ~COL_C_ulZMaxMask;
}
else
{
ulExploredPlan = ulVertex1Test;
}
}
if ( ulExploredPlan & COL_C_ulXMinMask )
{
*p_xT = MTH_M_xDiv ( MTH_M_xSub ( p_stMinPoint->xX, p_stVertex1->xX ), p_stVect12->xX );
if ( MTH_M_bGreaterEqualZero ( *p_xT ) )
{
p_stHit->xX = p_stMinPoint->xX;
p_stHit->xY = MTH_M_xMulAdd ( p_stVect12->xY, *p_xT, p_stVertex1->xY );
p_stHit->xZ = MTH_M_xMulAdd ( p_stVect12->xZ, *p_xT, p_stVertex1->xZ );
if ( INT_fn_bInYZRange ( p_stHit, p_stMinPoint, p_stMaxPoint ) )
{
*bBack = MTH_M_bLessZero ( p_stVect12->xX );
MTH3D_M_vCopyVector ( p_stNormal, &(COL_g_a6_stBoxSidesNormal[COL_C_xXMin]) );
return TRUE;
}
}
}
if ( ulExploredPlan & COL_C_ulXMaxMask )
{
*p_xT = MTH_M_xDiv ( MTH_M_xSub ( p_stMaxPoint->xX, p_stVertex1->xX ), p_stVect12->xX );
if ( MTH_M_bGreaterEqualZero ( *p_xT ) )
{
p_stHit->xX = p_stMaxPoint->xX;
p_stHit->xY = MTH_M_xMulAdd ( p_stVect12->xY, *p_xT, p_stVertex1->xY );
p_stHit->xZ = MTH_M_xMulAdd ( p_stVect12->xZ, *p_xT, p_stVertex1->xZ );
if ( INT_fn_bInYZRange ( p_stHit, p_stMinPoint, p_stMaxPoint ) )
{
*bBack = MTH_M_bGreaterZero ( p_stVect12->xX );
MTH3D_M_vCopyVector ( p_stNormal, &(COL_g_a6_stBoxSidesNormal[COL_C_xXMax]) );
return TRUE;
}
}
}
if ( ulExploredPlan & COL_C_ulYMinMask )
{
*p_xT = MTH_M_xDiv ( MTH_M_xSub ( p_stMinPoint->xY, p_stVertex1->xY ), p_stVect12->xY );
if ( MTH_M_bGreaterEqualZero ( *p_xT ) )
{
p_stHit->xX = MTH_M_xMulAdd ( p_stVect12->xX, *p_xT, p_stVertex1->xX );
p_stHit->xY = p_stMinPoint->xY;
p_stHit->xZ = MTH_M_xMulAdd ( p_stVect12->xZ, *p_xT, p_stVertex1->xZ );
if ( INT_fn_bInXZRange ( p_stHit, p_stMinPoint, p_stMaxPoint ) )
{
*bBack = MTH_M_bLessZero ( p_stVect12->xY );
MTH3D_M_vCopyVector ( p_stNormal, &(COL_g_a6_stBoxSidesNormal[COL_C_xYMin]) );
return TRUE;
}
}
}
if ( ulExploredPlan & COL_C_ulYMaxMask )
{
*p_xT = MTH_M_xDiv ( MTH_M_xSub ( p_stMaxPoint->xY, p_stVertex1->xY ), p_stVect12->xY );
if ( MTH_M_bGreaterEqualZero ( *p_xT ) )
{
p_stHit->xX = MTH_M_xMulAdd ( p_stVect12->xX, *p_xT, p_stVertex1->xX );
p_stHit->xY = p_stMaxPoint->xY;
p_stHit->xZ = MTH_M_xMulAdd ( p_stVect12->xZ, *p_xT, p_stVertex1->xZ );
if ( INT_fn_bInXZRange ( p_stHit, p_stMinPoint, p_stMaxPoint ) )
{
*bBack = MTH_M_bGreaterZero ( p_stVect12->xY );
MTH3D_M_vCopyVector ( p_stNormal, &(COL_g_a6_stBoxSidesNormal[COL_C_xYMax]) );
return TRUE;
}
}
}
if ( ulExploredPlan & COL_C_ulZMinMask )
{
*p_xT = MTH_M_xDiv ( MTH_M_xSub ( p_stMinPoint->xZ, p_stVertex1->xZ ), p_stVect12->xZ );
if ( MTH_M_bGreaterEqualZero ( *p_xT ) )
{
p_stHit->xX = MTH_M_xMulAdd ( p_stVect12->xX, *p_xT, p_stVertex1->xX );
p_stHit->xY = MTH_M_xMulAdd ( p_stVect12->xY, *p_xT, p_stVertex1->xY );
p_stHit->xZ = p_stMinPoint->xZ;
if ( INT_fn_bInXYRange ( p_stHit, p_stMinPoint, p_stMaxPoint ) )
{
*bBack = MTH_M_bLessZero ( p_stVect12->xZ );
MTH3D_M_vCopyVector ( p_stNormal, &(COL_g_a6_stBoxSidesNormal[COL_C_xZMin]) );
return TRUE;
}
}
}
if ( ulExploredPlan & COL_C_ulZMaxMask )
{
*p_xT = MTH_M_xDiv ( MTH_M_xSub ( p_stMaxPoint->xZ, p_stVertex1->xZ ), p_stVect12->xZ );
if ( MTH_M_bGreaterEqualZero ( *p_xT ) )
{
p_stHit->xX = MTH_M_xMulAdd ( p_stVect12->xX, *p_xT, p_stVertex1->xX );
p_stHit->xY = MTH_M_xMulAdd ( p_stVect12->xY, *p_xT, p_stVertex1->xY );
p_stHit->xZ = p_stMaxPoint->xZ;
if ( INT_fn_bInXYRange ( p_stHit, p_stMinPoint, p_stMaxPoint ) )
{
*bBack = MTH_M_bGreaterZero ( p_stVect12->xZ );
MTH3D_M_vCopyVector ( p_stNormal, &(COL_g_a6_stBoxSidesNormal[COL_C_xZMax]) );
return TRUE;
}
}
}
return FALSE;
}
#endif
/*
--------------------------------------------------------------------------------
-- Description : Semiaxe with box intersection test for octree
--------------------------------------------------------------------------------
-- Creation date : 19 mar 1997 Author : FPI
--------------------------------------------------------------------------------
*/
#ifdef ACTIVE_EDITOR
/* active editor only*/
ACP_tdxBool INT_fn_bIntersectSemiAxeWithBoxForOctree ( MTH3D_tdstVector *p_stVertex1,
MTH3D_tdstVector *p_stVertex2,
MTH3D_tdstVector *p_stVect12,
MTH3D_tdstVector *p_stMinPoint,
MTH3D_tdstVector *p_stMaxPoint,
ACP_tdxBool *bBack,
MTH_tdxReal *p_xT )
{
unsigned long ulVertex1Test;
unsigned long ulVertex2Test;
unsigned long ulExploredPlan;
MTH3D_tdstVector stHit;
/* optimisation sur les demi-espaces */
ulVertex1Test = INT_fn_ulGetPositionPointWithBox ( p_stVertex1, p_stMinPoint, p_stMaxPoint );
ulVertex2Test = INT_fn_ulGetPositionPointWithBox ( p_stVertex2, p_stMinPoint, p_stMaxPoint );
/* intersections demi droite - cotes boite */
if ( ulVertex1Test == COL_C_ulNullMask )
{
if ( ulVertex2Test == COL_C_ulNullMask )
{
ulExploredPlan = COL_C_ulNullMask;
if ( MTH_M_bGreaterZero ( p_stVect12->xX ) )
ulExploredPlan |= COL_C_ulXMaxMask;
else
ulExploredPlan |= COL_C_ulXMinMask;
if ( MTH_M_bIsNull ( p_stVect12->xX ) )
ulExploredPlan &= ~( COL_C_ulXMinMask | COL_C_ulXMaxMask );
if ( MTH_M_bGreaterZero ( p_stVect12->xY ) )
ulExploredPlan |= COL_C_ulYMaxMask;
else
ulExploredPlan |= COL_C_ulYMinMask;
if ( MTH_M_bIsNull ( p_stVect12->xY ) )
ulExploredPlan &= ~( COL_C_ulYMinMask | COL_C_ulYMaxMask );
if ( MTH_M_bGreaterZero ( p_stVect12->xZ ) )
ulExploredPlan |= COL_C_ulZMaxMask;
else
ulExploredPlan |= COL_C_ulZMinMask;
if ( MTH_M_bIsNull ( p_stVect12->xZ ) )
ulExploredPlan &= ~( COL_C_ulZMinMask | COL_C_ulZMaxMask );
}
else
{
ulExploredPlan = ulVertex2Test;
}
}
else
{
if ( ulVertex1Test & ulVertex2Test )
{
ulExploredPlan = ulVertex1Test & ulVertex2Test;
if ( ( ulExploredPlan & COL_C_ulXMinMask ) && ( MTH_M_bLessEqualZero ( p_stVect12->xX ) ) )
ulExploredPlan &= ~COL_C_ulXMinMask;
if ( ( ulExploredPlan & COL_C_ulXMaxMask ) && ( MTH_M_bGreaterEqualZero ( p_stVect12->xX ) ) )
ulExploredPlan &= ~COL_C_ulXMaxMask;
if ( ( ulExploredPlan & COL_C_ulYMinMask ) && ( MTH_M_bLessEqualZero ( p_stVect12->xY ) ) )
ulExploredPlan &= ~COL_C_ulYMinMask;
if ( ( ulExploredPlan & COL_C_ulYMaxMask ) && ( MTH_M_bGreaterEqualZero ( p_stVect12->xY ) ) )
ulExploredPlan &= ~COL_C_ulYMaxMask;
if ( ( ulExploredPlan & COL_C_ulZMinMask ) && ( MTH_M_bLessEqualZero ( p_stVect12->xZ ) ) )
ulExploredPlan &= ~COL_C_ulZMinMask;
if ( ( ulExploredPlan & COL_C_ulZMaxMask ) && ( MTH_M_bGreaterEqualZero ( p_stVect12->xZ ) ) )
ulExploredPlan &= ~COL_C_ulZMaxMask;
}
else
{
ulExploredPlan = ulVertex1Test;
}
}
if ( ulExploredPlan & COL_C_ulXMinMask )
{
*p_xT = MTH_M_xDiv ( MTH_M_xSub ( p_stMinPoint->xX, p_stVertex1->xX ), p_stVect12->xX );
if ( MTH_M_bGreaterEqualZero ( *p_xT ) )
{
stHit.xX = p_stMinPoint->xX;
stHit.xY = MTH_M_xMulAdd ( p_stVect12->xY, *p_xT, p_stVertex1->xY );
stHit.xZ = MTH_M_xMulAdd ( p_stVect12->xZ, *p_xT, p_stVertex1->xZ );
if ( INT_fn_bInYZRange ( &stHit, p_stMinPoint, p_stMaxPoint ) )
{
*bBack = MTH_M_bLessZero ( p_stVect12->xX );
return TRUE;
}
}
}
if ( ulExploredPlan & COL_C_ulXMaxMask )
{
*p_xT = MTH_M_xDiv ( MTH_M_xSub ( p_stMaxPoint->xX, p_stVertex1->xX ), p_stVect12->xX );
if ( MTH_M_bGreaterEqualZero ( *p_xT ) )
{
stHit.xX = p_stMaxPoint->xX;
stHit.xY = MTH_M_xMulAdd ( p_stVect12->xY, *p_xT, p_stVertex1->xY );
stHit.xZ = MTH_M_xMulAdd ( p_stVect12->xZ, *p_xT, p_stVertex1->xZ );
if ( INT_fn_bInYZRange ( &stHit, p_stMinPoint, p_stMaxPoint ) )
{
*bBack = MTH_M_bGreaterZero ( p_stVect12->xX );
return TRUE;
}
}
}
if ( ulExploredPlan & COL_C_ulYMinMask )
{
*p_xT = MTH_M_xDiv ( MTH_M_xSub ( p_stMinPoint->xY, p_stVertex1->xY ), p_stVect12->xY );
if ( MTH_M_bGreaterEqualZero ( *p_xT ) )
{
stHit.xX = MTH_M_xMulAdd ( p_stVect12->xX, *p_xT, p_stVertex1->xX );
stHit.xY = p_stMinPoint->xY;
stHit.xZ = MTH_M_xMulAdd ( p_stVect12->xZ, *p_xT, p_stVertex1->xZ );
if ( INT_fn_bInXZRange ( &stHit, p_stMinPoint, p_stMaxPoint ) )
{
*bBack = MTH_M_bLessZero ( p_stVect12->xY );
return TRUE;
}
}
}
if ( ulExploredPlan & COL_C_ulYMaxMask )
{
*p_xT = MTH_M_xDiv ( MTH_M_xSub ( p_stMaxPoint->xY, p_stVertex1->xY ), p_stVect12->xY );
if ( MTH_M_bGreaterEqualZero ( *p_xT ) )
{
stHit.xX = MTH_M_xMulAdd ( p_stVect12->xX, *p_xT, p_stVertex1->xX );
stHit.xY = p_stMaxPoint->xY;
stHit.xZ = MTH_M_xMulAdd ( p_stVect12->xZ, *p_xT, p_stVertex1->xZ );
if ( INT_fn_bInXZRange ( &stHit, p_stMinPoint, p_stMaxPoint ) )
{
*bBack = MTH_M_bGreaterZero ( p_stVect12->xY );
return TRUE;
}
}
}
if ( ulExploredPlan & COL_C_ulZMinMask )
{
*p_xT = MTH_M_xDiv ( MTH_M_xSub ( p_stMinPoint->xZ, p_stVertex1->xZ ), p_stVect12->xZ );
if ( MTH_M_bGreaterEqualZero ( *p_xT ) )
{
stHit.xX = MTH_M_xMulAdd ( p_stVect12->xX, *p_xT, p_stVertex1->xX );
stHit.xY = MTH_M_xMulAdd ( p_stVect12->xY, *p_xT, p_stVertex1->xY );
stHit.xZ = p_stMinPoint->xZ;
if ( INT_fn_bInXYRange ( &stHit, p_stMinPoint, p_stMaxPoint ) )
{
*bBack = MTH_M_bLessZero ( p_stVect12->xZ );
return TRUE;
}
}
}
if ( ulExploredPlan & COL_C_ulZMaxMask )
{
*p_xT = MTH_M_xDiv ( MTH_M_xSub ( p_stMaxPoint->xZ, p_stVertex1->xZ ), p_stVect12->xZ );
if ( MTH_M_bGreaterEqualZero ( *p_xT ) )
{
stHit.xX = MTH_M_xMulAdd ( p_stVect12->xX, *p_xT, p_stVertex1->xX );
stHit.xY = MTH_M_xMulAdd ( p_stVect12->xY, *p_xT, p_stVertex1->xY );
stHit.xZ = p_stMaxPoint->xZ;
if ( INT_fn_bInXYRange ( &stHit, p_stMinPoint, p_stMaxPoint ) )
{
*bBack = MTH_M_bGreaterZero ( p_stVect12->xZ );
return TRUE;
}
}
}
return FALSE;
}
#endif
/*
--------------------------------------------------------------------------------
-- Description : Semiaxe with box intersection detection
--------------------------------------------------------------------------------
-- Creation date : 06 feb 1997 Author : FPI
--------------------------------------------------------------------------------
*/
#ifdef ACTIVE_EDITOR
/* active editor only*/
ACP_tdxBool INT_fn_bDetectIntersectSemiAxeWithBox ( MTH3D_tdstVector *p_stVertex1,
MTH3D_tdstVector *p_stVertex2,
MTH3D_tdstVector *p_stVect12,
MTH3D_tdstVector *p_stMinPoint,
MTH3D_tdstVector *p_stMaxPoint )
{
unsigned long ulVertex1Test;
unsigned long ulVertex2Test;
unsigned long ulExploredPlan;
MTH_tdxReal xT;
MTH3D_tdstVector stHit;
/* optimisation sur les demi-espaces */
ulVertex1Test = INT_fn_ulGetPositionPointWithBox ( p_stVertex1, p_stMinPoint, p_stMaxPoint );
if ( ulVertex1Test == COL_C_ulNullMask )
{
return TRUE;
}
ulVertex2Test = INT_fn_ulGetPositionPointWithBox ( p_stVertex2, p_stMinPoint, p_stMaxPoint );
if ( ulVertex2Test == COL_C_ulNullMask )
{
return TRUE;
}
/* intersections demi droite - cotes boite */
if ( ulVertex1Test & ulVertex2Test )
{
ulExploredPlan = ulVertex1Test & ulVertex2Test;
/*
if ( ( ulExploredPlan & COL_C_ulXMinMask ) && ( MTH_M_bGreaterEqualZero ( p_stVect12->xX ) ) )
ulExploredPlan &= ~COL_C_ulXMinMask;
if ( ( ulExploredPlan & COL_C_ulXMaxMask ) && ( MTH_M_bLessEqualZero ( p_stVect12->xX ) ) )
ulExploredPlan &= ~COL_C_ulXMaxMask;
if ( ( ulExploredPlan & COL_C_ulYMinMask ) && ( MTH_M_bGreaterEqualZero ( p_stVect12->xY ) ) )
ulExploredPlan &= ~COL_C_ulYMinMask;
if ( ( ulExploredPlan & COL_C_ulYMaxMask ) && ( MTH_M_bLessEqualZero ( p_stVect12->xY ) ) )
ulExploredPlan &= ~COL_C_ulYMaxMask;
if ( ( ulExploredPlan & COL_C_ulZMinMask ) && ( MTH_M_bGreaterEqualZero ( p_stVect12->xZ ) ) )
ulExploredPlan &= ~COL_C_ulZMinMask;
if ( ( ulExploredPlan & COL_C_ulZMaxMask ) && ( MTH_M_bLessEqualZero ( p_stVect12->xZ ) ) )
ulExploredPlan &= ~COL_C_ulZMaxMask;
*/
if ( ( ulExploredPlan & COL_C_ulXMinMask ) && ( MTH_M_bLessZero ( p_stVect12->xX ) ) )
return FALSE;
if ( ( ulExploredPlan & COL_C_ulXMaxMask ) && ( MTH_M_bGreaterZero ( p_stVect12->xX ) ) )
return FALSE;
if ( ( ulExploredPlan & COL_C_ulYMinMask ) && ( MTH_M_bLessZero ( p_stVect12->xY ) ) )
return FALSE;
if ( ( ulExploredPlan & COL_C_ulYMaxMask ) && ( MTH_M_bGreaterZero ( p_stVect12->xY ) ) )
return FALSE;
if ( ( ulExploredPlan & COL_C_ulZMinMask ) && ( MTH_M_bLessZero ( p_stVect12->xZ ) ) )
return FALSE;
if ( ( ulExploredPlan & COL_C_ulZMaxMask ) && ( MTH_M_bGreaterZero ( p_stVect12->xZ ) ) )
return FALSE;
}
else
{
ulExploredPlan = ulVertex1Test;
}
if ( ulExploredPlan & COL_C_ulXMinMask )
{
/*HP 260898*/
xT=MTH_M_xSub ( p_stMinPoint->xX, p_stVertex1->xX );
if(p_stVect12->xX)
xT = MTH_M_xDiv ( xT, p_stVect12->xX );
if ( MTH_M_bGreaterEqualZero ( xT ) )
{
stHit.xX = p_stMinPoint->xX;
stHit.xY = MTH_M_xMulAdd ( p_stVect12->xY, xT, p_stVertex1->xY );
stHit.xZ = MTH_M_xMulAdd ( p_stVect12->xZ, xT, p_stVertex1->xZ );
if ( INT_fn_bInYZRange ( &stHit, p_stMinPoint, p_stMaxPoint ) )
return TRUE;
}
}
if ( ulExploredPlan & COL_C_ulXMaxMask )
{
/*HP 260898*/
xT=MTH_M_xSub ( p_stMaxPoint->xX, p_stVertex1->xX );
if(p_stVect12->xX)
xT = MTH_M_xDiv ( xT, p_stVect12->xX );
if ( MTH_M_bGreaterEqualZero ( xT ) )
{
stHit.xX = p_stMaxPoint->xX;
stHit.xY = MTH_M_xMulAdd ( p_stVect12->xY, xT, p_stVertex1->xY );
stHit.xZ = MTH_M_xMulAdd ( p_stVect12->xZ, xT, p_stVertex1->xZ );
if ( INT_fn_bInYZRange ( &stHit, p_stMinPoint, p_stMaxPoint ) )
return TRUE;
}
}
if ( ulExploredPlan & COL_C_ulYMinMask )
{
/*HP 260898*/
xT = MTH_M_xSub ( p_stMinPoint->xY, p_stVertex1->xY );
if(p_stVect12->xY)
xT = MTH_M_xDiv ( xT, p_stVect12->xY );
if ( MTH_M_bGreaterEqualZero ( xT ) )
{
stHit.xX = MTH_M_xMulAdd ( p_stVect12->xX, xT, p_stVertex1->xX );
stHit.xY = p_stMinPoint->xY;
stHit.xZ = MTH_M_xMulAdd ( p_stVect12->xZ, xT, p_stVertex1->xZ );
if ( INT_fn_bInXZRange ( &stHit, p_stMinPoint, p_stMaxPoint ) )
return TRUE;
}
}
if ( ulExploredPlan & COL_C_ulYMaxMask )
{
/*HP 260898*/
xT=MTH_M_xSub ( p_stMaxPoint->xY, p_stVertex1->xY );
if(p_stVect12->xY)
xT = MTH_M_xDiv ( xT, p_stVect12->xY );
if ( MTH_M_bGreaterEqualZero ( xT ) )
{
stHit.xX = MTH_M_xMulAdd ( p_stVect12->xX, xT, p_stVertex1->xX );
stHit.xY = p_stMaxPoint->xY;
stHit.xZ = MTH_M_xMulAdd ( p_stVect12->xZ, xT, p_stVertex1->xZ );
if ( INT_fn_bInXZRange ( &stHit, p_stMinPoint, p_stMaxPoint ) )
return TRUE;
}
}
if ( ulExploredPlan & COL_C_ulZMinMask )
{
/*HP 260898*/
xT=MTH_M_xSub ( p_stMinPoint->xZ, p_stVertex1->xZ );
if(p_stVect12->xZ)
xT = MTH_M_xDiv ( xT, p_stVect12->xZ );
if ( MTH_M_bGreaterEqualZero ( xT ) )
{
stHit.xX = MTH_M_xMulAdd ( p_stVect12->xX, xT, p_stVertex1->xX );
stHit.xY = MTH_M_xMulAdd ( p_stVect12->xY, xT, p_stVertex1->xY );
stHit.xZ = p_stMinPoint->xZ;
if ( INT_fn_bInXYRange ( &stHit, p_stMinPoint, p_stMaxPoint ) )
return TRUE;
}
}
if ( ulExploredPlan & COL_C_ulZMaxMask )
{
/*HP260898*/
xT=MTH_M_xSub ( p_stMaxPoint->xZ, p_stVertex1->xZ );
if(p_stVect12->xZ)
xT = MTH_M_xDiv (xT, p_stVect12->xZ );
if ( MTH_M_bGreaterEqualZero ( xT ) )
{
stHit.xX = MTH_M_xMulAdd ( p_stVect12->xX, xT, p_stVertex1->xX );
stHit.xY = MTH_M_xMulAdd ( p_stVect12->xY, xT, p_stVertex1->xY );
stHit.xZ = p_stMaxPoint->xZ;
if ( INT_fn_bInXYRange ( &stHit, p_stMinPoint, p_stMaxPoint ) )
return TRUE;
}
}
return FALSE;
}
#endif
/* this macros return x,y or z of the vector if num == 0,1 or 2 */
#define M_GetCoord(p_stVect,Num) \
*( ((MTH_tdxReal*)p_stVect) + Num)
/* result :*/
/* 0 --> no detection*/
/* 1 --> detection*/
/* 2 --> don't know*/
/* used*/
static unsigned char ucPlaneCrossingdetect(MTH3D_tdstVector *p_stVertex1,
MTH3D_tdstVector *p_stVect12,
MTH3D_tdstVector *p_stMinPoint,
MTH3D_tdstVector *p_stMaxPoint,
MTH_tdxReal xT,
char cFace)
{
unsigned long idx1,idx2;
MTH_tdxReal xTmp;
/* compute variables according to the face to manage*/
switch (cFace)
{
case 'X':
idx1 = 1;
idx2 = 2;
break;
case 'Y':
idx1 = 0;
idx2 = 2;
break;
case 'Z':
idx1 = 0;
idx2 = 1;
break;
default:
assert(0);
break;
}
/* all comments are written in the case 'X', with idx1 = 1 (Y) and idx2 = 2 (Z)*/
/* xTmp is the y of the intersection point with the side of the box*/
xTmp = MTH_M_xMulAdd (M_GetCoord(p_stVect12,idx1), xT, M_GetCoord(p_stVertex1,idx1));
if (MTH_M_bGreaterZero(M_GetCoord(p_stVect12,idx1)))
{
/* the A point is on the front, the B point is in the back*/
/* if it intersects the side of the box behind the back plane, it is out !*/
if (MTH_M_bGreater (xTmp,M_GetCoord(p_stMaxPoint,idx1)) )
return 0;
/* if it intersects the left side of the box behind the front plane, continue search on up / down plane !*/
if (MTH_M_bGreaterEqual(xTmp,M_GetCoord(p_stMinPoint,idx1)) )
{
/* xTmp is the z of the intersection point with the left side of the box*/
xTmp = MTH_M_xMulAdd (M_GetCoord(p_stVect12,idx2), xT, M_GetCoord(p_stVertex1,idx2));
if (MTH_M_bGreaterZero(M_GetCoord(p_stVect12,idx2)))
{
/* the A point is down, the B point is up*/
/* if it intersects the left side of the box higher than the up plane, it is out !*/
if (MTH_M_bGreater (xTmp,M_GetCoord(p_stMaxPoint,idx2)) )
return 0;
/* if it intersects the left side of the box higher than the down plane, it is in !!!*/
if (MTH_M_bGreaterEqual(xTmp,M_GetCoord(p_stMinPoint,idx2)) )
{
return 1;
}
/* else we don't know....*/
}
else
{
/* the A point is up, the B point is down*/
/* if it intersects the left side of the box lower than the down plane, it is out !*/
if (MTH_M_bLess (xTmp,M_GetCoord(p_stMinPoint,idx2)) )
return 0;
/* if it intersects the left side of the box lower than the up plane, it is in !!!*/
if (MTH_M_bLessEqual(xTmp,M_GetCoord(p_stMaxPoint,idx2)) )
{
return 1;
}
/* else we don't know....*/
}
}
/* else we don't know... continue searching*/
}
else
{
/* the A point is in the back, the B point is on the front*/
/* if it intersects the left side of the box before the front plane, it is out !*/
if (MTH_M_bLess (xTmp,M_GetCoord(p_stMinPoint,idx1)) )
return 0;
/* if it intersects the left side of the box before the back plane, continue search on up / down plane !*/
if (MTH_M_bLessEqual(xTmp,M_GetCoord(p_stMaxPoint,idx1)) )
{
/* xTmp is the z of the intersection point with the left side of the box*/
xTmp = MTH_M_xMulAdd (M_GetCoord(p_stVect12,idx2), xT, M_GetCoord(p_stVertex1,idx2));
if (MTH_M_bGreaterZero(M_GetCoord(p_stVect12,idx2)))
{
/* the A point is down, the B point is up*/
/* if it intersects the left side of the box higher than the up plane, it is out !*/
if (MTH_M_bGreater (xTmp,M_GetCoord(p_stMaxPoint,idx2)) )
return 0;
/* if it intersects the left side of the box higher than the down plane, it is in !!!*/
if (MTH_M_bGreaterEqual(xTmp,M_GetCoord(p_stMinPoint,idx2)) )
{
return 1;
}
/* else we don't know....*/
}
else
{
/* the A point is up, the B point is down*/
/* if it intersects the left side of the box lower than the down plane, it is out !*/
if (MTH_M_bLess (xTmp,M_GetCoord(p_stMinPoint,idx2)) )
return 0;
/* if it intersects the left side of the box lower than the up plane, it is in !!!*/
if (MTH_M_bLessEqual(xTmp,M_GetCoord(p_stMaxPoint,idx2)) )
{
return 1;
}
/* else we don't know....*/
}
}
/* else we don't know... continue searching*/
}
return 2;
}
/* used*/
ACP_tdxBool INT_fn_bDetectIntersectSegmentWithBox ( MTH3D_tdstVector *p_stVertex1,
MTH3D_tdstVector *p_stVect12,
MTH3D_tdstVector *p_stMinPoint,
MTH3D_tdstVector *p_stMaxPoint,
MTH_tdxReal *_p_xT)
{
unsigned long ulVertex1Test;
unsigned long ulVertex2Test;
unsigned long ulExploredPlan;
MTH_tdxReal xT,*p_xT;
MTH3D_tdstVector stVertex2;
ACP_tdxBool bResult,bWithxT;
if (_p_xT == NULL)
{
bWithxT = FALSE;
p_xT = &xT;
}
else
{
p_xT = _p_xT;
bWithxT = TRUE;
}
/* optimisation sur les demi-espaces */
ulVertex1Test = INT_fn_ulGetPositionPointWithBox ( p_stVertex1, p_stMinPoint, p_stMaxPoint );
if ( ulVertex1Test == COL_C_ulNullMask )
{
/* first point is inside the box !*/
*p_xT = MTH_C_ZERO;
return TRUE;
}
MTH3D_M_vAddVector(&stVertex2,p_stVertex1,p_stVect12);
ulVertex2Test = INT_fn_ulGetPositionPointWithBox ( &stVertex2, p_stMinPoint, p_stMaxPoint );
if ( ulVertex2Test == COL_C_ulNullMask )
{
/* second point is inside the box !*/
*p_xT = 1;
return TRUE;
}
if (ulVertex1Test & ulVertex2Test)
{
/* both point are located on the same side of the same plan of the box (but don't care which plan it is)*/
/* but they are located on the wrong side, so the segment can't intersect the box !*/
return FALSE;
}
ulExploredPlan = ulVertex1Test | ulVertex2Test;
if (!(ulExploredPlan & (COL_C_ulXMinMask | COL_C_ulXMaxMask | COL_C_ulYMinMask | COL_C_ulYMaxMask)))
{
/* both point are inside the box, according to X and Y planes*/
/* and those points can't be on the same side of the Z plane (already tested up there)... there is collision*/
if (!bWithxT)
return TRUE;
/* compute xT*/
if ( ulVertex1Test & COL_C_ulZMinMask )
{
*p_xT = MTH_M_xSub ( p_stMinPoint->xZ, p_stVertex1->xZ );
}
else
{
*p_xT = MTH_M_xSub ( p_stMaxPoint->xZ, p_stVertex1->xZ );
}
*p_xT = MTH_M_xDiv ( *p_xT, p_stVect12->xZ );
return TRUE;
}
if (!(ulExploredPlan & (COL_C_ulXMinMask | COL_C_ulXMaxMask | COL_C_ulZMinMask | COL_C_ulZMaxMask)))
{
/* both point are inside the box, according to X and Z planes*/
/* and those points can't be on the same side of the Y plane (already tested up there)... there is collision*/
if (!bWithxT)
return TRUE;
/* compute xT*/
if ( ulVertex1Test & COL_C_ulYMinMask )
{
*p_xT = MTH_M_xSub ( p_stMinPoint->xY, p_stVertex1->xY );
}
else
{
*p_xT = MTH_M_xSub ( p_stMaxPoint->xY, p_stVertex1->xY );
}
*p_xT = MTH_M_xDiv ( *p_xT, p_stVect12->xY );
return TRUE;
}
if (!(ulExploredPlan & (COL_C_ulZMinMask | COL_C_ulZMaxMask | COL_C_ulYMinMask | COL_C_ulYMaxMask)))
{
/* both point are inside the box, according to Z and Y planes*/
/* and those points can't be on the same side of the X plane (already tested up there)... there is collision*/
if (!bWithxT)
return TRUE;
/* compute xT*/
if ( ulVertex1Test & COL_C_ulXMinMask )
{
*p_xT = MTH_M_xSub ( p_stMinPoint->xX, p_stVertex1->xX );
}
else
{
*p_xT = MTH_M_xSub ( p_stMaxPoint->xX, p_stVertex1->xX );
}
*p_xT = MTH_M_xDiv ( *p_xT, p_stVect12->xX );
return TRUE;
}
/* complete calcul... (parametric, plane after plane... lot of code, but fast computation)*/
ulExploredPlan = ulVertex1Test;
if ( ulExploredPlan & COL_C_ulXMinMask )
{
/* left plane :*/
*p_xT=MTH_M_xSub ( p_stMinPoint->xX, p_stVertex1->xX );
/* xT must be >0 because the case COL_C_ulXMinMask means the point A is on the left of the box ! */
/* p_stVect12->xX must be > 0 else both A and B points will be on the left of the box, which is treated up there*/
assert(MTH_M_bGreaterZero(p_stVect12->xX));
assert(MTH_M_bGreaterZero(*p_xT));
*p_xT = MTH_M_xDiv ( *p_xT, p_stVect12->xX );
if ( (bResult = ucPlaneCrossingdetect(p_stVertex1,p_stVect12,p_stMinPoint,p_stMaxPoint,*p_xT,'X')) < 2)
{
return bResult;
}
}
if ( ulExploredPlan & COL_C_ulXMaxMask )
{
/* right plane :*/
*p_xT=MTH_M_xSub ( p_stMaxPoint->xX, p_stVertex1->xX );
/* xT must be <0 because the case COL_C_ulXMaxMask means the point A is on the right of the box ! */
/* p_stVect12->xX must be < 0 else both A and B points will be on the right of the box, which is treated up there*/
assert(MTH_M_bLessZero(p_stVect12->xX));
assert(MTH_M_bLessZero(*p_xT));
*p_xT = MTH_M_xDiv ( *p_xT, p_stVect12->xX );
if ( (bResult = ucPlaneCrossingdetect(p_stVertex1,p_stVect12,p_stMinPoint,p_stMaxPoint,*p_xT,'X')) < 2)
{
return bResult;
}
}
if ( ulExploredPlan & COL_C_ulYMinMask )
{
/* front plane :*/
*p_xT=MTH_M_xSub ( p_stMinPoint->xY, p_stVertex1->xY );
/* xT must be >0 because the case COL_C_ulYMinMask means the point A is in front of the box ! */
/* p_stVect12->xY must be > 0 else both A and B points will be in front of the box, which is treated up there*/
assert(MTH_M_bGreaterZero(p_stVect12->xY));
assert(MTH_M_bGreaterZero(*p_xT));
*p_xT = MTH_M_xDiv ( *p_xT, p_stVect12->xY );
if ( (bResult = ucPlaneCrossingdetect(p_stVertex1,p_stVect12,p_stMinPoint,p_stMaxPoint,*p_xT,'Y')) < 2)
{
return bResult;
}
}
if ( ulExploredPlan & COL_C_ulYMaxMask )
{
/* back plane :*/
*p_xT=MTH_M_xSub ( p_stMaxPoint->xY, p_stVertex1->xY );
/* xT must be <0 because the case COL_C_ulYMaxMask means the point A is behind the box ! */
/* p_stVect12->xY must be < 0 else both A and B points will be behind the box, which is treated up there*/
assert(MTH_M_bLessZero(p_stVect12->xY));
assert(MTH_M_bLessZero(*p_xT));
*p_xT = MTH_M_xDiv ( *p_xT, p_stVect12->xY );
if ( (bResult = ucPlaneCrossingdetect(p_stVertex1,p_stVect12,p_stMinPoint,p_stMaxPoint,*p_xT,'Y')) < 2)
{
return bResult;
}
}
if ( ulExploredPlan & COL_C_ulZMinMask )
{
/* bottom plane :*/
*p_xT=MTH_M_xSub ( p_stMinPoint->xZ, p_stVertex1->xZ );
/* xT must be >0 because the case COL_C_ulZMinMask means the point A is under the box ! */
/* p_stVect12->xZ must be > 0 else both A and B points will be under the box, which is treated up there*/
assert(MTH_M_bGreaterZero(p_stVect12->xZ));
assert(MTH_M_bGreaterZero(*p_xT));
*p_xT = MTH_M_xDiv ( *p_xT, p_stVect12->xZ );
if ( (bResult = ucPlaneCrossingdetect(p_stVertex1,p_stVect12,p_stMinPoint,p_stMaxPoint,*p_xT,'Z')) < 2)
{
return bResult;
}
}
if ( ulExploredPlan & COL_C_ulZMaxMask )
{
/* top plane :*/
*p_xT=MTH_M_xSub ( p_stMaxPoint->xZ, p_stVertex1->xZ );
/* xT must be <0 because the case COL_C_ulZMaxMask means the point A is above the box ! */
/* p_stVect12->xZ must be < 0 else both A and B points will be above the box, which is treated up there*/
assert(MTH_M_bLessZero(p_stVect12->xZ));
assert(MTH_M_bLessZero(*p_xT));
*p_xT = MTH_M_xDiv ( *p_xT, p_stVect12->xZ );
if ( (bResult = ucPlaneCrossingdetect(p_stVertex1,p_stVect12,p_stMinPoint,p_stMaxPoint,*p_xT,'Z')) < 2)
{
return bResult;
}
}
return FALSE;
}
/*
--------------------------------------------------------------------------------
-- Description : Get the inclusion of point in triangle
--------------------------------------------------------------------------------
-- Creation date : 29 oct 1996 Author : FPI
--------------------------------------------------------------------------------
*/
/* Test if 3D point is inside 3D triangle */
/* without epsilon = exact method and point vectors gligou */
/* used*/
ACP_tdxBool INT_fn_bGetPointInTriangle ( MTH3D_tdstVector *p_stPoint,
MTH3D_tdstVector *p_stVertex0,
MTH3D_tdstVector *p_stVertex1,
MTH3D_tdstVector *p_stVertex2,
MTH3D_tdstVector *p_stNormal )
{
MTH3D_tdstVector stVectP0;
MTH3D_tdstVector stVectP1;
MTH3D_tdstVector stVectP2;
MTH_tdxReal xDet;
MTH3D_M_vSubVector ( &stVectP0, p_stVertex0, p_stPoint );
MTH3D_M_vSubVector ( &stVectP1, p_stVertex1, p_stPoint );
MTH3D_M_vSubVector ( &stVectP2, p_stVertex2, p_stPoint );
/* on prend la composante maximale de la normale et on calcule les determinants */
if ( MTH_M_xAbs ( p_stNormal->xZ ) >= MTH_C_InvSqrt3 )
{ /* c est Z */
xDet = MTH3D_M_xDetXYVector ( &stVectP0, &stVectP1 );
if ( FUT_M_bSameSign ( xDet, p_stNormal->xZ ) )
{
xDet = MTH3D_M_xDetXYVector ( &stVectP1, &stVectP2 );
if ( FUT_M_bSameSign ( xDet, p_stNormal->xZ ) )
{
xDet = MTH3D_M_xDetXYVector ( &stVectP2, &stVectP0 );
return FUT_M_bSameSign ( xDet, p_stNormal->xZ );
}
else
{
return FALSE;
}
}
else
{
return FALSE;
}
}
else
{
if ( MTH_M_xAbs ( p_stNormal->xX ) >= MTH_C_InvSqrt3 )
{ /* c est X */
xDet = MTH3D_M_xDetYZVector ( &stVectP0, &stVectP1 );
if ( FUT_M_bSameSign ( xDet, p_stNormal->xX ) )
{
xDet = MTH3D_M_xDetYZVector ( &stVectP1, &stVectP2 );
if ( FUT_M_bSameSign ( xDet, p_stNormal->xX ) )
{
xDet = MTH3D_M_xDetYZVector ( &stVectP2, &stVectP0 );
return FUT_M_bSameSign ( xDet, p_stNormal->xX );
}
else
{
return FALSE;
}
}
else
{
return FALSE;
}
}
else
{ /* c est Y */
xDet = MTH3D_M_xDetZXVector ( &stVectP0, &stVectP1 );
if ( FUT_M_bSameSign ( xDet, p_stNormal->xY ) )
{
xDet = MTH3D_M_xDetZXVector ( &stVectP1, &stVectP2 );
if ( FUT_M_bSameSign ( xDet, p_stNormal->xY ) )
{
xDet = MTH3D_M_xDetZXVector ( &stVectP2, &stVectP0 );
return FUT_M_bSameSign ( xDet, p_stNormal->xY );
}
else
{
return FALSE;
}
}
else
{
return FALSE;
}
}
}
}
/*
--------------------------------------------------------------------------------
-- Description : fast rejection of triangle / segment intersection test
--------------------------------------------------------------------------------
*/
/* used*/
ACP_tdxBool INT_fn_bFastRejectIntersectSegmentWithTriangle
(
MTH3D_tdstVector *p_stVertexA,
MTH3D_tdstVector *p_stVectAB,
MTH3D_tdstVector *p_stVertex1,
MTH3D_tdstVector *p_stVertex2,
MTH3D_tdstVector *p_stVertex3
)
{
MTH_tdxReal xMin;
MTH_tdxReal xMax;
MTH3D_tdstVector stVertexB;
ACP_tdxBool bGreaterZero;
MTH3D_M_vAddVector(&stVertexB, p_stVertexA, p_stVectAB);
/* cas de rejection en X */
bGreaterZero = MTH_M_bGreaterZero ( p_stVectAB->xX );
/* min A, B */
xMin = bGreaterZero ? p_stVertexA->xX : stVertexB.xX;
/* max 1, 2, 3 */
xMax = FUT_M_xMaxValue3 ( p_stVertex1->xX, p_stVertex2->xX, p_stVertex3->xX );
if ( MTH_M_bLess ( xMax, xMin ) )
{
return FALSE;
}
/* max A, B */
xMax = bGreaterZero ? stVertexB.xX : p_stVertexA->xX;
/* min 1, 2, 3 */
xMin = FUT_M_xMinValue3 ( p_stVertex1->xX, p_stVertex2->xX, p_stVertex3->xX );
if ( MTH_M_bLess ( xMax, xMin ) )
{
return FALSE;
}
/* cas de rejection en Y */
bGreaterZero = MTH_M_bGreaterZero ( p_stVectAB->xY );
/* min A, B */
xMin = bGreaterZero ? p_stVertexA->xY : stVertexB.xY;
/* max 1, 2, 3 */
xMax = FUT_M_xMaxValue3 ( p_stVertex1->xY, p_stVertex2->xY, p_stVertex3->xY );
if ( MTH_M_bLess ( xMax, xMin ) )
{
return FALSE;
}
/* max A, B */
xMax = bGreaterZero ? stVertexB.xY : p_stVertexA->xY;
/* min 1, 2, 3 */
xMin = FUT_M_xMinValue3 ( p_stVertex1->xY, p_stVertex2->xY, p_stVertex3->xY );
if ( MTH_M_bLess ( xMax, xMin ) )
{
return FALSE;
}
/* cas de rejection en Z */
bGreaterZero = MTH_M_bGreaterZero ( p_stVectAB->xZ );
/* min A, B */
xMin = bGreaterZero ? p_stVertexA->xZ : stVertexB.xZ;
/* max 1, 2, 3 */
xMax = FUT_M_xMaxValue3 ( p_stVertex1->xZ, p_stVertex2->xZ, p_stVertex3->xZ );
if ( MTH_M_bLess ( xMax, xMin ) )
{
return FALSE;
}
/* max A, B */
xMax = bGreaterZero ? stVertexB.xZ : p_stVertexA->xZ;
/* min 1, 2, 3 */
xMin = FUT_M_xMinValue3 ( p_stVertex1->xZ, p_stVertex2->xZ, p_stVertex3->xZ );
if ( MTH_M_bLess ( xMax, xMin ) )
{
return FALSE;
}
return TRUE;
}
/*
--------------------------------------------------------------------------------
-- Description : Segment with triangle intersection test
--------------------------------------------------------------------------------
-- Creation date : 22 aug 1996 Author : FPI
--------------------------------------------------------------------------------
*/
/* teste l intersection d un segment et d un triangle */
/* used*/
ACP_tdxBool INT_fn_bIntersectSegmentWithTriangle ( MTH3D_tdstVector *p_stVertexA,
MTH3D_tdstVector *p_stVectAB,
MTH3D_tdstVector *p_stVertex1,
MTH3D_tdstVector *p_stVertex2,
MTH3D_tdstVector *p_stVertex3,
MTH3D_tdstVector *p_stNormal,
MTH_tdxReal xDPlan,
MTH_tdxReal *p_xT,
MTH3D_tdstVector *p_stHit )
{
MTH_tdxReal xDotProdPara;
MTH_tdxReal xDivid;
MTH_tdxReal xT;
#if 1
if ( !INT_fn_bFastRejectIntersectSegmentWithTriangle(p_stVertexA, p_stVectAB, p_stVertex1, p_stVertex2, p_stVertex3) )
return FALSE;
#endif
/* segment parallele au plan */
xDotProdPara = MTH3D_M_xDotProductVector ( p_stNormal, p_stVectAB );
/* backface du segment */
if ( MTH_M_bLessZero ( xDotProdPara ) )
{
xDivid = MTH_M_xAdd ( MTH3D_M_xDotProductVector ( p_stNormal, p_stVertexA ), xDPlan );
if ( ( MTH_M_bGreaterZero ( xDivid ) ) && ( MTH_M_bLess ( xDivid, MTH_M_xNeg ( xDotProdPara ) ) ) )
{
/* intersection segment plan du triangle */
xT = MTH_M_xNeg ( MTH_M_xDiv ( xDivid, xDotProdPara ) );
/* coordonnees du point d intersection */
MTH3D_M_vMulAddVector ( p_stHit, xT, p_stVectAB, p_stVertexA );
/* verification du point d intersection dans le triangle */
if ( INT_fn_bGetPointInTriangle ( p_stHit, p_stVertex1, p_stVertex2, p_stVertex3, p_stNormal ) )
{
*p_xT = xT;
return TRUE;
}
else
{
return FALSE;
}
}
else
{
/* point d intersection en dehors du segment */
return FALSE;
}
}
else
{
return FALSE;
}
}
/* teste l intersection d un segment et d un triangle */
/* used*/
ACP_tdxBool INT_fn_bIntersectSegmentWithTriangle2 ( MTH3D_tdstVector *p_stVertexA,
MTH3D_tdstVector *p_stVectAB,
MTH3D_tdstVector *p_stVertex1,
MTH3D_tdstVector *p_stVertex2,
MTH3D_tdstVector *p_stVertex3,
MTH3D_tdstVector *p_stNormal,
MTH_tdxReal xDPlan,
MTH_tdxReal xDotProduct,
MTH_tdxReal *p_xT,
MTH3D_tdstVector *p_stHit )
{
MTH_tdxReal xDivid;
MTH_tdxReal xT;
#if 1
if ( !INT_fn_bFastRejectIntersectSegmentWithTriangle(p_stVertexA, p_stVectAB, p_stVertex1, p_stVertex2, p_stVertex3) )
return FALSE;
#endif
xDivid = MTH_M_xAdd ( MTH3D_M_xDotProductVector ( p_stNormal, p_stVertexA ), xDPlan );
/* jt 22/02/99
correction : intersection si acteur au contact et se d<>place de epsilon vers la face ou est immobile
if ( ( MTH_M_bGreaterZero ( xDivid ) ) && ( MTH_M_bLess ( xDivid, MTH_M_xNeg ( xDotProduct ) ) ) ) */
/* jt 140699 */
/* si xDotProduct == 0 <20> un epsilon pr<70>s, il est possible de collisionner la face tangentiellemnt
/* et il ne faut pas rejetter la collision <20> priori */
if (MTH_M_bIsNullWithEpsilon ( xDivid, MTH_M_xDoubleToReal(1e-3)) && MTH_M_bLess(xDotProduct, MTH_M_xDoubleToReal(-1e-3)) )
{
*p_xT = MTH_C_ZERO;
*p_stHit = *p_stVertexA;
return TRUE;
}
/* end jt 140699 */
if ( ( MTH_M_bGreaterEqualZero ( xDivid ) ) && ( MTH_M_bLess ( xDivid, MTH_M_xNeg ( xDotProduct ) ) ) )
/* end jt */
{
/* intersection segment plan du triangle */
xT = MTH_M_xNeg ( MTH_M_xDiv ( xDivid, xDotProduct ) );
/* coordonnees du point d intersection */
MTH3D_M_vMulAddVector ( p_stHit, xT, p_stVectAB, p_stVertexA );
/* verification du point d intersection dans le triangle */
if ( INT_fn_bGetPointInTriangle ( p_stHit, p_stVertex1, p_stVertex2, p_stVertex3, p_stNormal ) )
{
*p_xT = xT;
return TRUE;
}
else
{
return FALSE;
}
}
else
{
/* point d intersection en dehors du segment */
return FALSE;
}
}
/*
--------------------------------------------------------------------------------
-- Description : Segment with triangle intersection test
--------------------------------------------------------------------------------
-- Creation date : 22 aug 1996 Author : FPI
--------------------------------------------------------------------------------
*/
/* teste l intersection d un segment et d un triangle */
/* used*/
ACP_tdxBool INT_fn_bDetectIntersectSegmentWithTriangle ( MTH3D_tdstVector *p_stVertexA,
MTH3D_tdstVector *p_stVectAB,
MTH3D_tdstVector *p_stVertex1,
MTH3D_tdstVector *p_stVertex2,
MTH3D_tdstVector *p_stVertex3,
MTH3D_tdstVector *p_stNormal,
MTH_tdxReal xDPlan )
{
MTH_tdxReal xDotProdPara;
MTH_tdxReal xDivid;
MTH_tdxReal xT;
MTH3D_tdstVector stHit;
#if 1
if ( !INT_fn_bFastRejectIntersectSegmentWithTriangle(p_stVertexA, p_stVectAB, p_stVertex1, p_stVertex2, p_stVertex3) )
return FALSE;
#endif
/* segment parallele au plan */
xDotProdPara = MTH3D_M_xDotProductVector ( p_stNormal, p_stVectAB );
/* backface du segment */
if ( MTH_M_bLessZero ( xDotProdPara ) )
{
xDivid = MTH_M_xAdd ( MTH3D_M_xDotProductVector ( p_stNormal, p_stVertexA ), xDPlan );
/* intersection segment plan du triangle */
xT = MTH_M_xNeg ( MTH_M_xDiv ( xDivid, xDotProdPara ) );
/* verification du point d intersection sur le segment */
if ( MTH_M_bInUnitEqual ( xT ) )
{
/* coordonnees du point d intersection */
MTH3D_M_vMulAddVector ( &stHit, xT, p_stVectAB, p_stVertexA );
/* verification du point d intersection dans le triangle */
return INT_fn_bGetPointInTriangle ( &stHit, p_stVertex1, p_stVertex2, p_stVertex3, p_stNormal );
}
else
{
/* point d intersection en dehors du segment */
return FALSE;
}
}
else
{
return FALSE;
}
}
/*
--------------------------------------------------------------------------------
-- Description : Semiaxe with triangle intersection test
--------------------------------------------------------------------------------
-- Creation date : 12 nov 1996 Author : FPI
--------------------------------------------------------------------------------
*/
/* teste l intersection d une demi droite et d un triangle */
#if defined(ACTIVE_EDITOR)
/*active editor only*/
ACP_tdxBool INT_fn_bIntersectSemiAxeWithTriangle ( MTH3D_tdstVector *p_stVertexA,
MTH3D_tdstVector *p_stVectAB,
MTH3D_tdstVector *p_stVertex1,
MTH3D_tdstVector *p_stVertex2,
MTH3D_tdstVector *p_stVertex3,
MTH3D_tdstVector *p_stNormal,
MTH_tdxReal xDPlan,
ACP_tdxBool *bBack,
MTH_tdxReal *p_xT,
MTH3D_tdstVector *p_stHit )
{
MTH_tdxReal xDotProd;
/* droite parallele au plan */
xDotProd = MTH3D_M_xDotProductVector ( p_stNormal, p_stVectAB );
/* parallelisme de la droite */
if ( xDotProd != MTH_C_ZERO )
{
/* backface */
*bBack = MTH_M_bGreaterEqualZero ( xDotProd );
/* intersection droite plan du triangle */
*p_xT = MTH_M_xNeg ( MTH_M_xDiv ( MTH_M_xAdd ( MTH3D_M_xDotProductVector ( p_stNormal, p_stVertexA ), xDPlan ), xDotProd ) );
/* verification du point d intersection sur la demi droite */
if ( MTH_C_ZERO <= *p_xT )
{
/* coordonnees du point d intersection */
MTH3D_M_vMulAddVector ( p_stHit, *p_xT, p_stVectAB, p_stVertexA );
/* verification du point d intersection dans le triangle */
return INT_fn_bGetPointInTriangle ( p_stHit, p_stVertex1, p_stVertex2, p_stVertex3, p_stNormal );
}
else
/* point d intersection en dehors de la demi droite */
return FALSE;
}
else
return FALSE;
}
#endif
/*--------------------------------------------------------------------------------------*/
/* Name : INT_fn_bIntersectTriangleWithBoxWithHit*/
/* Author : Thierry QUERE*/
/* Date : 04/03/98*/
/* Description : Idem as before but returns some important results*/
/*--------------------------------------------------------------------------------------*/
/* used*/
ACP_tdxBool INT_fn_bIntersectTriangleWithBoxWithHit ( MTH3D_tdstVector *p_stVertex1,
MTH3D_tdstVector *p_stVertex2,
MTH3D_tdstVector *p_stVertex3,
MTH3D_tdstVector *p_stNormal,
MTH3D_tdstVector *p_stMinPoint,
MTH3D_tdstVector *p_stMaxPoint,
MTH3D_tdstVector *p_stHit)
{
MTH3D_tdstVector stDelta;
MTH3D_tdstVector stNegDelta;
MTH3D_tdstVector stEdge;
MTH3D_tdstVector stHit;
MTH_tdxReal xDPlan;
MTH_tdxReal xTDiag;
MTH_tdxReal xDotProd;
MTH_tdxReal xDivid;
unsigned long ulVertex1Test, ulVertex2Test, ulVertex3Test;
/* un point du triangle est dans la boite */
if ( (ulVertex1Test = INT_fn_ulGetPositionPointWithBox ( p_stVertex1, p_stMinPoint, p_stMaxPoint )) == COL_C_ulNullMask )
return TRUE;
if ( (ulVertex2Test = INT_fn_ulGetPositionPointWithBox ( p_stVertex2, p_stMinPoint, p_stMaxPoint )) == COL_C_ulNullMask )
return TRUE;
if ( (ulVertex3Test = INT_fn_ulGetPositionPointWithBox ( p_stVertex3, p_stMinPoint, p_stMaxPoint )) == COL_C_ulNullMask )
return TRUE;
/* les trois points sont dans le meme demi espace exterieur */
if ( ulVertex1Test & ulVertex2Test & ulVertex3Test )
return FALSE;
/* delta de la boite */
MTH3D_M_vSubVector ( &stDelta, p_stMaxPoint, p_stMinPoint );
MTH3D_M_vNegVector ( &stNegDelta, &stDelta );
/* test sur les demi espaces des aretes */
ulVertex1Test |= INT_fn_ulGetPositionPointWithEdgeBox ( p_stVertex1, p_stMinPoint, p_stMaxPoint, &stDelta, &stNegDelta ) << 8;
ulVertex2Test |= INT_fn_ulGetPositionPointWithEdgeBox ( p_stVertex2, p_stMinPoint, p_stMaxPoint, &stDelta, &stNegDelta ) << 8;
ulVertex3Test |= INT_fn_ulGetPositionPointWithEdgeBox ( p_stVertex3, p_stMinPoint, p_stMaxPoint, &stDelta, &stNegDelta ) << 8;
if ( ulVertex1Test & ulVertex2Test & ulVertex3Test )
return FALSE;
if (p_stHit == NULL)
p_stHit = &stHit;
/* une arete du triangle intersecte la boite */
if ( (ulVertex1Test & ulVertex2Test) == COL_C_ulNullMask )
{
MTH3D_M_vSubVector ( &stEdge, p_stVertex2, p_stVertex1 );
if ( INT_fn_bIntersectEdgeWithBoxWithHit ( p_stVertex1, p_stVertex2, &stEdge, p_stMinPoint, p_stMaxPoint, ulVertex1Test|ulVertex2Test , p_stHit) )
return TRUE;
}
if ( (ulVertex1Test & ulVertex3Test) == COL_C_ulNullMask )
{
MTH3D_M_vSubVector ( &stEdge, p_stVertex3, p_stVertex1 );
if ( INT_fn_bIntersectEdgeWithBoxWithHit ( p_stVertex1, p_stVertex3, &stEdge, p_stMinPoint, p_stMaxPoint, ulVertex1Test|ulVertex3Test, p_stHit ) )
return TRUE;
}
if ( (ulVertex2Test & ulVertex3Test) == COL_C_ulNullMask )
{
MTH3D_M_vSubVector ( &stEdge, p_stVertex3, p_stVertex2 );
if ( INT_fn_bIntersectEdgeWithBoxWithHit ( p_stVertex2, p_stVertex3, &stEdge, p_stMinPoint, p_stMaxPoint, ulVertex2Test|ulVertex3Test, p_stHit ) )
return TRUE;
}
/* plan du triangle */
xDPlan = MTH_M_xNeg ( MTH3D_M_xDotProductVector ( p_stNormal, p_stVertex1 ) );
/* intersections avec les quatre diagonales */
/* le produit scalaire nous evite le plan parallele a la diagonale */
xDotProd = MTH_M_xMul ( p_stNormal->xX, stDelta.xX ) +
MTH_M_xMul ( p_stNormal->xY, stDelta.xY ) +
MTH_M_xMul ( p_stNormal->xZ, stDelta.xZ );
if ( MTH_M_bDifferentZero ( xDotProd ) )
{
xDivid = MTH_M_xMul ( p_stNormal->xX, p_stMinPoint->xX ) +
MTH_M_xMul ( p_stNormal->xY, p_stMinPoint->xY ) +
MTH_M_xMul ( p_stNormal->xZ, p_stMinPoint->xZ ) + xDPlan;
xTDiag = MTH_M_xNeg ( MTH_M_xDiv ( xDivid, xDotProd ) );
if ( MTH_M_bInUnitEqual ( xTDiag ) )
{
p_stHit->xX = MTH_M_xMulAdd ( stDelta.xX, xTDiag, p_stMinPoint->xX );
p_stHit->xY = MTH_M_xMulAdd ( stDelta.xY, xTDiag, p_stMinPoint->xY );
p_stHit->xZ = MTH_M_xMulAdd ( stDelta.xZ, xTDiag, p_stMinPoint->xZ );
if ( INT_fn_bGetPointInTriangle ( p_stHit, p_stVertex1, p_stVertex2, p_stVertex3, p_stNormal ) )
return TRUE;
}
}
xDotProd = MTH_M_xMul ( p_stNormal->xX, stDelta.xX ) +
MTH_M_xMul ( p_stNormal->xY, stNegDelta.xY ) +
MTH_M_xMul ( p_stNormal->xZ, stDelta.xZ );
if ( MTH_M_bDifferentZero ( xDotProd ) )
{
xDivid = MTH_M_xMul ( p_stNormal->xX, p_stMinPoint->xX ) +
MTH_M_xMul ( p_stNormal->xY, p_stMaxPoint->xY ) +
MTH_M_xMul ( p_stNormal->xZ, p_stMinPoint->xZ ) + xDPlan;
xTDiag = MTH_M_xNeg ( MTH_M_xDiv ( xDivid, xDotProd ) );
if ( MTH_M_bInUnitEqual ( xTDiag ) )
{
p_stHit->xX = MTH_M_xMulAdd ( stDelta.xX, xTDiag, p_stMinPoint->xX );
p_stHit->xY = MTH_M_xMulAdd ( stNegDelta.xY, xTDiag, p_stMaxPoint->xY );
p_stHit->xZ = MTH_M_xMulAdd ( stDelta.xZ, xTDiag, p_stMinPoint->xZ );
if ( INT_fn_bGetPointInTriangle ( p_stHit, p_stVertex1, p_stVertex2, p_stVertex3, p_stNormal ) )
return TRUE;
}
}
xDotProd = MTH_M_xMul ( p_stNormal->xX, stDelta.xX ) +
MTH_M_xMul ( p_stNormal->xY, stDelta.xY ) +
MTH_M_xMul ( p_stNormal->xZ, stNegDelta.xZ );
if ( MTH_M_bDifferentZero ( xDotProd ) )
{
xDivid = MTH_M_xMul ( p_stNormal->xX, p_stMinPoint->xX ) +
MTH_M_xMul ( p_stNormal->xY, p_stMinPoint->xY ) +
MTH_M_xMul ( p_stNormal->xZ, p_stMaxPoint->xZ ) + xDPlan;
xTDiag = MTH_M_xNeg ( MTH_M_xDiv ( xDivid, xDotProd ) );
if ( MTH_M_bInUnitEqual ( xTDiag ) )
{
p_stHit->xX = MTH_M_xMulAdd ( stDelta.xX, xTDiag, p_stMinPoint->xX );
p_stHit->xY = MTH_M_xMulAdd ( stDelta.xY, xTDiag, p_stMinPoint->xY );
p_stHit->xZ = MTH_M_xMulAdd ( stNegDelta.xZ, xTDiag, p_stMaxPoint->xZ );
if ( INT_fn_bGetPointInTriangle ( p_stHit, p_stVertex1, p_stVertex2, p_stVertex3, p_stNormal ) )
return TRUE;
}
}
xDotProd = MTH_M_xMul ( p_stNormal->xX, stDelta.xX ) +
MTH_M_xMul ( p_stNormal->xY, stNegDelta.xY ) +
MTH_M_xMul ( p_stNormal->xZ, stNegDelta.xZ );
if ( MTH_M_bDifferentZero ( xDotProd ) )
{
xDivid = MTH_M_xMul ( p_stNormal->xX, p_stMinPoint->xX ) +
MTH_M_xMul ( p_stNormal->xY, p_stMaxPoint->xY ) +
MTH_M_xMul ( p_stNormal->xZ, p_stMaxPoint->xZ ) + xDPlan;
xTDiag = MTH_M_xNeg ( MTH_M_xDiv ( xDivid, xDotProd ) );
if ( MTH_M_bInUnitEqual ( xTDiag ) )
{
p_stHit->xX = MTH_M_xMulAdd ( stDelta.xX, xTDiag, p_stMinPoint->xX );
p_stHit->xY = MTH_M_xMulAdd ( stNegDelta.xY, xTDiag, p_stMaxPoint->xY );
p_stHit->xZ = MTH_M_xMulAdd ( stNegDelta.xZ, xTDiag, p_stMaxPoint->xZ );
if ( INT_fn_bGetPointInTriangle ( p_stHit, p_stVertex1, p_stVertex2, p_stVertex3, p_stNormal ) )
return TRUE;
}
}
return FALSE;
}
/*
--------------------------------------------------------------------------------
-- Description : Inclusion of a point in a sphere
--------------------------------------------------------------------------------
-- Creation date : 17 jan 1997 Author : FPI
--------------------------------------------------------------------------------
*/
/* teste l inclusion d un point dans une sphere */
/* used*/
ACP_tdxBool INT_fn_bGetInclusionPointInSphere ( MTH3D_tdstVector *p_stPoint,
MTH3D_tdstVector *p_stSphereCenter,
MTH_tdxReal xSphereRadius )
{
return MTH_M_bLessEqual ( MTH3D_M_xVectorGapSqr ( p_stPoint, p_stSphereCenter ), MTH_M_xSqr ( xSphereRadius ) );
}
/*
--------------------------------------------------------------------------------
-- Description : fast rejection of sphere / segment intersection test
--------------------------------------------------------------------------------
*/
/* used*/
ACP_tdxBool INT_fn_bFastRejectIntersectSegmentWithSphere
(
MTH3D_tdstVector *p_stVertex1,
MTH3D_tdstVector *p_stVect12,
MTH3D_tdstVector *p_stSphereCenter,
MTH_tdxReal xSphereRadius
)
{
MTH3D_tdstVector stM;
MTH3D_tdstVector stMP;
MTH_tdxReal xNegSphereRadius;
MTH3D_M_vSubVector(&stM, p_stVertex1, p_stSphereCenter);
MTH3D_M_vAddVector(&stMP, &stM, p_stVect12);
xNegSphereRadius = MTH_M_xNeg(xSphereRadius);
if (MTH_M_bGreaterZero(p_stVect12->xX))
{
if (MTH_M_bGreater(stM.xX,xSphereRadius))
return FALSE;
if (MTH_M_bLess(stMP.xX,xNegSphereRadius))
return FALSE;
}
else
{
if (MTH_M_bLess(stM.xX,xNegSphereRadius))
return FALSE;
if (MTH_M_bGreater(stMP.xX,xSphereRadius))
return FALSE;
}
if (MTH_M_bGreaterZero(p_stVect12->xY))
{
if (MTH_M_bGreater(stM.xY,xSphereRadius))
return FALSE;
if (MTH_M_bLess(stMP.xY,xNegSphereRadius))
return FALSE;
}
else
{
if (MTH_M_bLess(stM.xY,xNegSphereRadius))
return FALSE;
if (MTH_M_bGreater(stMP.xY,xSphereRadius))
return FALSE;
}
if (MTH_M_bGreaterZero(p_stVect12->xZ))
{
if (MTH_M_bGreater(stM.xZ,xSphereRadius))
return FALSE;
if (MTH_M_bLess(stMP.xZ,xNegSphereRadius))
return FALSE;
}
else
{
if (MTH_M_bLess(stM.xZ,xNegSphereRadius))
return FALSE;
if (MTH_M_bGreater(stMP.xZ,xSphereRadius))
return FALSE;
}
return TRUE;
}
/*
--------------------------------------------------------------------------------
-- Description : Segment with sphere intersection test
--------------------------------------------------------------------------------
-- Creation date : 03 oct 1996 Author : FPI
--------------------------------------------------------------------------------
*/
/* teste l intersection d un segment et d une sphere */
/* used*/
ACP_tdxBool INT_fn_bIntersectSegmentWithSphere ( MTH3D_tdstVector *p_stVertex1,
MTH3D_tdstVector *p_stVect12,
MTH3D_tdstVector *p_stSphereCenter,
MTH_tdxReal xSphereRadius,
MTH_tdxReal *p_xT,
MTH3D_tdstVector *p_stHit,
MTH3D_tdstVector *p_stNormal )
{
MTH3D_tdstVector stVectS1;
MTH_tdxReal xA;
MTH_tdxReal xB;
MTH_tdxReal xC;
MTH_tdxReal xT1;
MTH_tdxReal xT2;
MTH_tdxReal xInvR;
MTH_tdxReal xT;
#if 1
if ( !INT_fn_bFastRejectIntersectSegmentWithSphere(p_stVertex1, p_stVect12, p_stSphereCenter, xSphereRadius) )
{
return FALSE;
}
#endif
MTH3D_M_vSubVector ( &stVectS1, p_stVertex1, p_stSphereCenter );
xA = MTH3D_M_xSqrVector ( p_stVect12 );
xB = MTH3D_M_xDotProductVector ( p_stVect12, &stVectS1 );
xB = MTH_M_xAdd ( xB, xB ); /* instead of multpiplication by 2, use add*/
xC = MTH_M_xSub ( MTH3D_M_xSqrVector ( &stVectS1 ), MTH_M_xSqr ( xSphereRadius ) );
/* resolution du trinome */
switch ( INT_fn_xTrinomeResolution ( xA, xB, xC, &xT1, &xT2 ) )
{
case INT_C_xTwoSolutions :
xT = MTH_M_xMin ( xT1, xT2 );
if ( MTH_M_bInUnitEqual ( xT ) )
{
*p_xT = xT;
MTH3D_M_vMulAddVector ( p_stHit, xT, p_stVect12, p_stVertex1 );
MTH3D_M_vSubVector ( p_stNormal, p_stHit, p_stSphereCenter );
xInvR = MTH_M_xInv ( xSphereRadius );
MTH3D_M_vMulScalarVector( p_stNormal, xInvR, p_stNormal );
return TRUE;
}
else
{
return FALSE;
}
break;
case INT_C_xOneSolution :
if ( MTH_M_bInUnitEqual ( xT1 ) )
{
*p_xT = xT1;
MTH3D_M_vMulAddVector ( p_stHit, xT1, p_stVect12, p_stVertex1 );
MTH3D_M_vSubVector ( p_stNormal, p_stHit, p_stSphereCenter );
xInvR = MTH_M_xInv ( xSphereRadius );
MTH3D_M_vMulScalarVector( p_stNormal, xInvR, p_stNormal );
return TRUE;
}
break;
default :
break;
}
return FALSE;
}
/*
--------------------------------------------------------------------------------
-- Description : Segment with sphere intersection detection
--------------------------------------------------------------------------------
-- Creation date : 08 oct 1998 Author : FBF
-- !!!! OPTIMIZED !!!!
--------------------------------------------------------------------------------
*/
/* detecte l intersection d un segment et d une sphere */
/* used*/
ACP_tdxBool INT_fn_bDetectIntersectSegmentWithSphere ( MTH3D_tdstVector *p_stVertexA,
MTH3D_tdstVector *p_stVectAB,
MTH3D_tdstVector *p_stSphereCenter,
MTH_tdxReal xSphereRadius )
{
MTH3D_tdstVector stVectCA;
MTH3D_tdstVector stVectCB;
MTH_tdxReal xdist,xTemp;
MTH_tdxReal xNegSphereRadius;
MTH_tdxReal xSpecialRadius;
MTH_tdxReal NormAB;
/* C means the center of the sphere*/
/* fast rejection*/
MTH3D_M_vSubVector(&stVectCA, p_stVertexA, p_stSphereCenter);
MTH3D_M_vAddVector(&stVectCB, &stVectCA, p_stVectAB);
xNegSphereRadius = MTH_M_xNeg(xSphereRadius);
xSpecialRadius = MTH_M_xSqr(xSphereRadius);
/* B is inside the sphere*/
if ( MTH_M_bLessEqual(MTH3D_M_xSqrVector(&stVectCB), xSpecialRadius) )
return TRUE;
/* A is inside the sphere*/
if ( MTH_M_bLessEqual(MTH3D_M_xSqrVector(&stVectCA), xSpecialRadius) )
return TRUE;
if (MTH_M_bGreaterZero(p_stVectAB->xX))
{
if (MTH_M_bGreater(stVectCA.xX,xSphereRadius))
return FALSE;
if (MTH_M_bLess(stVectCB.xX,xNegSphereRadius))
return FALSE;
}
else
{
if (MTH_M_bLess(stVectCA.xX,xNegSphereRadius))
return FALSE;
if (MTH_M_bGreater(stVectCB.xX,xSphereRadius))
return FALSE;
}
if (MTH_M_bGreaterZero(p_stVectAB->xY))
{
if (MTH_M_bGreater(stVectCA.xY,xSphereRadius))
return FALSE;
if (MTH_M_bLess(stVectCB.xY,xNegSphereRadius))
return FALSE;
}
else
{
if (MTH_M_bLess(stVectCA.xY,xNegSphereRadius))
return FALSE;
if (MTH_M_bGreater(stVectCB.xY,xSphereRadius))
return FALSE;
}
if (MTH_M_bGreaterZero(p_stVectAB->xZ))
{
if (MTH_M_bGreater(stVectCA.xZ,xSphereRadius))
return FALSE;
if (MTH_M_bLess(stVectCB.xZ,xNegSphereRadius))
return FALSE;
}
else
{
if (MTH_M_bLess(stVectCA.xZ,xNegSphereRadius))
return FALSE;
if (MTH_M_bGreater(stVectCB.xZ,xSphereRadius))
return FALSE;
}
/* check projection of C is on [AB)*/
xTemp = MTH3D_M_xDotProductVector (&stVectCA, p_stVectAB);
if (MTH_M_bGreater(xTemp,MTH_C_ZERO))
{
return FALSE;
}
/* compute value to test :*/
NormAB = MTH3D_M_xSqrVector (p_stVectAB);
/* check projection of C is on [BA)*/
if (MTH_M_bGreater(MTH_M_xNeg(xTemp),NormAB))
return FALSE;
/* here, we are sure that projection of C is on [AB]*/
/* there is certainly a collision...*/
/* complete check */
xSpecialRadius = MTH_M_xMul(xSpecialRadius,NormAB);
/* first test :*/
/* check if (x2*y1 - x1*y2)<29> > R<> * (AB)<29>*/
xdist = MTH_M_xSub(MTH_M_xMul(stVectCA.xX,p_stVectAB->xY),MTH_M_xMul(stVectCA.xY,p_stVectAB->xX));
xdist = MTH_M_xSqr(xdist);
if (MTH_M_bGreaterEqual(xdist,xSpecialRadius))
return FALSE;
/* if not*/
/* check if (x2*y1 - x1*y2)<29> + (x2*z1 - x1*z2)<29> > R<> * (AB)<29>*/
xTemp = MTH_M_xSub(MTH_M_xMul(stVectCA.xX,p_stVectAB->xZ),MTH_M_xMul(stVectCA.xZ,p_stVectAB->xX));
xdist = MTH_M_xAdd(MTH_M_xSqr(xTemp),xdist);
if (MTH_M_bGreaterEqual(xdist,xSpecialRadius))
return FALSE;
/* if not*/
/* check if (x2*y1 - x1*y2)<29> + (x2*z1 - x1*z2)<29> + (y2*z1 - y1*z2)<29> > R<> * (AB)<29>*/
xTemp = MTH_M_xSub(MTH_M_xMul(stVectCA.xY,p_stVectAB->xZ),MTH_M_xMul(stVectCA.xZ,p_stVectAB->xY));
xdist = MTH_M_xAdd(MTH_M_xSqr(xTemp),xdist);
if (MTH_M_bGreaterEqual(xdist,xSpecialRadius))
return FALSE;
/* if not, then the distance between the sphere center and the segment is < R */
return TRUE;
}
/* detecte l intersection d un segment et d une sphere */
/*ACP_tdxBool INT_fn_bDetectIntersectSegmentWithSphere ( MTH3D_tdstVector *p_stVertex1,
MTH3D_tdstVector *p_stVect12,
MTH3D_tdstVector *p_stSphereCenter,
MTH_tdxReal xSphereRadius )
{
MTH3D_tdstVector stVectS1;
MTH3D_tdstVector stVectS2;
MTH_tdxReal xA;
MTH_tdxReal xB;
MTH_tdxReal xC;
MTH_tdxReal xT;
#if 1
if ( !INT_fn_bFastRejectIntersectSegmentWithSphere(p_stVertex1, p_stVect12, p_stSphereCenter, xSphereRadius) )
return FALSE;
#endif
xA = MTH3D_M_xSqrVector ( p_stVect12 );
if ( MTH_M_bEqualZero ( xA ) )
return FALSE;
MTH3D_M_vSubVector ( &stVectS1, p_stVertex1, p_stSphereCenter );
if ( MTH_M_bLessEqual ( MTH3D_M_xSqrVector ( &stVectS1 ), MTH_M_xSqr ( xSphereRadius ) ) )
{
return TRUE;
}
else
{
xB = MTH3D_M_xDotProductVector ( p_stVect12, &stVectS1 );
xB = MTH_M_xAdd ( xB, xB ); // instead of multpiplication by 2, use add
xC = MTH_M_xSub ( MTH3D_M_xSqrVector ( &stVectS1 ), MTH_M_xSqr ( xSphereRadius ) );
// delta
if ( MTH_M_xTrinomeDelta ( xA, xB, xC ) >= MTH_C_ZERO )
{
// inclusion du point 2
MTH3D_M_vAddVector ( &stVectS2, &stVectS1, p_stVect12 );
if ( MTH_M_bLessEqual ( MTH3D_M_xSqrVector ( &stVectS2 ), MTH_M_xSqr ( xSphereRadius ) ) )
{
return TRUE;
}
else
{
// sans projection
xT = MTH3D_M_xDotProductVector ( p_stVect12, &stVectS1 );
if ( ( xT <= MTH_C_ZERO ) && ( xT >= MTH_M_xNeg ( xA ) ) )
{
return TRUE;
}
else
{
return FALSE;
}
}
}
else
{
return FALSE;
}
}
return FALSE;
}
*/
/*
--------------------------------------------------------------------------------
-- Description : fast rejection of sphere / semiaxe intersection test
--------------------------------------------------------------------------------
*/
#if defined(ACTIVE_EDITOR)
/*active editor only*/
ACP_tdxBool INT_fn_bFastRejectIntersectSemiaxeWithSphere
(
MTH3D_tdstVector *p_stVertex1,
MTH3D_tdstVector *p_stVect12,
MTH3D_tdstVector *p_stSphereCenter,
MTH_tdxReal xSphereRadius
)
{
MTH_tdxReal xMin;
MTH_tdxReal xMax;
/* far extremity of the segment*/
MTH3D_tdstVector stvertex2;
MTH3D_M_vAddVector(&stvertex2, p_stVertex1, p_stVect12);
/* cas de rejection en X */
if ( MTH_M_bGreaterZero ( p_stVect12->xX ) )
{
xMin = p_stVertex1->xX;
xMax = MTH_M_xAdd ( p_stSphereCenter->xX, xSphereRadius );
}
else
{
xMin = MTH_M_xSub ( p_stSphereCenter->xX, xSphereRadius );
xMax = p_stVertex1->xX;
}
if ( MTH_M_bLess ( xMax, xMin ) )
{
return FALSE;
}
/* cas de rejection en Y */
if ( MTH_M_bGreaterZero ( p_stVect12->xY ) )
{
xMin = p_stVertex1->xY;
xMax = MTH_M_xAdd ( p_stSphereCenter->xY, xSphereRadius );
}
else
{
xMin = MTH_M_xSub ( p_stSphereCenter->xY, xSphereRadius );
xMax = p_stVertex1->xY;
}
if ( MTH_M_bLess ( xMax, xMin ) )
{
return FALSE;
}
/* cas de rejection en Z */
if ( MTH_M_bGreaterZero ( p_stVect12->xZ ) )
{
xMin = p_stVertex1->xZ;
xMax = MTH_M_xAdd ( p_stSphereCenter->xZ, xSphereRadius );
}
else
{
xMin = MTH_M_xSub ( p_stSphereCenter->xZ, xSphereRadius );
xMax = p_stVertex1->xZ;
}
if ( MTH_M_bLess ( xMax, xMin ) )
{
return FALSE;
}
return TRUE;
}
#endif
/*
--------------------------------------------------------------------------------
-- Description : Semiaxe with sphere intersection test
--------------------------------------------------------------------------------
-- Creation date : 12 nov 1996 Author : FPI
--------------------------------------------------------------------------------
*/
/* teste l intersection d une demi droite et d une sphere */
#if defined(ACTIVE_EDITOR)
/*active editor only*/
ACP_tdxBool INT_fn_bIntersectSemiAxeWithSphere ( MTH3D_tdstVector *p_stVertex1,
MTH3D_tdstVector *p_stVect12,
MTH3D_tdstVector *p_stSphereCenter,
MTH_tdxReal xSphereRadius,
ACP_tdxBool *bBack,
MTH_tdxReal *p_xT,
MTH3D_tdstVector *p_stHit,
MTH3D_tdstVector *p_stNormal )
{
MTH3D_tdstVector stVectS1;
MTH_tdxReal xA;
MTH_tdxReal xB;
MTH_tdxReal xC;
MTH_tdxReal xT1;
MTH_tdxReal xT2;
MTH_tdxReal xInvR;
#if 1
if ( !INT_fn_bFastRejectIntersectSemiaxeWithSphere(p_stVertex1, p_stVect12, p_stSphereCenter, xSphereRadius) )
return FALSE;
#endif
MTH3D_M_vSubVector ( &stVectS1, p_stVertex1, p_stSphereCenter );
xA = MTH3D_M_xSqrVector ( p_stVect12 );
xB = MTH3D_M_xDotProductVector ( p_stVect12, &stVectS1 );
xB = MTH_M_xAdd ( xB, xB ); /* instead of multpiplication by 2, use add*/
xC = MTH_M_xSub ( MTH3D_M_xSqrVector ( &stVectS1 ), MTH_M_xSqr ( xSphereRadius ) );
/* resolution du trinome */
switch ( INT_fn_xTrinomeResolution ( xA, xB, xC, &xT1, &xT2 ) )
{
case INT_C_xTwoSolutions :
*p_xT = MTH_M_xMin ( xT1, xT2 );
if ( MTH_C_ZERO <= *p_xT )
{
*bBack = FALSE;
MTH3D_M_vMulAddVector ( p_stHit, *p_xT, p_stVect12, p_stVertex1 );
MTH3D_M_vSubVector ( p_stNormal, p_stHit, p_stSphereCenter );
xInvR = MTH_M_xInv ( xSphereRadius );
MTH3D_M_vMulScalarVector( p_stNormal, xInvR, p_stNormal );
return TRUE;
}
else
{
*p_xT = MTH_M_xMax ( xT1, xT2 );
if ( MTH_C_ZERO <= *p_xT )
{
*bBack = TRUE;
MTH3D_M_vMulAddVector ( p_stHit, *p_xT, p_stVect12, p_stVertex1 );
MTH3D_M_vSubVector ( p_stNormal, p_stHit, p_stSphereCenter );
xInvR = MTH_M_xInv ( xSphereRadius );
MTH3D_M_vMulScalarVector( p_stNormal, xInvR, p_stNormal );
return TRUE;
}
}
break;
case INT_C_xOneSolution :
if ( MTH_C_ZERO <= xT1 )
{
*bBack = TRUE;
*p_xT = xT1;
MTH3D_M_vMulAddVector ( p_stHit, *p_xT, p_stVect12, p_stVertex1 );
MTH3D_M_vSubVector ( p_stNormal, p_stHit, p_stSphereCenter );
xInvR = MTH_M_xInv ( xSphereRadius );
MTH3D_M_vMulScalarVector( p_stNormal, xInvR, p_stNormal );
return TRUE;
}
break;
default :
break;
}
return FALSE;
}
#endif
/*
--------------------------------------------------------------------------------
-- Description : Semiaxe with sphere intersection detection
--------------------------------------------------------------------------------
-- Creation date : 06 feb 1997 Author : FPI
--------------------------------------------------------------------------------
*/
/* detecte l intersection d une demi droite et d une sphere */
/* Vect12 n'est pas consid<69>r<EFBFBD> comme <20>tant norm<72>*/
/* optimised by FBF*/
#ifdef ACTIVE_EDITOR
/* active editor only*/
ACP_tdxBool INT_fn_bDetectIntersectSemiAxeWithSphere ( MTH3D_tdstVector *p_stPointA,
MTH3D_tdstVector *p_stVectAB,
MTH3D_tdstVector *p_stSphereCenter,
MTH_tdxReal xSphereRadius )
{
MTH3D_tdstVector stVectAC;
MTH_tdxReal xACNorm;
MTH_tdxReal xABNorm;
MTH_tdxReal xDist;
MTH_tdxReal xRadiusSqr;
MTH_tdxReal xDotPdt;
/* compute distance AC*/
MTH3D_M_vSubVector (&stVectAC, p_stPointA, p_stSphereCenter);
xACNorm = MTH3D_M_xSqrVector (&stVectAC);
xRadiusSqr = MTH_M_xSqr(xSphereRadius);
/* if A is inside the sphere, return TRUE;*/
if (MTH_M_bGreaterEqual(xRadiusSqr,xACNorm))
return TRUE;
/* compute dot product to see where the sphere center is according to the semiaxe beginning*/
xDotPdt = MTH3D_M_xDotProductVector (p_stVectAB, &stVectAC);
/* if dot product is <= 0, then the sphere is on the wrong side --> return FALSE;*/
if (MTH_M_bLessEqual(xDotPdt,MTH_C_ZERO))
return FALSE;
/* complete calculation, general case.*/
xABNorm = MTH3D_M_xSqrVector (p_stVectAB);
xDotPdt = MTH_M_xSqr(xDotPdt);
xDist = MTH_M_xSub(xACNorm, MTH_M_xDiv(xDotPdt,xABNorm));
if (MTH_M_bGreaterEqual(xRadiusSqr,xDist))
return TRUE;
}
#endif
/*
--------------------------------------------------------------------------------
-- Description : Segment with cylinder intersection test
--------------------------------------------------------------------------------
-- Creation date : 04 dec 1996 Author : FPI
--------------------------------------------------------------------------------
*/
/* teste l intersection d un segment et d un cylindre */
/* used*/
ACP_tdxBool INT_fn_bIntersectSegmentWithCylinder ( MTH3D_tdstVector *p_stVertex1,
MTH3D_tdstVector *p_stVect12,
MTH3D_tdstVector *p_stVertexA,
MTH3D_tdstVector *p_stVectAB,
MTH_tdxReal xCylinderRadius,
MTH_tdxReal *p_xTSegment,
MTH3D_tdstVector *p_stHitSegment,
MTH3D_tdstVector *p_stHitLine )
{
MTH3D_tdstVector stVectA1;
MTH3D_tdstVector stVectP;
MTH3D_tdstVector stVectQ;
MTH_tdxReal xTLine;
MTH_tdxReal xK;
MTH_tdxReal xL;
MTH_tdxReal xM;
MTH_tdxReal xA;
MTH_tdxReal xB;
MTH_tdxReal xC;
MTH_tdxReal xT1;
MTH_tdxReal xT2;
MTH_tdxReal xTmp;
#if 1
MTH_tdxReal xMin;
MTH_tdxReal xMax;
ACP_tdxBool bGreaterZero1, bGreaterZero2;
/* INT_g_lIntTriangle ++;*/
MTH3D_M_vAddVector(&stVectP, p_stVertex1, p_stVect12);
MTH3D_M_vAddVector(&stVectA1, p_stVertexA, p_stVectAB);
/* cas de rejection en X */
bGreaterZero1 = MTH_M_bGreaterZero ( p_stVect12->xX );
bGreaterZero2 = MTH_M_bGreaterZero ( p_stVectAB->xX );
/* min 1, 2 */
xMin = bGreaterZero1 ? p_stVertex1->xX : stVectP.xX;
/* max A, B */
xMax = bGreaterZero2 ? stVectA1.xX : p_stVertexA->xX;
if ( MTH_M_bLess ( MTH_M_xAdd ( xMax, xCylinderRadius ), xMin ) )
{
return FALSE;
}
/* max 1, 2 */
xMax = bGreaterZero1 ? stVectP.xX : p_stVertex1->xX;
/* min A, B */
xMin = bGreaterZero2 ? p_stVertexA->xX : stVectA1.xX;
if ( MTH_M_bLess ( xMax, MTH_M_xSub ( xMin, xCylinderRadius ) ) )
{
return FALSE;
}
/* cas de rejection en Y */
bGreaterZero1 = MTH_M_bGreaterZero ( p_stVect12->xY );
bGreaterZero2 = MTH_M_bGreaterZero ( p_stVectAB->xY );
/* min 1, 2 */
xMin = bGreaterZero1 ? p_stVertex1->xY : stVectP.xY;
/* max A, B */
xMax = bGreaterZero2 ? stVectA1.xY : p_stVertexA->xY;
if ( MTH_M_bLess ( MTH_M_xAdd ( xMax, xCylinderRadius ), xMin ) )
{
return FALSE;
}
/* max 1, 2 */
xMax = bGreaterZero1 ? stVectP.xY : p_stVertex1->xY;
/* min A, B */
xMin = bGreaterZero2 ? p_stVertexA->xY : stVectA1.xY;
if ( MTH_M_bLess ( xMax, MTH_M_xSub ( xMin, xCylinderRadius ) ) )
{
return FALSE;
}
/* cas de rejection en Z */
bGreaterZero1 = MTH_M_bGreaterZero ( p_stVect12->xZ );
bGreaterZero2 = MTH_M_bGreaterZero ( p_stVectAB->xZ );
/* min 1, 2 */
xMin = bGreaterZero1 ? p_stVertex1->xZ : stVectP.xZ;
/* max A, B */
xMax = bGreaterZero2 ? stVectA1.xZ : p_stVertexA->xZ;
if ( MTH_M_bLess ( MTH_M_xAdd ( xMax, xCylinderRadius ), xMin ) )
{
return FALSE;
}
/* max 1, 2 */
xMax = bGreaterZero1 ? stVectP.xZ : p_stVertex1->xZ;
/* min A, B */
xMin = bGreaterZero2 ? p_stVertexA->xZ : stVectA1.xZ;
if ( MTH_M_bLess ( xMax, MTH_M_xSub ( xMin, xCylinderRadius ) ) )
{
return FALSE;
}
#endif
#if 1
MTH3D_M_vSubVector ( &stVectA1, p_stVertex1, p_stVertexA );
xM = MTH3D_M_xSqrVector ( p_stVectAB );
if ( MTH_M_bEqualZero ( xM ) )
return FALSE;
xM = MTH_M_xInv ( xM );
xK = MTH3D_M_xDotProductVector ( p_stVectAB, p_stVect12 );
xL = MTH3D_M_xDotProductVector ( p_stVectAB, &stVectA1 );
xTmp = MTH_M_xMul ( xK, xM );
MTH3D_M_vMulScalarVector ( &stVectP, xTmp, p_stVectAB );
if ( !(MTH3D_M_bEqualVector ( &stVectP, p_stVect12 )) )
{
MTH3D_M_vSubVector ( &stVectP, &stVectP, p_stVect12 );
xTmp = MTH_M_xMul ( xL, xM );
MTH3D_M_vMulScalarVector ( &stVectQ, xTmp, p_stVectAB );
MTH3D_M_vSubVector ( &stVectQ, &stVectQ, &stVectA1 );
xA = MTH3D_M_xSqrVector ( &stVectP );
xB = MTH3D_M_xDotProductVector ( &stVectP, &stVectQ );
xB = MTH_M_xAdd ( xB, xB ); /* instead of multpiplication by 2, use add*/
xC = MTH_M_xSub ( MTH3D_M_xSqrVector ( &stVectQ ), MTH_M_xSqr ( xCylinderRadius ) );
/* resolution du trinome */
switch ( INT_fn_xTrinomeResolution ( xA, xB, xC, &xT1, &xT2 ) )
{
case INT_C_xTwoSolutions :
*p_xTSegment = MTH_M_xMin ( xT1, xT2 );
// *p_xTSegment = MTH_M_xMax ( xT1, xT2 );
if ( !(MTH_M_bInUnitEqual ( *p_xTSegment )) )
{
return FALSE;
}
break;
case INT_C_xNoSolution :
return FALSE;
case INT_C_xOneSolution :
if ( MTH_M_bInUnitEqual ( xT1 ) )
{
*p_xTSegment = xT1;
}
else
return FALSE;
break;
default :
break;
}
MTH3D_M_vMulAddVector ( p_stHitSegment, *p_xTSegment, p_stVect12, p_stVertex1 );
xTLine = MTH_M_xMul ( MTH_M_xAdd ( MTH_M_xMul ( xK, *p_xTSegment ), xL ), xM );
// xTLine = *p_xTSegment;
// if (MTH_M_bGreater(xTLine,MTH_C_ONE)) xTLine = MTH_C_ONE;
// if (MTH_M_bLess(xTLine,MTH_C_ZERO)) xTLine = MTH_C_ZERO;
if ( MTH_M_bInUnitEqual ( xTLine ) )
// if ( MTH_M_bGreater(xTLine,MTH_M_xDoubleToReal(-0.1)) && MTH_M_bLess(xTLine,MTH_M_xDoubleToReal(1.1)) )
{
MTH3D_M_vMulAddVector ( p_stHitLine, xTLine, p_stVectAB, p_stVertexA );
return TRUE;
}
else
{
return FALSE;
}
}
else
{
return FALSE;
}
#endif
return FALSE;
}
/*
--------------------------------------------------------------------------------
-- Description : Semiaxe with cone intersection test
--------------------------------------------------------------------------------
-- Creation date : 08 apr 1997 Author : FPI
--------------------------------------------------------------------------------
*/
/* teste l intersection d un semiaxe et d un cone */
#if defined(ACTIVE_EDITOR)
/*active editor only*/
ACP_tdxBool INT_fn_bIntersectSemiAxeWithCone ( MTH3D_tdstVector *p_stVertex1,
MTH3D_tdstVector *p_stVect12,
MTH3D_tdstVector *p_stTopPoint,
MTH3D_tdstVector *p_stBasePoint,
MTH_tdxReal xBaseRadius,
ACP_tdxBool *bBack,
MTH_tdxReal *p_xT,
MTH3D_tdstVector *p_stHit )
{
MTH3D_tdstVector stVectTB;
MTH3D_tdstVector stVectT1;
MTH_tdxReal xF;
MTH_tdxReal xG;
MTH_tdxReal xH;
MTH_tdxReal xM;
MTH_tdxReal xN;
MTH_tdxReal xP;
MTH_tdxReal xA;
MTH_tdxReal xB;
MTH_tdxReal xC;
MTH_tdxReal xT1;
MTH_tdxReal xT2;
MTH_tdxReal xTLine;
MTH3D_M_vSubVector ( &stVectTB, p_stBasePoint, p_stTopPoint );
MTH3D_M_vSubVector ( &stVectT1, p_stVertex1, p_stTopPoint );
xF = MTH_M_xSub ( MTH3D_M_xSqrVector ( &stVectTB ), MTH_M_xSqr ( xBaseRadius ) );
xG = MTH3D_M_xSqrVector ( &stVectT1 );
xH = MTH3D_M_xSqrVector ( p_stVect12 );
xM = MTH3D_M_xDotProductVector ( p_stVect12, &stVectTB );
xN = MTH3D_M_xDotProductVector ( &stVectT1, &stVectTB );
xP = MTH3D_M_xDotProductVector ( p_stVect12, &stVectT1 );
xA = MTH_M_xSub ( MTH_M_xSqr ( xM ), MTH_M_xMul ( xH, xF ) );
xB = MTH_M_xSub ( MTH_M_xMul ( xN, xM ), MTH_M_xMul ( xP, xF ) );
xB = MTH_M_xAdd ( xB, xB ); /* instead of multpiplication by 2, use add*/
xC = MTH_M_xSub ( MTH_M_xSqr ( xN ), MTH_M_xMul ( xG, xF ) );
/* resolution du trinome */
switch ( INT_fn_xTrinomeResolution ( xA, xB, xC, &xT1, &xT2 ) )
{
case INT_C_xOneSolution :
if ( MTH_C_ZERO <= xT1 )
{
*p_xT = xT1;
xTLine = MTH_M_xDiv ( MTH_M_xAdd ( MTH_M_xMul ( xM, *p_xT ), xN ), MTH3D_M_xSqrVector ( &stVectTB ) );
if ( MTH_M_bInUnitEqual ( xTLine ) )
{
*bBack = TRUE;
MTH3D_M_vMulAddVector ( p_stHit, *p_xT, p_stVect12, p_stVertex1 );
return TRUE;
}
}
break;
case INT_C_xTwoSolutions :
*p_xT = MTH_M_xMin ( xT1, xT2 );
if ( MTH_C_ZERO <= *p_xT )
{
xTLine = MTH_M_xDiv ( MTH_M_xAdd ( MTH_M_xMul ( xM, *p_xT ), xN ), MTH3D_M_xSqrVector ( &stVectTB ) );
if ( MTH_M_bInUnitEqual ( xTLine ) )
{
*bBack = FALSE;
MTH3D_M_vMulAddVector ( p_stHit, *p_xT, p_stVect12, p_stVertex1 );
return TRUE;
}
else
{
*p_xT = MTH_M_xMax ( xT1, xT2 );
if ( MTH_C_ZERO <= *p_xT )
{
xTLine = MTH_M_xDiv ( MTH_M_xAdd ( MTH_M_xMul ( xM, *p_xT ), xN ), MTH3D_M_xSqrVector ( &stVectTB ) );
if ( MTH_M_bInUnitEqual ( xTLine ) )
{
*bBack = FALSE;
MTH3D_M_vMulAddVector ( p_stHit, *p_xT, p_stVect12, p_stVertex1 );
return TRUE;
}
}
}
}
else
{
*p_xT = MTH_M_xMax ( xT1, xT2 );
if ( MTH_C_ZERO <= *p_xT )
{
xTLine = MTH_M_xDiv ( MTH_M_xAdd ( MTH_M_xMul ( xM, *p_xT ), xN ), MTH3D_M_xSqrVector ( &stVectTB ) );
if ( MTH_M_bInUnitEqual ( xTLine ) )
{
*bBack = TRUE;
MTH3D_M_vMulAddVector ( p_stHit, *p_xT, p_stVect12, p_stVertex1 );
return TRUE;
}
}
}
break;
default :
break;
}
return FALSE;
}
#endif
/*
--------------------------------------------------------------------------------
-- Description : Inclusion of a point in a cone
--------------------------------------------------------------------------------
-- Creation date : 21 jan 1997 Author : FPI
--------------------------------------------------------------------------------
*/
/* used*/
/* teste l inclusion d un point dans un cone */
ACP_tdxBool INT_fn_bGetInclusionPointInCone ( MTH3D_tdstVector *p_stPoint,
MTH3D_tdstVector *p_stTopPoint,
MTH3D_tdstVector *p_stBasePoint,
MTH_tdxReal xBaseRadius )
{
MTH_tdxReal xT;
MTH3D_tdstVector stHit;
MTH_tdxReal xDist;
/*ANNECY TQ 04/05/98{*/
MTH3D_tdstVector stTopBaseVector;
MTH3D_M_vSubVector(&stTopBaseVector, p_stBasePoint, p_stTopPoint);
xDist = INT_fn_xDistancePointToLine ( p_stPoint, p_stTopPoint, &stTopBaseVector,
&xT, &stHit );
/*ENDANNECY TQ}*/
return ( ( MTH_M_bInUnitEqual ( xT ) ) && ( MTH_M_bLessEqual ( xDist, MTH_M_xMul ( xT, xBaseRadius ) ) ) );
}
/*
--------------------------------------------------------------------------------
-- Description : Compute distance point to a line
--------------------------------------------------------------------------------
-- Creation date : 18 nov 1996 Author : FPI
--------------------------------------------------------------------------------
*/
/* used*/
MTH_tdxReal INT_fn_xDistancePointToLine ( MTH3D_tdstVector *p_stPoint,
MTH3D_tdstVector *p_stVertexA,
MTH3D_tdstVector *p_stVectAB,
MTH_tdxReal *p_xT,
MTH3D_tdstVector *p_stHit )
{
MTH3D_tdstVector stVectAP;
if ( !(MTH3D_M_bIsNullVector ( p_stVectAB )) )
{
MTH3D_M_vSubVector ( &stVectAP, p_stPoint, p_stVertexA );
/* 3 add */
*p_xT = MTH_M_xDiv ( MTH3D_M_xDotProductVector ( p_stVectAB, &stVectAP ), MTH3D_M_xSqrVector ( p_stVectAB ) );
/* 3 mul 2 add 3 mul 2 add 1 div */
MTH3D_M_vMulAddVector ( p_stHit, *p_xT, p_stVectAB, p_stVertexA );
/* 3 mul 3 add */
}
else
{
*p_xT = MTH_C_ZERO;
MTH3D_M_vCopyVector ( p_stHit, p_stVertexA );
}
return MTH3D_M_xVectorGap ( p_stHit, p_stPoint );
/* 3 add 3 mul 2 add 1 sqrt */
/* 15 add 12 mul 1 div 1 sqrt */
}
/*
--------------------------------------------------------------------------------
-- Description : Compute squared distance point to a segment
--------------------------------------------------------------------------------
-- Creation date : 04 jun 1997 Author : FPI
--------------------------------------------------------------------------------
*/
#ifndef U64
/* used only for complex shadow calculation*/
MTH_tdxReal INT_fn_xSqrDistancePointToSegment ( MTH3D_tdstVector *p_stPoint,
MTH3D_tdstVector *p_stVertexA,
MTH3D_tdstVector *p_stVectAB )
{
MTH3D_tdstVector stVectAP;
MTH_tdxReal xT;
MTH3D_tdstVector stHit;
MTH3D_M_vSubVector ( &stVectAP, p_stPoint, p_stVertexA );
if ( !(MTH3D_M_bIsNullVector ( p_stVectAB )) )
{
xT = MTH_M_xDiv ( MTH3D_M_xDotProductVector ( p_stVectAB, &stVectAP ), MTH3D_M_xSqrVector ( p_stVectAB ) );
if ( xT < MTH_C_ZERO )
{
MTH3D_M_vCopyVector ( &stHit, p_stVertexA );
}
else
{
if ( xT > MTH_C_ONE )
{
MTH3D_M_vAddVector ( &stHit, p_stVectAB, p_stVertexA );
}
else
{
MTH3D_M_vMulAddVector ( &stHit, xT, p_stVectAB, p_stVertexA );
}
}
}
else
{
MTH3D_M_vCopyVector ( &stHit, p_stVertexA );
}
return MTH3D_M_xVectorGapSqr ( &stHit, p_stPoint );
}
#endif
/*
--------------------------------------------------------------------------------
-- Description : Compute distance segment to a line
--------------------------------------------------------------------------------
-- Creation date : 18 nov 1996 Author : FPI
--------------------------------------------------------------------------------
*/
#if defined(ACTIVE_EDITOR)
/* active editor only*/
MTH_tdxReal INT_fn_xDistanceSegmentToLine ( MTH3D_tdstVector *p_stVertex1, /* segment */
MTH3D_tdstVector *p_stVect12,
MTH3D_tdstVector *p_stVertexA, /* line */
MTH3D_tdstVector *p_stVectAB,
MTH_tdxReal *p_xTLine,
MTH3D_tdstVector *p_stHitSegment,
MTH3D_tdstVector *p_stHitLine )
{
MTH3D_tdstVector stVectA1;
MTH_tdxReal xTSegment;
MTH_tdxReal xK;
MTH_tdxReal xL;
MTH_tdxReal xM;
MTH3D_tdstVector stVectP;
MTH3D_tdstVector stVectQ;
MTH3D_M_vSubVector ( &stVectA1, p_stVertex1, p_stVertexA );
xK = MTH3D_M_xDotProductVector ( p_stVectAB, p_stVect12 );
xL = MTH3D_M_xDotProductVector ( p_stVectAB, &stVectA1 );
xM = MTH_M_xInv ( MTH3D_M_xSqrVector ( p_stVectAB ) );
MTH3D_M_vMulScalarVector ( &stVectP, MTH_M_xMul ( xK, xM ), p_stVectAB );
if ( !(MTH3D_M_bEqualVector ( &stVectP, p_stVect12 )) )
{
MTH3D_M_vSubVector ( &stVectP, &stVectP, p_stVect12 );
MTH3D_M_vMulScalarVector ( &stVectQ, MTH_M_xMul ( xL, xM ), p_stVectAB );
MTH3D_M_vSubVector ( &stVectQ, &stVectQ, &stVectA1 );
xTSegment = MTH_M_xNeg ( MTH_M_xDiv ( MTH3D_M_xDotProductVector ( &stVectP, &stVectQ ), MTH3D_M_xSqrVector ( &stVectP ) ) );
if ( MTH_M_bLess ( xTSegment, MTH_C_ZERO ) )
{
xTSegment = MTH_C_ZERO;
MTH3D_M_vCopyVector ( p_stHitSegment, p_stVertex1 );
}
else
{
if ( MTH_M_bLess ( MTH_C_ONE, xTSegment ) )
{
xTSegment = MTH_C_ONE;
MTH3D_M_vAddVector ( p_stHitSegment, p_stVect12, p_stVertex1 );
}
else
{
MTH3D_M_vMulAddVector ( p_stHitSegment, xTSegment, p_stVect12, p_stVertex1 );
}
}
}
else
{
/* on prend vertex1 quand segment line parallele */
xTSegment = MTH_C_ZERO;
MTH3D_M_vCopyVector ( p_stHitSegment, p_stVertex1 );
}
*p_xTLine = MTH_M_xMul ( MTH_M_xAdd ( MTH_M_xMul ( xK, xTSegment ), xL ), xM );
MTH3D_M_vMulAddVector ( p_stHitLine, *p_xTLine, p_stVectAB, p_stVertexA );
return MTH3D_M_xVectorGap ( p_stHitSegment, p_stHitLine );
}
#endif
/*=======================================================================================
* Description TRUE if the I point is on the egdes of the [ABC] triangle (with epsilon)
*
* Creation date 26/03/98
* Author Marc Trabucato
*=====================================================================================*/
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
/*
ACP_tdxBool INT_fn_bIsOnTriangle( MTH3D_tdstVector *_p_stPointI, MTH3D_tdstVector *_p_stPointA,
MTH3D_tdstVector *_p_stPointB, MTH3D_tdstVector *_p_stPointC )
{
#define COL_C_Epsilon MTH_M_xFloatToReal(1e-3)
MTH_tdxReal xAlpha,xMin,xMax,xNorm2,xDotProduct;
MTH3D_tdstVector stAB, stAI, stIP, stPointP;
// X Test
xMin = FUT_M_xMinValue3( MTH3D_M_xGetXofVector( _p_stPointA ),
MTH3D_M_xGetXofVector( _p_stPointB ),
MTH3D_M_xGetXofVector( _p_stPointC ) );
if( MTH_M_bLess( MTH3D_M_xGetXofVector( _p_stPointI ), MTH_M_xSub( xMin, COL_C_Epsilon ) ) )
return FALSE;
xMax = FUT_M_xMaxValue3( MTH3D_M_xGetXofVector( _p_stPointA ),
MTH3D_M_xGetXofVector( _p_stPointB ),
MTH3D_M_xGetXofVector( _p_stPointC ) );
if( MTH_M_bGreater( MTH3D_M_xGetXofVector( _p_stPointI ), MTH_M_xAdd( xMax, COL_C_Epsilon ) ) )
return FALSE;
// Y Test
xMin = FUT_M_xMinValue3( MTH3D_M_xGetYofVector( _p_stPointA ),
MTH3D_M_xGetYofVector( _p_stPointB ),
MTH3D_M_xGetYofVector( _p_stPointC ) );
if( MTH_M_bLess( MTH3D_M_xGetYofVector( _p_stPointI ), MTH_M_xSub( xMin, COL_C_Epsilon ) ) )
return FALSE;
xMax = FUT_M_xMaxValue3( MTH3D_M_xGetYofVector( _p_stPointA ),
MTH3D_M_xGetYofVector( _p_stPointB ),
MTH3D_M_xGetYofVector( _p_stPointC ) );
if( MTH_M_bGreater( MTH3D_M_xGetYofVector( _p_stPointI ), MTH_M_xAdd( xMax, COL_C_Epsilon ) ) )
return FALSE;
// Z Test
xMin = FUT_M_xMinValue3( MTH3D_M_xGetZofVector( _p_stPointA ),
MTH3D_M_xGetZofVector( _p_stPointB ),
MTH3D_M_xGetZofVector( _p_stPointC ) );
if( MTH_M_bLess( MTH3D_M_xGetZofVector( _p_stPointI ), MTH_M_xSub( xMin, COL_C_Epsilon ) ) )
return FALSE;
xMax = FUT_M_xMaxValue3( MTH3D_M_xGetZofVector( _p_stPointA ),
MTH3D_M_xGetZofVector( _p_stPointB ),
MTH3D_M_xGetZofVector( _p_stPointC ) );
if( MTH_M_bGreater( MTH3D_M_xGetZofVector( _p_stPointI ), MTH_M_xAdd( xMax, COL_C_Epsilon ) ) )
return FALSE;
// segment AB
MTH3D_M_vSubVector( &stAB, _p_stPointB, _p_stPointA ); // AB
MTH3D_M_vSubVector( &stAI, _p_stPointI, _p_stPointA ); // AI
xDotProduct = MTH3D_M_xDotProductVector( &stAI, &stAB ); // AI.AB
xNorm2 = MTH3D_M_xSqrVector( &stAB ); // ||AB||<7C>
xAlpha = MTH_M_xDiv( xDotProduct, xNorm2 );
if( MTH_M_bGreaterEqual ( xAlpha, MTH_M_xNeg( COL_C_Epsilon ) ) && MTH_M_bLessEqual ( xAlpha, MTH_M_xAdd( MTH_C_ONE, COL_C_Epsilon ) ) )
{
MTH3D_M_vMulAddVector( &stPointP, xAlpha, &stAB, _p_stPointA ); // P
MTH3D_M_vSubVector( &stIP, & stPointP, _p_stPointI ); // IP
xNorm2 = MTH3D_M_xSqrVector( &stIP );
if( MTH_M_bLessEqual (xNorm2 , MTH_M_xSqr( COL_C_Epsilon ) ) )
return TRUE;
}
// segment AC
MTH3D_M_vSubVector( &stAB, _p_stPointC, _p_stPointA ); // AC
xDotProduct = MTH3D_M_xDotProductVector( &stAI, &stAB ); // AI.AC
xNorm2 = MTH3D_M_xSqrVector( &stAB ); // ||AC||<7C>
xAlpha = MTH_M_xDiv( xDotProduct, xNorm2 );
if( MTH_M_bGreaterEqual ( xAlpha, MTH_M_xNeg( COL_C_Epsilon ) ) && MTH_M_bLessEqual ( xAlpha, MTH_M_xAdd( MTH_C_ONE, COL_C_Epsilon ) ) )
{
MTH3D_M_vMulAddVector( &stPointP, xAlpha, &stAB, _p_stPointA ); // P
MTH3D_M_vSubVector( &stIP, & stPointP, _p_stPointI ); // IP
xNorm2 = MTH3D_M_xSqrVector( &stIP );
if( MTH_M_bLessEqual (xNorm2 , MTH_M_xSqr( COL_C_Epsilon ) ) )
return TRUE;
}
// segment BC
MTH3D_M_vSubVector( &stAB, _p_stPointC, _p_stPointB ); // BC
MTH3D_M_vSubVector( &stAI, _p_stPointI, _p_stPointB ); // BI
xDotProduct = MTH3D_M_xDotProductVector( &stAI, &stAB ); // BI.BC
xNorm2 = MTH3D_M_xSqrVector( &stAB ); // ||BC||<7C>
xAlpha = MTH_M_xDiv( xDotProduct, xNorm2 );
if( MTH_M_bGreaterEqual ( xAlpha, MTH_M_xNeg( COL_C_Epsilon ) ) && MTH_M_bLessEqual ( xAlpha, MTH_M_xAdd( MTH_C_ONE, COL_C_Epsilon ) ) )
{
MTH3D_M_vMulAddVector( &stPointP, xAlpha, &stAB, _p_stPointB ); // P
MTH3D_M_vSubVector( &stIP, & stPointP, _p_stPointI ); // IP
xNorm2 = MTH3D_M_xSqrVector( &stIP );
if( MTH_M_bLessEqual (xNorm2 , MTH_M_xSqr( COL_C_Epsilon ) ) )
return TRUE;
}
return FALSE;
}
*/
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */