drleviathan wrote:As I mentioned: in general rotations don't commute, which means rotating first by Q1 and then by Q2 does not necessarily produce the same result as first rotating by Q2 and then by Q1. This means the order of qz * qy * qx matters very much.
The order that the rotations are applied, as you wrote them, is as follows: first an angle around the object's local xAxis, then an angle about the object's local yAxis, and finally a angle about its local zAxis. The rotations operate from the left on the vector, and the nearest rotation to the vector operates first.
If you know the three angles and you know that they should be applied in the order you've written them then it should Just Work. Since it isn't working we must conclude that the angles are not actually known, or the order is wrong. Since I don't know where you got your angles or ordering I can't know how to fix them. You'll have to supply more info. Specifically, what are you really trying to do? What object are you trying to rotate? How do you know the final rotation that you want to achieve?
Thank you again.
What I want to do is rotate a object(say,a cube)using free-hand.The data of two hands are from Kinect depth data. Here is the full function of object rotation which works well when rotates object around one of x,y,z axis each time. The axis will be selected by calculate the movement of two hands.
Code: Select all
void CGLPainter::BulletObjRotation(CVirtualObj **_obj)
{
if(_obj[0] == NULL) return;
S3float hand0(m_handInfo[0].x,m_handInfo[0].y,m_handInfo[0].z);
S3float hand1(m_handInfo[1].x,m_handInfo[1].y,m_handInfo[1].z);
int objNum = GetObjNum();
for (int idx = 0; idx < objNum; idx++)
{
S3float mov;
btVector3 pos = _obj[idx]->mp_btRidObj->getCenterOfMassPosition();
btTransform tranf = _obj[idx]->mp_btRidObj->getCenterOfMassTransform();
S3float center(pos[0],pos[1],pos[2]);
if (!_obj[idx]->m_xrot && !_obj[idx]->m_yrot && !_obj[idx]->m_zrot)
{
tranf.getBasis().getRotation(_obj[idx]->m_lastRot);
}
if (m_handInfo[0].status !=LOST && m_handInfo[1].status !=LOST
&& GetDisOf2Pts(hand0,center) < 180
&& GetDisOf2Pts(hand1,center) < 180)
{
btVector3 newpos = btVector3(
(m_handInfo[0].x + m_handInfo[1].x)/2.f,
(m_handInfo[0].y + m_handInfo[1].y)/2.f,
(m_handInfo[0].z + m_handInfo[1].z)/2.f
);
_obj[idx]->mp_btRidObj->setGravity(btVector3(0,0,0));
_obj[idx]->mp_btRidObj->setLinearVelocity(btVector3(0,0,0));
_obj[idx]->mp_btRidObj->setAngularVelocity(btVector3(0,0,0));
mov.x = abs(m_handDisplacement[0].x)+ abs(m_handDisplacement[1].x);
mov.y = abs(m_handDisplacement[0].y)+ abs(m_handDisplacement[1].y);
mov.z = abs(m_handDisplacement[0].z)+ abs(m_handDisplacement[1].z);
float thr = 25;
if ( !_obj[idx]->m_xrot && !_obj[idx]->m_yrot && !_obj[idx]->m_zrot)
{
DrawCircle(center,110,'n');
if (mov.x < mov.y && mov.x < mov.z)
{
if(mov.y + mov.z>thr+10)
{
_obj[idx]->m_lastAng.x = -1*atan2( (m_handInfo[0].y - m_handInfo[1].y),
(m_handInfo[0].z - m_handInfo[1].z));
_obj[idx]->m_xrot = true;
_obj[idx]->m_yrot = _obj[idx]->m_zrot = false;
}
}
else if (mov.y < mov.x && mov.y < mov.z)
{
if(mov.x + mov.z>thr)
{
_obj[idx]->m_lastAng.y = -1*atan2( (m_handInfo[0].z - m_handInfo[1].z),
(m_handInfo[0].x - m_handInfo[1].x));
_obj[idx]->m_yrot = true;
_obj[idx]->m_xrot = _obj[idx]->m_zrot = false;
}
}
else if (mov.z < mov.x && mov.z < mov.y)
{
if(mov.x + mov.y>thr)
{
_obj[idx]->m_lastAng.z = -1*atan2( (m_handInfo[0].x - m_handInfo[1].x),
(m_handInfo[0].y - m_handInfo[1].y));
_obj[idx]->m_zrot = true;
_obj[idx]->m_xrot = _obj[idx]->m_yrot = false;
}
}
}
else //in rotation
{
float angX = -1*atan2( (m_handInfo[0].y - m_handInfo[1].y),
(m_handInfo[0].z - m_handInfo[1].z));
float angY = -1*atan2( (m_handInfo[0].z - m_handInfo[1].z),
(m_handInfo[0].x - m_handInfo[1].x));
float angZ = -1*atan2( (m_handInfo[0].x - m_handInfo[1].x),
(m_handInfo[0].y - m_handInfo[1].y));
btQuaternion qx(btVector3(1,0,0),angX - _obj[idx]->m_lastAng.x);
btQuaternion qy(btVector3(0,1,0),angY - _obj[idx]->m_lastAng.y);
btQuaternion qz(btVector3(0,0,1),angZ - _obj[idx]->m_lastAng.z);
if (_obj[idx]->m_xrot)
{
DrawCircle(center,110,'x');
tranf.setRotation(qx * _obj[idx]->m_lastRot);
if(mov.y + mov.z <1.3 && mov.y + mov.z !=0)
_obj[idx]->m_xrot = false;
}
else if (_obj[idx]->m_yrot)
{
DrawCircle(center,110,'y');
tranf.setRotation(qy * _obj[idx]->m_lastRot);
if(mov.x + mov.z<1.3 && mov.x + mov.z !=0)
_obj[idx]->m_yrot = false;
}
else if (_obj[idx]->m_zrot)
{
DrawCircle(center,110,'z');
tranf.setRotation(qz * _obj[idx]->m_lastRot);
if(mov.x + mov.y<1.3 && mov.x + mov.y != 0)
_obj[idx]->m_zrot = false;
}
}
tranf.setOrigin(newpos);
_obj[idx]->mp_btRidObj->setCenterOfMassTransform(tranf);
}
//release
if ( (m_handInfo[0].status ==LOST && m_handInfo[1].status ==LOST)
|| GetDisOf2Pts(hand0,center) > 180
|| GetDisOf2Pts(hand1,center) > 180)
{
_obj[idx]->mp_btRidObj->activate();
_obj[idx]->mp_btRidObj->setGravity(btVector3(0,m_gravity,0));
_obj[idx]->m_xrot = _obj[idx]->m_yrot = _obj[idx]->m_zrot = false;
}
}
}
Also the code below is what I am trying to do and it does not work as I expected.
Code: Select all
void CGLPainter::BulletObjRotation3(CVirtualObj **_obj)
{
if(_obj[0] == NULL) return;
S3float hand0(m_handInfo[0].x,m_handInfo[0].y,m_handInfo[0].z);
S3float hand1(m_handInfo[1].x,m_handInfo[1].y,m_handInfo[1].z);
int objNum = GetObjNum();
for (int idx = 0; idx < objNum; idx++)
{
S3float mov;
btVector3 pos = _obj[idx]->mp_btRidObj->getCenterOfMassPosition();
btTransform tranf = _obj[idx]->mp_btRidObj->getCenterOfMassTransform();
S3float center(pos[0],pos[1],pos[2]);
if (m_handInfo[0].status !=LOST && m_handInfo[1].status !=LOST
&& GetDisOf2Pts(hand0,center) < 180
&& GetDisOf2Pts(hand1,center) < 180)
{
btVector3 newpos = btVector3(
(m_handInfo[0].x + m_handInfo[1].x)/2.f,
(m_handInfo[0].y + m_handInfo[1].y)/2.f,
(m_handInfo[0].z + m_handInfo[1].z)/2.f
);
_obj[idx]->mp_btRidObj->setGravity(btVector3(0,0,0));
_obj[idx]->mp_btRidObj->setLinearVelocity(btVector3(0,0,0));
_obj[idx]->mp_btRidObj->setAngularVelocity(btVector3(0,0,0));
mov.x = abs(m_handDisplacement[0].x)+ abs(m_handDisplacement[1].x);
mov.y = abs(m_handDisplacement[0].y)+ abs(m_handDisplacement[1].y);
mov.z = abs(m_handDisplacement[0].z)+ abs(m_handDisplacement[1].z);
float thr = 20;
if ( !_obj[idx]->m_xrot && !_obj[idx]->m_yrot && !_obj[idx]->m_zrot)
{
DrawCircle(center,110,'n');
tranf.getBasis().getRotation(_obj[idx]->m_lastRot);
if (mov.x < mov.y && mov.x < mov.z)
{
if(mov.y + mov.z>thr+10)
{
_obj[idx]->m_lastAng.x = -1*atan2( (m_handInfo[0].y - m_handInfo[1].y),
(m_handInfo[0].z - m_handInfo[1].z));
_obj[idx]->m_lastAng.y = -1*atan2( (m_handInfo[0].z - m_handInfo[1].z),
(m_handInfo[0].x - m_handInfo[1].x));
_obj[idx]->m_lastAng.z = -1*atan2( (m_handInfo[0].x - m_handInfo[1].x),
(m_handInfo[0].y - m_handInfo[1].y));
_obj[idx]->m_xrot = true;
_obj[idx]->m_yrot = _obj[idx]->m_zrot = false;
}
}
else if (mov.y < mov.x && mov.y < mov.z)
{
if(mov.x + mov.z>thr)
{
_obj[idx]->m_lastAng.x = -1*atan2( (m_handInfo[0].y - m_handInfo[1].y),
(m_handInfo[0].z - m_handInfo[1].z));
_obj[idx]->m_lastAng.y = -1*atan2( (m_handInfo[0].z - m_handInfo[1].z),
(m_handInfo[0].x - m_handInfo[1].x));
_obj[idx]->m_lastAng.z = -1*atan2( (m_handInfo[0].x - m_handInfo[1].x),
(m_handInfo[0].y - m_handInfo[1].y));
_obj[idx]->m_yrot = true;
_obj[idx]->m_xrot = _obj[idx]->m_zrot = false;
}
}
else if (mov.z < mov.x && mov.z < mov.y)
{
if(mov.x + mov.y>thr)
{
_obj[idx]->m_lastAng.x = -1*atan2( (m_handInfo[0].y - m_handInfo[1].y),
(m_handInfo[0].z - m_handInfo[1].z));
_obj[idx]->m_lastAng.y = -1*atan2( (m_handInfo[0].z - m_handInfo[1].z),
(m_handInfo[0].x - m_handInfo[1].x));
_obj[idx]->m_lastAng.z = -1*atan2( (m_handInfo[0].x - m_handInfo[1].x),
(m_handInfo[0].y - m_handInfo[1].y));
_obj[idx]->m_zrot = true;
_obj[idx]->m_xrot = _obj[idx]->m_yrot = false;
}
}
}
else //in rotation
{
float angX = -1*atan2( (m_handInfo[0].y - m_handInfo[1].y),
(m_handInfo[0].z - m_handInfo[1].z));
float angY = -1*atan2( (m_handInfo[0].z - m_handInfo[1].z),
(m_handInfo[0].x - m_handInfo[1].x));
float angZ = -1*atan2( (m_handInfo[0].x - m_handInfo[1].x),
(m_handInfo[0].y - m_handInfo[1].y));
btQuaternion qx(btVector3(1,0,0),angX - _obj[idx]->m_lastAng.x);
btQuaternion qy(btVector3(0,1,0),angY - _obj[idx]->m_lastAng.y);
btQuaternion qz(btVector3(0,0,1),angZ - _obj[idx]->m_lastAng.z);
DrawCircle(center,110,'x');
DrawCircle(center,110,'y');
DrawCircle(center,110,'z');
tranf.setRotation(qz * qy * qx *_obj[idx]->m_lastRot);
if(mov.y + mov.z < 2 && mov.y + mov.z !=0)
_obj[idx]->m_xrot = false;
if(mov.x + mov.z<2 && mov.x + mov.z !=0)
_obj[idx]->m_yrot = false;
if (mov.x + mov.y<2 && mov.x + mov.y != 0)
_obj[idx]->m_zrot = false;
}
tranf.setOrigin(newpos);
_obj[idx]->mp_btRidObj->setCenterOfMassTransform(tranf);
}
//release
if ( (m_handInfo[0].status ==LOST && m_handInfo[1].status ==LOST)
|| GetDisOf2Pts(hand0,center) > 180
|| GetDisOf2Pts(hand1,center) > 180)
{
_obj[idx]->mp_btRidObj->activate();
_obj[idx]->mp_btRidObj->setGravity(btVector3(0,m_gravity,0));
_obj[idx]->m_xrot = _obj[idx]->m_yrot = _obj[idx]->m_zrot = false;
}
}
}
I would really appreciate it if you could help me with this problem.