651 lines
14 KiB
C
651 lines
14 KiB
C
/******************/
|
|
/*** Misc Utils ***/
|
|
/******************/
|
|
|
|
#ifndef __UTILS_HEADER__
|
|
#define __UTILS_HEADER__
|
|
|
|
#include "utils\mathmip.h"
|
|
|
|
#ifndef __GLOBAL_STRUCTS_HEADER__
|
|
#include "gstruct.h"
|
|
#endif
|
|
#ifndef __MATHTABLE_HEADER__
|
|
#include "utils\mathtab.h"
|
|
#endif
|
|
|
|
/*****************************************************************************/
|
|
#define NO_SIN 64
|
|
#define SINMASK (NO_SIN - 1)
|
|
#define COSPOS (NO_SIN / 4)
|
|
|
|
extern const s16 c_circle[ NO_SIN ];
|
|
extern const MATRIX IdentityMtx;
|
|
|
|
/*****************************************************************************/
|
|
u8 *MakePtr(void *BasePtr,int Offset);
|
|
|
|
/*****************************************************************************/
|
|
/*** Loads of inlines ********************************************************/
|
|
/*****************************************************************************/
|
|
inline void SetIdent(MATRIX *Mtx)
|
|
{
|
|
Mtx->m[0][0]=ONE; Mtx->m[0][1]=0; Mtx->m[0][2]=0;
|
|
Mtx->m[1][0]=0; Mtx->m[1][1]=ONE; Mtx->m[1][2]=0;
|
|
Mtx->m[2][0]=0; Mtx->m[2][1]=0; Mtx->m[2][2]=ONE;
|
|
Mtx->t[0]=0; Mtx->t[1]=0; Mtx->t[2]=0;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
inline void SetIdentNoTrans(MATRIX *Mtx)
|
|
{
|
|
Mtx->m[0][0]=ONE; Mtx->m[0][1]=0; Mtx->m[0][2]=0;
|
|
Mtx->m[1][0]=0; Mtx->m[1][1]=ONE; Mtx->m[1][2]=0;
|
|
Mtx->m[2][0]=0; Mtx->m[2][1]=0; Mtx->m[2][2]=ONE;
|
|
// Mtx->t[0]=0; Mtx->t[1]=0; Mtx->t[2]=0;
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
inline void SetIdentScale(MATRIX *Mtx,u32 Scale)
|
|
{
|
|
Mtx->m[0][0]=Scale; Mtx->m[0][1]=0; Mtx->m[0][2]=0;
|
|
Mtx->m[1][0]=0; Mtx->m[1][1]=Scale; Mtx->m[1][2]=0;
|
|
Mtx->m[2][0]=0; Mtx->m[2][1]=0; Mtx->m[2][2]=Scale;
|
|
Mtx->t[0]=0; Mtx->t[1]=0; Mtx->t[2]=0;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
inline void SetIdentScaleNoTrans(MATRIX *Mtx,u32 Scale)
|
|
{
|
|
Mtx->m[0][0]=Scale; Mtx->m[0][1]=0; Mtx->m[0][2]=0;
|
|
Mtx->m[1][0]=0; Mtx->m[1][1]=Scale; Mtx->m[1][2]=0;
|
|
Mtx->m[2][0]=0; Mtx->m[2][1]=0; Mtx->m[2][2]=Scale;
|
|
// Mtx->t[0]=0; Mtx->t[1]=0; Mtx->t[2]=0;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
inline void InverseMatrix(MATRIX *m, MATRIX &im) //assumes no scale, just transformation and rotation
|
|
{
|
|
TransposeMatrix(m, &im);
|
|
ApplyMatrixLV(&im, (VECTOR*)&m->t[0], (VECTOR*)&im.t[0]);
|
|
im.t[0] = -im.t[0];
|
|
im.t[1] = -im.t[1];
|
|
im.t[2] = -im.t[2];
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/*****************************************************************************/
|
|
/*****************************************************************************/
|
|
extern long s_randomSeed;
|
|
inline long getRndSeed()
|
|
{
|
|
const u32 INCREMENT = 1;
|
|
const u32 MULTIPLIER = 0x015a4e35L;
|
|
s_randomSeed = MULTIPLIER * s_randomSeed + INCREMENT;
|
|
return abs(s_randomSeed);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
inline void setRndSeed( long seed )
|
|
{
|
|
s_randomSeed = seed;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
inline long getRnd()
|
|
{
|
|
return getRndSeed();
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
inline long getRndRange( long v )
|
|
{
|
|
if (v <= 0) return 0;
|
|
|
|
// high order bits are more "random" than low order bits
|
|
if (v < 0x0ffff) return (getRndSeed() >> 16) % v;
|
|
|
|
return getRndSeed() % v;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/*****************************************************************************/
|
|
/*****************************************************************************/
|
|
|
|
// -- VECTOR Operator Arithmetic operation --
|
|
|
|
inline VECTOR operator - (const VECTOR& a)
|
|
{
|
|
VECTOR ret;
|
|
ret.vx = -a.vx;
|
|
ret.vy = -a.vy;
|
|
ret.vz = -a.vz;
|
|
return ret;
|
|
}
|
|
|
|
inline VECTOR operator + (const VECTOR& a, const VECTOR& b)
|
|
{
|
|
VECTOR ret;
|
|
ret.vx = a.vx + b.vx;
|
|
ret.vy = a.vy + b.vy;
|
|
ret.vz = a.vz + b.vz;
|
|
return ret;
|
|
}
|
|
|
|
inline VECTOR operator - (const VECTOR& a, const VECTOR& b)
|
|
{
|
|
VECTOR ret;
|
|
ret.vx = a.vx - b.vx;
|
|
ret.vy = a.vy - b.vy;
|
|
ret.vz = a.vz - b.vz;
|
|
return ret;
|
|
}
|
|
|
|
inline VECTOR operator *= (const VECTOR& a, const int & b)
|
|
{
|
|
VECTOR ret;
|
|
ret.vx = a.vx * b;
|
|
ret.vy = a.vy * b;
|
|
ret.vz = a.vz * b;
|
|
return ret;
|
|
}
|
|
|
|
inline VECTOR operator >>= (const VECTOR& a, const int & b)
|
|
{
|
|
VECTOR ret;
|
|
ret.vx = a.vx >> b;
|
|
ret.vy = a.vy >> b;
|
|
ret.vz = a.vz >> b;
|
|
return ret;
|
|
}
|
|
|
|
inline VECTOR operator += (const VECTOR& a, const VECTOR& b)
|
|
{
|
|
VECTOR ret;
|
|
ret.vx = a.vx + b.vx;
|
|
ret.vy = a.vy + b.vy;
|
|
ret.vz = a.vz + b.vz;
|
|
return ret;
|
|
}
|
|
|
|
inline int operator == (const VECTOR& a, const VECTOR& b)
|
|
{
|
|
return (a.vx == b.vx) && (a.vy == b.vy) && (a.vz == b.vz);
|
|
}
|
|
|
|
inline int operator != (const VECTOR& a, const VECTOR& b)
|
|
{
|
|
return !(a == b);
|
|
}
|
|
|
|
|
|
// -- VECTOR to sVtx Operator Arithmetic operation --
|
|
|
|
inline VECTOR operator - (const sShortXYZ& a, const sVtx& b)
|
|
{
|
|
VECTOR ret;
|
|
ret.vx = a.vx - b.vx;
|
|
ret.vy = a.vy - b.vy;
|
|
ret.vz = a.vz - b.vz;
|
|
return ret;
|
|
}
|
|
|
|
inline VECTOR operator - (const sVtx& a, const sVtx& b)
|
|
{
|
|
VECTOR ret;
|
|
ret.vx = a.vx - b.vx;
|
|
ret.vy = a.vy - b.vy;
|
|
ret.vz = a.vz - b.vz;
|
|
return ret;
|
|
}
|
|
|
|
inline VECTOR operator *= (const sVtx& a, const int & b)
|
|
{
|
|
VECTOR ret;
|
|
ret.vx = a.vx * b;
|
|
ret.vy = a.vy * b;
|
|
ret.vz = a.vz * b;
|
|
return ret;
|
|
}
|
|
|
|
inline VECTOR operator >>= (const sVtx& a, const int & b)
|
|
{
|
|
VECTOR ret;
|
|
ret.vx = a.vx >> b;
|
|
ret.vy = a.vy >> b;
|
|
ret.vz = a.vz >> b;
|
|
return ret;
|
|
}
|
|
|
|
// -- sShortXYZ Operator Arithmetic operation --
|
|
|
|
inline sShortXYZ operator - (const sShortXYZ& a)
|
|
{
|
|
sShortXYZ ret;
|
|
ret.vx = -a.vx;
|
|
ret.vy = -a.vy;
|
|
ret.vz = -a.vz;
|
|
return ret;
|
|
}
|
|
|
|
inline sShortXYZ operator + (const sShortXYZ& a, const sShortXYZ& b)
|
|
{
|
|
sShortXYZ ret;
|
|
ret.vx = a.vx + b.vx;
|
|
ret.vy = a.vy + b.vy;
|
|
ret.vz = a.vz + b.vz;
|
|
return ret;
|
|
}
|
|
|
|
inline sShortXYZ operator >> (const VECTOR& a, const int& b)
|
|
{
|
|
sShortXYZ ret;
|
|
ret.vx = a.vx >> b;
|
|
ret.vy = a.vy >> b;
|
|
ret.vz = a.vz >> b;
|
|
return ret;
|
|
}
|
|
|
|
inline int operator * (const sShortXYZ& a, const sShortXYZ& b) // DOT PRODUCT
|
|
{
|
|
return (a.vx * b.vx) + (a.vy * b.vy) + (a.vz * b.vz);
|
|
}
|
|
|
|
inline int operator == (const sShortXYZ& a, const sShortXYZ& b)
|
|
{
|
|
return (a.vx == b.vx) && (a.vy == b.vy) && (a.vz == b.vz);
|
|
}
|
|
|
|
inline int operator != (const sShortXYZ& a, const sShortXYZ& b)
|
|
{
|
|
return !(a == b);
|
|
}
|
|
|
|
// -- sShortXYZ to VECTOR Operator Arithmetic operation --
|
|
|
|
inline VECTOR operator + (const VECTOR& a, const sShortXYZ& b)
|
|
{
|
|
VECTOR ret;
|
|
ret.vx = a.vx + b.vx;
|
|
ret.vy = a.vy + b.vy;
|
|
ret.vz = a.vz + b.vz;
|
|
return ret;
|
|
}
|
|
|
|
inline VECTOR operator - (const VECTOR& a, const sShortXYZ& b)
|
|
{
|
|
VECTOR ret;
|
|
ret.vx = a.vx - b.vx;
|
|
ret.vy = a.vy - b.vy;
|
|
ret.vz = a.vz - b.vz;
|
|
return ret;
|
|
}
|
|
|
|
inline VECTOR operator - (const sShortXYZ& a, const sShortXYZ& b)
|
|
{
|
|
VECTOR ret;
|
|
ret.vx = a.vx - b.vx;
|
|
ret.vy = a.vy - b.vy;
|
|
ret.vz = a.vz - b.vz;
|
|
return ret;
|
|
}
|
|
|
|
inline int operator * (const VECTOR& a, const sShortXYZ& b) // DOT PRODUCT
|
|
{
|
|
return (a.vx * b.vx) + (a.vy * b.vy) + (a.vz * b.vz);
|
|
}
|
|
|
|
inline int operator * (const sShortXYZ& a, const VECTOR& b) // DOT PRODUCT
|
|
{
|
|
return (a.vx * b.vx) + (a.vy * b.vy) + (a.vz * b.vz);
|
|
}
|
|
|
|
inline VECTOR operator ^ (const VECTOR& a, const sShortXYZ& b) // CROSS PRODUCT
|
|
{
|
|
VECTOR ret;
|
|
ret.vx = (a.vy * b.vz) - (a.vz * b.vy);
|
|
ret.vy = (a.vz * b.vx) - (a.vx * b.vz);
|
|
ret.vz = (a.vx * b.vy) - (a.vy * b.vx);
|
|
return ret;
|
|
}
|
|
|
|
inline VECTOR operator ^ (const sShortXYZ& a, const sShortXYZ& b) // CROSS PRODUCT
|
|
{
|
|
VECTOR ret;
|
|
ret.vx = (a.vy * b.vz) - (a.vz * b.vy);
|
|
ret.vy = (a.vz * b.vx) - (a.vx * b.vz);
|
|
ret.vz = (a.vx * b.vy) - (a.vy * b.vx);
|
|
return ret;
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/*** Inlines *****************************************************************/
|
|
/*****************************************************************************/
|
|
inline u32 isqrt2(u32 v)
|
|
{
|
|
register u32 root = 0;
|
|
register u32 remhi = 0;
|
|
register u32 remlo = v;
|
|
register u32 count = 15;
|
|
register u32 testdiv;
|
|
|
|
do
|
|
{
|
|
remhi = (remhi << 2) | (remlo >> 30);
|
|
remlo <<= 2;
|
|
root <<= 1;
|
|
testdiv = (root << 1) + 1;
|
|
if (remhi >= testdiv)
|
|
{
|
|
remhi -= testdiv;
|
|
root += 1;
|
|
}
|
|
} while (count -- != 0);
|
|
return(root);
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
inline u32 CalcLength(const SVECTOR *s)
|
|
{
|
|
int Dt;
|
|
gte_ldsv(s);
|
|
gte_sqr0();
|
|
CMX_StVecXYZMag(&Dt);
|
|
return(Dt);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
inline u32 CalcLengthSquared(const SVECTOR *s)
|
|
{
|
|
u32 Dt;
|
|
gte_ldsv(s);
|
|
gte_sqr0();
|
|
CMX_StVecXYZMag(&Dt);
|
|
return(Dt);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
inline u32 CalcLengthV(const VECTOR *s)
|
|
{
|
|
u32 Dt;
|
|
gte_ldlvl(s);
|
|
gte_sqr0();
|
|
CMX_StVecXYZMag(&Dt);
|
|
return(isqrt2(Dt));
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
inline u32 CalcLengthSquaredV(const VECTOR *s)
|
|
{
|
|
u32 Dt;
|
|
gte_ldlvl(s);
|
|
gte_sqr0();
|
|
CMX_StVecXYZMag(&Dt);
|
|
return(Dt);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
inline u32 CalcDist(const SVECTOR *s, const SVECTOR *e)
|
|
{
|
|
s32 Dx = s->vx - e->vx;
|
|
s32 Dy = s->vy - e->vy;
|
|
s32 Dz = s->vz - e->vz;
|
|
u32 Dt;
|
|
|
|
CMX_ldXYZ(Dx,Dy,Dz);
|
|
gte_sqr0();
|
|
CMX_StVecXYZMag(&Dt);
|
|
return(isqrt2(Dt));
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
inline u32 CalcDistXZ(const SVECTOR *s, const SVECTOR *e)
|
|
{
|
|
s32 Dx = s->vx - e->vx;
|
|
s32 Dz = s->vz - e->vz;
|
|
u32 Dt;
|
|
|
|
CMX_ldXZ(Dx,Dz);
|
|
gte_sqr0();
|
|
CMX_StVecXZMag(&Dt);
|
|
return(isqrt2(Dt));
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
inline u32 CalcDistV(const VECTOR *s, const VECTOR *e)
|
|
{
|
|
s32 Dx = s->vx - e->vx;
|
|
s32 Dy = s->vy - e->vy;
|
|
s32 Dz = s->vz - e->vz;
|
|
u32 Dt;
|
|
|
|
CMX_ldXYZ(Dx,Dy,Dz);
|
|
gte_sqr0();
|
|
CMX_StVecXYZMag(&Dt);
|
|
return(isqrt2(Dt));
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
inline u32 CalcDistV(const VECTOR *s, const VECTOR *e, u16 shift)
|
|
{
|
|
s32 Dx = (s->vx - e->vx) >> shift;
|
|
s32 Dz = (s->vz - e->vz) >> shift;
|
|
u32 Dt;
|
|
|
|
CMX_ldXZ(Dx,Dz);
|
|
gte_sqr0();
|
|
CMX_StVecXZMag(&Dt);
|
|
return(isqrt2(Dt) << shift);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
inline u32 CalcDistXZV(const VECTOR *s, const VECTOR *e)
|
|
{
|
|
s32 Dx = s->vx - e->vx;
|
|
s32 Dz = s->vz - e->vz;
|
|
u32 Dt;
|
|
CMX_ldXZ(Dx,Dz);
|
|
gte_sqr0();
|
|
CMX_StVecXZMag(&Dt);
|
|
return(isqrt2(Dt));
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
inline u32 CalcDistXZVSquared(const VECTOR *s, const VECTOR *e)
|
|
{
|
|
s32 Dx = s->vx - e->vx;
|
|
s32 Dz = s->vz - e->vz;
|
|
u32 Dt;
|
|
|
|
CMX_ldXZ(Dx,Dz);
|
|
gte_sqr0();
|
|
CMX_StVecXZMag(&Dt);
|
|
return abs(Dt);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
inline u32 CalcDistXZV(const VECTOR *s, const VECTOR *e, u16 shift)
|
|
{
|
|
s32 Dx = (s->vx - e->vx) >> shift;
|
|
s32 Dz = (s->vz - e->vz) >> shift;
|
|
u32 Dt;
|
|
|
|
CMX_ldXZ(Dx,Dz);
|
|
gte_sqr0();
|
|
CMX_StVecXZMag(&Dt);
|
|
return(isqrt2(Dt) << shift);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
inline long CalcDistXZVAccurate(const VECTOR *s, const VECTOR *e)
|
|
{
|
|
long Dx = s->vx - e->vx;
|
|
long Dz = s->vz - e->vz;
|
|
long Dt = (Dx*Dx) + (Dz*Dz);
|
|
long len = SquareRoot0(Dt);
|
|
return(len);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
inline u32 CalcDist(const sShortXYZ *s, const sShortXYZ *e)
|
|
{
|
|
s32 Dx = s->vx - e->vx;
|
|
s32 Dy = s->vy - e->vy;
|
|
s32 Dz = s->vz - e->vz;
|
|
u32 Dt;
|
|
|
|
CMX_ldXYZ(Dx,Dy,Dz);
|
|
gte_sqr0();
|
|
CMX_StVecXYZMag(&Dt);
|
|
return(isqrt2(Dt));
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
inline u32 CalcDistXZ(const sShortXYZ *s, const sShortXYZ *e)
|
|
{
|
|
s32 Dx = s->vx - e->vx;
|
|
s32 Dz = s->vz - e->vz;
|
|
u32 Dt;
|
|
|
|
CMX_ldXZ(Dx,Dz);
|
|
gte_sqr0();
|
|
CMX_StVecXZMag(&Dt);
|
|
return(isqrt2(Dt));
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
inline u32 CalcDistXZSquared(const sShortXYZ *s, const sShortXYZ *e)
|
|
{
|
|
s32 Dx = s->vx - e->vx;
|
|
s32 Dz = s->vz - e->vz;
|
|
u32 Dt;
|
|
|
|
CMX_ldXZ(Dx,Dz);
|
|
gte_sqr0();
|
|
CMX_StVecXZMag(&Dt);
|
|
return(Dt);
|
|
}
|
|
/*****************************************************************************/
|
|
inline s32 DotProduct(const SVECTOR *V0, const SVECTOR *V1)
|
|
{
|
|
s32 Dpx,Dpy,Dpz;
|
|
Dpx=V0->vx*V1->vx;
|
|
Dpy=V0->vy*V1->vy;
|
|
Dpz=V0->vz*V1->vz;
|
|
return(Dpx+Dpy+Dpz);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
inline s32 DotProductV( const VECTOR *V0, const VECTOR *V1 )
|
|
{
|
|
s32 ax, ay, az;
|
|
s32 bx, by, bz;
|
|
s32 Dpx, Dpy, Dpz;
|
|
|
|
ax = V0->vx;
|
|
ay = V0->vy;
|
|
az = V0->vz;
|
|
|
|
bx = V1->vx;
|
|
by = V1->vy;
|
|
bz = V1->vz;
|
|
|
|
Dpx = ax * bx;
|
|
Dpy = ay * by;
|
|
Dpz = az * bz;
|
|
|
|
return (Dpx + Dpy + Dpz);
|
|
}
|
|
/*****************************************************************************/
|
|
inline s32 DotProductSV( const SVECTOR *V0, const VECTOR *V1 )
|
|
{
|
|
s32 ax, ay, az;
|
|
s32 bx, by, bz;
|
|
s32 Dpx, Dpy, Dpz;
|
|
|
|
ax = V0->vx;
|
|
ay = V0->vy;
|
|
az = V0->vz;
|
|
|
|
bx = V1->vx;
|
|
by = V1->vy;
|
|
bz = V1->vz;
|
|
|
|
Dpx = ax * bx;
|
|
Dpy = ay * by;
|
|
Dpz = az * bz;
|
|
|
|
return (Dpx + Dpy + Dpz);
|
|
}
|
|
/*****************************************************************************/
|
|
inline void QuatSlerp(sQuat *s, sQuat *d, int t, sQuat *o)
|
|
{
|
|
s32 xx, yy, zz, ww;
|
|
s32 cs;
|
|
s32 c0, c1;
|
|
sQuat to;
|
|
|
|
xx = (s->vx * d->vx);
|
|
yy = (s->vy * d->vy);
|
|
zz = (s->vz * d->vz);
|
|
ww = (s->vw * d->vw);
|
|
|
|
cs = xx + yy + zz + ww;
|
|
if (cs<0)
|
|
{
|
|
cs = -cs;
|
|
to.vx = -d->vx;
|
|
to.vy = -d->vy;
|
|
to.vz = -d->vz;
|
|
to.vw = -d->vw;
|
|
}
|
|
else
|
|
{
|
|
to.vx = d->vx;
|
|
to.vy = d->vy;
|
|
to.vz = d->vz;
|
|
to.vw = d->vw;
|
|
}
|
|
|
|
cs >>= 12;
|
|
s32 omega;
|
|
if (cs < 3500)
|
|
{ // standard case (slerp)
|
|
omega = macos(cs);
|
|
s32 sinom = monesin(omega);
|
|
c0 = (msin((((4096 - t) * omega) >> 12) & 4095) * sinom)>>12;
|
|
c1 = (msin(((t * omega) >> 12) & 4095) * sinom)>>12;
|
|
}
|
|
else
|
|
{
|
|
c0 = 4096 - t;
|
|
c1 = t;
|
|
}
|
|
|
|
gte_LoadAverageShort12(s, &to, c0, c1, o);
|
|
o->vw = ((c0 * s->vw) + (c1 * to.vw)) >> 12;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
static const s32 DeltaErr = 1000;
|
|
inline void NormalizeQuaternion(sQuat *o)
|
|
{
|
|
s32 t = (u32)((s32)o->vx*o->vx+(s32)o->vy*o->vy+(s32)o->vz*o->vz+(s32)o->vw*o->vw);
|
|
s32 diff = abs((1<<24) - t);
|
|
if (diff>DeltaErr)
|
|
{
|
|
s32 isqrs = isqrt2(t);
|
|
if (isqrs)
|
|
{
|
|
o->vx = (s16)(((s32)o->vx << 12) / (s32)isqrs);
|
|
o->vy = (s16)(((s32)o->vy << 12) / (s32)isqrs);
|
|
o->vz = (s16)(((s32)o->vz << 12) / (s32)isqrs);
|
|
o->vw = (s16)(((s32)o->vw << 12) / (s32)isqrs);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif |