Here is the minimal example.
It is just a single link rotation using quaternion. Could it be the skeleton matrix calculation has this error in the update transform? Don't know.
Code: Select all
#include <irrlicht.h>
using namespace irr;
using namespace irr::core;
using namespace irr::scene;
using namespace irr::video;
using namespace irr::io;
using namespace irr::gui;
#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
#endif
int main()
{
IrrlichtDevice *device = createDevice(video::EDT_OPENGL, dimension2d<u32>(640, 480), 16, false, false, false, 0);
if (!device)
return 1;
device->setWindowCaption(L"Hello World! - Irrlicht Engine Demo");
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
IGUIEnvironment* guienv = device->getGUIEnvironment();
guienv->addStaticText(L"Hello World! This is the Irrlicht Software renderer!",
rect<s32>(10, 10, 260, 22), true);
IAnimatedMesh* mesh = smgr->getMesh("media/jgSally.b3d");
if (!mesh)
{
device->drop();
return 1;
}
IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode(mesh);
if (node)
{
node->setMaterialFlag(EMF_LIGHTING, false);
//node->setScale(vector3df( 0.1f));
node->setFrameLoop(1, 24);
node->setJointMode(E_JOINT_UPDATE_ON_RENDER::EJUOR_CONTROL);
node->setMaterialTexture(0, driver->getTexture("media/jgSally2.jpg"));
}
ISceneNode *vNode = device->getSceneManager()->addSphereSceneNode(0.5f);
vNode->setPosition(vector3df(0.f, 15.f, 5.f));
vNode->setName("Flyer");
scene::ISceneNodeAnimator * flyCircleAnimator = device->getSceneManager()->createFlyCircleAnimator(core::vector3df(0.f, 15.f, 5.f), 5.0f, 0.002f, vector3df(0, 0, 1));
vNode->addAnimator(flyCircleAnimator);
vNode->setMaterialFlag(E_MATERIAL_FLAG::EMF_LIGHTING, true);
smgr->addCameraSceneNode(0, vector3df(0, 20, 20), vector3df(0, 8, 0));
irr::scene::IBoneSceneNode *base = ((IAnimatedMeshSceneNode *)node)->getJointNode("Rshoulder");
irr::scene::IBoneSceneNode *endEffector = ((IAnimatedMeshSceneNode *)node)->getJointNode("Relbow");
while (device->run())
{
driver->beginScene(true, true, SColor(255, 100, 101, 140));
smgr->drawAll();
guienv->drawAll();
driver->endScene();
vector3df rot = node->getRotation();
rot.Y += 0.01f;
rot.Y = rot.Y > 360 ? rot.Y - 360 : rot.Y;
node->setRotation(rot);
node->updateAbsolutePosition();
//((IBoneSceneNode *)*node->getChildren().begin())->updateAbsolutePositionOfAllChildren();
vector3df basePos = base->getAbsolutePosition();
vector3df target = vNode->getAbsolutePosition();
vector3df endEffPos = endEffector->getAbsolutePosition();
vector3df p1 = endEffPos - basePos;
vector3df p2 = target - basePos;
p1.normalize();
p2.normalize();
vector3df axis = p1.crossProduct(p2);
axis.normalize();
float dot = p1.dotProduct(p2);
float angle = acosf(dot);
if (abs(angle) > 0.0001)
{
//printf("%f,%f\n", dot, angle);
quaternion q1;
//q1.rotationFromTo(p1, p2);
q1.fromAngleAxis(angle, axis);
q1.normalize();
quaternion q2;
q2.set(base->getRotation()*DEGTORAD);
q2.normalize();
q2 = q2*q1;
q2.normalize();
vector3df anglexx;
q2.toEuler(anglexx);
anglexx *= RADTODEG;
base->setRotation(q2.getMatrix().getRotationDegrees());
base->updateAbsolutePosition();
endEffector->updateAbsolutePosition();
}
}
device->drop();
return 0;
}
b3dFile:
http://s000.tinyupload.com/index.php?fi ... 1653798266