mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-07-12 13:35:35 -04:00
fcb2ab00e1
Stubbing out all OS* functions to stubs.cpp, these will likely have to be replaced with the operating system's primitives for locking/heaps/threads/etc. Moved some generic globals into globals.cpp, not sure where they're actually to be used. Stub DSP functions Stub JSUMemoryOutputStream, JORServer, Z2Audio mDoExt stubs add memcpy add some more stubs, add extras c++ mangled functions add extras.cpp AR/AQ stubbing stub DVD stub CARD more stubs, more extras add missing mtx functions to dusk file finish mtx stub GX KPAD and LC, also do pragma marks for better visualization finish mtx, add a few more stubs gf/wpad/vi translate some matrix math from ppc to C jorserver/debugpad/fap/dmsgobject add m_Do_ext functions from debug block to separate file make small janges to JSystem, does this need upstreaming reorg DVD stubs reorganize stubs by mark
731 lines
22 KiB
C++
731 lines
22 KiB
C++
// This should go into aurora, but for now we'll place it here:
|
|
#include <dolphin/mtx.h>
|
|
#include <math.h>
|
|
#include <cstdio>
|
|
|
|
#define ASSERTLINE(line, cond) (void)0
|
|
#define ASSERTMSGLINE(line, cond, msg) (void)0
|
|
#define ASSERTMSG1LINE(line, cond, msg, arg1) (void)0
|
|
#define ASSERTMSG2LINE(line, cond, msg, arg1, arg2) (void)0
|
|
#define ASSERTMSGLINEV(line, cond, ...) (void)0
|
|
|
|
// SNIP : after here, place it into aurora
|
|
|
|
void C_MTXLightOrtho(Mtx m, f32 t, f32 b, f32 l, f32 r, f32 scaleS, f32 scaleT, f32 transS, f32 transT) {
|
|
f32 tmp;
|
|
|
|
ASSERTMSGLINE(2672, m, "MTXLightOrtho(): NULL MtxPtr 'm' ");
|
|
ASSERTMSGLINE(2673, (t != b), "MTXLightOrtho(): 't' and 'b' clipping planes are equal ");
|
|
ASSERTMSGLINE(2674, (l != r), "MTXLightOrtho(): 'l' and 'r' clipping planes are equal ");
|
|
tmp = 1 / (r - l);
|
|
m[0][0] = (2 * tmp * scaleS);
|
|
m[0][1] = 0;
|
|
m[0][2] = 0;
|
|
m[0][3] = (transS + (scaleS * (tmp * -(r + l))));
|
|
tmp = 1/ (t - b);
|
|
m[1][0] = 0;
|
|
m[1][1] = (2 * tmp * scaleT);
|
|
m[1][2] = 0;
|
|
m[1][3] = (transT + (scaleT * (tmp * -(t + b))));
|
|
m[2][0] = 0;
|
|
m[2][1] = 0;
|
|
m[2][2] = 0;
|
|
m[2][3] = 1;
|
|
}
|
|
|
|
void C_MTXLightPerspective(Mtx m, f32 fovY, f32 aspect, f32 scaleS, f32 scaleT, f32 transS, f32 transT) {
|
|
f32 angle;
|
|
f32 cot;
|
|
|
|
ASSERTMSGLINE(2604, m, "MTXLightPerspective(): NULL MtxPtr 'm' ");
|
|
ASSERTMSGLINE(2605, (fovY > 0.0) && (fovY < 180.0), "MTXLightPerspective(): 'fovY' out of range ");
|
|
ASSERTMSGLINE(2606, 0 != aspect, "MTXLightPerspective(): 'aspect' is 0 ");
|
|
|
|
angle = (0.5f * fovY);
|
|
angle = MTXDegToRad(angle);
|
|
cot = 1 / tanf(angle);
|
|
m[0][0] = (scaleS * (cot / aspect));
|
|
m[0][1] = 0;
|
|
m[0][2] = -transS;
|
|
m[0][3] = 0;
|
|
m[1][0] = 0;
|
|
m[1][1] = (cot * scaleT);
|
|
m[1][2] = -transT;
|
|
m[1][3] = 0;
|
|
m[2][0] = 0;
|
|
m[2][1] = 0;
|
|
m[2][2] = -1;
|
|
m[2][3] = 0;
|
|
}
|
|
|
|
void C_MTXLookAt(Mtx m, const Point3d* camPos, const Vec* camUp, const Point3d* target) {
|
|
Vec vLook;
|
|
Vec vRight;
|
|
Vec vUp;
|
|
|
|
ASSERTMSGLINE(2437, m, "MTXLookAt(): NULL MtxPtr 'm' ");
|
|
ASSERTMSGLINE(2438, camPos, "MTXLookAt(): NULL VecPtr 'camPos' ");
|
|
ASSERTMSGLINE(2439, camUp, "MTXLookAt(): NULL VecPtr 'camUp' ");
|
|
ASSERTMSGLINE(2440, target, "MTXLookAt(): NULL Point3dPtr 'target' ");
|
|
|
|
vLook.x = camPos->x - target->x;
|
|
vLook.y = camPos->y - target->y;
|
|
vLook.z = camPos->z - target->z;
|
|
VECNormalize(&vLook, &vLook);
|
|
VECCrossProduct(camUp, &vLook, &vRight);
|
|
VECNormalize(&vRight, &vRight);
|
|
VECCrossProduct(&vLook, &vRight, &vUp);
|
|
m[0][0] = vRight.x;
|
|
m[0][1] = vRight.y;
|
|
m[0][2] = vRight.z;
|
|
m[0][3] = -((camPos->z * vRight.z) + ((camPos->x * vRight.x) + (camPos->y * vRight.y)));
|
|
m[1][0] = vUp.x;
|
|
m[1][1] = vUp.y;
|
|
m[1][2] = vUp.z;
|
|
m[1][3] = -((camPos->z * vUp.z) + ((camPos->x * vUp.x) + (camPos->y * vUp.y)));
|
|
m[2][0] = vLook.x;
|
|
m[2][1] = vLook.y;
|
|
m[2][2] = vLook.z;
|
|
m[2][3] = -((camPos->z * vLook.z) + ((camPos->x * vLook.x) + (camPos->y * vLook.y)));
|
|
}
|
|
|
|
void C_MTXPerspective(Mtx44 m, f32 fovY, f32 aspect, f32 n, f32 f) {
|
|
f32 angle;
|
|
f32 cot;
|
|
f32 tmp;
|
|
|
|
ASSERTMSGLINE(179, m, "MTXPerspective(): NULL Mtx44Ptr 'm' ");
|
|
ASSERTMSGLINE(180, (fovY > 0.0) && (fovY < 180.0), "MTXPerspective(): 'fovY' out of range ");
|
|
ASSERTMSGLINE(181, 0.0f != aspect, "MTXPerspective(): 'aspect' is 0 ");
|
|
|
|
angle = (0.5f * fovY);
|
|
angle = MTXDegToRad(angle);
|
|
cot = 1 / tanf(angle);
|
|
m[0][0] = (cot / aspect);
|
|
m[0][1] = 0;
|
|
m[0][2] = 0;
|
|
m[0][3] = 0;
|
|
m[1][0] = 0;
|
|
m[1][1] = (cot);
|
|
m[1][2] = 0;
|
|
m[1][3] = 0;
|
|
m[2][0] = 0;
|
|
m[2][1] = 0;
|
|
tmp = 1 / (f - n);
|
|
m[2][2] = (-n * tmp);
|
|
m[2][3] = (tmp * -(f * n));
|
|
m[3][0] = 0;
|
|
m[3][1] = 0;
|
|
m[3][2] = -1;
|
|
m[3][3] = 0;
|
|
}
|
|
|
|
void C_MTXRotRad(Mtx m, char axis, f32 rad) {
|
|
f32 sinA;
|
|
f32 cosA;
|
|
|
|
ASSERTMSGLINE(1447, m, "MTXRotRad(): NULL MtxPtr 'm' ");
|
|
sinA = sinf(rad);
|
|
cosA = cosf(rad);
|
|
C_MTXRotTrig(m, axis, sinA, cosA);
|
|
}
|
|
|
|
void C_MTXScale(Mtx m, f32 xS, f32 yS, f32 zS) {
|
|
ASSERTMSGLINE(2008, m, "MTXScale(): NULL MtxPtr 'm' ");
|
|
m[0][0] = xS;
|
|
m[0][1] = 0;
|
|
m[0][2] = 0;
|
|
m[0][3] = 0;
|
|
m[1][0] = 0;
|
|
m[1][1] = yS;
|
|
m[1][2] = 0;
|
|
m[1][3] = 0;
|
|
m[2][0] = 0;
|
|
m[2][1] = 0;
|
|
m[2][2] = zS;
|
|
m[2][3] = 0;
|
|
}
|
|
|
|
void C_MTXScaleApply(const Mtx src, Mtx dst, f32 xS, f32 yS, f32 zS) {
|
|
ASSERTMSGLINE(2070, src, "MTXScaleApply(): NULL MtxPtr 'src' ");
|
|
ASSERTMSGLINE(2071, dst, "MTXScaleApply(): NULL MtxPtr 'dst' ");
|
|
dst[0][0] = (src[0][0] * xS);
|
|
dst[0][1] = (src[0][1] * xS);
|
|
dst[0][2] = (src[0][2] * xS);
|
|
dst[0][3] = (src[0][3] * xS);
|
|
dst[1][0] = (src[1][0] * yS);
|
|
dst[1][1] = (src[1][1] * yS);
|
|
dst[1][2] = (src[1][2] * yS);
|
|
dst[1][3] = (src[1][3] * yS);
|
|
dst[2][0] = (src[2][0] * zS);
|
|
dst[2][1] = (src[2][1] * zS);
|
|
dst[2][2] = (src[2][2] * zS);
|
|
dst[2][3] = (src[2][3] * zS);
|
|
}
|
|
|
|
void C_MTXTransApply(const Mtx src, Mtx dst, f32 xT, f32 yT, f32 zT) {
|
|
ASSERTMSGLINE(1933, src, "MTXTransApply(): NULL MtxPtr 'src' ");
|
|
ASSERTMSGLINE(1934, dst, "MTXTransApply(): NULL MtxPtr 'src' "); //! wrong assert string
|
|
|
|
if (src != dst) {
|
|
dst[0][0] = src[0][0];
|
|
dst[0][1] = src[0][1];
|
|
dst[0][2] = src[0][2];
|
|
dst[1][0] = src[1][0];
|
|
dst[1][1] = src[1][1];
|
|
dst[1][2] = src[1][2];
|
|
dst[2][0] = src[2][0];
|
|
dst[2][1] = src[2][1];
|
|
dst[2][2] = src[2][2];
|
|
}
|
|
|
|
dst[0][3] = (src[0][3] + xT);
|
|
dst[1][3] = (src[1][3] + yT);
|
|
dst[2][3] = (src[2][3] + zT);
|
|
}
|
|
|
|
void C_MTXRotTrig(Mtx m, char axis, f32 sinA, f32 cosA) {
|
|
ASSERTMSGLINE(1502, m, "MTXRotTrig(): NULL MtxPtr 'm' ");
|
|
switch(axis) {
|
|
case 'x':
|
|
case 'X':
|
|
m[0][0] = 1;
|
|
m[0][1] = 0;
|
|
m[0][2] = 0;
|
|
m[0][3] = 0;
|
|
m[1][0] = 0;
|
|
m[1][1] = cosA;
|
|
m[1][2] = -sinA;
|
|
m[1][3] = 0;
|
|
m[2][0] = 0;
|
|
m[2][1] = sinA;
|
|
m[2][2] = cosA;
|
|
m[2][3] = 0;
|
|
break;
|
|
case 'y':
|
|
case 'Y':
|
|
m[0][0] = cosA;
|
|
m[0][1] = 0;
|
|
m[0][2] = sinA;
|
|
m[0][3] = 0;
|
|
m[1][0] = 0;
|
|
m[1][1] = 1;
|
|
m[1][2] = 0;
|
|
m[1][3] = 0;
|
|
m[2][0] = -sinA;
|
|
m[2][1] = 0;
|
|
m[2][2] = cosA;
|
|
m[2][3] = 0;
|
|
break;
|
|
case 'z':
|
|
case 'Z':
|
|
m[0][0] = cosA;
|
|
m[0][1] = -sinA;
|
|
m[0][2] = 0;
|
|
m[0][3] = 0;
|
|
m[1][0] = sinA;
|
|
m[1][1] = cosA;
|
|
m[1][2] = 0;
|
|
m[1][3] = 0;
|
|
m[2][0] = 0;
|
|
m[2][1] = 0;
|
|
m[2][2] = 1;
|
|
m[2][3] = 0;
|
|
break;
|
|
default:
|
|
ASSERTMSGLINE(1529, FALSE, "MTXRotTrig(): invalid 'axis' value ");
|
|
break;
|
|
}
|
|
}
|
|
|
|
void C_VECAdd(const Vec* a, const Vec* b, Vec* ab) {
|
|
ASSERTMSGLINE(114, a, "VECAdd(): NULL VecPtr 'a' ");
|
|
ASSERTMSGLINE(115, b, "VECAdd(): NULL VecPtr 'b' ");
|
|
ASSERTMSGLINE(116, ab, "VECAdd(): NULL VecPtr 'ab' ");
|
|
ab->x = a->x + b->x;
|
|
ab->y = a->y + b->y;
|
|
ab->z = a->z + b->z;
|
|
}
|
|
|
|
// MTX QUAT
|
|
|
|
void C_QUATMultiply(const Quaternion* p, const Quaternion* q, Quaternion* pq) {
|
|
Quaternion* r;
|
|
Quaternion pqTmp;
|
|
|
|
ASSERTMSGLINE(193, p, "QUATMultiply(): NULL QuaternionPtr 'p' ");
|
|
ASSERTMSGLINE(194, q, "QUATMultiply(): NULL QuaternionPtr 'q' ");
|
|
ASSERTMSGLINE(195, pq, "QUATMultiply(): NULL QuaternionPtr 'pq' ");
|
|
|
|
if (p == pq || q == pq){
|
|
r = &pqTmp;
|
|
} else {
|
|
r = pq;
|
|
}
|
|
|
|
r->w = (p->w * q->w) - (p->x * q->x) - (p->y * q->y) - (p->z * q->z);
|
|
r->x = (p->w * q->x) + (p->x * q->w) + (p->y * q->z) - (p->z * q->y);
|
|
r->y = (p->w * q->y) + (p->y * q->w) + (p->z * q->x) - (p->x * q->z);
|
|
r->z = (p->w * q->z) + (p->z * q->w) + (p->x * q->y) - (p->y * q->x);
|
|
|
|
if (r == &pqTmp) {
|
|
*pq = pqTmp;
|
|
}
|
|
}
|
|
|
|
void C_QUATRotAxisRad(Quaternion* r, const Vec* axis, f32 rad) {
|
|
f32 half, sh, ch;
|
|
Vec nAxis;
|
|
|
|
ASSERTMSGLINE(758, r, "QUATRotAxisRad(): NULL QuaternionPtr 'r' ");
|
|
ASSERTMSGLINE(759, axis, "QUATRotAxisRad(): NULL VecPtr 'axis' ");
|
|
|
|
VECNormalize(axis, &nAxis);
|
|
|
|
half = rad * 0.5f;
|
|
sh = sinf(half);
|
|
ch = cosf(half);
|
|
|
|
r->x = sh * nAxis.x;
|
|
r->y = sh * nAxis.y;
|
|
r->z = sh * nAxis.z;
|
|
r->w = ch;
|
|
}
|
|
|
|
void C_QUATSlerp(const Quaternion* p, const Quaternion* q, Quaternion* r, f32 t) {
|
|
f32 theta, sin_th, cos_th;
|
|
f32 tp, tq;
|
|
|
|
ASSERTMSGLINE(869, p, "QUATSlerp(): NULL QuaternionPtr 'p' ");
|
|
ASSERTMSGLINE(870, q, "QUATSlerp(): NULL QuaternionPtr 'q' ");
|
|
ASSERTMSGLINE(871, r, "QUATSlerp(): NULL QuaternionPtr 'r' ");
|
|
|
|
cos_th = p->x * q->x + p->y * q->y + p->z * q->z + p->w * q->w;
|
|
tq = 1.0f;
|
|
|
|
if (cos_th < 0.0f) {
|
|
cos_th = -cos_th;
|
|
tq = -tq;
|
|
}
|
|
|
|
if (cos_th <= 0.99999f) {
|
|
theta = acosf(cos_th);
|
|
sin_th = sinf(theta);
|
|
|
|
tp = sinf((1.0f - t) * theta) / sin_th;
|
|
tq *= sinf(t * theta) / sin_th;
|
|
} else {
|
|
tp = 1.0f - t;
|
|
tq *= t;
|
|
}
|
|
|
|
r->x = (tp * p->x) + (tq * q->x);
|
|
r->y = (tp * p->y) + (tq * q->y);
|
|
r->z = (tp * p->z) + (tq * q->z);
|
|
r->w = (tp * p->w) + (tq * q->w);
|
|
}
|
|
|
|
void C_VECHalfAngle(const Vec* a, const Vec* b, Vec* half) {
|
|
Vec aTmp;
|
|
Vec bTmp;
|
|
Vec hTmp;
|
|
|
|
ASSERTMSGLINE(713, a, "VECHalfAngle(): NULL VecPtr 'a' ");
|
|
ASSERTMSGLINE(714, b, "VECHalfAngle(): NULL VecPtr 'b' ");
|
|
ASSERTMSGLINE(715, half, "VECHalfAngle(): NULL VecPtr 'half' ");
|
|
|
|
aTmp.x = -a->x;
|
|
aTmp.y = -a->y;
|
|
aTmp.z = -a->z;
|
|
bTmp.x = -b->x;
|
|
bTmp.y = -b->y;
|
|
bTmp.z = -b->z;
|
|
|
|
VECNormalize(&aTmp, &aTmp);
|
|
VECNormalize(&bTmp, &bTmp);
|
|
VECAdd(&aTmp, &bTmp, &hTmp);
|
|
|
|
if (VECDotProduct(&hTmp, &hTmp) > 0.0f) {
|
|
VECNormalize(&hTmp, half);
|
|
return;
|
|
}
|
|
*half = hTmp;
|
|
}
|
|
|
|
void C_VECNormalize(const Vec* src, Vec* unit) {
|
|
f32 mag;
|
|
|
|
ASSERTMSGLINE(321, src, "VECNormalize(): NULL VecPtr 'src' ");
|
|
ASSERTMSGLINE(322, unit, "VECNormalize(): NULL VecPtr 'unit' ");
|
|
|
|
mag = (src->z * src->z) + ((src->x * src->x) + (src->y * src->y));
|
|
ASSERTMSGLINE(327, 0.0f != mag, "VECNormalize(): zero magnitude vector ");
|
|
|
|
mag = 1.0f/ sqrtf(mag);
|
|
unit->x = src->x * mag;
|
|
unit->y = src->y * mag;
|
|
unit->z = src->z * mag;
|
|
}
|
|
|
|
void C_VECReflect(const Vec* src, const Vec* normal, Vec* dst) {
|
|
f32 cosA;
|
|
Vec uI;
|
|
Vec uN;
|
|
|
|
ASSERTMSGLINE(769, src, "VECReflect(): NULL VecPtr 'src' ");
|
|
ASSERTMSGLINE(770, normal, "VECReflect(): NULL VecPtr 'normal' ");
|
|
ASSERTMSGLINE(771, dst, "VECReflect(): NULL VecPtr 'dst' ");
|
|
|
|
uI.x = -src->x;
|
|
uI.y = -src->y;
|
|
uI.z = -src->z;
|
|
|
|
VECNormalize(&uI, &uI);
|
|
VECNormalize(normal, &uN);
|
|
|
|
cosA = VECDotProduct(&uI, &uN);
|
|
dst->x = (2.0f * uN.x * cosA) - uI.x;
|
|
dst->y = (2.0f * uN.y * cosA) - uI.y;
|
|
dst->z = (2.0f * uN.z * cosA) - uI.z;
|
|
VECNormalize(dst, dst);
|
|
}
|
|
|
|
u32 C_MTXInverse(const Mtx src, Mtx inv) {
|
|
Mtx mTmp;
|
|
MtxPtr m;
|
|
f32 det;
|
|
|
|
ASSERTMSGLINE(950, src, "MTXInverse(): NULL MtxPtr 'src' ");
|
|
ASSERTMSGLINE(951, inv, "MTXInverse(): NULL MtxPtr 'inv' ");
|
|
|
|
if (src == inv) {
|
|
m = mTmp;
|
|
} else {
|
|
m = inv;
|
|
}
|
|
det = ((((src[2][1] * (src[0][2] * src[1][0]))
|
|
+ ((src[2][2] * (src[0][0] * src[1][1]))
|
|
+ (src[2][0] * (src[0][1] * src[1][2]))))
|
|
- (src[0][2] * (src[2][0] * src[1][1])))
|
|
- (src[2][2] * (src[1][0] * src[0][1])))
|
|
- (src[1][2] * (src[0][0] * src[2][1]));
|
|
if (0 == det) {
|
|
return 0;
|
|
}
|
|
det = 1 / det;
|
|
m[0][0] = (det * +((src[1][1] * src[2][2]) - (src[2][1] * src[1][2])));
|
|
m[0][1] = (det * -((src[0][1] * src[2][2]) - (src[2][1] * src[0][2])));
|
|
m[0][2] = (det * +((src[0][1] * src[1][2]) - (src[1][1] * src[0][2])));
|
|
|
|
m[1][0] = (det * -((src[1][0] * src[2][2]) - (src[2][0] * src[1][2])));
|
|
m[1][1] = (det * +((src[0][0] * src[2][2]) - (src[2][0] * src[0][2])));
|
|
m[1][2] = (det * -((src[0][0] * src[1][2]) - (src[1][0] * src[0][2])));
|
|
|
|
m[2][0] = (det * +((src[1][0] * src[2][1]) - (src[2][0] * src[1][1])));
|
|
m[2][1] = (det * -((src[0][0] * src[2][1]) - (src[2][0] * src[0][1])));
|
|
m[2][2] = (det * +((src[0][0] * src[1][1]) - (src[1][0] * src[0][1])));
|
|
|
|
m[0][3] = ((-m[0][0] * src[0][3]) - (m[0][1] * src[1][3])) - (m[0][2] * src[2][3]);
|
|
m[1][3] = ((-m[1][0] * src[0][3]) - (m[1][1] * src[1][3])) - (m[1][2] * src[2][3]);
|
|
m[2][3] = ((-m[2][0] * src[0][3]) - (m[2][1] * src[1][3])) - (m[2][2] * src[2][3]);
|
|
|
|
if (m == mTmp) {
|
|
C_MTXCopy(mTmp, inv);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
void C_MTXConcatArray(const Mtx a, const Mtx* srcBase, Mtx* dstBase, u32 count) {
|
|
u32 i;
|
|
|
|
ASSERTMSGLINE(580, a != 0, "MTXConcatArray(): NULL MtxPtr 'a' ");
|
|
ASSERTMSGLINE(581, srcBase != 0, "MTXConcatArray(): NULL MtxPtr 'srcBase' ");
|
|
ASSERTMSGLINE(582, dstBase != 0, "MTXConcatArray(): NULL MtxPtr 'dstBase' ");
|
|
ASSERTMSGLINE(583, count > 1, "MTXConcatArray(): count must be greater than 1.");
|
|
|
|
for (i = 0; i < count; i++) {
|
|
C_MTXConcat(a, *srcBase, *dstBase);
|
|
srcBase++;
|
|
dstBase++;
|
|
}
|
|
}
|
|
|
|
void C_MTXMultVecArray(const Mtx m, const Vec* srcBase, Vec* dstBase, u32 count) {
|
|
u32 i;
|
|
Vec vTmp;
|
|
|
|
ASSERTMSGLINE(168, m, "MTXMultVecArray(): NULL MtxPtr 'm' ");
|
|
ASSERTMSGLINE(169, srcBase, "MTXMultVecArray(): NULL VecPtr 'srcBase' ");
|
|
ASSERTMSGLINE(170, dstBase, "MTXMultVecArray(): NULL VecPtr 'dstBase' ");
|
|
ASSERTMSGLINE(171, count > 1, "MTXMultVecArray(): count must be greater than 1.");
|
|
|
|
for(i = 0; i < count; i++) {
|
|
vTmp.x = m[0][3] + ((m[0][2] * srcBase->z) + ((m[0][0] * srcBase->x) + (m[0][1] * srcBase->y)));
|
|
vTmp.y = m[1][3] + ((m[1][2] * srcBase->z) + ((m[1][0] * srcBase->x) + (m[1][1] * srcBase->y)));
|
|
vTmp.z = m[2][3] + ((m[2][2] * srcBase->z) + ((m[2][0] * srcBase->x) + (m[2][1] * srcBase->y)));
|
|
dstBase->x = vTmp.x;
|
|
dstBase->y = vTmp.y;
|
|
dstBase->z = vTmp.z;
|
|
srcBase++;
|
|
dstBase++;
|
|
}
|
|
}
|
|
|
|
void C_MTXMultVecArraySR(const Mtx m, const Vec* srcBase, Vec* dstBase, u32 count) {
|
|
u32 i;
|
|
Vec vTmp;
|
|
|
|
ASSERTMSGLINE(410, m, "MTXMultVecArraySR(): NULL MtxPtr 'm' ");
|
|
ASSERTMSGLINE(411, srcBase, "MTXMultVecArraySR(): NULL VecPtr 'srcBase' ");
|
|
ASSERTMSGLINE(412, dstBase, "MTXMultVecArraySR(): NULL VecPtr 'dstBase' ");
|
|
ASSERTMSGLINE(413, count > 1, "MTXMultVecArraySR(): count must be greater than 1.");
|
|
|
|
for(i = 0; i < count; i++) {
|
|
vTmp.x = (m[0][2] * srcBase->z) + ((m[0][0] * srcBase->x) + (m[0][1] * srcBase->y));
|
|
vTmp.y = (m[1][2] * srcBase->z) + ((m[1][0] * srcBase->x) + (m[1][1] * srcBase->y));
|
|
vTmp.z = (m[2][2] * srcBase->z) + ((m[2][0] * srcBase->x) + (m[2][1] * srcBase->y));
|
|
dstBase->x = vTmp.x;
|
|
dstBase->y = vTmp.y;
|
|
dstBase->z = vTmp.z;
|
|
srcBase++;
|
|
dstBase++;
|
|
}
|
|
}
|
|
|
|
void C_MTXQuat(Mtx m, const Quaternion* q) {
|
|
f32 s;
|
|
f32 xs;
|
|
f32 ys;
|
|
f32 zs;
|
|
f32 wx;
|
|
f32 wy;
|
|
f32 wz;
|
|
f32 xx;
|
|
f32 xy;
|
|
f32 xz;
|
|
f32 yy;
|
|
f32 yz;
|
|
f32 zz;
|
|
|
|
ASSERTMSGLINE(2145, m, "MTXQuat(): NULL MtxPtr 'm' ");
|
|
ASSERTMSGLINE(2146, q, "MTXQuat(): NULL QuaternionPtr 'q' ");
|
|
ASSERTMSGLINE(2147, q->x || q->y || q->z || q->w, "MTXQuat(): zero-value quaternion ");
|
|
s = 2 / ((q->w * q->w) + ((q->z * q->z) + ((q->x * q->x) + (q->y * q->y))));
|
|
xs = q->x * s;
|
|
ys = q->y * s;
|
|
zs = q->z * s;
|
|
wx = q->w * xs;
|
|
wy = q->w * ys;
|
|
wz = q->w * zs;
|
|
xx = q->x * xs;
|
|
xy = q->x * ys;
|
|
xz = q->x * zs;
|
|
yy = q->y * ys;
|
|
yz = q->y * zs;
|
|
zz = q->z * zs;
|
|
m[0][0] = (1 - (yy + zz));
|
|
m[0][1] = (xy - wz);
|
|
m[0][2] = (xz + wy);
|
|
m[0][3] = 0;
|
|
m[1][0] = (xy + wz);
|
|
m[1][1] = (1 - (xx + zz));
|
|
m[1][2] = (yz - wx);
|
|
m[1][3] = 0;
|
|
m[2][0] = (xz - wy);
|
|
m[2][1] = (yz + wx);
|
|
m[2][2] = (1 - (xx + yy));
|
|
m[2][3] = 0;
|
|
}
|
|
void C_MTXRotAxisRad(Mtx m, const Vec* axis, f32 rad) {
|
|
Vec vN;
|
|
f32 s;
|
|
f32 c;
|
|
f32 t;
|
|
f32 x;
|
|
f32 y;
|
|
f32 z;
|
|
f32 xSq;
|
|
f32 ySq;
|
|
f32 zSq;
|
|
|
|
ASSERTMSGLINE(1677, m, "MTXRotAxisRad(): NULL MtxPtr 'm' ");
|
|
ASSERTMSGLINE(1678, axis, "MTXRotAxisRad(): NULL VecPtr 'axis' ");
|
|
|
|
s = sinf(rad);
|
|
c = cosf(rad);
|
|
t = 1 - c;
|
|
C_VECNormalize(axis, &vN);
|
|
x = vN.x;
|
|
y = vN.y;
|
|
z = vN.z;
|
|
xSq = (x * x);
|
|
ySq = (y * y);
|
|
zSq = (z * z);
|
|
m[0][0] = (c + (t * xSq));
|
|
m[0][1] = (y * (t * x)) - (s * z);
|
|
m[0][2] = (z * (t * x)) + (s * y);
|
|
m[0][3] = 0;
|
|
m[1][0] = ((y * (t * x)) + (s * z));
|
|
m[1][1] = (c + (t * ySq));
|
|
m[1][2] = ((z * (t * y)) - (s * x));
|
|
m[1][3] = 0;
|
|
m[2][0] = ((z * (t * x)) - (s * y));
|
|
m[2][1] = ((z * (t * y)) + (s * x));
|
|
m[2][2] = (c + (t * zSq));
|
|
m[2][3] = 0;
|
|
}
|
|
|
|
// VEC
|
|
void C_VECCrossProduct(const Vec* a, const Vec* b, Vec* axb) {
|
|
Vec vTmp;
|
|
|
|
ASSERTMSGLINE(608, a, "VECCrossProduct(): NULL VecPtr 'a' ");
|
|
ASSERTMSGLINE(609, b, "VECCrossProduct(): NULL VecPtr 'b' ");
|
|
ASSERTMSGLINE(610, axb, "VECCrossProduct(): NULL VecPtr 'axb' ");
|
|
|
|
vTmp.x = (a->y * b->z) - (a->z * b->y);
|
|
vTmp.y = (a->z * b->x) - (a->x * b->z);
|
|
vTmp.z = (a->x * b->y) - (a->y * b->x);
|
|
axb->x = vTmp.x;
|
|
axb->y = vTmp.y;
|
|
axb->z = vTmp.z;
|
|
}
|
|
|
|
f32 C_VECDistance(const Vec* a, const Vec* b) {
|
|
return sqrtf(C_VECSquareDistance(a, b));
|
|
}
|
|
|
|
f32 C_VECDotProduct(const Vec* a, const Vec* b) {
|
|
f32 dot;
|
|
|
|
ASSERTMSGLINE(546, a, "VECDotProduct(): NULL VecPtr 'a' ");
|
|
ASSERTMSGLINE(547, b, "VECDotProduct(): NULL VecPtr 'b' ");
|
|
dot = (a->z * b->z) + ((a->x * b->x) + (a->y * b->y));
|
|
return dot;
|
|
}
|
|
|
|
f32 C_VECMag(const Vec* v) {
|
|
return sqrtf(C_VECSquareMag(v));
|
|
}
|
|
|
|
void C_VECScale(const Vec* src, Vec* dst, f32 scale) {
|
|
ASSERTMSGLINE(253, src, "VECScale(): NULL VecPtr 'src' ");
|
|
ASSERTMSGLINE(254, dst, "VECScale(): NULL VecPtr 'dst' ");
|
|
dst->x = (src->x * scale);
|
|
dst->y = (src->y * scale);
|
|
dst->z = (src->z * scale);
|
|
}
|
|
|
|
f32 C_VECSquareDistance(const Vec* a, const Vec* b) {
|
|
Vec diff;
|
|
|
|
diff.x = a->x - b->x;
|
|
diff.y = a->y - b->y;
|
|
diff.z = a->z - b->z;
|
|
return (diff.z * diff.z) + ((diff.x * diff.x) + (diff.y * diff.y));
|
|
}
|
|
|
|
f32 C_VECSquareMag(const Vec* v) {
|
|
f32 sqmag;
|
|
|
|
ASSERTMSGLINE(411, v, "VECMag(): NULL VecPtr 'v' ");
|
|
|
|
sqmag = v->z * v->z + ((v->x * v->x) + (v->y * v->y));
|
|
return sqmag;
|
|
}
|
|
|
|
void C_VECSubtract(const Vec* a, const Vec* b, Vec* a_b) {
|
|
ASSERTMSGLINE(183, a, "VECSubtract(): NULL VecPtr 'a' ");
|
|
ASSERTMSGLINE(184, b, "VECSubtract(): NULL VecPtr 'b' ");
|
|
ASSERTMSGLINE(185, a_b, "VECSubtract(): NULL VecPtr 'a_b' ");
|
|
a_b->x = a->x - b->x;
|
|
a_b->y = a->y - b->y;
|
|
a_b->z = a->z - b->z;
|
|
}
|
|
|
|
#pragma mark PSMTX
|
|
// I think these are PPC ASM implemntations?
|
|
// this can be done just with defining DEBUG, but that has some other
|
|
// implecations, so we'll just define them here for now. These are all just wrappers around the C versions, so we can just call those directly.
|
|
void PSMTXConcatArray(const __REGISTER Mtx a, const __REGISTER Mtx* srcBase, __REGISTER Mtx* dstBase, __REGISTER u32 count) {
|
|
C_MTXConcatArray(a, srcBase, dstBase, count);
|
|
}
|
|
void PSMTXCopy(const __REGISTER Mtx src, __REGISTER Mtx dst) {
|
|
C_MTXCopy(src, dst);
|
|
}
|
|
void PSMTXIdentity(__REGISTER Mtx m) {
|
|
C_MTXIdentity(m);
|
|
}
|
|
u32 PSMTXInverse(const __REGISTER Mtx src, __REGISTER Mtx inv) {
|
|
return C_MTXInverse(src, inv);
|
|
}
|
|
void PSMTXMultVec(const __REGISTER Mtx m, const __REGISTER Vec* src, __REGISTER Vec* dst) {
|
|
C_MTXMultVec(m, src, dst);
|
|
}
|
|
void PSMTXConcat(const __REGISTER Mtx a, const __REGISTER Mtx b, __REGISTER Mtx ab) {
|
|
C_MTXConcat(a, b, ab);
|
|
}
|
|
void PSMTXMultVecArray(const Mtx m, const Vec* srcBase, Vec* dstBase, u32 count) {
|
|
C_MTXMultVecArray(m, srcBase, dstBase, count);
|
|
}
|
|
void PSMTXMultVecArraySR(const __REGISTER Mtx m, const __REGISTER Vec* srcBase, __REGISTER Vec* dstBase, __REGISTER u32 count) {
|
|
C_MTXMultVecArraySR(m, srcBase, dstBase, count);
|
|
}
|
|
void PSMTXMultVecSR(const __REGISTER Mtx m, const __REGISTER Vec* src, __REGISTER Vec* dst) {
|
|
C_MTXMultVecSR(m, src, dst);
|
|
}
|
|
void PSMTXQuat(__REGISTER Mtx m, const __REGISTER Quaternion* q) {
|
|
C_MTXQuat(m, q);
|
|
}
|
|
void PSMTXRotAxisRad(Mtx m, const Vec* axis, f32 rad) {
|
|
C_MTXRotAxisRad(m, axis, rad);
|
|
}
|
|
void PSMTXRotRad(Mtx m, char axis, f32 rad) {
|
|
C_MTXRotRad(m, axis, rad);
|
|
}
|
|
void PSMTXScale(__REGISTER Mtx m, __REGISTER f32 xS, __REGISTER f32 yS, __REGISTER f32 zS) {
|
|
C_MTXScale(m, xS, yS, zS);
|
|
}
|
|
void PSMTXScaleApply(const __REGISTER Mtx src, __REGISTER Mtx dst, __REGISTER f32 xS, __REGISTER f32 yS, __REGISTER f32 zS) {
|
|
C_MTXScaleApply(src, dst, xS, yS, zS);
|
|
}
|
|
void PSMTXTrans(__REGISTER Mtx m, __REGISTER f32 xT, __REGISTER f32 yT, __REGISTER f32 zT) {
|
|
C_MTXTrans(m, xT, yT, zT);
|
|
}
|
|
void PSMTXTransApply(const __REGISTER Mtx src, __REGISTER Mtx dst, __REGISTER f32 xT, __REGISTER f32 yT, __REGISTER f32 zT) {
|
|
C_MTXTransApply(src, dst, xT, yT, zT);
|
|
}
|
|
void PSQUATMultiply(const __REGISTER Quaternion* p, const __REGISTER Quaternion* q, __REGISTER Quaternion* pq) {
|
|
C_QUATMultiply(p, q, pq);
|
|
}
|
|
void PSVECAdd(const __REGISTER Vec* a, const __REGISTER Vec* b, __REGISTER Vec* ab) {
|
|
C_VECAdd(a, b, ab);
|
|
}
|
|
void PSVECCrossProduct(const __REGISTER Vec* a, const __REGISTER Vec* b, __REGISTER Vec* axb) {
|
|
C_VECCrossProduct(a, b, axb);
|
|
}
|
|
f32 PSVECDistance(const __REGISTER Vec* a, const __REGISTER Vec* b) {
|
|
return C_VECDistance(a, b);
|
|
}
|
|
f32 PSVECDotProduct(const __REGISTER Vec* a, const __REGISTER Vec* b) {
|
|
return C_VECDotProduct(a, b);
|
|
}
|
|
f32 PSVECMag(const __REGISTER Vec* v) {
|
|
return C_VECMag(v);
|
|
}
|
|
void PSVECNormalize(const __REGISTER Vec* src, __REGISTER Vec* unit) {
|
|
C_VECNormalize(src, unit);
|
|
}
|
|
void PSVECScale(const __REGISTER Vec* src, __REGISTER Vec* dst, __REGISTER f32 scale) {
|
|
C_VECScale(src, dst, scale);
|
|
}
|
|
f32 PSVECSquareDistance(const __REGISTER Vec* a, const __REGISTER Vec* b) {
|
|
return C_VECSquareDistance(a, b);
|
|
}
|
|
f32 PSVECSquareMag(const __REGISTER Vec* v) {
|
|
return C_VECSquareMag(v);
|
|
}
|
|
void PSVECSubtract(const __REGISTER Vec* a, const __REGISTER Vec* b, __REGISTER Vec* a_b) {
|
|
C_VECSubtract(a, b, a_b);
|
|
}
|