www.pudn.com > coolMEMORY.rar > AS_Math.cpp
//-----------------------------------------------------------------------------
// File: AS_Math.cpp
//-----------------------------------------------------------------------------
#include "AS_Engine.h"
// Variables: *****************************************************************
unsigned int ASFastSqrtTable[0x10000]; // Declare table of square roots
float two = 2.0f;
///////////////////////////////////////////////////////////////////////////////
// Functions: *****************************************************************
void ASBuildSqrtTable(void);
void NormalizeFace(FLOAT3 *, FLOAT3, FLOAT3, FLOAT3);
void ASAddVec(FLOAT3, FLOAT3, FLOAT3 *);
void ASSubVec(FLOAT3, FLOAT3, FLOAT3 *);
void ASMulVec(FLOAT3, FLOAT3, FLOAT3 *);
void ASScaleVec(FLOAT3, float, FLOAT3 *);
void ASInvertVec(FLOAT3, FLOAT3 *);
void ASRotateVectorX(FLOAT3, float, FLOAT3 *);
void ASRotateVectorY(FLOAT3, float, FLOAT3 *);
void ASRotateVectorZ(FLOAT3, float, FLOAT3 *);
void ASNormalize(FLOAT3 *);
void ASVectMult(FLOAT3, FLOAT3, FLOAT3 *);
void ASCatmullRom(FLOAT3 [4], float, FLOAT3 *);
void ASRotateAroundLine(FLOAT3, FLOAT3, FLOAT3, float, FLOAT3 *);
void ASMultVecMatrix(FLOAT3, float [16], FLOAT3 *);
///////////////////////////////////////////////////////////////////////////////
void ASBuildSqrtTable(void)
{ // begin ASBuildSqrtTable()
unsigned int i;
FastSqrtUnion s;
for(i = 0; i <= 0x7FFF; i++)
{
// Build a float with the bit pattern i as mantissa
// and an exponent of 0, stored as 127:
s.i = (i << 8) | (0x7F << 23);
s.f = (float) sqrt(s.f);
// Take the square root then strip the first 7 bits of
// the mantissa into the table:
ASFastSqrtTable[i + 0x8000] = (s.i & 0x7FFFFF);
// Repeat the process, this time with an exponent of 1,
// stored as 128:
s.i = (i << 8) | (0x80 << 23);
s.f = (float)sqrt(s.f);
ASFastSqrtTable[i] = (s.i & 0x7FFFFF);
}
} // end ASBuildSqrtTable()
void NormalizeFace(FLOAT3 *ResultV, FLOAT3 V1, FLOAT3 V2, FLOAT3 V3)
{
FLOAT3 V1_V2, V1_V3;
float fLength;
SubtVer(V1_V2, V1, V2);
SubtVer(V1_V3, V1, V3);
CrossProductVer(*ResultV, V1_V2, V1_V3);
fLength = (float) ASFastSqrt((*ResultV)[X]*(*ResultV)[X]+(*ResultV)[Y]*(*ResultV)[Y]+(*ResultV)[Z]*(*ResultV)[Z]);
(*ResultV)[X] /= fLength;
(*ResultV)[Y] /= fLength;
(*ResultV)[Z] /= fLength;
}
void ASAddVec(FLOAT3 v1, FLOAT3 v2, FLOAT3 *res)
{ // begin ASAddVec()
(*res)[0] = v1[0]+v2[0];
(*res)[1] = v1[1]+v2[1];
(*res)[2] = v1[2]+v2[2];
} // end ASAddVec()
void ASSubVec(FLOAT3 v1, FLOAT3 v2, FLOAT3 *res)
{ // begin ASSubVec()
(*res)[0] = v1[0]-v2[0];
(*res)[1] = v1[1]-v2[1];
(*res)[2] = v1[2]-v2[2];
} // end ASSubVec()
void ASMulVec(FLOAT3 v, FLOAT3 v2, FLOAT3 *res)
{ // begin ASMulVec()
(*res)[0] = v[0]*v2[0];
(*res)[1] = v[1]*v2[1];
(*res)[2] = v[2]*v2[2];
} // end ASMulVec()
void ASScaleVec(FLOAT3 v, float fScale, FLOAT3 *res)
{ // begin ASScaleVec()
(*res)[0] = v[0]*fScale;
(*res)[1] = v[1]*fScale;
(*res)[2] = v[2]*fScale;
} // end ASScaleVec()
void ASInvertVec(FLOAT3 v, FLOAT3 *res)
{ // begin ASInvertVec()
(*res)[0] = -v[0];
(*res)[1] = -v[1];
(*res)[2] = -v[2];
} // end ASInvertVec()
void ASRotateVectorX(FLOAT3 fVec, float amnt, FLOAT3 *fDestVec)
{ // begin ASRotateVectorX()
amnt *= (float) PI/180;
float s = (float) sin(amnt);
float c = (float) cos(amnt);
float y = fVec[1];
float z = fVec[2];
(*fDestVec)[0] = fVec[0];
(*fDestVec)[1] = (y * c) - (z * s);
(*fDestVec)[2] = (y * s) + (z * c);
} // ned ASRotateVectorX()
void ASRotateVectorY(FLOAT3 fVec, float amnt, FLOAT3 *fDestVec)
{ // begin ASRotateVectorY()
amnt *= (float) PI/180;
float s = (float) sin(amnt);
float c = (float) cos(amnt);
float x = fVec[0];
float z = fVec[2];
(*fDestVec)[0] = (x * c) + (z * s);
(*fDestVec)[1] = fVec[1];
(*fDestVec)[2] = (z * c) - (x * s);
} // end ASRotateVectorY()
void ASRotateVectorZ(FLOAT3 fVec, float amnt, FLOAT3 *fDestVec)
{ // begin ASRotateVectorZ()
amnt *= (float) PI/180;
float s = (float) sin(amnt);
float c = (float) cos(amnt);
float x = fVec[0];
float y = fVec[1];
(*fDestVec)[0] = (x * c) - (y * s);
(*fDestVec)[1] = (y * c) + (x * s);
(*fDestVec)[2] = fVec[2];
} // end // begin ASRotateVectorZ()
void ASNormalize(FLOAT3 *fV)
{ // begin ASNormalize()
float fLength = (float) ASFastSqrt((*fV)[X]*(*fV)[X]+(*fV)[Y]*(*fV)[Y]+(*fV)[Z]*(*fV)[Z]);
(*fV)[X] /= fLength; (*fV)[Y] /= fLength; (*fV)[Z] /= fLength;
} // end ASNormalize()
void ASVectMult(FLOAT3 fV1, FLOAT3 fV2, FLOAT3 *fRes)
{ // begin ASVectMult()
(*fRes)[X] = fV1[Y]*fV2[Z]-fV1[Z]*fV2[Y];
(*fRes)[Y] = fV1[Z]*fV2[X]-fV1[X]*fV2[Z];
(*fRes)[Z] = fV1[X]*fV2[Y]-fV1[Y]*fV2[X];
} // end ASVectMult()
void ASCatmullRom(FLOAT3 fP[4], float t, FLOAT3 *fRes)
{ // begin ASCatmullRom()
float t1 = (1-t)*(1-t), t2 = t*t, t3 = t*t*t;
(*fRes)[X] = (-t*t1*fP[0][X]+(2-5*t2+3*t3)*fP[1][X]+t*(1+4*t-3*t2)*fP[2][X]-t2*(1-t)*fP[3][X])/2;
(*fRes)[Y] = (-t*t1*fP[0][Y]+(2-5*t2+3*t3)*fP[1][Y]+t*(1+4*t-3*t2)*fP[2][Y]-t2*(1-t)*fP[3][Y])/2;
(*fRes)[Z] = (-t*t1*fP[0][Z]+(2-5*t2+3*t3)*fP[1][Z]+t*(1+4*t-3*t2)*fP[2][Z]-t2*(1-t)*fP[3][Z])/2;
} // end ASCatmullRom()
//=================== Point Rotating Around Line ===========================
// fPO - original point
// fPP - pivot point
// fPL - pivot line (vector)
// fA - angle to rotate in radians
// fRes - output point
//==========================================================================
void ASRotateAroundLine(FLOAT3 fPO, FLOAT3 fPP, FLOAT3 fPL, float fA, FLOAT3 *fRes)
{ // begin ASRotateAroundLine()
float l, m, n, ca, sa;
FLOAT3 p1, p2;
p1[X] = fPO[X]-fPP[X];
p1[Y] = fPO[Y]-fPP[Y];
p1[Z] = fPO[Z]-fPP[Z];
l = fPL[X];
m = fPL[Y];
n = fPL[Z];
ca = (float) cos(fA);
sa = (float) sin(fA);
p2[X] = p1[X]*((l*l)+ca*(1-l*l))+p1[Y]*(l*(1-ca)*m+n*sa)+p1[Z]*(l*(1-ca)*n-m*sa);
p2[Y] = p1[X]*(l*(1-ca)*m-n*sa)+p1[Y]*(m*m+ca*(1-m*m))+p1[Z]*(m*(1-ca)*n+l*sa);
p2[Z] = p1[X]*(l*(1-ca)*n+m*sa)+p1[Y]*(m*(1-ca)*n-l*sa)+p1[Z]*(n*n+ca*(1-n*n));
(*fRes)[X] = p2[X]+fPP[X];
(*fRes)[Y] = p2[Y]+fPP[Y];
(*fRes)[Z] = p2[Z]+fPP[Z];
} // end ASRotateAroundLine()
void ASMultVecMatrix(FLOAT3 fV, float fM[16], FLOAT3 *fRes)
{ // begin ASMultVecMatrix()
#define M(row,col) fM[row * 4 + col]
(*fRes)[X] = fV[0] * M(0,0) + fV[1] * M(1,0) + fV[2] * M(2,0);
(*fRes)[Y] = fV[0] * M(0,1) + fV[1] * M(1,1) + fV[2] * M(2,1);
(*fRes)[Z] = fV[0] * M(0,2) + fV[1] * M(1,2) + fV[2] * M(2,2);
#undef M
} // end ASMultVecMatrix()