Code: Select all
vector3df absRotation = myISceneNode->getAbsoluteTransformation().getRotationDegrees();
To fix matrix4::setScale, replace it with the following:
Code: Select all
inline void matrix4::setScale( const vector3df& scale )
{
M[0] *= scale.X;
M[1] *= scale.X;
M[2] *= scale.X;
M[4] *= scale.Y;
M[5] *= scale.Y;
M[6] *= scale.Y;
M[8] *= scale.Z;
M[9] *= scale.Z;
M[10] *= scale.Z;
}
Code: Select all
const matrix4 &mat = *this;
Code: Select all
matrix4 mat(*this);
vector3df scale = getScale();
mat.setScale( vector3df(1.0/scale.X, 1.0/scale.Y, 1.0/scale.Z) );
Code: Select all
inline vector3df matrix4::getScale() const{
return vector3df( sqrt(M[0]*M[0] + M[1]*M[1] + M[2]*M[2]),
sqrt(M[4]*M[4] + M[5]*M[5] + M[6]*M[6]),
sqrt(M[8]*M[8] + M[9]*M[9] + M[10]*M[10]) );
}
Code: Select all
vector3df scale = getScale();
Code: Select all
setScale(scale);
A similar fix is needed for the rotateVect() and inverseRotateVect() functions, or else when you use them to rotate a vector, the vector also ends up getting scaled by the matrix's scale (like calling transformVect, except without the translation). At the beginning of these functions, insert the line:
Code: Select all
f32 len = vect.getLength();
Code: Select all
vect.setLength(len);
Finally, if all this norm-taking raises efficiency concerns, one could just maintain boolean flags in matrix4f like "rotationWasSet" and "scaleWasSet", such that the scale-sensitive code above is only run when both flags are true. But I didn't bother, as my frames per second didn't go down at all.
-- Matt