ConcatT:
PUBLIC PROC[xfm1, xfm2: Xfm3d]
RETURNS[xfmOut: Xfm3d] ~{
Multiply 2 4x4 matrices
QuadProd:
PROC[q1, q2: Quad]
RETURNS [
REAL]
~ {
RETURN [q1.x * q2.x + q1.y * q2.y + q1.z * q2.z + q1.w * q2.w]; };
col2x, col2y, col2z, col2w: Quad;
col2x ← [xfm2.a.x, xfm2.b.x, xfm2.c.x, xfm2.d.x];
col2y ← [xfm2.a.y, xfm2.b.y, xfm2.c.y, xfm2.d.y];
col2z ← [xfm2.a.z, xfm2.b.z, xfm2.c.z, xfm2.d.z];
col2w ← [xfm2.a.w, xfm2.b.w, xfm2.c.w, xfm2.d.w];
xfmOut.a.x ← QuadProd[xfm1.a, col2x]; xfmOut.a.y ← QuadProd[xfm1.a, col2y];
xfmOut.a.z ← QuadProd[xfm1.a, col2z]; xfmOut.a.w ← QuadProd[xfm1.a, col2w];
xfmOut.b.x ← QuadProd[xfm1.b, col2x]; xfmOut.b.y ← QuadProd[xfm1.b, col2y];
xfmOut.b.z ← QuadProd[xfm1.b, col2z]; xfmOut.b.w ← QuadProd[xfm1.b, col2w];
xfmOut.c.x ← QuadProd[xfm1.c, col2x]; xfmOut.c.y ← QuadProd[xfm1.c, col2y];
xfmOut.c.z ← QuadProd[xfm1.c, col2z]; xfmOut.c.w ← QuadProd[xfm1.c, col2w];
xfmOut.d.x ← QuadProd[xfm1.d, col2x]; xfmOut.d.y ← QuadProd[xfm1.d, col2y];
xfmOut.d.z ← QuadProd[xfm1.d, col2z]; xfmOut.d.w ← QuadProd[xfm1.d, col2w];
};
Rotate3d:
PUBLIC
PROC[base, axis: Triple, theta:
REAL]
RETURNS[Xfm3d] ~ {
xfm, mtx: Xfm3d ← IdentityXfm;
cosTheta: REAL ← RealFns.CosDeg[theta];
sinTheta: REAL ← RealFns.SinDeg[theta];
xfm.d.x ← -base.x; xfm.d.y ← -base.y; xfm.d.z ← -base.z;
axis ← Normalize[axis];
mtx.a.x ← Sqr[axis.x] + (1.0 - Sqr[axis.x]) * cosTheta;
mtx.b.y ← Sqr[axis.y] + (1.0 - Sqr[axis.y]) * cosTheta;
mtx.c.z ← Sqr[axis.z] + (1.0 - Sqr[axis.z]) * cosTheta;
mtx.b.x ← axis.x * axis.y * (1.0 - cosTheta) + axis.z * sinTheta;
mtx.a.y ← axis.x * axis.y * (1.0 - cosTheta) - axis.z * sinTheta;
mtx.c.x ← axis.x * axis.z * (1.0 - cosTheta) - axis.y * sinTheta;
mtx.a.z ← axis.x * axis.z * (1.0 - cosTheta) + axis.y * sinTheta;
mtx.c.y ← axis.y * axis.z * (1.0 - cosTheta) + axis.x * sinTheta;
mtx.b.z ← axis.y * axis.z * (1.0 - cosTheta) - axis.x * sinTheta;
xfm ← ConcatT[xfm, mtx];
mtx ← IdentityXfm;
mtx.d.x ← base.x; mtx.d.y ← base.y; mtx.d.z ← base.z;
xfm ← ConcatT[xfm, mtx];
RETURN[xfm];
};