void Matrix4::makeInverseTransform(const Vector3& position, const Vector3& scale, const Quaternion& orientation) { Vector3 invTranslate = -position; Vector3 invScale(1 / scale.x, 1 / scale.y, 1 / scale.z); Quaternion invRot = orientation.inverse(); invTranslate *= invScale; invTranslate = invRot.rotate(invTranslate); Matrix3 rot3x3, scale3x3; rot3x3 = invRot.toRotationMatrix(); scale3x3 = Matrix3::ZERO; scale3x3[0][0] = invScale.x; scale3x3[1][1] = invScale.y; scale3x3[2][2] = invScale.z; *this = scale3x3 * rot3x3; this->setTrans(invTranslate); d[3][0] = 0; d[3][1] = 0; d[3][2] = 0; d[3][3] = 1; }
//----------------------------------------------------------------------- void Matrix4::makeInverseTransform(const Vector3& position, const Vector3& scale, const Quaternion& orientation) { // Invert the parameters Vector3 invTranslate = -position; Vector3 invScale(1 / scale.x, 1 / scale.y, 1 / scale.z); Quaternion invRot = orientation.Inverse(); // Because we're inverting, order is translation, rotation, scale // So make translation relative to scale & rotation invTranslate *= invScale; // scale invTranslate = invRot * invTranslate; // rotate // Next, make a 3x3 rotation matrix and apply inverse scale Matrix3 rot3x3, scale3x3; invRot.ToRotationMatrix(rot3x3); scale3x3 = Matrix3::ZERO; scale3x3[0][0] = invScale.x; scale3x3[1][1] = invScale.y; scale3x3[2][2] = invScale.z; // Set up final matrix with scale, rotation and translation *this = scale3x3 * rot3x3; this->setTrans(invTranslate); // No projection term m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1; }
//----------------------------------------------------------------------- void Matrix4::MakeInverseTransform(Vector3 position, Vector3 scale, Quaternion orientation) { // Invert the parameters Vector3 invTranslate = -position; Vector3 invScale(1 / scale.x, 1 / scale.y, 1 / scale.z); Quaternion invRot = orientation.Inverse(); // Because we're inverting, order is translation, rotation, scale // So make translation relative to scale & rotation invTranslate *= invScale; // scale invTranslate = invRot * invTranslate; // rotate // Next, make a 3x3 rotation matrix and apply inverse scale Matrix3^ rot3x3, ^scale3x3; rot3x3 = invRot.ToRotationMatrix(); scale3x3 = Matrix3::ZERO; scale3x3->m00 = invScale.x; scale3x3->m11 = invScale.y; scale3x3->m22 = invScale.z; // Set up final matrix with scale, rotation and translation *this = scale3x3 * rot3x3; this->SetTrans(invTranslate); // No projection term m30 = 0; m31 = 0; m32 = 0; m33 = 1; }
void Matrix3x4::Decompose(Vector3& translation, Quaternion& rotation, Vector3& scale) const { translation.x_ = m03_; translation.y_ = m13_; translation.z_ = m23_; scale.x_ = sqrtf(m00_ * m00_ + m10_ * m10_ + m20_ * m20_); scale.y_ = sqrtf(m01_ * m01_ + m11_ * m11_ + m21_ * m21_); scale.z_ = sqrtf(m02_ * m02_ + m12_ * m12_ + m22_ * m22_); Vector3 invScale(1.0f / scale.x_, 1.0f / scale.y_, 1.0f / scale.z_); rotation = Quaternion(ToMatrix3().Scaled(invScale)); }
void Matrix4::makeInverseTransform(const Vector3& position, const Vector3& scale, const Quaternion& orientation) { Vector3 invTranslate = -position; Vector3 invScale(1 / scale.x, 1 / scale.y, 1 / scale.z); Quaternion invRot = orientation.getInverse(); invTranslate *= invScale; invTranslate = invRot * invTranslate; Matrix3 rot3x3 = invRot.ToRotationMatrix(); m[0][0] = invScale.x * rot3x3[0][0]; m[0][1] = invScale.x * rot3x3[0][1]; m[0][2] = invScale.x * rot3x3[0][2]; m[0][3] = invTranslate.x; m[1][0] = invScale.y * rot3x3[1][0]; m[1][1] = invScale.y * rot3x3[1][1]; m[1][2] = invScale.y * rot3x3[1][2]; m[1][3] = invTranslate.y; m[2][0] = invScale.z * rot3x3[2][0]; m[2][1] = invScale.z * rot3x3[2][1]; m[2][2] = invScale.z * rot3x3[2][2]; m[2][3] = invTranslate.z; m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1; }
void Matrix4::makeInverseTransform(const Vector3& position, const Vector3& scale, const Quaternion& orientation) { // Invert the parameters Vector3 invTranslate = Vector3(-position.x,-position.y,-position.z); Vector3 invScale(1 / scale.x, 1 / scale.y, 1 / scale.z); Quaternion invRot = orientation.inverse(); // Because we're inverting, order is translation, rotation, scale // So make translation relative to scale & rotation invTranslate = invRot * invTranslate; // rotate invTranslate *= invScale; // scale // Next, make a 3x3 rotation matrix Matrix3 rot3x3; invRot.ToRotationMatrix(rot3x3); // Set up final matrix with scale, rotation and translation m[0][0] = invScale.x * rot3x3[0][0]; m[0][1] = invScale.x * rot3x3[0][1]; m[0][2] = invScale.x * rot3x3[0][2]; m[0][3] = invTranslate.x; m[1][0] = invScale.y * rot3x3[1][0]; m[1][1] = invScale.y * rot3x3[1][1]; m[1][2] = invScale.y * rot3x3[1][2]; m[1][3] = invTranslate.y; m[2][0] = invScale.z * rot3x3[2][0]; m[2][1] = invScale.z * rot3x3[2][1]; m[2][2] = invScale.z * rot3x3[2][2]; m[2][3] = invTranslate.z; // No projection term m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1; }
//-------------------------------------- static void m_matF_x_scale_x_planeF_C(const F32* m, const F32* s, const F32* p, F32* presult) { // We take in a matrix, a scale factor, and a plane equation. We want to output // the resultant normal // We have T = m*s // To multiply the normal, we want Inv(Tr(m*s)) // Inv(Tr(ms)) = Inv(Tr(s) * Tr(m)) // = Inv(Tr(m)) * Inv(Tr(s)) // // Inv(Tr(s)) = Inv(s) = [ 1/x 0 0 0] // [ 0 1/y 0 0] // [ 0 0 1/z 0] // [ 0 0 0 1] // // Since m is an affine matrix, // Tr(m) = [ [ ] 0 ] // [ [ R ] 0 ] // [ [ ] 0 ] // [ [ x y z ] 1 ] // // Inv(Tr(m)) = [ [ -1 ] 0 ] // [ [ R ] 0 ] // [ [ ] 0 ] // [ [ A B C ] 1 ] // Where: // // P = (x, y, z) // A = -(Row(0, r) * P); // B = -(Row(1, r) * P); // C = -(Row(2, r) * P); MatrixF invScale(true); F32* pScaleElems = invScale; pScaleElems[MatrixF::idx(0, 0)] = 1.0f / s[0]; pScaleElems[MatrixF::idx(1, 1)] = 1.0f / s[1]; pScaleElems[MatrixF::idx(2, 2)] = 1.0f / s[2]; const Point3F shear( m[MatrixF::idx(3, 0)], m[MatrixF::idx(3, 1)], m[MatrixF::idx(3, 2)] ); const Point3F row0(m[MatrixF::idx(0, 0)], m[MatrixF::idx(0, 1)], m[MatrixF::idx(0, 2)]); const Point3F row1(m[MatrixF::idx(1, 0)], m[MatrixF::idx(1, 1)], m[MatrixF::idx(1, 2)]); const Point3F row2(m[MatrixF::idx(2, 0)], m[MatrixF::idx(2, 1)], m[MatrixF::idx(2, 2)]); const F32 A = -mDot(row0, shear); const F32 B = -mDot(row1, shear); const F32 C = -mDot(row2, shear); MatrixF invTrMatrix(true); F32* destMat = invTrMatrix; destMat[MatrixF::idx(0, 0)] = m[MatrixF::idx(0, 0)]; destMat[MatrixF::idx(1, 0)] = m[MatrixF::idx(1, 0)]; destMat[MatrixF::idx(2, 0)] = m[MatrixF::idx(2, 0)]; destMat[MatrixF::idx(0, 1)] = m[MatrixF::idx(0, 1)]; destMat[MatrixF::idx(1, 1)] = m[MatrixF::idx(1, 1)]; destMat[MatrixF::idx(2, 1)] = m[MatrixF::idx(2, 1)]; destMat[MatrixF::idx(0, 2)] = m[MatrixF::idx(0, 2)]; destMat[MatrixF::idx(1, 2)] = m[MatrixF::idx(1, 2)]; destMat[MatrixF::idx(2, 2)] = m[MatrixF::idx(2, 2)]; destMat[MatrixF::idx(0, 3)] = A; destMat[MatrixF::idx(1, 3)] = B; destMat[MatrixF::idx(2, 3)] = C; invTrMatrix.mul(invScale); Point3F norm(p[0], p[1], p[2]); Point3F point = norm * -p[3]; invTrMatrix.mulP(norm); norm.normalize(); MatrixF temp; memcpy(temp, m, sizeof(F32) * 16); point.x *= s[0]; point.y *= s[1]; point.z *= s[2]; temp.mulP(point); PlaneF resultPlane(point, norm); presult[0] = resultPlane.x; presult[1] = resultPlane.y; presult[2] = resultPlane.z; presult[3] = resultPlane.d; }