171 lines
4.5 KiB
C++
Executable File
171 lines
4.5 KiB
C++
Executable File
//-----------------------------------------------------------------------------
|
|
// Torque Game Engine
|
|
// Copyright (C) GarageGames.com, Inc.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include "math/mMath.h"
|
|
#include "math/mathUtils.h"
|
|
#include "math/mRandom.h"
|
|
|
|
namespace MathUtils
|
|
{
|
|
|
|
MRandomLCG sgRandom(0xdeadbeef); ///< Our random number generator.
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Creates orientation matrix from a direction vector. Assumes ( 0 0 1 ) is up.
|
|
//------------------------------------------------------------------------------
|
|
MatrixF createOrientFromDir( Point3F &direction )
|
|
{
|
|
Point3F j = direction;
|
|
Point3F k(0.0f, 0.0f, 1.0f);
|
|
Point3F i;
|
|
|
|
mCross( j, k, &i );
|
|
|
|
if( i.magnitudeSafe() == 0.0f )
|
|
{
|
|
i.set( 0.0f, -1.0f, 0.0f );
|
|
}
|
|
|
|
i.normalizeSafe();
|
|
mCross( i, j, &k );
|
|
|
|
MatrixF mat( true );
|
|
mat.setColumn( 0, i );
|
|
mat.setColumn( 1, j );
|
|
mat.setColumn( 2, k );
|
|
|
|
return mat;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Creates random direction given angle parameters similar to the particle system.
|
|
// The angles are relative to the specified axis.
|
|
//------------------------------------------------------------------------------
|
|
Point3F randomDir( Point3F &axis, F32 thetaAngleMin, F32 thetaAngleMax,
|
|
F32 phiAngleMin, F32 phiAngleMax )
|
|
{
|
|
MatrixF orient = createOrientFromDir( axis );
|
|
Point3F axisx;
|
|
orient.getColumn( 0, &axisx );
|
|
|
|
F32 theta = (thetaAngleMax - thetaAngleMin) * sgRandom.randF() + thetaAngleMin;
|
|
F32 phi = (phiAngleMax - phiAngleMin) * sgRandom.randF() + phiAngleMin;
|
|
|
|
// Both phi and theta are in degs. Create axis angles out of them, and create the
|
|
// appropriate rotation matrix...
|
|
AngAxisF thetaRot(axisx, theta * (M_PI_F / 180.0f));
|
|
AngAxisF phiRot(axis, phi * (M_PI_F / 180.0f));
|
|
|
|
Point3F ejectionAxis = axis;
|
|
|
|
MatrixF temp(true);
|
|
thetaRot.setMatrix(&temp);
|
|
temp.mulP(ejectionAxis);
|
|
phiRot.setMatrix(&temp);
|
|
temp.mulP(ejectionAxis);
|
|
|
|
return ejectionAxis;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// 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.
|
|
// ASSUMES Z AXIS IS UP
|
|
//------------------------------------------------------------------------------
|
|
void getAnglesFromVector( VectorF &vec, F32 &yawAng, F32 &pitchAng )
|
|
{
|
|
yawAng = mAtan( vec.x, vec.y );
|
|
|
|
if( yawAng < 0.0f )
|
|
{
|
|
yawAng += M_2PI_F;
|
|
}
|
|
|
|
if( fabs(vec.x) > fabs(vec.y) )
|
|
{
|
|
pitchAng = mAtan( fabs(vec.z), fabs(vec.x) );
|
|
}
|
|
else
|
|
{
|
|
pitchAng = mAtan( fabs(vec.z), fabs(vec.y) );
|
|
}
|
|
|
|
if( vec.z < 0.0f )
|
|
{
|
|
pitchAng = -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.
|
|
// ASSUMES Z AXIS IS UP
|
|
//------------------------------------------------------------------------------
|
|
void getVectorFromAngles( VectorF &vec, F32 &yawAng, F32 &pitchAng )
|
|
{
|
|
VectorF pnt( 0.0f, 1.0f, 0.0f );
|
|
|
|
EulerF rot( -pitchAng, 0.0f, 0.0f );
|
|
MatrixF mat( rot );
|
|
|
|
rot.set( 0.0f, 0.0f, yawAng );
|
|
MatrixF mat2( rot );
|
|
|
|
mat.mulV( pnt );
|
|
mat2.mulV( pnt );
|
|
|
|
vec = pnt;
|
|
}
|
|
|
|
|
|
// transform bounding box making sure to keep original box entirely contained - JK...
|
|
void transformBoundingBox(const Box3F &sbox, const MatrixF &mat, Box3F &dbox)
|
|
{
|
|
Point3F center;
|
|
|
|
// set transformed center...
|
|
sbox.getCenter(¢er);
|
|
mat.mulP(center);
|
|
dbox.min = center;
|
|
dbox.max = center;
|
|
|
|
Point3F val;
|
|
for(U32 ix=0; ix<2; ix++)
|
|
{
|
|
if(ix & 0x1)
|
|
val.x = sbox.min.x;
|
|
else
|
|
val.x = sbox.max.x;
|
|
|
|
for(U32 iy=0; iy<2; iy++)
|
|
{
|
|
if(iy & 0x1)
|
|
val.y = sbox.min.y;
|
|
else
|
|
val.y = sbox.max.y;
|
|
|
|
for(U32 iz=0; iz<2; iz++)
|
|
{
|
|
if(iz & 0x1)
|
|
val.z = sbox.min.z;
|
|
else
|
|
val.z = sbox.max.z;
|
|
|
|
Point3F newval;
|
|
mat.mulP(val, &newval);
|
|
dbox.min.setMin(newval);
|
|
dbox.max.setMax(newval);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
} // end namespace MathUtils
|