123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #ifndef _MPLANE_H_
- #define _MPLANE_H_
- #ifndef _MPOINT3_H_
- #include "math/mPoint3.h"
- #endif
- #ifndef _MBOX_H_
- #include "math/mBox.h"
- #endif
- #ifndef _MORIENTEDBOX_H_
- #include "math/mOrientedBox.h"
- #endif
- #ifndef _MSPHERE_H_
- #include "math/mSphere.h"
- #endif
- /// A 3D plane defined by a normal and a distance along the normal.
- ///
- /// @note The distance is stored negative.
- class PlaneF : public Point3F
- {
- public:
- /// *NEGATIVE* distance along the xyz normal.
- F32 d;
- /// Return the plane's normal.
- const Point3F& getNormal() const { return *this; }
- /// Return the plane's position.
- Point3F getPosition() const { return Point3F( x, y, z ) * -d; }
- bool isHorizontal() const;
- bool isVertical() const;
- bool isParallelTo( const PlaneF& plane, F32 epsilon = POINT_EPSILON ) const;
- bool isPerpendicularTo( const PlaneF& plane, F32 epsilon = POINT_EPSILON ) const;
- /// @name Initialization
- /// @{
- PlaneF() :d(0.0f) {}
- PlaneF( const Point3F& p, const Point3F& n );
- /// NOTE: d is the NEGATIVE distance along the xyz normal.
- PlaneF( F32 _x, F32 _y, F32 _z, F32 _d);
- PlaneF( const Point3F& j, const Point3F& k, const Point3F& l );
- void set( F32 _x, F32 _y, F32 _z );
- /// NOTE: d is the NEGATIVE distance along the xyz normal.
- void set( F32 _x, F32 _y, F32 _z, F32 _d );
- void set( const Point3F& p, const Point3F& n);
- void set( const Point3F& k, const Point3F& j, const Point3F& l );
- void setPoint(const Point3F &p); // assumes the x,y,z fields are already set
- // creates an un-normalized plane
- void setXY(F32 zz);
- void setYZ(F32 xx);
- void setXZ(F32 yy);
- void setXY(const Point3F& P, F32 dir);
- void setYZ(const Point3F& P, F32 dir);
- void setXZ(const Point3F& P, F32 dir);
- /// @}
- void shiftX(F32 xx);
- void shiftY(F32 yy);
- void shiftZ(F32 zz);
- void invert();
- void neg();
- /// Return the distance of the given point from the plane.
- F32 distToPlane( const Point3F& cp ) const;
- /// Project the given point onto the plane.
- Point3F project(const Point3F &pt) const;
- /// @name Intersection
- /// @{
- enum Side
- {
- Front = 1,
- On = 0,
- Back = -1
- };
- /// Compute on which side of the plane the given point lies.
- Side whichSide( const Point3F& cp ) const;
- /// Compute which side the given sphere lies on.
- Side whichSide( const SphereF& sphere ) const;
- /// Compute which side the given AABB lies on.
- Side whichSide( const Box3F& aabb ) const;
- /// Compute which side the given OBB lies on.
- Side whichSide( const OrientedBox3F& obb ) const;
- /// Compute which side the given box lies on.
- ///
- /// @param center Center point.
- /// @param axisx X-Axis vector. Length is box half-extent along X.
- /// @param axisy Y-Axis vector. Length is box half-extent along Y.
- /// @param axisz Z-Axis vector. Length is box half-extent along Z.
- ///
- /// @return Side that the given box is on.
- Side whichSideBox( const Point3F& center,
- const Point3F& axisx,
- const Point3F& axisy,
- const Point3F& axisz ) const;
- /// @}
- /// @name Intersection
- /// @{
- /// Compute the distance at which the ray traveling from @a start in the direction
- /// of @end intersects the plane
- /// @param start Starting point of the ray.
- /// @param end Point in the direction of which the ray travels from @a start.
- /// @return The distance (as a fraction/multiple of the length of the vector between
- /// @a start and @a end) at which the ray intersects the plane or PARALLEL_PLANE if the
- /// ray is parallel to the plane.
- F32 intersect( const Point3F &start, const Point3F &end ) const;
- /// Compute the intersection of the ray that emanates at @a start in the direction
- /// @dir.
- /// @param start Point where the ray emanates.
- /// @param dir Direction in which the ray travels. Must be normalized.
- /// @param outHit Resulting intersection point. Only set if there indeed is a hit.
- /// @return True if the ray intersects the plane or false if not.
- bool intersect( const Point3F &start, const Point3F &dir, Point3F *outHit ) const;
- /// Compute the intersection between two planes.
- ///
- /// @param plane Plane to intersect with.
- /// @param outLineOrigin Used to store the origin of the resulting intersection line.
- /// @param outLineDirection Used to store the direction of the resulting intersection line.
- ///
- /// @return True if there is an intersection or false if the two planes are coplanar.
- bool intersect( const PlaneF& plane, Point3F& outLineOrigin, Point3F& outLineDirection ) const;
- /// @}
- /// @name Clipping
- /// @{
- /// Clip a convex polygon by the plane.
- ///
- /// The resulting polygon will be the input polygon minus the part on the negative side
- /// of the plane. The input polygon must be convex and @a inVertices must be in CCW or CW order.
- ///
- /// @param inVertices Array holding the vertices of the input polygon.
- /// @param inNumVertices Number of vertices in @a inVertices.
- /// @param outVertices Array to hold the vertices of the clipped polygon. Must have space for one additional
- /// vertex in case the polygon is split by the plane such that an additional vertex appears. Must not
- /// be the same as @a inVertices.
- /// @return Number of vertices in the clipped polygon, i.e. number of vertices in @a outVertices.
- ///
- /// @note Be aware that if the polygon fully lies on the negative side of the plane,
- /// the resulting @a outNumVertices will be zero, i.e. no polygon will result from the clip.
- U32 clipPolygon( const Point3F* inVertices, U32 inNumVertices, Point3F* outVertices ) const;
- /// Clip a line segment by the plane.
- ///
- /// @param start Start point of the line segment.
- /// @param end End point of the line segment.
- /// @param outNewEnd New end point if there is an intersection with the plane.
- ///
- /// @return True
- bool clipSegment( const Point3F& start, const Point3F& end, Point3F& outNewEnd ) const;
- /// @}
- };
- #define PARALLEL_PLANE 1e20f
- #define PlaneSwitchCode(s, e) (s * 3 + e)
- //---------------------------------------------------------------------------
- inline PlaneF::PlaneF( F32 _x, F32 _y, F32 _z, F32 _d )
- {
- set( _x, _y, _z, _d );
- }
- //-----------------------------------------------------------------------------
- inline PlaneF::PlaneF( const Point3F& p, const Point3F& n )
- {
- set(p,n);
- }
- //-----------------------------------------------------------------------------
- inline PlaneF::PlaneF( const Point3F& j, const Point3F& k, const Point3F& l )
- {
- set(j,k,l);
- }
- //-----------------------------------------------------------------------------
- inline void PlaneF::setXY( F32 zz )
- {
- x = y = 0.0f; z = 1.0f; d = -zz;
- }
- //-----------------------------------------------------------------------------
- inline void PlaneF::setYZ( F32 xx )
- {
- x = 1.0f; z = y = 0.0f; d = -xx;
- }
- //-----------------------------------------------------------------------------
- inline void PlaneF::setXZ( F32 yy )
- {
- x = z = 0.0f; y = 1.0f; d = -yy;
- }
- //-----------------------------------------------------------------------------
- inline void PlaneF::setXY(const Point3F& point, F32 dir) // Normal = (0, 0, -1|1)
- {
- x = y = 0.0f;
- d = -((z = dir) * point.z);
- }
- //-----------------------------------------------------------------------------
- inline void PlaneF::setYZ(const Point3F& point, F32 dir) // Normal = (-1|1, 0, 0)
- {
- z = y = 0.0f;
- d = -((x = dir) * point.x);
- }
- //-----------------------------------------------------------------------------
- inline void PlaneF::setXZ(const Point3F& point, F32 dir) // Normal = (0, -1|1, 0)
- {
- x = z = 0.0f;
- d = -((y = dir) * point.y);
- }
- //-----------------------------------------------------------------------------
- inline void PlaneF::shiftX( F32 xx )
- {
- d -= xx * x;
- }
- //-----------------------------------------------------------------------------
- inline void PlaneF::shiftY( F32 yy )
- {
- d -= yy * y;
- }
- //-----------------------------------------------------------------------------
- inline void PlaneF::shiftZ( F32 zz )
- {
- d -= zz * z;
- }
- //-----------------------------------------------------------------------------
- inline bool PlaneF::isHorizontal() const
- {
- return (x == 0.0f && y == 0.0f) ? true : false;
- }
- //-----------------------------------------------------------------------------
- inline bool PlaneF::isVertical() const
- {
- return ((x != 0.0f || y != 0.0f) && z == 0.0f) ? true : false;
- }
- //-----------------------------------------------------------------------------
- inline Point3F PlaneF::project(const Point3F &pt) const
- {
- F32 dist = distToPlane(pt);
- return Point3F(pt.x - x * dist, pt.y - y * dist, pt.z - z * dist);
- }
- //-----------------------------------------------------------------------------
- inline F32 PlaneF::distToPlane( const Point3F& cp ) const
- {
- // return mDot(*this,cp) + d;
- return (x * cp.x + y * cp.y + z * cp.z) + d;
- }
- //-----------------------------------------------------------------------------
- inline PlaneF::Side PlaneF::whichSide(const Point3F& cp) const
- {
- F32 dist = distToPlane(cp);
- if (dist >= 0.005f) // if (mFabs(dist) < 0.005f)
- return Front; // return On;
- else if (dist <= -0.005f) // else if (dist > 0.0f)
- return Back; // return Front;
- else // else
- return On; // return Back;
- }
- //-----------------------------------------------------------------------------
- inline PlaneF::Side PlaneF::whichSide( const SphereF& sphere ) const
- {
- const F32 dist = distToPlane( sphere.center );
- if( dist > sphere.radius )
- return Front;
- else if( dist < - sphere.radius )
- return Back;
- else
- return On;
- }
- //-----------------------------------------------------------------------------
- inline PlaneF::Side PlaneF::whichSide( const Box3F& aabb ) const
- {
- // See Graphics Gems IV, 1.7 and "A Faster Overlap Test for a Plane and a Bounding Box"
- // (http://replay.waybackmachine.org/19981203032829/http://www.cs.unc.edu/~hoff/research/vfculler/boxplane.html)
- // for details.
- Point3F pVertex;
- Point3F nVertex;
- pVertex.x = ( x > 0.0f ) ? aabb.maxExtents.x : aabb.minExtents.x;
- pVertex.y = ( y > 0.0f ) ? aabb.maxExtents.y : aabb.minExtents.y;
- pVertex.z = ( z > 0.0f ) ? aabb.maxExtents.z : aabb.minExtents.z;
- if( whichSide( pVertex ) == Back )
- return Back;
- nVertex.x = ( x > 0.0f ) ? aabb.minExtents.x : aabb.maxExtents.x;
- nVertex.y = ( y > 0.0f ) ? aabb.minExtents.y : aabb.maxExtents.y;
- nVertex.z = ( z > 0.0f ) ? aabb.minExtents.z : aabb.maxExtents.z;
- if( whichSide( nVertex ) == Front )
- return Front;
- return On;
- }
- //-----------------------------------------------------------------------------
- inline PlaneF::Side PlaneF::whichSide( const OrientedBox3F& obb ) const
- {
- // Project the box onto the line defined by the plane center and normal.
- // See "3D Game Engine Design" chapter 4.3.2.
- Point3F mObbHalf = obb.getHalfExtents();
- const F32 r = mObbHalf.x * mFabs( mDot( obb.getAxis( 0 ), *this ) ) +
- mObbHalf.y * mFabs( mDot( obb.getAxis( 1 ), *this ) ) +
- mObbHalf.z * mFabs( mDot( obb.getAxis( 2 ), *this ) );
- const F32 dist = distToPlane( obb.getCenter() );
- if( dist > r )
- return Front;
- else if( dist < - r )
- return Back;
- else
- return On;
- }
- //-----------------------------------------------------------------------------
- inline PlaneF::Side PlaneF::whichSideBox(const Point3F& center,
- const Point3F& axisx,
- const Point3F& axisy,
- const Point3F& axisz) const
- {
- F32 baseDist = distToPlane(center);
- F32 compDist = mFabs(mDot(axisx, *this)) +
- mFabs(mDot(axisy, *this)) +
- mFabs(mDot(axisz, *this));
- if (baseDist >= compDist)
- return Front;
- else if (baseDist <= -compDist)
- return Back;
- else
- return On;
- }
- inline void PlaneF::set( F32 _x, F32 _y, F32 _z )
- {
- Point3F::set(_x,_y,_z);
- }
- inline void PlaneF::set( F32 _x, F32 _y, F32 _z, F32 _d )
- {
- Point3F::set(_x,_y,_z);
- d = _d;
- }
- //---------------------------------------------------------------------------
- /// Calculate the coefficients of the plane passing through
- /// a point with the given normal.
- inline void PlaneF::setPoint(const Point3F &p)
- {
- d = -(p.x * x + p.y * y + p.z * z);
- }
- inline void PlaneF::set( const Point3F& p, const Point3F& n )
- {
- x = n.x; y = n.y; z = n.z;
- normalize();
- // Calculate the last plane coefficient.
- d = -(p.x * x + p.y * y + p.z * z);
- }
- //---------------------------------------------------------------------------
- // Calculate the coefficients of the plane passing through
- // three points. Basically it calculates the normal to the three
- // points then calculates a plane through the middle point with that
- // normal.
- inline void PlaneF::set( const Point3F& k, const Point3F& j, const Point3F& l )
- {
- // Point3F kj, lj, pv;
- // kj = k - j;
- // lj = l - j;
- // mCross( kj, lj, &pv );
- // set(j, pv);
- // Inline for speed...
- const F32 ax = k.x-j.x;
- const F32 ay = k.y-j.y;
- const F32 az = k.z-j.z;
- const F32 bx = l.x-j.x;
- const F32 by = l.y-j.y;
- const F32 bz = l.z-j.z;
- x = ay*bz - az*by;
- y = az*bx - ax*bz;
- z = ax*by - ay*bx;
-
- m_point3F_normalize( (F32 *)(&x) );
- d = -(j.x * x + j.y * y + j.z * z);
- }
- inline void PlaneF::invert()
- {
- x = -x;
- y = -y;
- z = -z;
- d = -d;
- }
- inline void PlaneF::neg()
- {
- invert();
- }
- inline F32 PlaneF::intersect(const Point3F &p1, const Point3F &p2) const
- {
- const F32 den = mDot(p2 - p1, *this);
- if( mIsZero( den ) )
- return PARALLEL_PLANE;
- return -distToPlane(p1) / den;
- }
- inline bool PlaneF::intersect( const Point3F &start, const Point3F &dir, Point3F *outHit ) const
- {
- const F32 den = mDot( dir, *this );
- if ( mIsZero( den ) )
- return false;
- F32 dist = -distToPlane( start ) / den;
- *outHit = start + dir * dist;
- return true;
- }
- class PlaneD: public Point3D
- {
- public:
- /// NOTE: d is the NEGATIVE distance along the xyz normal.
- F64 d;
- PlaneD();
- PlaneD( const PlaneF& copy);
- PlaneD( const Point3D& p, const Point3D& n );
- /// NOTE: d is the NEGATIVE distance along the xyz normal.
- PlaneD( F64 _x, F64 _y, F64 _z, F64 _d);
- PlaneD( const Point3D& j, const Point3D& k, const Point3D& l );
- // Methods
- //using Point3D::set;
- void set(const F64 _x, const F64 _y, const F64 _z);
- void set( const Point3D& p, const Point3D& n);
- void set( const Point3D& k, const Point3D& j, const Point3D& l );
- void setPoint(const Point3D &p); // assumes the x,y,z fields are already set
- // creates an un-normalized plane
- void setXY(F64 zz);
- void setYZ(F64 xx);
- void setXZ(F64 yy);
- void setXY(const Point3D& P, F64 dir);
- void setYZ(const Point3D& P, F64 dir);
- void setXZ(const Point3D& P, F64 dir);
- void shiftX(F64 xx);
- void shiftY(F64 yy);
- void shiftZ(F64 zz);
- void invert();
- void neg();
- Point3D project(const Point3D &pt) const; // projects the point onto the plane.
- F64 distToPlane( const Point3D& cp ) const;
- enum Side {
- Front = 1,
- On = 0,
- Back = -1
- };
- Side whichSide(const Point3D& cp) const;
- F64 intersect(const Point3D &start, const Point3D &end) const;
- //DLLAPI bool split( const Poly3F& poly, Poly3F* front, Poly3F* back );
- bool isHorizontal() const;
- bool isVertical() const;
- Side whichSideBox(const Point3D& center,
- const Point3D& axisx,
- const Point3D& axisy,
- const Point3D& axisz) const;
- };
- //#define PARALLEL_PLANE 1e20f
- //#define PlaneSwitchCode(s, e) (s * 3 + e)
- //---------------------------------------------------------------------------
- inline PlaneD::PlaneD()
- {
- d = 0.0;
- }
- inline PlaneD::
- PlaneD( F64 _x, F64 _y, F64 _z, F64 _d )
- {
- x = _x; y = _y; z = _z; d = _d;
- }
- inline PlaneD::PlaneD( const PlaneF& copy)
- {
- x = copy.x; y = copy.y; z = copy.z; d = copy.d;
- }
- inline PlaneD::PlaneD( const Point3D& p, const Point3D& n )
- {
- set(p,n);
- }
- inline PlaneD::PlaneD( const Point3D& j, const Point3D& k, const Point3D& l )
- {
- set(j,k,l);
- }
- inline void PlaneD::setXY( F64 zz )
- {
- x = y = 0; z = 1; d = -zz;
- }
- inline void PlaneD::setYZ( F64 xx )
- {
- x = 1; z = y = 0; d = -xx;
- }
- inline void PlaneD::setXZ( F64 yy )
- {
- x = z = 0; y = 1; d = -yy;
- }
- inline void PlaneD::setXY(const Point3D& point, F64 dir) // Normal = (0, 0, -1|1)
- {
- x = y = 0;
- d = -((z = dir) * point.z);
- }
- inline void PlaneD::setYZ(const Point3D& point, F64 dir) // Normal = (-1|1, 0, 0)
- {
- z = y = 0;
- d = -((x = dir) * point.x);
- }
- inline void PlaneD::setXZ(const Point3D& point, F64 dir) // Normal = (0, -1|1, 0)
- {
- x = z = 0;
- d = -((y = dir) * point.y);
- }
- inline void PlaneD::shiftX( F64 xx )
- {
- d -= xx * x;
- }
- inline void PlaneD::shiftY( F64 yy )
- {
- d -= yy * y;
- }
- inline void PlaneD::shiftZ( F64 zz )
- {
- d -= zz * z;
- }
- inline bool PlaneD::isHorizontal() const
- {
- return (x == 0 && y == 0) ? true : false;
- }
- inline bool PlaneD::isVertical() const
- {
- return ((x != 0 || y != 0) && z == 0) ? true : false;
- }
- inline Point3D PlaneD::project(const Point3D &pt) const
- {
- F64 dist = distToPlane(pt);
- return Point3D(pt.x - x * dist, pt.y - y * dist, pt.z - z * dist);
- }
- inline F64 PlaneD::distToPlane( const Point3D& cp ) const
- {
- // return mDot(*this,cp) + d;
- return (x * cp.x + y * cp.y + z * cp.z) + d;
- }
- inline PlaneD::Side PlaneD::whichSide(const Point3D& cp) const
- {
- F64 dist = distToPlane(cp);
- if (dist >= 0.005f) // if (mFabs(dist) < 0.005f)
- return Front; // return On;
- else if (dist <= -0.005f) // else if (dist > 0.0f)
- return Back; // return Front;
- else // else
- return On; // return Back;
- }
- inline void PlaneD::set(const F64 _x, const F64 _y, const F64 _z)
- {
- Point3D::set(_x,_y,_z);
- }
- //---------------------------------------------------------------------------
- // Calculate the coefficients of the plane passing through
- // a point with the given normal.
- ////inline void PlaneD::set( const Point3D& p, const Point3D& n )
- inline void PlaneD::setPoint(const Point3D &p)
- {
- d = -(p.x * x + p.y * y + p.z * z);
- }
- inline void PlaneD::set( const Point3D& p, const Point3D& n )
- {
- x = n.x; y = n.y; z = n.z;
- normalize();
- // Calculate the last plane coefficient.
- d = -(p.x * x + p.y * y + p.z * z);
- }
- //---------------------------------------------------------------------------
- // Calculate the coefficients of the plane passing through
- // three points. Basically it calculates the normal to the three
- // points then calculates a plane through the middle point with that
- // normal.
- inline void PlaneD::set( const Point3D& k, const Point3D& j, const Point3D& l )
- {
- // Point3D kj,lj,pv;
- // kj = k;
- // kj -= j;
- // lj = l;
- // lj -= j;
- // mCross( kj, lj, &pv );
- // set(j,pv);
- // Above ends up making function calls up the %*#...
- // This is called often enough to be a little more direct
- // about it (sqrt should become intrinsic in the future)...
- F64 ax = k.x-j.x;
- F64 ay = k.y-j.y;
- F64 az = k.z-j.z;
- F64 bx = l.x-j.x;
- F64 by = l.y-j.y;
- F64 bz = l.z-j.z;
- x = ay*bz - az*by;
- y = az*bx - ax*bz;
- z = ax*by - ay*bx;
- F64 squared = x*x + y*y + z*z;
- AssertFatal(squared != 0.0, "Error, no plane possible!");
- // In non-debug mode
- if (squared != 0)
- {
- F64 invSqrt = 1.0 / (F64)mSqrt(x*x + y*y + z*z);
- x *= invSqrt;
- y *= invSqrt;
- z *= invSqrt;
- d = -(j.x * x + j.y * y + j.z * z);
- }
- else
- {
- x = 0;
- y = 0;
- z = 1;
- d = -(j.x * x + j.y * y + j.z * z);
- }
- }
- inline void PlaneD::invert()
- {
- x = -x;
- y = -y;
- z = -z;
- d = -d;
- }
- inline void PlaneD::neg()
- {
- invert();
- }
- inline F64 PlaneD::intersect(const Point3D &p1, const Point3D &p2) const
- {
- F64 den = mDot(p2 - p1, *this);
- if(den == 0)
- return PARALLEL_PLANE;
- return -distToPlane(p1) / den;
- }
- inline PlaneD::Side PlaneD::whichSideBox(const Point3D& center,
- const Point3D& axisx,
- const Point3D& axisy,
- const Point3D& axisz) const
- {
- F64 baseDist = distToPlane(center);
- F64 compDist = mFabs(mDot(axisx, *this)) +
- mFabs(mDot(axisy, *this)) +
- mFabs(mDot(axisz, *this));
- // Intersects
- if (baseDist >= compDist)
- return Front;
- else if (baseDist <= -compDist)
- return Back;
- else
- return On;
- // if (compDist > mFabs(baseDist))
- // return On;
- // else
- // return baseDist < 0.0 ? Back : Front;
- }
- #endif // _MPLANE_H_
|