I'm having problems rotating GameObjects in my engine. I'm trying to rotate in 2 ways. I'm using MathGeoLib to calculate maths in the engine.
First way: Rotates correctly around axis but if I want to rotate back, if I don't do it following the inverse order then rotation doesn't work properly.
e.g:
Rotate X axis 50 degrees, Rotate Y axis 30 degrees -> Rotate Y axis -50 degrees, Rotate X axis -30 degrees. Works.
Rotate X axis 50 degrees, Rotate Y axis 30 degrees -> Rotate X axis -50 degrees, Rotate Y axis -30 degrees. Doesn't.
Code:
void ComponentTransform::SetRotation(float3 euler_rotation)
{
float3 diff = euler_rotation - editor_rotation;
editor_rotation = euler_rotation;
math::Quat mod = math::Quat::FromEulerXYZ(diff.x * DEGTORAD, diff.y * DEGTORAD, diff.z * DEGTORAD);
quat_rotation = quat_rotation * mod;
UpdateMatrix();
}
Second way: Starts rotating good around axis but after rotating some times, then it stops to rotate correctly around axis, but if I rotate it back regardless of the rotation order it works, not like the first way.
Code:
void ComponentTransform::SetRotation(float3 euler_rotation)
{
editor_rotation = euler_rotation;
quat_rotation = math::Quat::FromEulerXYZ(euler_rotation.x * DEGTORAD, euler_rotation.y * DEGTORAD, euler_rotation.z * DEGTORAD);
UpdateMatrix();
}
Rest of code:
#define DEGTORAD 0.0174532925199432957f
void ComponentTransform::UpdateMatrix()
{
if (!this->GetGameObject()->IsParent())
{
//Get parent transform component
ComponentTransform* parent_transform = (ComponentTransform*)this->GetGameObject()->GetParent()->GetComponent(Component::CompTransform);
//Create matrix from position, rotation(quaternion) and scale
transform_matrix = math::float4x4::FromTRS(position, quat_rotation, scale);
//Multiply the object transform by parent transform
transform_matrix = parent_transform->transform_matrix * transform_matrix;
//If object have childs, call this function in childs objects
for (std::list<GameObject*>::iterator it = this->GetGameObject()->childs.begin(); it != this->GetGameObject()->childs.end(); it++)
{
ComponentTransform* child_transform = (ComponentTransform*)(*it)->GetComponent(Component::CompTransform);
child_transform->UpdateMatrix();
}
}
else
{
//Create matrix from position, rotation(quaternion) and scale
transform_matrix = math::float4x4::FromTRS(position, quat_rotation, scale);
//If object have childs, call this function in childs objects
for (std::list<GameObject*>::iterator it = this->GetGameObject()->childs.begin(); it != this->GetGameObject()->childs.end(); it++)
{
ComponentTransform* child_transform = (ComponentTransform*)(*it)->GetComponent(Component::CompTransform);
child_transform->UpdateMatrix();
}
}
}
MathGeoLib:
Quat MUST_USE_RESULT Quat::FromEulerXYZ(float x, float y, float z) { return (Quat::RotateX(x) * Quat::RotateY(y) * Quat::RotateZ(z)).Normalized(); }
Quat MUST_USE_RESULT Quat::RotateX(float angle)
{
return Quat(float3(1,0,0), angle);
}
Quat MUST_USE_RESULT Quat::RotateY(float angle)
{
return Quat(float3(0,1,0), angle);
}
Quat MUST_USE_RESULT Quat::RotateZ(float angle)
{
return Quat(float3(0,0,1), angle);
}
Quat(const float3 &rotationAxis, float rotationAngleRadians) { SetFromAxisAngle(rotationAxis, rotationAngleRadians); }
void Quat::SetFromAxisAngle(const float3 &axis, float angle)
{
assume1(axis.IsNormalized(), axis);
assume1(MATH_NS::IsFinite(angle), angle);
float sinz, cosz;
SinCos(angle*0.5f, sinz, cosz);
x = axis.x * sinz;
y = axis.y * sinz;
z = axis.z * sinz;
w = cosz;
}
Any help?
Thanks.