Skip to content

Commit

Permalink
Main: Plane - move all definitions to header to allow inlining
Browse files Browse the repository at this point in the history
  • Loading branch information
paroj committed Dec 9, 2018
1 parent 886e60c commit c98d77e
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 198 deletions.
16 changes: 1 addition & 15 deletions OgreMain/include/OgreMatrix4.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ THE SOFTWARE.

#include "OgreMatrix3.h"
#include "OgreVector4.h"
#include "OgrePlane.h"

namespace Ogre
{
/** \addtogroup Core
Expand Down Expand Up @@ -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;
}
/** @} */
/** @} */

Expand Down
1 change: 1 addition & 0 deletions OgreMain/include/OgreMeshManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ THE SOFTWARE.
#include "OgreHardwareVertexBuffer.h"
#include "OgrePatchSurface.h"
#include "OgreHeaderPrefix.h"
#include "OgrePlane.h"

namespace Ogre {

Expand Down
136 changes: 119 additions & 17 deletions OgreMain/include/OgrePlane.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ THE SOFTWARE.
#include "OgrePrerequisites.h"

#include "OgreVector3.h"
#include "OgreAxisAlignedBox.h"

namespace Ogre {

Expand Down Expand Up @@ -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
Expand All @@ -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.
Expand All @@ -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,
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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<Plane> PlaneList;
/** @} */
/** @} */
Expand Down
Loading

0 comments on commit c98d77e

Please # to comment.