Serious-Engine/Sources/Engine/Math/Geometry.inl
Ryan C. Gordon 24cb244d43 First attempt to hand-merge Ryan's Linux and Mac OS X port.
This was a _ton_ of changes, made 15 years ago, so there are probably some
problems to work out still.

Among others: Engine/Base/Stream.* was mostly abandoned and will need to be
re-ported.

Still, this is a pretty good start, and probably holds a world record for
lines of changes or something.  :)
2016-03-28 23:46:13 -04:00

139 lines
4.2 KiB
C++

#ifndef SE_INCL_GEOMETRY_INL
#define SE_INCL_GEOMETRY_INL
#ifdef PRAGMA_ONCE
#pragma once
#endif
// mirror a position vector by a given plane
inline void ReflectPositionVectorByPlane(const FLOATplane3D &plPlane, FLOAT3D &vPoint)
{
vPoint-=((FLOAT3D &)plPlane)*(2*plPlane.PointDistance(vPoint));
}
// mirror a direction vector by a given plane
inline void ReflectDirectionVectorByPlane(const FLOATplane3D &plPlane, FLOAT3D &vDirection)
{
vDirection-=((FLOAT3D &)plPlane)*(2*(((FLOAT3D &)plPlane)%vDirection));
}
// mirror a rotation matrix by a given plane
inline void ReflectRotationMatrixByPlane_cols(const FLOATplane3D &plPlane, FLOATmatrix3D &m)
{ // reflect columns vectors
FLOAT3D vX(m(1,1),m(2,1),m(3,1));
FLOAT3D vY(m(1,2),m(2,2),m(3,2));
FLOAT3D vZ(m(1,3),m(2,3),m(3,3));
ReflectDirectionVectorByPlane(plPlane, vX);
ReflectDirectionVectorByPlane(plPlane, vY);
ReflectDirectionVectorByPlane(plPlane, vZ);
m(1,1) = vX(1); m(1,2) = vY(1); m(1,3) = vZ(1);
m(2,1) = vX(2); m(2,2) = vY(2); m(2,3) = vZ(2);
m(3,1) = vX(3); m(3,2) = vY(3); m(3,3) = vZ(3);
}
inline void ReflectRotationMatrixByPlane_rows(const FLOATplane3D &plPlane, FLOATmatrix3D &m)
{ // reflect row vectors
FLOAT3D vX(m(1,1),m(1,2),m(1,3));
FLOAT3D vY(m(2,1),m(2,2),m(2,3));
FLOAT3D vZ(m(3,1),m(3,2),m(3,3));
ReflectDirectionVectorByPlane(plPlane, vX);
ReflectDirectionVectorByPlane(plPlane, vY);
ReflectDirectionVectorByPlane(plPlane, vZ);
m(1,1) = vX(1); m(2,1) = vY(1); m(3,1) = vZ(1);
m(1,2) = vX(2); m(2,2) = vY(2); m(3,2) = vZ(2);
m(1,3) = vX(3); m(2,3) = vY(3); m(3,3) = vZ(3);
}
// get component of a vector parallel to given reference vector
static inline void GetParallelComponent(
const FLOAT3D &vFull, const FLOAT3D &vReference, FLOAT3D &vParallel)
{
vParallel = vReference*(vFull%vReference);
}
// get component of a vector normal to given reference vector
static inline void GetNormalComponent(
const FLOAT3D &vFull, const FLOAT3D &vReference, FLOAT3D &vNormal)
{
vNormal = vFull-vReference*(vFull%vReference);
}
// get components of a vector parallel and normal to given reference vector
static inline void GetParallelAndNormalComponents(
const FLOAT3D &vFull, const FLOAT3D &vReference, FLOAT3D &vParallel, FLOAT3D &vNormal)
{
vParallel = vReference*(vFull%vReference);
vNormal = vFull-vParallel;
}
// get measure of validity of a rotation matrix (should be around zero)
static inline FLOAT RotationMatrixValidity(const FLOATmatrix3D &m)
{
FLOATmatrix3D mSqr;
mSqr(1,1) = m(1,1)*m(1,1);
mSqr(1,2) = m(1,2)*m(1,2);
mSqr(1,3) = m(1,3)*m(1,3);
mSqr(2,1) = m(2,1)*m(2,1);
mSqr(2,2) = m(2,2)*m(2,2);
mSqr(2,3) = m(2,3)*m(2,3);
mSqr(3,1) = m(3,1)*m(3,1);
mSqr(3,2) = m(3,2)*m(3,2);
mSqr(3,3) = m(3,3)*m(3,3);
FLOAT3D vH;
vH(1) = Sqrt(mSqr(1,1)+mSqr(1,2)+mSqr(1,3))-1;
vH(2) = Sqrt(mSqr(2,1)+mSqr(2,2)+mSqr(2,3))-1;
vH(3) = Sqrt(mSqr(3,1)+mSqr(3,2)+mSqr(3,3))-1;
FLOAT3D vV;
vV(1) = Sqrt(mSqr(1,1)+mSqr(2,1)+mSqr(3,1))-1;
vV(2) = Sqrt(mSqr(1,2)+mSqr(2,2)+mSqr(3,2))-1;
vV(3) = Sqrt(mSqr(1,3)+mSqr(2,3)+mSqr(3,3))-1;
return Sqrt(
vH(1)*vH(1)+vH(2)*vH(2)+vH(3)*vH(3)+
vV(1)*vV(1)+vV(2)*vV(2)+vV(3)*vV(3));
}
// normalize rotation matrix to be special orthogonal
static inline void OrthonormalizeRotationMatrix( FLOATmatrix3D &m)
{
FLOAT3D vX(m(1,1),m(2,1),m(3,1));
FLOAT3D vY(m(1,2),m(2,2),m(3,2));
FLOAT3D vZ;
vX.Normalize();
vZ = vX*vY;
vZ.Normalize();
vY = vZ*vX;
vY.Normalize();
m(1,1) = vX(1); m(1,2) = vY(1); m(1,3) = vZ(1);
m(2,1) = vX(2); m(2,2) = vY(2); m(2,3) = vZ(2);
m(3,1) = vX(3); m(3,2) = vY(3); m(3,3) = vZ(3);
}
inline void GetMajorAxesForPlane(
const FLOATplane3D &plPlane, INDEX &iMajorAxis1, INDEX &iMajorAxis2)
{
// get maximum normal axis
INDEX iMaxNormalAxis = plPlane.GetMaxNormal();
// the major axes are the other two axes
switch (iMaxNormalAxis) {
case 1: iMajorAxis1 = 2; iMajorAxis2 = 3;
break;
case 2: iMajorAxis1 = 3; iMajorAxis2 = 1;
break;
case 3: iMajorAxis1 = 1; iMajorAxis2 = 2;
break;
default:
ASSERT(FALSE);
iMajorAxis1 = 2;
iMajorAxis2 = 3;
}
ASSERT(Abs(plPlane(iMaxNormalAxis))>=Abs(plPlane(iMajorAxis1))
&&Abs(plPlane(iMaxNormalAxis))>=Abs(plPlane(iMajorAxis2)));
}
#endif /* include-once checker ... */