Quaternion and Euler angles to limit bone rotation

Problems building or running the engine, queries about how to use features etc.
Maya
Halfling
Posts: 71
Joined: Fri Oct 11, 2013 8:50 pm

Quaternion and Euler angles to limit bone rotation

Post by Maya »

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
Maya
Halfling
Posts: 71
Joined: Fri Oct 11, 2013 8:50 pm

Re: Quaternion and Euler angles to limit bone rotation

Post by Maya »

i can't yet reorient the bone to the boundery of the limit
idea? :shock:
User avatar
tod
Troll
Posts: 1394
Joined: Wed Aug 02, 2006 9:41 am
Location: Bucharest
x 94

Re: Quaternion and Euler angles to limit bone rotation

Post by tod »

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.
Maya
Halfling
Posts: 71
Joined: Fri Oct 11, 2013 8:50 pm

Re: Quaternion and Euler angles to limit bone rotation

Post by Maya »

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

Code: Select all

angl=skel->getBone("elbow")->getOrienttaion()->getYaw();
if (angl >limitmax)
{
   skel->getBone("elbow")->yaw(limitmax);
}
is it like that?
User avatar
tod
Troll
Posts: 1394
Joined: Wed Aug 02, 2006 9:41 am
Location: Bucharest
x 94

Re: Quaternion and Euler angles to limit bone rotation

Post by tod »

Not sure if yaw is absolute or relative, it may be relative.
Maya
Halfling
Posts: 71
Joined: Fri Oct 11, 2013 8:50 pm

Re: Quaternion and Euler angles to limit bone rotation

Post by Maya »

Hi
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));}
nothing was changed
Maya
Halfling
Posts: 71
Joined: Fri Oct 11, 2013 8:50 pm

Re: Quaternion and Euler angles to limit bone rotation

Post by Maya »

No it's relative , the limits are relative to their parent
User avatar
tod
Troll
Posts: 1394
Joined: Wed Aug 02, 2006 9:41 am
Location: Bucharest
x 94

Re: Quaternion and Euler angles to limit bone rotation

Post by tod »

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.
Maya
Halfling
Posts: 71
Joined: Fri Oct 11, 2013 8:50 pm

Re: Quaternion and Euler angles to limit bone rotation

Post by Maya »

Code: Select all

newOrientation = oldOrientation * newRotation (if this is the correct order?)
i did not understnd well what you want to said to me here,
did you mean that instead using

Code: Select all

skel->getBone(i)->getParent()->rotate(quat1,Ogre::Node::TS_WORLD);
i use this ewOrientation = oldOrientation * newRotation?
User avatar
tod
Troll
Posts: 1394
Joined: Wed Aug 02, 2006 9:41 am
Location: Bucharest
x 94

Re: Quaternion and Euler angles to limit bone rotation

Post by tod »

I mean you compute the final orientation before actually rotating/orienting, and you only allow the rotation if it is inside the desired zone.
Maya
Halfling
Posts: 71
Joined: Fri Oct 11, 2013 8:50 pm

Re: Quaternion and Euler angles to limit bone rotation

Post by Maya »

that's short screen what i get with my first code
arm_op.png
in the red circle you can see that's there is problem in this bone
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
You do not have the required permissions to view the files attached to this post.
Maya
Halfling
Posts: 71
Joined: Fri Oct 11, 2013 8:50 pm

Re: Quaternion and Euler angles to limit bone rotation

Post by Maya »

I mean you compute the final orientation before actually rotating/orienting, and you only allow the rotation if it is inside the desired zone.
i tried using this code

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);
it give me the same result
Stepan_
Gnoblar
Posts: 2
Joined: Tue Mar 04, 2014 7:33 am

Re: Quaternion and Euler angles to limit bone rotation

Post by Stepan_ »

I have similar problem. I want some range to limit pitch of camera.

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));
    }
}
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