Page 1 of 2

How set rotation cylinderSceneNode ?

Posted: Thu Feb 19, 2009 11:42 pm
by marian.ek
How set rotation cylinderSceneNode (n1)?
Image
(link to image)

code it's not work :

Code: Select all

vector3df v2 = n2->getTransformedBoundingBox().getCenter();
vector3df v3 = n3->getTransformedBoundingBox().getCenter();
vector3df direct = v3 - v2;
n1->setRotation(direct.getHorizontalAngle());
how rotate it ?

Posted: Sun Feb 22, 2009 7:18 am
by lizhigang34
:)

Posted: Wed Mar 04, 2009 6:30 am
by lizhigang34
I am troubled by this problem as well,no one can help us??

Posted: Wed Mar 04, 2009 4:44 pm
by Alpha Omega
Well if your object is just a simple cylinder you could always just load an external mesh and use

Code: Select all

ISceneNode* mesh = smgr->getMesh("yourmesh.mesh');
mesh->setRotation(core::vector3df(0,90,0));
I couldnt find the cylinderSceneNode in the API so this is all I could come up with sorry if it is too noobie. :D [/code]

Posted: Wed Mar 04, 2009 5:57 pm
by Acki
what he wants to do is to rotate (and place) the cylinder (n1) so it's like a connection between n2 and n3... ;)

Posted: Wed Mar 04, 2009 7:19 pm
by Alpha Omega
Oh well i see your problem is your saying to get the Horizontal Angle of each of the 3d components when you shold be finding the angle of the horizontal of the vector. Or putting it this way the horizontal of the x and z component are always going to be zero, and the y component will always be 90.

You need to find the components of your vector "direct" and then use the fact the cos(x)=direct_X / (direct); cos(y)=direct_y / (direct); cos(z) = direct_z / (direct).

Im not sure if Irrlicht can do inverse cosines or not... if it can then it should be simply....

Code: Select all


int x = cos-1(direct_x/direct);
int y = cos-1(direct_y/direct);
int z = cos-1(direct_z/direct);
n1->setRotation(core::vector3df(x,y,z));
however note that this isnt real code just a basic format of what it should look like.
[/code]

Posted: Thu Mar 05, 2009 1:42 am
by lizhigang34
My problem is very similar to the author's.Look this image.
Image
I hope my cylinder can rotate around Y axis, and can rotate around the vector which I can compute on XOZ plane,finally,the cylinder must can rotate around it's middle axis.

Posted: Thu Mar 05, 2009 12:05 pm
by lizhigang34
Acki wrote:what he wants to do is to rotate (and place) the cylinder (n1) so it's like a connection between n2 and n3... ;)
can you show more?

Posted: Thu Mar 05, 2009 1:12 pm
by arras

Code: Select all

#include <irrlicht.h>
using namespace irr;

int main()
{
   IrrlichtDevice *device = createDevice(video::EDT_OPENGL,
      core::dimension2d<s32>(640, 480), 16, false, false, false);

   video::IVideoDriver* driver = device->getVideoDriver();
   scene::ISceneManager* smgr = device->getSceneManager();

   // add arrow to the scene which will represent object rotating towards target
   scene::IMesh *mesh = smgr->addArrowMesh("arrow", video::SColor(180,255,0,255),
      video::SColor(180,0,0,255), 4,8, 20,15, 0.5f,1 )->getMesh(0);
   // arrow mesh points along Y axis originaly we have to change that
   core::matrix4 m;
   m.setRotationDegrees(core::vector3df(90,0,0));
   smgr->getMeshManipulator()->transformMesh(mesh, m);
   scene::ISceneNode *node = smgr->addMeshSceneNode(mesh);
   node->setMaterialFlag(video::EMF_LIGHTING, false);
   //node->setPosition(core::vector3df(0,0,10));

   // origin marker
   mesh = smgr->addSphereMesh("sphere1", 1)->getMesh(0);
   smgr->getMeshManipulator()->setVertexColors(mesh, video::SColor(255,0,255,0));
   scene::ISceneNode *origin = smgr->addMeshSceneNode(mesh);
   origin->setPosition(core::vector3df(5,0,5));
   origin->setMaterialFlag(video::EMF_LIGHTING, false);

   // target marker
   mesh = smgr->addSphereMesh("sphere2", 1)->getMesh(0);
   smgr->getMeshManipulator()->setVertexColors(mesh, video::SColor(255,255,0,0));
   scene::ISceneNode *target = smgr->addMeshSceneNode(mesh);
   target->setPosition(core::vector3df(21,10,21));
   target->setMaterialFlag(video::EMF_LIGHTING, false);

   //! getHorizontalAngle() return horizontal(Y) and vertical(X) angle between two points
   //! you have to use relative position of target to origin
   core::vector3df relativeTarget = target->getPosition()-origin->getPosition();
   node->setRotation(relativeTarget.getHorizontalAngle());
   node->setPosition(origin->getPosition());

   // camera
   smgr->addCameraSceneNode(0, node->getPosition()+core::vector3df(20,20,-20),node->getPosition());

   while(device->run())
   {
      driver->beginScene(true, true, video::SColor(0,50,50,50));

      smgr->drawAll();

      driver->endScene();
   }

   device->drop();

   return 0;
}

Posted: Thu Mar 05, 2009 1:25 pm
by arras
Image

If you need some offset as seen on your picture than this will do the trick (note that cilinder/arrow should point along Z axis as this is considered front):

Code: Select all

#include <iostream>
using namespace std;

#include <irrlicht.h>
using namespace irr;

int main()
{
   IrrlichtDevice *device = createDevice(video::EDT_OPENGL,
      core::dimension2d<s32>(640, 480), 16, false, false, false);

   video::IVideoDriver* driver = device->getVideoDriver();
   scene::ISceneManager* smgr = device->getSceneManager();

   // add arrow to the scene which will represent object rotating towards target
   scene::IMesh *mesh = smgr->addArrowMesh("arrow", video::SColor(180,255,0,255),
      video::SColor(180,0,0,255), 4,8, 20,15, 0.5f,1 )->getMesh(0);
   // arrow mesh points along Y axis originaly we have to change that to Z
   core::matrix4 m;
   m.setRotationDegrees(core::vector3df(90,0,0));
   smgr->getMeshManipulator()->transformMesh(mesh, m);
   scene::ISceneNode *node = smgr->addMeshSceneNode(mesh);
   node->setMaterialFlag(video::EMF_LIGHTING, false);
   //node->setPosition(core::vector3df(0,0,10));

   // origin marker
   mesh = smgr->addSphereMesh("sphere1", 1)->getMesh(0);
   smgr->getMeshManipulator()->setVertexColors(mesh, video::SColor(255,0,255,0));
   scene::ISceneNode *origin = smgr->addMeshSceneNode(mesh);
   origin->setPosition(core::vector3df(5,0,5));
   origin->setMaterialFlag(video::EMF_LIGHTING, false);

   // target marker
   mesh = smgr->addSphereMesh("sphere2", 1)->getMesh(0);
   smgr->getMeshManipulator()->setVertexColors(mesh, video::SColor(255,255,0,0));
   scene::ISceneNode *target = smgr->addMeshSceneNode(mesh);
   target->setPosition(core::vector3df(21,10,21));
   target->setMaterialFlag(video::EMF_LIGHTING, false);

   //! arrow offset from origin
   core::vector3df offset(0,0,3);

   //! getHorizontalAngle() return horizontal(Y) and vertical(X) angle between two points
   //! you have to use relative position of target to origin
   core::vector3df relativeTarget = target->getPosition()-origin->getPosition();
   core::vector3df rotation = relativeTarget.getHorizontalAngle();

   //! rotate offset around origin
   core::matrix4 n;
   n.setRotationDegrees(rotation);
   n.rotateVect(offset);
   offset += origin->getPosition();

   //! update arrow
   node->setRotation(rotation);
   node->setPosition(offset);

   // camera
   smgr->addCameraSceneNode(0, node->getPosition()+core::vector3df(20,20,-20),node->getPosition());

   while(device->run())
   {
      driver->beginScene(true, true, video::SColor(0,50,50,50));

      smgr->drawAll();

      driver->endScene();
   }

   device->drop();

   return 0;
}

Posted: Fri Mar 06, 2009 3:03 am
by lizhigang34
thanks arras,your code let cylinder rotate to a point..but,how to rotate the cylinder around it's middle axis..look at these two images.
Image Image
I want to rotate the cylinder around vector OP.

Posted: Fri Mar 06, 2009 9:26 am
by arras
To rotate node around one of its own axes you can use turn(Y), pitch(X) and roll(Z) functions from this post: Free Flight (space flight) functions. You have to count with gimbal lock however.

Posted: Fri Mar 06, 2009 4:23 pm
by lizhigang34
thanks arras for your code..But I still don't know how to count gimbal lock. For example,I have loaded the cylinder mesh successfully,I set cylinder position use cylinder->setPosition(-20,-20,0),then I roll(cylinder, -45) to make sure the cylinder cross the point(0,0,0).Now I want it can rotate around its own axis,how to use the functions turn(), pitch(), roll().

Posted: Sat Mar 07, 2009 12:22 am
by arras
turn() rotate node around its Y axis
pitch() around X
roll() around Z

to rotate node around its Z axis 45 degrees just call: roll(yourCilinderNode, 45.0f)

Posted: Sat Mar 07, 2009 10:14 am
by lizhigang34
arras wrote:turn() rotate node around its Y axis
pitch() around X
roll() around Z

to rotate node around its Z axis 45 degrees just call: roll(yourCilinderNode, 45.0f)
Image

Here is my cylinder, it is a vertical.
It’s position is (x,y,z),I want rotate it,but it must cross point(0,0,0).the cylinder which drawn by broken line is the cylinder after rotated.
My code snippet as follows.

Code: Select all

void CHickey::Rotate()
{
	vector3df pos = m_pHickeyNode->getPosition();
	f32 x = abs(atan2(pos.X, pos.Y));
	f32 z = abs(atan2(pos.Z, pos.Y));
	x *= RADTODEG;
	z *= RADTODEG;
	pos.X < 0 ? roll(m_pHickeyNode, x) : roll(m_pHickeyNode, -x); //roll() around Z
	pos.Z < 0 ? pitch(m_pHickeyNode, z) : pitch(m_pHickeyNode, -z);//pitch() around X
	turn(m_pHickeyNode, m_fAngleSelfRotate);//turn() around its own axis
}