mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-20 12:44:46 +00:00
SPECIAL NOTE: highly suggest https://github.com/GarageGames/Torque3D/pull/1441 or a variation thereof to prevent debug spew and false-postives for occlusion results. With significant research, development and prototyping assistance from both @andr3wmac (shaders and partial hook work), and @LuisAntonRebollo (additional culling) System operates as follows: 1) materials are given an additional castDynamicShadows boolean entry. (Default at time of writing is true by request. Personal usage at time of writing defaults to false. value is default-initialized in materialDefinition.cpp. script/gui exposed) 2) lights are given a staticRefreshFreq and dynamicRefreshFreq (in milliseconds). script/gui exposed 3) materials are (effectively) sorted into dynamic and static shadowmap render lists based on flag. (see shadowMapPass.cpp) 4) initial shadowmaps are generated for each light and 'list'. 5) as each refreshFreq times out, the relevant shadowmap for a given light is refreshed. Special notes: dynamicRefreshFreq for all lights is set to a (script exposed) 8MS refresh timer. StaticRefreshFreq for the lions share of lights defaults to 250 MS (1/4 of a second) scattersky's embedded light, which is intended to operate in a mobile manner, defaults to 8 to reiterate, these are all customizable per-light via script/inspector gui in the case of alternate project needs.
426 lines
18 KiB
C++
426 lines
18 KiB
C++
//-----------------------------------------------------------------------------
|
|
// 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 _MATHUTILS_H_
|
|
#define _MATHUTILS_H_
|
|
|
|
#ifndef _MPOINT3_H_
|
|
#include "math/mPoint3.h"
|
|
#endif
|
|
|
|
#ifndef _MMATRIX_H_
|
|
#include "math/mMatrix.h"
|
|
#endif
|
|
|
|
#ifndef _MRECT_H_
|
|
#include "math/mRect.h"
|
|
#endif
|
|
|
|
#ifndef _TVECTOR_H_
|
|
#include "core/util/tVector.h"
|
|
#endif
|
|
|
|
#ifndef _MATHUTIL_FRUSTUM_H_
|
|
#include "math/util/frustum.h"
|
|
#endif
|
|
|
|
|
|
class Box3F;
|
|
class RectI;
|
|
class Frustum;
|
|
|
|
|
|
/// Miscellaneous math utility functions.
|
|
namespace MathUtils
|
|
{
|
|
/// A simple helper struct to define a line.
|
|
struct Line
|
|
{
|
|
Point3F origin;
|
|
VectorF direction;
|
|
};
|
|
|
|
/// A ray is also a line.
|
|
typedef Line Ray;
|
|
|
|
/// A simple helper struct to define a line segment.
|
|
struct LineSegment
|
|
{
|
|
Point3F p0;
|
|
Point3F p1;
|
|
};
|
|
|
|
/// A simple helper struct to define a clockwise
|
|
/// winding quad.
|
|
struct Quad
|
|
{
|
|
Point3F p00;
|
|
Point3F p01;
|
|
Point3F p10;
|
|
Point3F p11;
|
|
};
|
|
|
|
/// Used by mTriangleDistance() to pass along collision info
|
|
struct IntersectInfo
|
|
{
|
|
LineSegment segment; // Starts at given point, ends at collision
|
|
Point3F bary; // Barycentric coords for collision
|
|
};
|
|
|
|
/// Rotate the passed vector around the world-z axis by the passed radians.
|
|
void vectorRotateZAxis( Point3F &vector, F32 radians );
|
|
void vectorRotateZAxis( F32 radians, Point3F *vectors, U32 count );
|
|
|
|
/// Generates a projection matrix with the near plane
|
|
/// moved forward by the bias amount. This function is a helper primarily
|
|
/// for working around z-fighting issues.
|
|
///
|
|
/// @param bias The amount to move the near plane forward.
|
|
/// @param frustum The frustum to generate the new projection matrix from.
|
|
/// @param outMat The resulting z-biased projection matrix. Note: It must be initialized before the call.
|
|
/// @param rotate Optional parameter specifying whether to rotate the projection matrix similarly to GFXDevice.
|
|
///
|
|
void getZBiasProjectionMatrix( F32 bias, const Frustum &frustum, MatrixF *outMat, bool rotate = true );
|
|
|
|
/// Creates orientation matrix from a direction vector. Assumes ( 0 0 1 ) is up.
|
|
MatrixF createOrientFromDir( const Point3F &direction );
|
|
|
|
/// Creates an orthonormal basis matrix with the unit length
|
|
/// input vector in column 2 (up vector).
|
|
///
|
|
/// @param up The non-zero unit length up vector.
|
|
/// @param outMat The output matrix which must be initialized prior to the call.
|
|
///
|
|
void getMatrixFromUpVector( const VectorF &up, MatrixF *outMat );
|
|
|
|
/// Creates an orthonormal basis matrix with the unit length
|
|
/// input vector in column 1 (forward vector).
|
|
///
|
|
/// @param forward The non-zero unit length forward vector.
|
|
/// @param outMat The output matrix which must be initialized prior to the call.
|
|
///
|
|
void getMatrixFromForwardVector( const VectorF &forward, MatrixF *outMat );
|
|
|
|
/// Creates random direction given angle parameters similar to the particle system.
|
|
///
|
|
/// The angles are relative to the specified axis. Both phi and theta are in degrees.
|
|
Point3F randomDir( const Point3F &axis, F32 thetaAngleMin, F32 thetaAngleMax, F32 phiAngleMin = 0.0, F32 phiAngleMax = 360.0 );
|
|
|
|
/// Returns a random 3D point within a sphere of the specified radius
|
|
/// centered at the origin.
|
|
Point3F randomPointInSphere( F32 radius );
|
|
|
|
/// Returns a random 2D point within a circle of the specified radius
|
|
/// centered at the origin.
|
|
Point2F randomPointInCircle( F32 radius );
|
|
|
|
/// Returns yaw and pitch angles from a given vector.
|
|
///
|
|
/// Angles are in RADIANS.
|
|
///
|
|
/// Assumes north is (0.0, 1.0, 0.0), the degrees move upwards clockwise.
|
|
///
|
|
/// The range of yaw is 0 - 2PI. The range of pitch is -PI/2 - PI/2.
|
|
///
|
|
/// <b>ASSUMES Z AXIS IS UP</b>
|
|
void getAnglesFromVector( const VectorF &vec, F32 &yawAng, F32 &pitchAng );
|
|
|
|
/// Returns vector from given yaw and pitch angles.
|
|
///
|
|
/// Angles are in RADIANS.
|
|
///
|
|
/// Assumes north is (0.0, 1.0, 0.0), the degrees move upwards clockwise.
|
|
///
|
|
/// The range of yaw is 0 - 2PI. The range of pitch is -PI/2 - PI/2.
|
|
///
|
|
/// <b>ASSUMES Z AXIS IS UP</b>
|
|
void getVectorFromAngles( VectorF &vec, F32 yawAng, F32 pitchAng );
|
|
|
|
/// Simple reflection equation - pass in a vector and a normal to reflect off of
|
|
inline Point3F reflect( Point3F &inVec, Point3F &norm )
|
|
{
|
|
return inVec - norm * ( mDot( inVec, norm ) * 2.0f );
|
|
}
|
|
|
|
/// Collide two capsules (sphere swept lines) against each other, reporting only if they intersect or not.
|
|
/// Based on routine from "Real Time Collision Detection" by Christer Ericson pp 114.
|
|
bool capsuleCapsuleOverlap(const Point3F & a1, const Point3F & b1, F32 radius1, const Point3F & a2, const Point3F & b2, F32 radius2);
|
|
|
|
/// Return capsule-sphere overlap. Returns time of first overlap, where time
|
|
/// is viewed as a sphere of radius radA moving from point A0 to A1.
|
|
bool capsuleSphereNearestOverlap(const Point3F & A0, const Point3F A1, F32 radA, const Point3F & B, F32 radB, F32 & t);
|
|
|
|
/// Intersect two line segments (p1,q1) and (p2,q2), returning points on lines (c1 & c2) and line parameters (s,t).
|
|
/// Based on routine from "Real Time Collision Detection" by Christer Ericson pp 149.
|
|
F32 segmentSegmentNearest(const Point3F & p1, const Point3F & q1, const Point3F & p2, const Point3F & q2, F32 & s, F32 & t, Point3F & c1, Point3F & c2);
|
|
|
|
/// Transform bounding box making sure to keep original box entirely contained.
|
|
void transformBoundingBox(const Box3F &sbox, const MatrixF &mat, const Point3F scale, Box3F &dbox);
|
|
|
|
bool mProjectWorldToScreen( const Point3F &in,
|
|
Point3F *out,
|
|
const RectI &view,
|
|
const MatrixF &world,
|
|
const MatrixF &projection );
|
|
bool mProjectWorldToScreen( const Point3F &in,
|
|
Point3F *out,
|
|
const RectI &view,
|
|
const MatrixF &worldProjection );
|
|
|
|
void mProjectScreenToWorld( const Point3F &in,
|
|
Point3F *out,
|
|
const RectI &view,
|
|
const MatrixF &world,
|
|
const MatrixF &projection,
|
|
F32 far,
|
|
F32 near);
|
|
|
|
/// Clip @a inFrustum by the given polygon.
|
|
///
|
|
/// @note The input polygon is limited to 58 vertices.
|
|
///
|
|
/// @param points Polygon vertices.
|
|
/// @param numPoints Number of vertices in @a points.
|
|
/// @param viewport Screen viewport. Note that this corresponds to the root frustum and not necessarily to @a inFrustum.
|
|
/// @param world World->view transform.
|
|
/// @param projection Projection matrix.
|
|
/// @param inFrustum Frustum to clip.
|
|
/// @param rootFrustum Frustum corresponding to @a viewport.
|
|
/// @param outFrustum Resulting clipped frustum.
|
|
///
|
|
/// @return True if the frustum was successfully clipped and @a outFrustum is valid, false otherwise
|
|
/// (if, for example, the input polygon is completely outside @a inFrustum).
|
|
bool clipFrustumByPolygon( const Point3F* points,
|
|
U32 numPoints,
|
|
const RectI& viewport,
|
|
const MatrixF& world,
|
|
const MatrixF& projection,
|
|
const Frustum& inFrustum,
|
|
const Frustum& rootFrustum,
|
|
Frustum& outFrustum );
|
|
|
|
/// Returns true if the test point is within the polygon.
|
|
/// @param verts The array of points which forms the polygon.
|
|
/// @param vertCount The number of points in the polygon.
|
|
/// @param testPt The point to test.
|
|
bool pointInPolygon( const Point2F *verts, U32 vertCount, const Point2F &testPt );
|
|
|
|
/// Remove all edges from the given polygon that have a total length shorter
|
|
/// than @a epsilon.
|
|
///
|
|
U32 removeShortPolygonEdges( const Point3F* verts, U32 vertCount, F32 epsilon );
|
|
|
|
/// Calculates the shortest line segment between two lines.
|
|
///
|
|
/// @param outSegment The result where .p0 is the point on line0 and .p1 is the point on line1.
|
|
///
|
|
void mShortestSegmentBetweenLines( const Line &line0, const Line &line1, LineSegment *outSegment );
|
|
|
|
/// Returns the greatest common divisor of two positive integers.
|
|
U32 greatestCommonDivisor( U32 u, U32 v );
|
|
|
|
/// Returns the barycentric coordinates and time of intersection between
|
|
/// a line segment and a triangle.
|
|
///
|
|
/// @param p1 The first point of the line segment.
|
|
/// @param p2 The second point of the line segment.
|
|
/// @param t1 The first point of the triangle.
|
|
/// @param t2 The second point of the triangle.
|
|
/// @param t2 The third point of the triangle.
|
|
/// @param outUVW The optional output barycentric coords.
|
|
/// @param outT The optional output time of intersection.
|
|
///
|
|
/// @return Returns true if a collision occurs.
|
|
///
|
|
bool mLineTriangleCollide( const Point3F &p1, const Point3F &p2,
|
|
const Point3F &t1, const Point3F &t2, const Point3F &t3,
|
|
Point3F *outUVW = NULL,
|
|
F32 *outT = NULL );
|
|
|
|
/// Returns the uv coords and time of intersection between
|
|
/// a ray and a quad.
|
|
///
|
|
/// @param quad The quad.
|
|
/// @param ray The ray.
|
|
/// @param outUV The optional output UV coords of the intersection.
|
|
/// @param outT The optional output time of intersection.
|
|
///
|
|
/// @return Returns true if a collision occurs.
|
|
///
|
|
bool mRayQuadCollide( const Quad &quad,
|
|
const Ray &ray,
|
|
Point2F *outUV = NULL,
|
|
F32 *outT = NULL );
|
|
|
|
/// Returns the distance between a point and triangle 'abc'.
|
|
F32 mTriangleDistance( const Point3F &a, const Point3F &b, const Point3F &c, const Point3F &p, IntersectInfo* info=NULL );
|
|
|
|
/// Returns the normal of the passed triangle 'abc'.
|
|
///
|
|
/// If we assume counter-clockwise triangle culling, normal will point
|
|
/// out from the 'solid' side of the triangle.
|
|
///
|
|
Point3F mTriangleNormal( const Point3F &a, const Point3F &b, const Point3F &c );
|
|
|
|
/// Returns the closest point on the segment defined by
|
|
/// points a, b to the point p.
|
|
Point3F mClosestPointOnSegment( const Point3F &a,
|
|
const Point3F &b,
|
|
const Point3F &p );
|
|
|
|
/// Sort the passed verts ( Point3F ) in a clockwise or counter-clockwise winding order.
|
|
/// Verts must be co-planar and non-collinear.
|
|
///
|
|
/// @param quadMat Transform matrix from vert space to quad space.
|
|
/// @param clockwise Sort clockwise or counter-clockwise
|
|
/// @param verts Array of Point3F verts.
|
|
/// @param vertMap Output - Array of vert element ids sorted by winding order.
|
|
/// @param count Element count of the verts and vertMap arrays which must be allocated prior to this call.
|
|
///
|
|
void sortQuadWindingOrder( const MatrixF &quadMat, bool clockwise, const Point3F *verts, U32 *vertMap, U32 count );
|
|
|
|
/// Same as above except we assume that the passed verts ( Point3F ) are already
|
|
/// transformed into 'quad space'. If this was done correctly and the points
|
|
/// are coplanar this means their z components will all be zero.
|
|
void sortQuadWindingOrder( bool clockwise, const Point3F *verts, U32 *vertMap, U32 count );
|
|
|
|
///
|
|
/// WORK IN PROGRESS
|
|
///
|
|
/// Creates an orthonormal basis matrix from one, two, or three unit length
|
|
/// input vectors. If more than one input vector is provided they must be
|
|
/// mutually perpendicular.
|
|
///
|
|
/// @param rvec Optional unit length right vector.
|
|
/// @param fvec Optional unit length forward vector.
|
|
/// @param uvec Optional unit length up vector.
|
|
/// @param pos Optional position to initialize the matrix.
|
|
/// @param outMat The output matrix which must be initialized prior to the call.
|
|
///
|
|
void buildMatrix( const VectorF *rvec, const VectorF *fvec, const VectorF *uvec, const VectorF *pos, MatrixF *outMat );
|
|
|
|
///
|
|
bool reduceFrustum( const Frustum& frustum, const RectI& viewport, const RectF& area, Frustum& outFrustum );
|
|
|
|
/// Build the frustum near plane dimensions from the parameters.
|
|
void makeFrustum( F32 *outLeft,
|
|
F32 *outRight,
|
|
F32 *outTop,
|
|
F32 *outBottom,
|
|
F32 fovYInRadians,
|
|
F32 aspectRatio,
|
|
F32 nearPlane );
|
|
|
|
void makeFovPortFrustum( Frustum *outFrustum,
|
|
bool isOrtho,
|
|
F32 nearDist,
|
|
F32 farDist,
|
|
const FovPort &inPort,
|
|
const MatrixF &transform = MatrixF(1) );
|
|
|
|
/// Build a GFX projection matrix from the frustum parameters
|
|
/// including the optional rotation required by GFX.
|
|
void makeProjection( MatrixF *outMatrix,
|
|
F32 fovYInRadians,
|
|
F32 aspectRatio,
|
|
F32 nearPlane,
|
|
F32 farPlane,
|
|
bool gfxRotate );
|
|
|
|
/// Build a projection matrix from the frustum near plane dimensions
|
|
/// including the optional rotation required by GFX.
|
|
void makeProjection( MatrixF *outMatrix,
|
|
F32 left,
|
|
F32 right,
|
|
F32 top,
|
|
F32 bottom,
|
|
F32 nearPlane,
|
|
F32 farPlane,
|
|
bool gfxRotate );
|
|
|
|
/// Build an orthographic projection matrix from the frustum near
|
|
/// plane dimensions including the optional rotation required by GFX.
|
|
void makeOrthoProjection( MatrixF *outMatrix,
|
|
F32 left,
|
|
F32 right,
|
|
F32 top,
|
|
F32 bottom,
|
|
F32 nearPlane,
|
|
F32 farPlane,
|
|
bool gfxRotate );
|
|
|
|
/// Find the intersection of the line going from @a edgeA to @a edgeB with the triangle
|
|
/// given by @a faceA, @a faceB, and @a faceC.
|
|
/// @param edgeA Starting point of edge.
|
|
/// @param edgeB End point of edge.
|
|
/// @param faceA First vertex of triangle.
|
|
/// @param faceB Second vertex of triangle.
|
|
/// @param faceC Third vertex of triangle.
|
|
/// @param intersection If there is an intersection, the point of intersection on the triangle's
|
|
/// face is stored here.
|
|
/// @param True if there is an intersection, false otherwise.
|
|
bool edgeFaceIntersect( const Point3F &edgeA, const Point3F &edgeB,
|
|
const Point3F &faceA, const Point3F &faceB, const Point3F &faceC, const Point3F &faceD, Point3F *intersection );
|
|
|
|
/// Find out whether the given polygon is planar.
|
|
/// @param vertices Array of vertices of the polygon.
|
|
/// @param numVertices Number of vertices in @a vertices.
|
|
/// @return True if the polygon is planar, false otherwise.
|
|
bool isPlanarPolygon( const Point3F* vertices, U32 numVertices );
|
|
|
|
/// Find out whether the given polygon is convex.
|
|
/// @param vertices Array of vertices of the polygon.
|
|
/// @param numVertices Number of vertices in @a vertices.
|
|
/// @return True if the polygon is convex, false otherwise.
|
|
bool isConvexPolygon( const Point3F* vertices, U32 numVertices );
|
|
|
|
/// Extrude the given polygon along the given direction.
|
|
U32 extrudePolygonEdges( const Point3F* vertices, U32 numVertices, const Point3F& direction, PlaneF* outPlanes );
|
|
|
|
/// Extrude the edges of the given polygon away from @a fromPoint by constructing a set of planes
|
|
/// that each go through @a fromPoint and a pair of vertices.
|
|
///
|
|
/// The resulting planes are in the same order as the vertices and have their normals facing *inwards*,
|
|
/// i.e. the resulting volume will enclose the polygon's interior space.
|
|
///
|
|
/// @param vertices Vertices of the polygon in CCW or CW order (both are acceptable).
|
|
/// @param numVertices Number of vertices in @a vertices.
|
|
/// @param fromPoint
|
|
/// @param outPlanes Array in which the resulting planes are stored. Must have room for at least as many
|
|
/// planes are there are edges in the polygon.
|
|
///
|
|
/// @return
|
|
///
|
|
/// @note The input polygon does not necessarily need to be planar but it must be convex.
|
|
U32 extrudePolygonEdgesFromPoint( const Point3F* vertices, U32 numVertices,
|
|
const Point3F& fromPoint,
|
|
PlaneF* outPlanes );
|
|
|
|
//void findFarthestPoint( const Point3F* points, U32 numPoints, const Point3F& fromPoint, )
|
|
|
|
/// Build a convex hull from a cloud of 2D points, first and last hull point are the same.
|
|
void mBuildHull2D(const Vector<Point2F> inPoints, Vector<Point2F> &hullPoints);
|
|
|
|
} // namespace MathUtils
|
|
|
|
#endif // _MATHUTILS_H_
|