//---------------------------------------------------------------------------- void SESphereBV::TransformBy(const SETransformation& rTransform, SEBoundingVolume* pResult) { SESphere3f& rTarget = ((SESphereBV*)pResult)->m_Sphere; rTransform.ApplyForwardToPoint(m_Sphere.Center, rTarget.Center); rTarget.Radius = rTransform.GetNorm() * m_Sphere.Radius; }
//---------------------------------------------------------------------------- void SEBoxBV::TransformBy(const SETransformation& rTransform, SEBoundingVolume* pResult) { SEBox3f& rTarget = ((SEBoxBV*)pResult)->m_Box; rTransform.ApplyForwardToPoint(m_Box.Center, rTarget.Center); for( int i = 0; i < 3; ++i ) { rTarget.Axis[i] = m_Box.Axis[i] * rTransform.GetRotate(); rTarget.Extent[i] = rTransform.GetNorm() * m_Box.Extent[i]; } }
//---------------------------------------------------------------------------- void SEColladaScene::GetInverseBindingTransformation(SETransformation& rDstTransformation, domListOfFloats* pSrcMatrix, int iSrcBase) { // Given a COLLADA homogeneous inverse binding matrix M: // m00 m01 m02 t0 // m10 m11 m12 t1 // m20 m21 m22 t2 // 0 0 0 1 // in column major order. // // Given a Swing Engine homogeneous vector V: // x // y // z // w // in column major order. // // We should construct a homogeneous matrix that could finish the // following operations: // (1) Transform V back to the original DCC right-handed system, // say, V0, by using a homogeneous matrix M0: // // Y_UP: Z_UP: X_UP: // 1 0 0 0 1 0 0 0 0 1 0 0 // 0 1 0 0 0 0 1 0 -1 0 0 0 // 0 0 -1 0 0 1 0 0 0 0 -1 0 // 0 0 0 1 0 0 0 1 0 0 0 1 // in column major order. // // (2) Transform V0 into the COLLADA binding joint's local right- // handed system, say, V1, by using M. // // (3) Transform V1 back to the Swing Engine binding joint's local // left-handed system, say, V2, by using a homogeneous matrix M1: // // Y_UP: Z_UP: X_UP: // 1 0 0 0 1 0 0 0 0 -1 0 0 // 0 1 0 0 0 0 1 0 1 0 0 0 // 0 0 -1 0 0 1 0 0 0 0 -1 0 // 0 0 0 1 0 0 0 1 0 0 0 1 // in column major order. // // The final combination of these three operations will be: // V2 = M1*M*M0*V. // So M1*M*M0 is the matrix we want: // // Y_UP: Z_UP: X_UP: // m00 m01 -m02 t0 m00 m02 m01 t0 m11 -m10 m12 -t1 // m10 m11 -m12 t1 m20 m22 m21 t2 -m01 m00 -m02 t0 // -m20 -m21 m22 -t2 m10 m12 m11 t1 m21 -m20 m22 -t2 // 0 0 0 1 0 0 0 1 0 0 0 1 // in column major order. float fM00, fM01, fM02, fM10, fM11, fM12, fM20, fM21, fM22; float fT0, fT1, fT2; fM00 = (float)(*pSrcMatrix)[iSrcBase ]; fM01 = (float)(*pSrcMatrix)[iSrcBase + 1]; fM02 = (float)(*pSrcMatrix)[iSrcBase + 2]; fM10 = (float)(*pSrcMatrix)[iSrcBase + 4]; fM11 = (float)(*pSrcMatrix)[iSrcBase + 5]; fM12 = (float)(*pSrcMatrix)[iSrcBase + 6]; fM20 = (float)(*pSrcMatrix)[iSrcBase + 8]; fM21 = (float)(*pSrcMatrix)[iSrcBase + 9]; fM22 = (float)(*pSrcMatrix)[iSrcBase + 10]; fT0 = (float)(*pSrcMatrix)[iSrcBase + 3]; fT1 = (float)(*pSrcMatrix)[iSrcBase + 7]; fT2 = (float)(*pSrcMatrix)[iSrcBase + 11]; // MT form is enough for our usage. switch( ms_eOrientationMode ) { case OM_Y_UP: { SEVector3f vec3fRow0(fM00, fM01, -fM02); SEVector3f vec3fRow1(fM10, fM11, -fM12); SEVector3f vec3fRow2(-fM20, -fM21, fM22); SEMatrix3f mat3fM(vec3fRow0, vec3fRow1, vec3fRow2, false); SEVector3f vec3fT(fT0, fT1, -fT2); rDstTransformation.SetMatrix(mat3fM); rDstTransformation.SetTranslate(vec3fT); } break; case OM_Z_UP: { SEVector3f vec3fRow0(fM00, fM02, fM01); SEVector3f vec3fRow1(fM20, fM22, fM21); SEVector3f vec3fRow2(fM10, fM12, fM11); SEMatrix3f mat3fM(vec3fRow0, vec3fRow1, vec3fRow2, false); SEVector3f vec3fT(fT0, fT2, fT1); rDstTransformation.SetMatrix(mat3fM); rDstTransformation.SetTranslate(vec3fT); } break; case OM_X_UP: { SEVector3f vec3fRow0(fM11, -fM10, fM12); SEVector3f vec3fRow1(-fM01, fM00, -fM02); SEVector3f vec3fRow2(fM21, -fM20, fM22); SEMatrix3f mat3fM(vec3fRow0, vec3fRow1, vec3fRow2, false); SEVector3f vec3fT(-fT1, fT0, -fT2); rDstTransformation.SetMatrix(mat3fM); rDstTransformation.SetTranslate(vec3fT); } break; default: SE_ASSERT( false ); break; } }
//---------------------------------------------------------------------------- SETransformation SEColladaTransformation::ToTransformation() { SETransformation tempRes; switch( TransType ) { case TT_SCALE: { // Get the scale data. SEVector3f vec3fScale = SEColladaScene::GetTransformedVector( SRTData[0], SRTData[1], SRTData[2]); // Is this an uniform scale? if( vec3fScale.X == vec3fScale.Y && vec3fScale.Y == vec3fScale.Z ) { tempRes.SetUniformScale(vec3fScale.X); } else { tempRes.SetScale(vec3fScale); } } break; case TT_ROTATE: { // Get the rotation data. SEVector3f vec3fRotAxis = SEColladaScene::GetTransformedVector( SRTData[0], SRTData[1], SRTData[2]); float fRotAngle = -SRTData[3]*SEMath<float>::DEG_TO_RAD; SEMatrix3f mat3fR(vec3fRotAxis, fRotAngle); tempRes.SetRotate(mat3fR); } break; case TT_TRANSLATE: { // Get the transation data. SEVector3f vec3fTrans = SEColladaScene::GetTransformedVector( SRTData[0], SRTData[1], SRTData[2]); tempRes.SetTranslate(vec3fTrans); } break; case TT_MATRIX: // TODO: // Support this transformation. SE_ASSERT( false ); break; case TT_LOOKAT: // TODO: // Support this transformation. SE_ASSERT( false ); break; case TT_SKEW: // TODO: // Support this transformation. SE_ASSERT( false ); break; default: break; } return tempRes; }