Initial commit
This commit is contained in:
501
engines/hpl1/engine/math/Math.h
Normal file
501
engines/hpl1/engine/math/Math.h
Normal file
@@ -0,0 +1,501 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2010 - Frictional Games
|
||||
*
|
||||
* This file is part of HPL1 Engine.
|
||||
*/
|
||||
|
||||
#ifndef HPL_MATH_H
|
||||
#define HPL_MATH_H
|
||||
|
||||
#include "hpl1/engine/math/BoundingVolume.h"
|
||||
#include "hpl1/engine/math/MathTypes.h"
|
||||
#include "hpl1/engine/math/MeshTypes.h"
|
||||
|
||||
#include "hpl1/engine/graphics/Color.h"
|
||||
|
||||
namespace hpl {
|
||||
|
||||
class cMath {
|
||||
public:
|
||||
//////////////////////////////////////////////////////
|
||||
////////// RANDOM GENERATION ////////////////////////
|
||||
//////////////////////////////////////////////////////
|
||||
/**
|
||||
* Generates a random integer from min to max
|
||||
* \param alMin
|
||||
* \param alMax
|
||||
* \return
|
||||
*/
|
||||
static int RandRectl(int alMin, int alMax);
|
||||
|
||||
/**
|
||||
* Generates a random float from min to max
|
||||
* \param alMin
|
||||
* \param alMax
|
||||
* \return
|
||||
*/
|
||||
static float RandRectf(float alMin, float alMax);
|
||||
|
||||
/**
|
||||
* Generates a random float from min to max
|
||||
*/
|
||||
static cVector2f RandRectVector2f(const cVector3f &avMin, const cVector3f &avMax);
|
||||
|
||||
/**
|
||||
* Generates a random float from min to max
|
||||
*/
|
||||
static cVector3f RandRectVector3f(const cVector3f &avMin, const cVector3f &avMax);
|
||||
|
||||
/**
|
||||
* Generates a random float from min to max
|
||||
*/
|
||||
static cColor RandRectColor(const cColor &aMin, const cColor &aMax);
|
||||
|
||||
/**
|
||||
* Randomize the rand funcs.
|
||||
* \param alSeed the seed, -1 = random seed.
|
||||
*/
|
||||
static void Randomize(int alSeed = -1);
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
////////// COLLSION //////////////////////////////////
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
static bool BoxCollision(cRect2l aRect1, cRect2l aRect2);
|
||||
static bool BoxCollision(cRect2f aRect1, cRect2f aRect2);
|
||||
|
||||
static bool PointBoxCollision(cVector2f avPoint, cRect2f aRect);
|
||||
|
||||
static bool BoxFit(cRect2l aRectSrc, cRect2l aRectDest);
|
||||
static bool BoxFit(cRect2f aRectSrc, cRect2f aRectDest);
|
||||
|
||||
static float Dist2D(const cVector2f &avPosA, const cVector2f &avPosB);
|
||||
static float Dist2D(const cVector3f &avPosA, const cVector3f &avPosB);
|
||||
|
||||
static float SqrDist2D(const cVector2f &avPosA, const cVector2f &avPosB);
|
||||
static float SqrDist2D(const cVector3f &avPosA, const cVector3f &avPosB);
|
||||
|
||||
static cRect2f &ClipRect(cRect2f &aRectSrc, const cRect2f &aRectDest);
|
||||
|
||||
/**
|
||||
* Checks collison between two bounding volumes.
|
||||
* \return true if collision, else false.
|
||||
*/
|
||||
static bool CheckCollisionBV(cBoundingVolume &aBV1, cBoundingVolume &aBV2);
|
||||
|
||||
static bool PointBVCollision(const cVector3f &avPoint, cBoundingVolume &aBV2);
|
||||
|
||||
/**
|
||||
* Creates a clip rect for a bounding volume in screen space.
|
||||
* \return false if behind near clip.
|
||||
*/
|
||||
static bool GetClipRectFromBV(cRect2l &aDestRect, cBoundingVolume &aBV,
|
||||
const cMatrixf &a_mtxView, const cMatrixf &a_mtxProj,
|
||||
float afNearClipPlane, const cVector2l &avScreenSize);
|
||||
|
||||
static bool CheckSphereInPlanes(const cVector3f &avCenter, float afRadius,
|
||||
const cPlanef *apPlanes, int alPlaneCount);
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
////////// FLOAT OPERATIONS ////////////////////////
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Get fraction part of a float
|
||||
* \param afVal
|
||||
* \return
|
||||
*/
|
||||
static float GetFraction(float afVal);
|
||||
/**
|
||||
* Moldus (%) of a float
|
||||
* \param afDividend
|
||||
* \param afDivisor
|
||||
* \return
|
||||
*/
|
||||
static float Modulus(float afDividend, float afDivisor);
|
||||
|
||||
static float ToRad(float afAngle);
|
||||
static float ToDeg(float afAngle);
|
||||
|
||||
/**
|
||||
* Get the Log 2 of an int.
|
||||
*/
|
||||
static int Log2ToInt(int alX);
|
||||
|
||||
/**
|
||||
* Checks if the number is a power of two.
|
||||
*/
|
||||
static bool IsPow2(int alX);
|
||||
|
||||
/**
|
||||
* Wraps a value (afX) between min and max. Example: Wrap(-1, 0,10) returns 9.
|
||||
* \param afMin The minimum value. Must be lower than max.
|
||||
* \param afMax The maximum value. Must be higher than min and NOT 0.
|
||||
*/
|
||||
static float Wrap(float afX, float afMin, float afMax);
|
||||
|
||||
/**
|
||||
* Clamps a value between min and max. Example Clamp(-1, 0,1) return 0.
|
||||
*/
|
||||
static float Clamp(float afX, float afMin, float afMax);
|
||||
|
||||
inline static float Max(float afX, float afY) {
|
||||
if (afX > afY)
|
||||
return afX;
|
||||
return afY;
|
||||
}
|
||||
inline static float Min(float afX, float afY) {
|
||||
if (afX < afY)
|
||||
return afX;
|
||||
return afY;
|
||||
}
|
||||
|
||||
inline static int Max(int alX, int alY) {
|
||||
if (alX > alY)
|
||||
return alX;
|
||||
return alY;
|
||||
}
|
||||
inline static int Min(int alX, int alY) {
|
||||
if (alX < alY)
|
||||
return alX;
|
||||
return alY;
|
||||
}
|
||||
|
||||
inline static float Abs(float afX) { return afX < 0 ? -afX : afX; }
|
||||
inline static int Abs(int alX) { return alX < 0 ? -alX : alX; }
|
||||
|
||||
static float GetAngleDistance(float afAngle1, float afAngle2, float afMaxAngle);
|
||||
static float GetAngleDistanceRad(float afAngle1, float afAngle2);
|
||||
static float GetAngleDistanceDeg(float afAngle1, float afAngle2);
|
||||
|
||||
static float TurnAngle(float afAngle, float afFinalAngle, float afSpeed, float afMaxAngle);
|
||||
static float TurnAngleRad(float afAngle, float afFinalAngle, float afSpeed);
|
||||
static float TurnAngleDeg(float afAngle, float afFinalAngle, float afSpeed);
|
||||
|
||||
static float InterpolateFloat(float afA, float afB, float afT);
|
||||
|
||||
template<typename Vector>
|
||||
static decltype(Vector::x) & GetVectorX(Vector &v) {
|
||||
return v.x;
|
||||
}
|
||||
|
||||
template<typename Vector>
|
||||
static decltype(Vector::y) & GetVectorY(Vector &v) {
|
||||
return v.y;
|
||||
}
|
||||
template<typename Vector>
|
||||
static decltype(Vector::z) & GetVectorZ(Vector &v) {
|
||||
return v.z;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
////////// VECTOR 2D ///////////////////////////////
|
||||
//////////////////////////////////////////////////////
|
||||
/**
|
||||
* Get the angle a vector at aStartPos has to have to look at aGoalPos
|
||||
* \param &aStartPos
|
||||
* \param &avGoalPos
|
||||
* \return
|
||||
*/
|
||||
static float GetAngleFromPoints2D(const cVector2f &aStartPos, const cVector2f &avGoalPos);
|
||||
/**
|
||||
* Get a vector from an angle and a length
|
||||
* \param afAngle
|
||||
* \param afLength
|
||||
* \return
|
||||
*/
|
||||
static cVector2f GetVectorFromAngle2D(float afAngle, float afLength);
|
||||
/**
|
||||
* Get angle and length of a vector
|
||||
* \param &avVec
|
||||
* \param *apAngle
|
||||
* \param *apLength
|
||||
*/
|
||||
static void GetAngleFromVector(const cVector2f &avVec, float *apAngle, float *apLength);
|
||||
|
||||
/**
|
||||
* Project Src on Dest
|
||||
* \param &avSrcVec
|
||||
* \param &avDestVec
|
||||
* \return
|
||||
*/
|
||||
static cVector2f ProjectVector2D(const cVector2f &avSrcVec, const cVector2f &avDestVec);
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
////////// VECTOR 3D ///////////////////////////////
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
static inline cVector3f Vector3ToRad(const cVector3f &avVec) {
|
||||
return cVector3f(ToRad(avVec.x), ToRad(avVec.y), ToRad(avVec.z));
|
||||
}
|
||||
|
||||
static inline cVector3f Vector3ToDeg(const cVector3f &avVec) {
|
||||
return cVector3f(ToDeg(avVec.x), ToDeg(avVec.y), ToDeg(avVec.z));
|
||||
}
|
||||
|
||||
static inline cVector3f Vector3Normalize(const cVector3f &avVec) {
|
||||
cVector3f vNorm = avVec;
|
||||
vNorm.Normalise();
|
||||
return vNorm;
|
||||
}
|
||||
|
||||
static inline float Vector3DistSqr(const cVector3f &avStartPos, const cVector3f &avEndPos) {
|
||||
float fDX = avEndPos.x - avStartPos.x;
|
||||
float fDY = avEndPos.y - avStartPos.y;
|
||||
float fDZ = avEndPos.z - avStartPos.z;
|
||||
|
||||
return fDX * fDX + fDY * fDY + fDZ * fDZ;
|
||||
}
|
||||
|
||||
static inline float Vector3Dist(const cVector3f &avStartPos, const cVector3f &avEndPos) {
|
||||
return sqrt(Vector3DistSqr(avStartPos, avEndPos));
|
||||
}
|
||||
|
||||
static cVector3f GetAngleFromPoints3D(const cVector3f &avStartPos, const cVector3f &avGoalPos);
|
||||
|
||||
/**
|
||||
* Vector cross product, A x B = R
|
||||
* \param avVecA
|
||||
* \param avVecB
|
||||
* \return
|
||||
*/
|
||||
static cVector3f Vector3Cross(const cVector3f &avVecA, const cVector3f &avVecB);
|
||||
|
||||
/**
|
||||
* Vector dot product, A * B = R
|
||||
* \param avVecA
|
||||
* \param avVecB
|
||||
* \return
|
||||
*/
|
||||
static float Vector3Dot(const cVector3f &avVecA, const cVector3f &avVecB);
|
||||
|
||||
/**
|
||||
* Project Src on Dest
|
||||
* \param &avSrcVec, must be normalized
|
||||
* \param &avDestVec, must be normalized
|
||||
* \return
|
||||
*/
|
||||
static cVector3f ProjectVector3D(const cVector3f &avSrcVec, const cVector3f &avDestVec);
|
||||
|
||||
/**
|
||||
* Calculates the angle between two vectors.
|
||||
* \param avVecA
|
||||
* \param avVecB
|
||||
* \return
|
||||
*/
|
||||
static float Vector3Angle(const cVector3f &avVecA, const cVector3f &avVecB);
|
||||
|
||||
/**
|
||||
* Unprojects a vector from screen size and coords.
|
||||
*/
|
||||
static cVector3f Vector3UnProject(const cVector3f &avVec, const cRect2f &aScreenRect,
|
||||
cMatrixf a_mtxViewProj);
|
||||
|
||||
/**
|
||||
* Calculates distance from a point to a plane
|
||||
* \param aPlane The plane must be normalised!
|
||||
* \param avVec
|
||||
* \return >0 if in front of plane, 0 if on plane and <0 if behind plane
|
||||
*/
|
||||
static float PlaneToPointDist(const cPlanef &aPlane, const cVector3f &avVec);
|
||||
|
||||
/**
|
||||
* Get the line defining the intersection of 2 planes.
|
||||
* \param aPA
|
||||
* \param aPB
|
||||
* \param avDir The direction of the line will be placed here
|
||||
* \param avPoint A point on the line will be placed here.
|
||||
*/
|
||||
static void PlaneIntersectionLine(const cPlanef &aPA, const cPlanef &aPB,
|
||||
cVector3f &avDir, cVector3f &avPoint);
|
||||
|
||||
/**
|
||||
* Checks intersection with a frustum, an array of alPairNum plane pairs(alPairNum*2 planes), and a line,
|
||||
*/
|
||||
static bool CheckFrustumLineIntersection(const cPlanef *apPlanePairs, const cVector3f &avPoint1,
|
||||
const cVector3f &avPoint2, int alPairNum);
|
||||
|
||||
/**
|
||||
* Checks intersection with a a frustum, an array of alPairNum plane pairs(alPairNum * 2 planes), and a quad mesh.
|
||||
* \param apPoints the points of the quad mesh, every 4 points is a face.
|
||||
*/
|
||||
static bool CheckFrustumQuadMeshIntersection(const cPlanef *apPlanePairs, tVector3fVec *apPoints,
|
||||
int alPairNum);
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
////////// QUATERNIONS ///////////////////////////////
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Spherical Linear Interpolation between quaternions A and B
|
||||
* \param afT The amount in-between the quaternions. 0.0 is A and 1 is B.
|
||||
* \param abShortestPath Move the the shortest path.
|
||||
* \return
|
||||
*/
|
||||
static cQuaternion QuaternionSlerp(float afT, const cQuaternion &aqA, const cQuaternion &aqB,
|
||||
bool abShortestPath);
|
||||
|
||||
static float QuaternionDot(const cQuaternion &aqA, const cQuaternion &aqB);
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
////////// MATRIX ////////////////////////////////////
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Spherical Linear Interpolation between matrix A and B
|
||||
* \param afT The amount in-between the quaternions. 0.0 is A and 1 is B.
|
||||
* \param abShortestPath Move the the shortest path.
|
||||
* \return
|
||||
*/
|
||||
static cMatrixf MatrixSlerp(float afT, const cMatrixf &a_mtxA, const cMatrixf &a_mtxB,
|
||||
bool abShortestPath);
|
||||
|
||||
/**
|
||||
* Matrix mulitplication, A * B = R. This means that B is applied BEFORE A.
|
||||
*/
|
||||
static cMatrixf MatrixMul(const cMatrixf &a_mtxA, const cMatrixf &a_mtxB);
|
||||
/**
|
||||
* Multiply and matrix and a 3d vector
|
||||
*/
|
||||
static cVector3f MatrixMul(const cMatrixf &a_mtxA, const cVector3f &avB);
|
||||
/**
|
||||
* Multiply and matrix and a 3d vector and divide the result with W.
|
||||
*/
|
||||
static cVector3f MatrixMulDivideW(const cMatrixf &a_mtxA, const cVector3f &avB);
|
||||
|
||||
/**
|
||||
* Multiply matrix and a float.
|
||||
*/
|
||||
static cMatrixf MatrixMulScalar(const cMatrixf &a_mtxA, float afB);
|
||||
|
||||
/**
|
||||
* Creates a rotation matrix along all axes according to order.
|
||||
*/
|
||||
static cMatrixf MatrixRotate(cVector3f avRot, eEulerRotationOrder aOrder);
|
||||
/**
|
||||
* Create a rotation matrix around the X-axis according to the right hand rule
|
||||
*/
|
||||
static cMatrixf MatrixRotateX(float afAngle);
|
||||
/**
|
||||
* Create a rotation matrix around the Y-axis according to the right hand rule
|
||||
*/
|
||||
static cMatrixf MatrixRotateY(float afAngle);
|
||||
/**
|
||||
* Create a rotation matrix around the Z-axis according to the right hand rule
|
||||
*/
|
||||
static cMatrixf MatrixRotateZ(float afAngle);
|
||||
static cMatrixf MatrixScale(cVector3f avScale);
|
||||
static cMatrixf MatrixTranslate(cVector3f avTrans);
|
||||
|
||||
/**
|
||||
* Creates a matrix from a quaternion.
|
||||
* \return
|
||||
*/
|
||||
static cMatrixf MatrixQuaternion(const cQuaternion &aqRot);
|
||||
|
||||
/**
|
||||
* Get the minor of a matrix.
|
||||
*/
|
||||
static inline float MatrixMinor(const cMatrixf &a_mtxA,
|
||||
const size_t r0, const size_t r1, const size_t r2,
|
||||
const size_t c0, const size_t c1, const size_t c2);
|
||||
/**
|
||||
* Get the adjoint of a matrix.
|
||||
*/
|
||||
static inline cMatrixf MatrixAdjoint(const cMatrixf &a_mtxA);
|
||||
|
||||
/**
|
||||
* Get the determinant of a matrix.
|
||||
*/
|
||||
static inline float MatrixDeterminant(const cMatrixf &a_mtxA);
|
||||
|
||||
/**
|
||||
* Gets the inverse of a matrix.
|
||||
*/
|
||||
static cMatrixf MatrixInverse(const cMatrixf &a_mtxA);
|
||||
|
||||
/**
|
||||
* Converts the matrix into Euler angles, XYZ only supported at the moment.
|
||||
* \param &a_mtxA
|
||||
* \param aOrder
|
||||
*/
|
||||
static cVector3f MatrixToEulerAngles(const cMatrixf &a_mtxA, eEulerRotationOrder aOrder);
|
||||
|
||||
/**
|
||||
* Create a char string from the matrix
|
||||
*/
|
||||
static const char *MatrixToChar(const cMatrixf &a_mtxA);
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
////////// POLYGONS //////////////////////////////////
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Creates an array with 4d tangent vectors for triangles. alIndexNum % 3 must be 0.
|
||||
* \param apDestArray The destination array, must be 4 * number of vertices large
|
||||
* \param apIndexArray The indices
|
||||
* \param alIndexNum Number of indices
|
||||
* \param apVertexArray Vertices indexed by the indices
|
||||
* \param apTexArray The texture coords
|
||||
* \param apNormalArray The normals
|
||||
* \param alVertexNum Number of vertex, normals and texcoords.
|
||||
* \return true if success, else false
|
||||
*/
|
||||
static bool CreateTriTangentVectors(float *apDestArray,
|
||||
const unsigned int *apIndexArray, int alIndexNum,
|
||||
const float *apVertexArray, int alVtxStride,
|
||||
const float *apTexArray,
|
||||
const float *apNormalArray, int alVertexNum);
|
||||
|
||||
/**
|
||||
* Creates triangle data for a triangle mesh. alIndexNum % 3 must be 0.
|
||||
* \param avTriangles Where the data will be stored. If empty, this function resizes it.
|
||||
* \param apIndexArray The indices
|
||||
* \param alIndexNum Number of indices
|
||||
* \param apVertexArray Vertices indexed by the indices
|
||||
* \param alVertexNum Number of vertices
|
||||
* \return true if success, else false
|
||||
*/
|
||||
static bool CreateTriangleData(tTriangleDataVec &avTriangles,
|
||||
const unsigned int *apIndexArray, int alIndexNum,
|
||||
const float *apVertexArray, int alVtxStride, int alVertexNum);
|
||||
|
||||
/**
|
||||
* Creates edges for a triangle mesh. alIndexNum % 3 must be 0.
|
||||
* \param avEdges An empty edge vector, this is where the edges will be stored.
|
||||
* \param apIndexArray The indices
|
||||
* \param alIndexNum Number of indices
|
||||
* \param apVertexArray Vertices indexed by the indices
|
||||
* \param alVertexNum Number of vertices
|
||||
* \return true if success, else false
|
||||
*/
|
||||
static bool CreateEdges(tTriEdgeVec &avEdges,
|
||||
const unsigned int *apIndexArray, int alIndexNum,
|
||||
const float *apVertexArray, int alVtxStride, int alVertexNum,
|
||||
bool *apIsDoubleSided);
|
||||
};
|
||||
|
||||
} // namespace hpl
|
||||
|
||||
#endif // HPL_MATH_H
|
||||
Reference in New Issue
Block a user