From 158ca9fb20fd7b567707179dab105e836dea5e5d Mon Sep 17 00:00:00 2001 From: hikerstk Date: Thu, 4 Nov 2010 21:52:48 +0000 Subject: [PATCH] Fixed rotational IPOs (problems were caused by a different order of rotations in blender and irrlicht). NOTE: all tracks that are using animations WILL NOT WORK PROPERLY till they have been re-exported with the new track exporter (which will be done shortly). git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@6396 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/animations/ipo.cpp | 6 +++--- src/animations/three_d_animation.cpp | 20 +++++++++++++++++--- src/animations/three_d_animation.hpp | 5 +++++ 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/animations/ipo.cpp b/src/animations/ipo.cpp index b4d5e677b..77b654e93 100644 --- a/src/animations/ipo.cpp +++ b/src/animations/ipo.cpp @@ -123,9 +123,9 @@ void Ipo::update(float dt, core::vector3df *xyz, core::vector3df *hpr, case Ipo::IPO_LOCX : xyz->X = get(); break; case Ipo::IPO_LOCY : xyz->Y = get(); break; case Ipo::IPO_LOCZ : xyz->Z = get(); break; - case Ipo::IPO_ROTX : hpr->X = -get(); break; // the - signs are odd, - case Ipo::IPO_ROTY : hpr->Y = -get(); break; // but it works - case Ipo::IPO_ROTZ : hpr->Z = get(); break; // why no - ?? + case Ipo::IPO_ROTX : hpr->X = get(); break; + case Ipo::IPO_ROTY : hpr->Y = get(); break; + case Ipo::IPO_ROTZ : hpr->Z = get(); break; case Ipo::IPO_SCALEX : scale->X = get(); break; case Ipo::IPO_SCALEY : scale->Y = get(); break; case Ipo::IPO_SCALEZ : scale->Z = get(); break; diff --git a/src/animations/three_d_animation.cpp b/src/animations/three_d_animation.cpp index 0297c59ac..7163088a5 100644 --- a/src/animations/three_d_animation.cpp +++ b/src/animations/three_d_animation.cpp @@ -42,6 +42,7 @@ ThreeDAnimation::ThreeDAnimation(const Track &track, m_body = NULL; m_motion_state = NULL; m_collision_shape = NULL; + m_hpr = AnimationBase::m_animated_node->getRotation(); std::string shape; node.get("shape", &shape); if(shape!="") @@ -123,12 +124,25 @@ ThreeDAnimation::~ThreeDAnimation() void ThreeDAnimation::update(float dt) { core::vector3df xyz = m_animated_node->getPosition(); - core::vector3df hpr = m_animated_node->getRotation(); core::vector3df scale = m_animated_node->getScale(); - AnimationBase::update(dt, &xyz, &hpr, &scale); //updates all IPOs + AnimationBase::update(dt, &xyz, &m_hpr, &scale); //updates all IPOs m_animated_node->setPosition(xyz); - m_animated_node->setRotation(hpr); m_animated_node->setScale(scale); + // Note that the rotation order of irrlicht is different from the one + // in blender. So in order to reproduce the blender IPO rotations + // correctly, we have to get the rotations around each axis and combine + // them in the right order for irrlicht + core::matrix4 m; + m.makeIdentity(); + core::matrix4 mx; + mx.setRotationDegrees(core::vector3df(m_hpr.X, 0, 0)); + core::matrix4 my; + my.setRotationDegrees(core::vector3df(0, m_hpr.Y, 0)); + core::matrix4 mz; + mz.setRotationDegrees(core::vector3df(0, 0, m_hpr.Z)); + m = my*mz*mx; + core::vector3df hpr = m.getRotationDegrees(); + m_animated_node->setRotation(hpr); // Now update the position of the bullet body if there is one: if(m_body) diff --git a/src/animations/three_d_animation.hpp b/src/animations/three_d_animation.hpp index 71ca481a0..5974508bf 100644 --- a/src/animations/three_d_animation.hpp +++ b/src/animations/three_d_animation.hpp @@ -52,6 +52,11 @@ private: /** A user pointer to connect a bullet body with this object. */ UserPointer m_user_pointer; + /** We have to store the rotation value as computed in blender, since + * irrlicht uses a different order, so for rotation animations we + * can not use the value returned by getRotation from a scene node. */ + core::vector3df m_hpr; + void createPhysicsBody(const std::string &shape); public: