Hello,
I was hoping someone could help.
I have a node positioned at (0,0,0) and would like to rotate it around x,y,z axis' and also around an axis 45 degree between x,y (diagonal)
I've been trying to translate code for my IDE but I need more input to do the translation. I have been using setRotation but it sucks.
Could someone help by posting the simplest code for a node to do a rotation around a point 45 degrees between x,y (with comments ) vs. a rotation around the x axis (using matrix4)
Matrix rotation
-
- Posts: 22
- Joined: Tue Nov 09, 2010 7:03 pm
- Location: ohiio
Matrix rotation
Only after disaster can we be resurrected.
-
- Posts: 22
- Joined: Tue Nov 09, 2010 7:03 pm
- Location: ohiio
Picture
Only after disaster can we be resurrected.
-
- Posts: 22
- Joined: Tue Nov 09, 2010 7:03 pm
- Location: ohiio
I have been looking at quaternions
I am using realbasic and an irrlicht plugin called Franklin3d.
I have not done any coding for about 20 years.
I understand quaternions a little.
I am having trouble converting code or suggestions, that others have posted because:
1. It's has too much going on, ie. several nodes being moved and rotated.
or nodes being the camera and more.
and so many other things.
2. I have to figure out what's going on and then rewrite the code so it
works with my version of irrlicht, in my IDE RealBasic.
(very minor differences = big bugs)
3. I was hoping that someone could give me an example of code to rotate
one node(no distance from center) using matrix4 and /or quaternions.
Just one node, doing one function. So I can figure out where my
syntax error is, or why the method does not exist, or why I need to
use the value returned. Small differences but it is very difficult to debug
with so much going on. I have tried so many variations of sample code
I'm just trying to dumb it down.
4. setRotation is not an option for many reasons.
5. Any help would be appreciated.
The main rotation I need to learn is around the "axis" between x,y.
Did I just make this more confusing?
I have not done any coding for about 20 years.
I understand quaternions a little.
I am having trouble converting code or suggestions, that others have posted because:
1. It's has too much going on, ie. several nodes being moved and rotated.
or nodes being the camera and more.
and so many other things.
2. I have to figure out what's going on and then rewrite the code so it
works with my version of irrlicht, in my IDE RealBasic.
(very minor differences = big bugs)
3. I was hoping that someone could give me an example of code to rotate
one node(no distance from center) using matrix4 and /or quaternions.
Just one node, doing one function. So I can figure out where my
syntax error is, or why the method does not exist, or why I need to
use the value returned. Small differences but it is very difficult to debug
with so much going on. I have tried so many variations of sample code
I'm just trying to dumb it down.
4. setRotation is not an option for many reasons.
5. Any help would be appreciated.
The main rotation I need to learn is around the "axis" between x,y.
Did I just make this more confusing?
Last edited by speedy15453 on Tue Nov 30, 2010 9:09 pm, edited 1 time in total.
Only after disaster can we be resurrected.
The hardest thing here is trying to think about and visualize it... at least for me. I end up just having to trust the math, which works fine.
The direct way to do it is to use the matrix4 class. That way you can rotate an arbitrary amount about any arbitrary axis without having to worry about things like gimbal lock.
All of the math is here: http://inside.mines.edu/~gmurray/Arbitr ... ation.html
You really only need the last section of that document, but they walk you through the entire thing. Some of their variables may be zero in your case, which means that horrific matrix will reduce to something manageable.
Once you have your magic matrix, you can use a mesh manipulator and pass the matrix to its transform method.
The direct way to do it is to use the matrix4 class. That way you can rotate an arbitrary amount about any arbitrary axis without having to worry about things like gimbal lock.
All of the math is here: http://inside.mines.edu/~gmurray/Arbitr ... ation.html
You really only need the last section of that document, but they walk you through the entire thing. Some of their variables may be zero in your case, which means that horrific matrix will reduce to something manageable.
Once you have your magic matrix, you can use a mesh manipulator and pass the matrix to its transform method.
-
- Posts: 22
- Joined: Tue Nov 09, 2010 7:03 pm
- Location: ohiio
I love the link.
Thanks Mikhail9,
The link you provided is very helpful.
I am still have problems just getting started with the code.
I'm going to mess around for the next couple of days.
I think it may all be just syntax in my IDE.
I'll post some code if I have any success.
Thanks!
The link you provided is very helpful.
I am still have problems just getting started with the code.
I'm going to mess around for the next couple of days.
I think it may all be just syntax in my IDE.
I'll post some code if I have any success.
Thanks!
Only after disaster can we be resurrected.
I had this sitting around for a while. I cleaned it up some, added better comments and it does show how to use quaternions in a simple context. However, it does not work so well for quaternion axes which match any of the global axes. I can think of a quick and dirty solution to avoid allowing the quaternion's axis from matching the global ones but that seems hacky.
My question is: Is this in the nature of quaternions, is it a bug, or am I using this wrong? (Okay, maybe that's three questions). Any help would be appreciated.
My question is: Is this in the nature of quaternions, is it a bug, or am I using this wrong? (Okay, maybe that's three questions). Any help would be appreciated.
Code: Select all
#include <iostream>
#include <irrlicht.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#pragma comment(linker, "/subsystem:console /ENTRY:mainCRTStartup")/*windows*/
#endif
int main()
{
// ************
// quick set up
IrrlichtDevice *device = createDevice( video::EDT_OPENGL, dimension2d<u32>(640, 480), 16, false, false, false, 0);
if (!device)
return 1;
device->setWindowCaption(L"Quaternion Rotation Test");
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
IGUIEnvironment* guienv = device->getGUIEnvironment();
guienv->addStaticText(L"The yellow line is the axis of rotation.", rect<s32>(10,10,260,22), true);
// ***************************************
// Let's set up the meshes and scene node, et al.
// create a set of axes that show rotation
IAnimatedMesh* xArrow = smgr->addArrowMesh( "xArrow", SColor(255,60,40,40), SColor(255,255,0,0) );
xArrow->setMaterialFlag(EMF_LIGHTING, false);
IAnimatedMesh* yArrow = smgr->addArrowMesh( "yArrow", SColor(255,40,60,40), SColor(255,0,255,0) );
yArrow->setMaterialFlag(EMF_LIGHTING, false);
IAnimatedMesh* zArrow = smgr->addArrowMesh( "zArrow", SColor(255,40,40,100), SColor(255,0,0,255) );
zArrow->setMaterialFlag(EMF_LIGHTING, false);
ISceneNode* gizmo = smgr->addEmptySceneNode();
if (gizmo)
{
IMeshSceneNode* right = smgr->addMeshSceneNode(xArrow, gizmo, -1, vector3df(0), vector3df(0,0,-90), vector3df(10,25,10));
IMeshSceneNode* up = smgr->addMeshSceneNode(yArrow, gizmo, -1, vector3df(0), vector3df(0,0,0), vector3df(10,25,10));
IMeshSceneNode* forward = smgr->addMeshSceneNode(zArrow, gizmo, -1, vector3df(0), vector3df(90,0,0), vector3df(10,25,10));
gizmo->setMaterialFlag(EMF_LIGHTING, false);
}
else
return 0;
// this is just used for output to the console
vector3df nodeRot;
//ICameraSceneNode* cam = smgr->addCameraSceneNodeMaya();
ICameraSceneNode* cam = smgr->addCameraSceneNode(0, vector3df(0,0,-50), vector3df(0,0,30));
if (cam)
cam->setTarget( gizmo->getAbsolutePosition() );
// this will be used to create a yellow line that shows the quaternion's axis of rotation
SMaterial someMaterial;
someMaterial.Lighting = false;
someMaterial.DiffuseColor = SColor(255,255,255,0);
someMaterial.Thickness = 2;
// ***************************************
// Let's set up the quaternions, matrices, et al.
// Here's the axis of rotation. Quaternion's need to have them normalized or strange stuff happens.
vector3df axis(1,1,0); // or whatever. Note: vector3df(0,1,0) gives NaNs, other axis aligned vectors only give half rotations :-/
axis.normalize();
// Multiple rotations of different amounts and/or around different axes can be set into different
// quaternions which can then be multiplied into each other to accumulate arbitrary (i.e. local) rotations.
// The order in which they are multiplied matters strongly! ( (quatM * quatN) != (quatN * quatM) )
// In this example, we're only using one quaternion/rotation, though.
// This quat represents a single (set) rotation of some degrees (converted to radians, as necessary).
quaternion quatAxisRoll;
quatAxisRoll.fromAngleAxis (15 * DEGTORAD, axis );
// Once we've accumulated all our quaternions through multiplication we'll need to convert them to a matrix.
// This stays the same throughout this program, so rotation is not frame rate independent. For that, you
// can reset the quaternion or use slerp().
matrix4 rotationMtxFromQuat( quatAxisRoll.getMatrix() );
// We can use that to set the node rotation directly to the same position every frame, but if we want to
// animate the node we'll need a matrix for the node's rotation so that we can multiply our rotationMtxFromQuat into it.
matrix4 currentRotMtx; // of the node
// ************
// start 'er up!
while(device->run())
{
// find node's current rotation
currentRotMtx = gizmo->getAbsoluteTransformation();
// alter it by our rotation (note the order of multiplication)
currentRotMtx *= rotationMtxFromQuat;
// apply the new, accumulated rotation
gizmo->setRotation( currentRotMtx.getRotationDegrees() );
// this is just for checking the console output
nodeRot = gizmo->getRotation();
std::cout << "\nRotX: " << nodeRot.X << "\nRotY: " << nodeRot.Y << "\nRotZ: " << nodeRot.Z << "\n\n";
// draw everything
driver->beginScene(true, true, SColor(255,50,50,140));
smgr->drawAll();
guienv->drawAll();
// draw axis
driver->setMaterial(someMaterial);
driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
driver->draw3DLine( -axis * 25, axis * 25, SColor(255, 255, 255, 0) );
driver->endScene();
device->sleep(100, false);
}
device->drop();
return 0;
}
"Computers don't make mistakes! What they do they do on purpose!!"
-Dale Gribble
-Dale Gribble