void plAnimPath::ICalcBounds() { if( !fController ) return; plController* pc = fController->GetPosController(); int i; hsPoint3 pos; hsTArray<float> keyTimes; pc->GetKeyTimes(keyTimes); fCenter.Set(0,0,0); for( i = 0; i < keyTimes.GetCount() ; i++ ) { pc->Interp(keyTimes[i], &pos); fCenter += pos; } fCenter *= hsInvert((float)keyTimes.GetCount()); fRadius = 0; for( i = 0; i < keyTimes.GetCount(); i++ ) { pc->Interp(keyTimes[i], &pos); float rad = (pos - fCenter).Magnitude(); if( rad > fRadius ) fRadius = rad; } }
void plViewTransform::ISetCameraToNDC() const { fCameraToNDC.Reset(); fCameraToNDC.NotIdentity(); if( GetOrthogonal() ) { hsPoint3 worldSizeInv; worldSizeInv.fX = hsInvert( fMax.fX - fMin.fX ) * 2.f; worldSizeInv.fY = hsInvert( fMax.fY - fMin.fY ) * 2.f; worldSizeInv.fZ = hsInvert( fMax.fZ - fMin.fZ ); fCameraToNDC.fMap[0][0] = worldSizeInv.fX; fCameraToNDC.fMap[0][3] = -fMin.fX * worldSizeInv.fX - 1.f; fCameraToNDC.fMap[1][1] = worldSizeInv.fY; fCameraToNDC.fMap[1][3] = -fMin.fY * worldSizeInv.fY - 1.f; // Map Screen Z to range 0 (at hither) to 1 (at yon) fCameraToNDC.fMap[2][2] = worldSizeInv.fZ; fCameraToNDC.fMap[2][3] = -fMin.fZ * worldSizeInv.fZ; } else { fCameraToNDC.fMap[0][0] = 2.f / (fMax.fX - fMin.fX); fCameraToNDC.fMap[0][2] = (fMax.fX + fMin.fX) / (fMax.fX - fMin.fX); fCameraToNDC.fMap[1][1] = 2.f / (fMax.fY - fMin.fY); fCameraToNDC.fMap[1][2] = (fMax.fY + fMin.fY) / (fMax.fY - fMin.fY); fCameraToNDC.fMap[2][2] = fMax.fZ / (fMax.fZ - fMin.fZ); fCameraToNDC.fMap[2][3] = -fMax.fZ * fMin.fZ / (fMax.fZ - fMin.fZ); fCameraToNDC.fMap[3][2] = 1.f; fCameraToNDC.fMap[3][3] = 0.f; } ISetFlag(kCameraToNDCSet); }
hsMatrix44* hsMatrix44::GetInverse(hsMatrix44* inverse) const { float det = GetDeterminant(); int i,j; if (det == 0.0f) { inverse->Reset(); return inverse; } det = hsInvert(det); GetAdjoint(inverse); for (i=0; i<4; i++) for (j=0; j<4; j++) inverse->fMap[i][j] *= det; return inverse; }
void hsAffineParts::ComposeInverseMatrix(hsMatrix44 *out) const { plProfile_BeginTiming(Compose); #ifndef PL_OPTIMIZE_COMPOSE // Built U matrix hsMatrix44 U; fU.Conjugate().MakeMatrix(&U); // Build scale factor matrix hsMatrix44 K; hsVector3 invK; invK.Set(hsInvert(fK.fX),hsInvert(fK.fY),hsInvert(fK.fZ)); K.MakeScaleMat(&invK); // Build Utranspose matrix hsMatrix44 Utp; U.GetTranspose(&Utp); // Build R matrix hsMatrix44 R; fQ.Conjugate().MakeMatrix(&R); // Build flip matrix // hsAssert(fF == 1.0 || fF == -1.0, "Invalid flip portion of affine parts"); hsMatrix44 F; if (fF==-1.0) { hsVector3 s; s.Set(-1,-1,-1); F.MakeScaleMat(&s); } else F.Reset(); // Build translate matrix hsMatrix44 T; T.MakeTranslateMat(&-fT); // // Concat mats // *out = Utp * K; *out = (*out) * U; *out = (*out) * R; *out = (*out) * F; *out = (*out) * T; #else // PL_OPTIMIZE_COMPOSE // Same kind of thing here, except now M = Ut K U R F T // and again // T = |1 0 0 Tx| // |0 1 0 Ty| // |0 0 1 Tz| // F = |f 0 0 0| // |0 f 0 0| // |0 0 f 0|, where f is either 1 or -1 // R = |R00 R01 R02 0| // |R10 R11 R12 0| // |R20 R21 R22 0| // U = |U00 U01 U02 0| // |U10 U11 U12 0| // |U20 U21 U22 0| // K = |Sx 0 0 0| // |0 Sy 0 0| // |0 0 Sz 0| // Ut = |U00 U10 U20 0| // |U01 U11 U21 0| // |U02 U12 U22 0|, where Uij is from matrix U // // So, Ut * K = // |U00*Sx U10*Sy U20*Sz 0| // |U01*Sx U11*Sy U21*Sz 0| // |U02*Sx U12*Sy U22*Sz 0| // // (Ut * K) * U = UK = // |Ut0*S dot Ut0 Ut0*S dot Ut1 Ut0*S dot Ut2 0| // |Ut1*S dot Ut0 Ut1*S dot Ut1 Ut1*S dot Ut2 0| // |Ut2*S dot Ut0 Ut2*S dot Ut1 Ut2*S dot Ut2 0| // // (((Ut * K) * U) * R)[i][j] = UK[i] dot Rc[j] // // Again we'll stuff the flip into the scale. // // Now, because the T is on the other end of the concat (closest // to the vertex), we can't just stuff it in. If Mr is the // rotation part of the final matrix (Ut * K * U * R * F), then // the translation components M[i][3] = Mr[i] dot T. // // hsVector3 Ut[3]; QuatTo3VectorsTranspose(fU.Conjugate(), Ut); int i, j; hsVector3 invK; invK.Set(hsInvert(fK.fX),hsInvert(fK.fY),hsInvert(fK.fZ)); hsVector3 UK[3]; for( i = 0; i < 3; i++ ) { for( j = 0; j < 3; j++ ) { // SUt[i] = (Ut[i].fX * invK.fX, Ut[i].fY * invK.fY, Ut[i].fZ * invK.fZ) // So SUt[i].InnerProduct(Ut[j]) == // Ut[i].fX * invK.fX * Ut[j].fX // + Ut[i].fY * invK.fY * Ut[j].fY // + Ut[i].fZ * invK.fZ * Ut[j].fZ UK[i][j] = Ut[i].fX * invK.fX * Ut[j].fX + Ut[i].fY * invK.fY * Ut[j].fY + Ut[i].fZ * invK.fZ * Ut[j].fZ; } } hsVector3 Rt[3]; QuatTo3VectorsTranspose(fQ.Conjugate(), Rt); float f = fF < 0 ? -1.f : 1.f; for( i = 0; i < 3; i++ ) { for( j = 0; j < 3; j++ ) { out->fMap[i][j] = UK[i].InnerProduct(Rt[j]) * f; } out->fMap[i][3] = -(fT.InnerProduct((hsPoint3*)(&out->fMap[i]))); } out->fMap[3][0] = out->fMap[3][1] = out->fMap[3][2] = 0.f; out->fMap[3][3] = 1.f; out->NotIdentity(); #endif // PL_OPTIMIZE_COMPOSE plProfile_EndTiming(Compose); }