From c98d77ec06e43c58381bca3ca1e27827dcc01dcc Mon Sep 17 00:00:00 2001 From: Pavel Rojtberg Date: Sun, 9 Dec 2018 16:48:58 +0100 Subject: [PATCH] Main: Plane - move all definitions to header to allow inlining --- OgreMain/include/OgreMatrix4.h | 16 +-- OgreMain/include/OgreMeshManager.h | 1 + OgreMain/include/OgrePlane.h | 136 ++++++++++++++++++++--- OgreMain/src/OgrePlane.cpp | 166 ----------------------------- 4 files changed, 121 insertions(+), 198 deletions(-) delete mode 100644 OgreMain/src/OgrePlane.cpp diff --git a/OgreMain/include/OgreMatrix4.h b/OgreMain/include/OgreMatrix4.h index 29144d6ebf7..9cd72e804dd 100644 --- a/OgreMain/include/OgreMatrix4.h +++ b/OgreMain/include/OgreMatrix4.h @@ -33,7 +33,7 @@ THE SOFTWARE. #include "OgreMatrix3.h" #include "OgreVector4.h" -#include "OgrePlane.h" + namespace Ogre { /** \addtogroup Core @@ -552,20 +552,6 @@ namespace Ogre v.x*mat[0][3] + v.y*mat[1][3] + v.z*mat[2][3] + v.w*mat[3][3] ); } - - inline Plane operator * (const Matrix4& mat, const Plane& p) - { - Plane ret; - Matrix4 invTrans = mat.inverse().transpose(); - Vector4 v4( p.normal.x, p.normal.y, p.normal.z, p.d ); - v4 = invTrans * v4; - ret.normal.x = v4.x; - ret.normal.y = v4.y; - ret.normal.z = v4.z; - ret.d = v4.w / ret.normal.normalise(); - - return ret; - } /** @} */ /** @} */ diff --git a/OgreMain/include/OgreMeshManager.h b/OgreMain/include/OgreMeshManager.h index 9fb15abfb47..c426ed8f13c 100644 --- a/OgreMain/include/OgreMeshManager.h +++ b/OgreMain/include/OgreMeshManager.h @@ -37,6 +37,7 @@ THE SOFTWARE. #include "OgreHardwareVertexBuffer.h" #include "OgrePatchSurface.h" #include "OgreHeaderPrefix.h" +#include "OgrePlane.h" namespace Ogre { diff --git a/OgreMain/include/OgrePlane.h b/OgreMain/include/OgrePlane.h index 50ea3617788..45dd02594f5 100644 --- a/OgreMain/include/OgrePlane.h +++ b/OgreMain/include/OgrePlane.h @@ -39,6 +39,7 @@ THE SOFTWARE. #include "OgrePrerequisites.h" #include "OgreVector3.h" +#include "OgreAxisAlignedBox.h" namespace Ogre { @@ -67,15 +68,23 @@ namespace Ogre { public: /** Default constructor - sets everything to 0. */ - Plane (); - Plane (const Plane& rhs); + Plane() : normal(Vector3::ZERO), d(0.0f) {} /** Construct a plane through a normal, and a distance to move the plane along the normal.*/ - Plane (const Vector3& rkNormal, Real fConstant); + Plane(const Vector3& rkNormal, Real fConstant) + { + normal = rkNormal; + d = -fConstant; + } /** Construct a plane using the 4 constants directly **/ - Plane (Real a, Real b, Real c, Real d); - Plane (const Vector3& rkNormal, const Vector3& rkPoint); - Plane (const Vector3& rkPoint0, const Vector3& rkPoint1, - const Vector3& rkPoint2); + Plane(Real a, Real b, Real c, Real _d) : normal(a, b, c), d(_d) {} + Plane(const Vector3& rkNormal, const Vector3& rkPoint) + { + redefine(rkNormal, rkPoint); + } + Plane(const Vector3& p0, const Vector3& p1, const Vector3& p2) + { + redefine(p0, p1, p2); + } /** The "positive side" of the plane is the half space to which the plane normal points. The "negative side" is the other half @@ -89,13 +98,32 @@ namespace Ogre { BOTH_SIDE }; - Side getSide (const Vector3& rkPoint) const; + Side getSide(const Vector3& rkPoint) const + { + Real fDistance = getDistance(rkPoint); + + if (fDistance < 0.0) + return Plane::NEGATIVE_SIDE; + + if (fDistance > 0.0) + return Plane::POSITIVE_SIDE; + + return Plane::NO_SIDE; + } /** Returns the side where the alignedBox is. The flag BOTH_SIDE indicates an intersecting box. One corner ON the plane is sufficient to consider the box and the plane intersecting. */ - Side getSide (const AxisAlignedBox& rkBox) const; + Side getSide(const AxisAlignedBox& box) const + { + if (box.isNull()) + return NO_SIDE; + if (box.isInfinite()) + return BOTH_SIDE; + + return getSide(box.getCenter(), box.getHalfSize()); + } /** Returns which side of the plane that the given box lies on. The box is defined as centre/half-size pairs for effectively. @@ -106,7 +134,23 @@ namespace Ogre { NEGATIVE_SIDE if the box complete lies on the "negative side" of the plane, and BOTH_SIDE if the box intersects the plane. */ - Side getSide (const Vector3& centre, const Vector3& halfSize) const; + Side getSide(const Vector3& centre, const Vector3& halfSize) const + { + // Calculate the distance between box centre and the plane + Real dist = getDistance(centre); + + // Calculate the maximise allows absolute distance for + // the distance between box centre and plane + Real maxAbsDist = normal.absDotProduct(halfSize); + + if (dist < -maxAbsDist) + return NEGATIVE_SIDE; + + if (dist > +maxAbsDist) + return POSITIVE_SIDE; + + return BOTH_SIDE; + } /** This is a pseudodistance. The sign of the return value is positive if the point is on the positive side of the plane, @@ -116,14 +160,24 @@ namespace Ogre { The absolute value of the return value is the true distance only when the plane normal is a unit length vector. */ - Real getDistance (const Vector3& rkPoint) const; + Real getDistance(const Vector3& rkPoint) const + { + return normal.dotProduct(rkPoint) + d; + } /** Redefine this plane based on 3 points. */ - void redefine(const Vector3& rkPoint0, const Vector3& rkPoint1, - const Vector3& rkPoint2); + void redefine(const Vector3& p0, const Vector3& p1, const Vector3& p2) + { + normal = Math::calculateBasicFaceNormal(p0, p1, p2); + d = -normal.dotProduct(p0); + } /** Redefine this plane based on a normal and a point. */ - void redefine(const Vector3& rkNormal, const Vector3& rkPoint); + void redefine(const Vector3& rkNormal, const Vector3& rkPoint) + { + normal = rkNormal; + d = -rkNormal.dotProduct(rkPoint); + } /** Project a vector onto the plane. @remarks This gives you the element of the input vector that is perpendicular @@ -132,7 +186,21 @@ namespace Ogre { from the original vector, since parallel + perpendicular = original. @param v The input vector */ - Vector3 projectVector(const Vector3& v) const; + Vector3 projectVector(const Vector3& v) const + { + // We know plane normal is unit length, so use simple method + Matrix3 xform; + xform[0][0] = 1.0f - normal.x * normal.x; + xform[0][1] = -normal.x * normal.y; + xform[0][2] = -normal.x * normal.z; + xform[1][0] = -normal.y * normal.x; + xform[1][1] = 1.0f - normal.y * normal.y; + xform[1][2] = -normal.y * normal.z; + xform[2][0] = -normal.z * normal.x; + xform[2][1] = -normal.z * normal.y; + xform[2][2] = 1.0f - normal.z * normal.z; + return xform * v; + } /** Normalises the plane. @remarks @@ -143,7 +211,22 @@ namespace Ogre { will be no changes made to their components. @return The previous length of the plane's normal. */ - Real normalise(void); + Real normalise(void) + { + Real fLength = normal.length(); + + // Will also work for zero-sized vectors, but will change nothing + // We're not using epsilons because we don't need to. + // Read http://www.ogre3d.org/forums/viewtopic.php?f=4&t=61259 + if (fLength > Real(0.0f)) + { + Real fInvLength = 1.0f / fLength; + normal *= fInvLength; + d *= fInvLength; + } + + return fLength; + } /// Get flipped plane, with same location but reverted orientation Plane operator - () const @@ -161,9 +244,28 @@ namespace Ogre { return (rhs.d != d || rhs.normal != normal); } - _OgreExport friend std::ostream& operator<< (std::ostream& o, const Plane& p); + _OgreExport friend std::ostream& operator<<(std::ostream& o, + const Plane& p) + { + o << "Plane(normal=" << p.normal << ", d=" << p.d << ")"; + return o; + } }; + inline Plane operator * (const Matrix4& mat, const Plane& p) + { + Plane ret; + Matrix4 invTrans = mat.inverse().transpose(); + Vector4 v4( p.normal.x, p.normal.y, p.normal.z, p.d ); + v4 = invTrans * v4; + ret.normal.x = v4.x; + ret.normal.y = v4.y; + ret.normal.z = v4.z; + ret.d = v4.w / ret.normal.normalise(); + + return ret; + } + typedef std::vector PlaneList; /** @} */ /** @} */ diff --git a/OgreMain/src/OgrePlane.cpp b/OgreMain/src/OgrePlane.cpp deleted file mode 100644 index d24167af307..00000000000 --- a/OgreMain/src/OgrePlane.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* ------------------------------------------------------------------------------ -This source file is part of OGRE -(Object-oriented Graphics Rendering Engine) -For the latest info, see http://www.ogre3d.org/ - -Copyright (c) 2000-2014 Torus Knot Software Ltd - -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. ------------------------------------------------------------------------------ -*/ -#include "OgreStableHeaders.h" - -namespace Ogre { - //----------------------------------------------------------------------- - Plane::Plane () - { - normal = Vector3::ZERO; - d = 0.0; - } - //----------------------------------------------------------------------- - Plane::Plane (const Plane& rhs) - { - normal = rhs.normal; - d = rhs.d; - } - //----------------------------------------------------------------------- - Plane::Plane (const Vector3& rkNormal, Real fConstant) - { - normal = rkNormal; - d = -fConstant; - } - //--------------------------------------------------------------------- - Plane::Plane (Real a, Real b, Real c, Real _d) - : normal(a, b, c), d(_d) - { - } - //----------------------------------------------------------------------- - Plane::Plane (const Vector3& rkNormal, const Vector3& rkPoint) - { - redefine(rkNormal, rkPoint); - } - //----------------------------------------------------------------------- - Plane::Plane (const Vector3& rkPoint0, const Vector3& rkPoint1, - const Vector3& rkPoint2) - { - redefine(rkPoint0, rkPoint1, rkPoint2); - } - //----------------------------------------------------------------------- - Real Plane::getDistance (const Vector3& rkPoint) const - { - return normal.dotProduct(rkPoint) + d; - } - //----------------------------------------------------------------------- - Plane::Side Plane::getSide (const Vector3& rkPoint) const - { - Real fDistance = getDistance(rkPoint); - - if ( fDistance < 0.0 ) - return Plane::NEGATIVE_SIDE; - - if ( fDistance > 0.0 ) - return Plane::POSITIVE_SIDE; - - return Plane::NO_SIDE; - } - - - //----------------------------------------------------------------------- - Plane::Side Plane::getSide (const AxisAlignedBox& box) const - { - if (box.isNull()) - return NO_SIDE; - if (box.isInfinite()) - return BOTH_SIDE; - - return getSide(box.getCenter(), box.getHalfSize()); - } - //----------------------------------------------------------------------- - Plane::Side Plane::getSide (const Vector3& centre, const Vector3& halfSize) const - { - // Calculate the distance between box centre and the plane - Real dist = getDistance(centre); - - // Calculate the maximise allows absolute distance for - // the distance between box centre and plane - Real maxAbsDist = normal.absDotProduct(halfSize); - - if (dist < -maxAbsDist) - return Plane::NEGATIVE_SIDE; - - if (dist > +maxAbsDist) - return Plane::POSITIVE_SIDE; - - return Plane::BOTH_SIDE; - } - //----------------------------------------------------------------------- - void Plane::redefine(const Vector3& rkPoint0, const Vector3& rkPoint1, - const Vector3& rkPoint2) - { - normal = Math::calculateBasicFaceNormal(rkPoint0, rkPoint1, rkPoint2); - d = -normal.dotProduct(rkPoint0); - } - //----------------------------------------------------------------------- - void Plane::redefine(const Vector3& rkNormal, const Vector3& rkPoint) - { - normal = rkNormal; - d = -rkNormal.dotProduct(rkPoint); - } - //----------------------------------------------------------------------- - Vector3 Plane::projectVector(const Vector3& p) const - { - // We know plane normal is unit length, so use simple method - Matrix3 xform; - xform[0][0] = 1.0f - normal.x * normal.x; - xform[0][1] = -normal.x * normal.y; - xform[0][2] = -normal.x * normal.z; - xform[1][0] = -normal.y * normal.x; - xform[1][1] = 1.0f - normal.y * normal.y; - xform[1][2] = -normal.y * normal.z; - xform[2][0] = -normal.z * normal.x; - xform[2][1] = -normal.z * normal.y; - xform[2][2] = 1.0f - normal.z * normal.z; - return xform * p; - - } - //----------------------------------------------------------------------- - Real Plane::normalise(void) - { - Real fLength = normal.length(); - - // Will also work for zero-sized vectors, but will change nothing - // We're not using epsilons because we don't need to. - // Read http://www.ogre3d.org/forums/viewtopic.php?f=4&t=61259 - if ( fLength > Real(0.0f) ) - { - Real fInvLength = 1.0f / fLength; - normal *= fInvLength; - d *= fInvLength; - } - - return fLength; - } - //----------------------------------------------------------------------- - std::ostream& operator<< (std::ostream& o, const Plane& p) - { - o << "Plane(normal=" << p.normal << ", d=" << p.d << ")"; - return o; - } -} // namespace Ogre