"L. Spiro Engine"
|
00001 00016 #ifndef __LSE_PLANE3BASE_H__ 00017 #define __LSE_PLANE3BASE_H__ 00018 00019 #include "../LSMMathLib.h" 00020 00021 namespace lsm { 00022 00023 // == Enumerations. 00027 enum LSM_PLANE_INTERSECT { 00028 LSM_PI_FRONT, 00029 LSM_PI_BACK, 00030 LSM_PI_INTERSECT, 00031 LSM_PI_STRADDLING, 00032 LSM_PI_COPLANAR, 00033 }; 00034 00041 template <typename _tType, typename _tVec3Type> 00042 class CPlane3Base { 00043 // All is public. This class has no secrets. 00044 public : 00045 // == Various constructors. 00046 LSE_INLINE LSE_CALLCTOR CPlane3Base() { 00047 } 00048 LSE_INLINE LSE_CALLCTOR CPlane3Base( const CPlane3Base<_tType, _tVec3Type> &_pPlane ) { 00049 (*this) = _pPlane; 00050 } 00051 LSE_INLINE LSE_CALLCTOR CPlane3Base( const _tVec3Type &_vPoint0, const _tVec3Type &_vPoint1, const _tVec3Type &_vPoint2 ) { 00052 n = (_vPoint1 - _vPoint0) % (_vPoint2 - _vPoint0); 00053 n.Normalize(); 00054 dist = n.Dot( _vPoint0 ); 00055 } 00056 LSE_INLINE LSE_CALLCTOR CPlane3Base( const _tVec3Type &_vNormal, _tType _fDistance ) { 00057 n = _vNormal; 00058 dist = _fDistance; 00059 } 00060 LSE_INLINE LSE_CALLCTOR CPlane3Base( const _tVec3Type &_vPoint, const _tVec3Type &_vNormal ) { 00061 n = _vNormal; 00062 dist = n.Dot( _vPoint ); 00063 } 00064 00065 00066 // == Operators. 00073 CPlane3Base<_tType, _tVec3Type> & LSE_FCALL 00074 operator = ( const CPlane3Base<_tType, _tVec3Type> &_pPlane ) { 00075 n = _pPlane.n; 00076 dist = _pPlane.dist; 00077 return (*this); 00078 } 00079 00086 LSBOOL LSE_CALL operator == ( const CPlane3Base<_tType, _tVec3Type> &_pOther ) const { 00087 return dist == _pOther.dist && n == _pOther.n; 00088 } 00089 00095 CPlane3Base<_tType, _tVec3Type> LSE_CALL 00096 operator - () const { 00097 return CPlane3Base<_tType, _tVec3Type>( -n, -dist ); 00098 } 00099 00100 00101 // == Functions. 00108 LSE_INLINE _tType LSE_FCALL SignedDistance( const _tVec3Type &_vPoint ) const { 00109 return n.Dot( _vPoint ) - dist; 00110 } 00111 00118 LSE_INLINE _tType LSE_FCALL SignedDistanceNonNormal( const _tVec3Type &_vPoint ) const { 00119 return (n.Dot( _vPoint ) - dist) / n.LenSq(); 00120 } 00121 00128 LSE_INLINE _tVec3Type LSE_FCALL ProjectPointToPlane( const _tVec3Type &_vPoint ) const { 00129 _tType fDist = -SignedDistance( _vPoint ); 00130 return CVector3( (n.x * fDist) + _vPoint.x, 00131 (n.y * fDist) + _vPoint.y, 00132 (n.z * fDist) + _vPoint.z ); 00133 } 00134 00141 LSE_INLINE _tVec3Type LSE_FCALL ClosestPointOnPlane( const _tVec3Type &_vPoint ) const { 00142 _tType fT = n.Dot( _vPoint ) - dist; 00143 return _vPoint - (n * fT); 00144 } 00145 00152 LSE_INLINE _tVec3Type LSE_FCALL ClosestPointOnNonNormalPlane( const _tVec3Type &_vPoint ) const { 00153 _tType fT = (n.Dot( _vPoint ) - dist) / n.LenSq(); 00154 return _vPoint - (n * fT); 00155 } 00156 00160 LSE_INLINE LSVOID LSE_FCALL Normalize() { 00161 _tType fInvMag = static_cast<_tType>(1.0) / n.Len(); 00162 00163 n.x *= fInvMag; 00164 n.y *= fInvMag; 00165 n.z *= fInvMag; 00166 dist *= fInvMag; 00167 } 00168 00179 static LSBOOL LSE_CALL PlanesFormConvexEdge( const CPlane3Base<_tType, _tVec3Type> &_pbLeft, const CPlane3Base<_tType, _tVec3Type> &_pbRight, 00180 _tType _tEpsilon ) { 00181 // Get the direction of the intersecting line. 00182 _tVec3Type vDir = _pbLeft.n % _pbRight.n; 00183 00184 _tType tDenom = vDir * vDir; 00185 if ( tDenom < _tEpsilon ) { return false; } // Not forming an edge at all. 00186 00187 vDir.Normalize(); 00188 _tVec3Type vDirFromLefToRight = vDir % _pbLeft.n; 00189 _tType tInDirFromLeft = vDirFromLefToRight * _pbRight.n; 00190 00191 return tInDirFromLeft < _tType( 0 ); 00192 } 00193 00194 00195 // == Members. 00199 _tVec3Type n; 00200 00204 _tType dist; 00205 00206 }; 00207 00208 } // namespace lsm 00209 00210 #endif // __LSE_PLANE3BASE_H__