Quaternion and Euler angles to limit bone rotation
-
- Halfling
- Posts: 71
- Joined: Fri Oct 11, 2013 8:50 pm
Quaternion and Euler angles to limit bone rotation
Hi,
I set rotation for my bones using Quaternion .
I want now limit the rotation angles of the the bone for each axis .
So first i get the current angle using
bone->_getDerivedOrientation() and then using getYaw(), getPItch(), getRoll()
my problem now is i need idea what is the next step how i can reorient the bone to be in thevalid range
I set rotation for my bones using Quaternion .
I want now limit the rotation angles of the the bone for each axis .
So first i get the current angle using
bone->_getDerivedOrientation() and then using getYaw(), getPItch(), getRoll()
my problem now is i need idea what is the next step how i can reorient the bone to be in thevalid range
-
- Halfling
- Posts: 71
- Joined: Fri Oct 11, 2013 8:50 pm
Re: Quaternion and Euler angles to limit bone rotation
i can't yet reorient the bone to the boundery of the limit
idea?
idea?

-
- Troll
- Posts: 1394
- Joined: Wed Aug 02, 2006 9:41 am
- Location: Bucharest
- x 94
Re: Quaternion and Euler angles to limit bone rotation
If you have a pitch, roll and yaw limit, what is the problem? You rotate the bone and if it's outside the limit on some axis you set that rotation to your chosen limit.
-
- Halfling
- Posts: 71
- Joined: Fri Oct 11, 2013 8:50 pm
Re: Quaternion and Euler angles to limit bone rotation
yes i have the pich,roll and yaw limits
for exemple i have the yaw limit of the elbow relative to it's parent
so
i will test like that
is it like that?
for exemple i have the yaw limit of the elbow relative to it's parent
so
i will test like that
Code: Select all
angl=skel->getBone("elbow")->getOrienttaion()->getYaw();
if (angl >limitmax)
{
skel->getBone("elbow")->yaw(limitmax);
}
-
- Troll
- Posts: 1394
- Joined: Wed Aug 02, 2006 9:41 am
- Location: Bucharest
- x 94
Re: Quaternion and Euler angles to limit bone rotation
Not sure if yaw is absolute or relative, it may be relative.
-
- Halfling
- Posts: 71
- Joined: Fri Oct 11, 2013 8:50 pm
Re: Quaternion and Euler angles to limit bone rotation
Hi
that's my code, in my case bone(i) ="elbow"
nothing was changed
that's my code, in my case bone(i) ="elbow"
Code: Select all
/// rotate bone(i) parent that allow bone(i) to be in the desired pos
v1=(skel->getBone(i)->_getDerivedPosition()-skel->getBone(i)->getParent()->_getDerivedPosition());
v2= desiredPos-skel->getBone(i)->getParent()->_getDerivedPosition();
quat1=v1.getRotationTo(v2);
skel->getBone(i)->getParent()->rotate(quat1,Ogre::Node::TS_WORLD);
skel->getBone(i)->_setDerivedPosition(desiredPos);
///// test the rotation of the bone(i)
rad1=skel->getBone(i)->getOrientation().getYaw();
if (rad1 > Ogre::Degree(0)){cout<<"i enter elbow"; cout<<"\n"; skel->getBone(i)->yaw(Ogre::Degree(0));}
if (rad1 < Ogre::Degree(-145)) {cout<<"i enter elbow"; cout<<"\n";skel->getBone(i)->yaw(Ogre::Degree(-145));}
rad2=skel->getBone(i)->getOrientation().getPitch();
if (rad2 > Ogre::Degree(90)) {cout<<"i enter elbow"; cout<<"\n";skel->getBone(i)->pitch(Ogre::Degree(90));}
if (rad2 < Ogre::Degree(-90)) {cout<<"i enter elbow"; cout<<"\n";skel->getBone(i)->pitch(Ogre::Degree(-90));}
-
- Halfling
- Posts: 71
- Joined: Fri Oct 11, 2013 8:50 pm
Re: Quaternion and Euler angles to limit bone rotation
No it's relative , the limits are relative to their parent
-
- Troll
- Posts: 1394
- Joined: Wed Aug 02, 2006 9:41 am
- Location: Bucharest
- x 94
Re: Quaternion and Euler angles to limit bone rotation
By relative I meant that it is not an absolute rotation, but a cumulative one. In rotates with each call further.
If you update every frame and the rotation is not very fast, I would go with something like this.
You have oldOrientation and newRotation quaternions. Then you do newOrientation = oldOrientation * newRotation (if this is the correct order?)
for newOrientation you do getYaw etc and check to see if it's ok. If not you don't rotate the node.
This will have some positional error, but maybe it's small enough. If not you will have to somehow set the exceeded values, let say yaw to the maxYaw. Not sure how this goes.
If you update every frame and the rotation is not very fast, I would go with something like this.
You have oldOrientation and newRotation quaternions. Then you do newOrientation = oldOrientation * newRotation (if this is the correct order?)
for newOrientation you do getYaw etc and check to see if it's ok. If not you don't rotate the node.
This will have some positional error, but maybe it's small enough. If not you will have to somehow set the exceeded values, let say yaw to the maxYaw. Not sure how this goes.
-
- Halfling
- Posts: 71
- Joined: Fri Oct 11, 2013 8:50 pm
Re: Quaternion and Euler angles to limit bone rotation
Code: Select all
newOrientation = oldOrientation * newRotation (if this is the correct order?)
did you mean that instead using
Code: Select all
skel->getBone(i)->getParent()->rotate(quat1,Ogre::Node::TS_WORLD);
-
- Troll
- Posts: 1394
- Joined: Wed Aug 02, 2006 9:41 am
- Location: Bucharest
- x 94
Re: Quaternion and Euler angles to limit bone rotation
I mean you compute the final orientation before actually rotating/orienting, and you only allow the rotation if it is inside the desired zone.
-
- Halfling
- Posts: 71
- Joined: Fri Oct 11, 2013 8:50 pm
Re: Quaternion and Euler angles to limit bone rotation
that's short screen what i get with my first code
i can't decide what bone that i must reorient to get the right motion , i must rotate the father bone ? the child ?
and how i must rotate them
in the red circle you can see that's there is problem in this bonei can't decide what bone that i must reorient to get the right motion , i must rotate the father bone ? the child ?
and how i must rotate them
You do not have the required permissions to view the files attached to this post.
-
- Halfling
- Posts: 71
- Joined: Fri Oct 11, 2013 8:50 pm
Re: Quaternion and Euler angles to limit bone rotation
i tried using this codeI mean you compute the final orientation before actually rotating/orienting, and you only allow the rotation if it is inside the desired zone.
Code: Select all
v1=(skel->getBone(i)->_getDerivedPosition()-skel->getBone(i)->getParent()->_getDerivedPosition());
v2= desiredPos-skel->getBone(i)->getParent()->_getDerivedPosition();
oldOrientation=skel->getBone(i)->getParent()->_getDerivedOrientation();
newRotation=v1.getRotationTo(v2);
newOrientation = oldOrientation*newRotation;
skel->getBone(i)->getParent()->rotate(newOrientation,Ogre::Node::TS_WORLD);
-
- Gnoblar
- Posts: 2
- Joined: Tue Mar 04, 2014 7:33 am
Re: Quaternion and Euler angles to limit bone rotation
I have similar problem. I want some range to limit pitch of camera.
it works only when yaw not so closely to +-90 degrees. When q.getYaw().valueDegrees() is near +-90 degrees, q.getPitch().valueDegrees() returns incorrect result and limitations doesn't work as expected.
Full code: https://www.dropbox.com/s/toadod8ducp5i ... UIView.zip
Code: Select all
(void)handleTouchMoved:(UIPanGestureRecognizer *)gestureRecognizer {
if(gestureRecognizer.state != UIGestureRecognizerStateEnded && gestureRecognizer.state != UIGestureRecognizerStateFailed)
{
CGPoint trans = [gestureRecognizer velocityInView:gestureRecognizer.view];
const float limit = 30.;
Ogre::Camera *mCamera = m_ogreFramework->m_pCamera;
Ogre::SceneNode* mTarget = m_ogreFramework->m_pSceneMgr->getRootSceneNode();
Ogre::Real dist = (mCamera->getPosition() - mTarget->_getDerivedPosition()).length();
mCamera->setPosition(mTarget->_getDerivedPosition());
Quaternion oldOrientation = mCamera->getOrientation();
mCamera->yaw(Ogre::Degree(-trans.x * kRotationSpeed));
mCamera->pitch(Ogre::Degree((-trans.y) * kRotationSpeed));
Quaternion q = mCamera->getOrientation();
float pitch = ABS(q.getPitch().valueDegrees());
float roll = ABS(q.getRoll().valueDegrees());
if((pitch > (180. - limit) || pitch < limit) && (roll > (180. - limit) || roll < limit)) {
NSLog(@"Pitch = %f, yaw = %f, roll = %f", q.getPitch().valueDegrees(), q.getYaw().valueDegrees(), q.getRoll().valueDegrees());
} else {
mCamera->setOrientation(oldOrientation);
}
mCamera->moveRelative(Ogre::Vector3(0, 0, dist));
}
}
Full code: https://www.dropbox.com/s/toadod8ducp5i ... UIView.zip