![]() |
|
|||||||
| Orbiter SDK Orbiter software developers post your questions and answers about the SDK, the API interface, LUA, meshing, etc. |
![]() |
|
|
Thread Tools |
|
|
#1 |
|
Crazy about real time sims
|
Hi,
I am trying to use meshgroup tranform to translate and orient a mesh. Basically I undo the previous translations and rotations(x, y, z). Tnen do the new rotations and translation. This way I do not need to calculate a delta each time for translation or rotations. Also my rotations are from a OpenGL based system (right handed system). The rotations are Euler angles in the range of [-PI to PI] Given all these conditions how do I transform the mesh ? Code:
//Get the physics transform
rbSimple->getMotionState()->getWorldTransform(trans);
v = trans.getOrigin();
VISHANDLE hvisCar = *oapiObjectVisualPtr (oapiGetObjectByName("Brighton Beach"));
if(hvisCar != NULL){
MESHGROUP_TRANSFORM mt;
float angle;
//undo translation
mt.P.transparam.shift = -rposCurrent;
mt.transform = mt.TRANSLATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);
//undo x rotation first as it will be applied last
mt.P.rotparam.angle = -x1;
mt.P.rotparam.ref = _V(0, 0, 0);
mt.P.rotparam.axis = _V(1, 0, 0);
mt.transform = mt.ROTATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);
//undo y rotation
mt.P.rotparam.angle = -y1 ;
mt.P.rotparam.ref = _V(0.f, 0.f, 0.f);
mt.P.rotparam.axis = _V(0, 1, 0);
mt.transform = mt.ROTATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);
//undo z rotation
mt.P.rotparam.angle = -z1;
mt.P.rotparam.ref = _V(0, 0, 0);
mt.P.rotparam.axis = _V(0, 0, 1);
mt.transform = mt.ROTATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);
//-------------------------- now do the current iteration transform -----------------------
// get rotations from physics
trans.getBasis().getEulerZYX(rz, ry, rx);
//do z rotation
z1 = (rz >= 0) ? rz : (PI2 + rz);
mt.P.rotparam.angle = z1;
mt.P.rotparam.ref = _V(0, 0, 0);
mt.P.rotparam.axis = _V(0, 0, 1);
mt.transform = mt.ROTATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);
//do y rotation
y1 = (ry >= 0) ? ry : (PI2 + ry);
mt.P.rotparam.angle = y1 ;
mt.P.rotparam.ref = _V(0.f, 0.f, 0.f);
mt.P.rotparam.axis = _V(0, 1, 0);
mt.transform = mt.ROTATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);
//do x rotation finally !!
x1 = (rx >= 0) ? rx : (PI2 + rx);
mt.P.rotparam.angle = x1;
mt.P.rotparam.ref = _V(0, 0, 0);
mt.P.rotparam.axis = _V(1, 0, 0);
mt.transform = mt.ROTATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);
//now we can happily translate !
mt.P.transparam.shift = _V(BT3ARGS(v));
mt.transform = mt.TRANSLATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);
oapiWriteLogV("%f, %f, %f >> %f, %f, %f", rx, ry, rz, x1, y1, z1);
}
rposCurrent = _V(BT3ARGS(v));
Well anyway, the lines [/code] x1 = (rx >= 0) ? rx : (PI2 + rx); [/code] are for handling the negative range and converting it to the range of [0, 2*PI], I think the angle parameter in the rotations accept angles only in [0, 2*PI]. The mesh does not rotate correctly or ends up in weird angles. Maybe the order is not correct, I don't know . Anyone has some sample code or knows the order of rotation ?---------- Post added at 01:12 PM ---------- Previous post was at 11:53 AM ---------- This is the code I use when I use the delta of the rotations : Code:
//Get the physics transform
rbSimple->getMotionState()->getWorldTransform(trans);
v = trans.getOrigin();
VECTOR3 delta = _V(BT3ARGS(v)) - rposCurrent;
trans.getBasis().getEulerYPR(ry, rx, rz);
x1 = (rx >= 0) ? rx : (PI2 + rx);
y1 = (ry >= 0) ? ry : (PI2 + ry);
z1 = (rz >= 0) ? rz : (PI2 + rz);
VECTOR3 deltaRot = _V(x1, y1, z1) - rot;
VISHANDLE hvisCar = *oapiObjectVisualPtr (oapiGetObjectByName("Brighton Beach"));
if(hvisCar != NULL){
MESHGROUP_TRANSFORM mt;
float angle;
mt.P.transparam.shift = -rposCurrent;
mt.transform = mt.TRANSLATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);
//Forward left wheel
mt.P.rotparam.angle = deltaRot.y ;
mt.P.rotparam.ref = _V(0.f, 0.f, 0.f);
mt.P.rotparam.axis = _V(0, 1, 0);
mt.transform = mt.ROTATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);
//Forward left wheel
mt.P.rotparam.angle = deltaRot.z;
mt.P.rotparam.ref = _V(0, 0, 0);
mt.P.rotparam.axis = _V(0, 0, 1);
mt.transform = mt.ROTATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);
//Forward left wheel
mt.P.rotparam.angle = deltaRot.x;
mt.P.rotparam.ref = _V(0, 0, 0);
mt.P.rotparam.axis = _V(1, 0, 0);
mt.transform = mt.ROTATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);
//translation
mt.P.transparam.shift = _V(BT3ARGS(v));
mt.transform = mt.TRANSLATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);
oapiWriteLogV("phy:%f, %f, %f, delta: %f, %f, %f >> %f, %f, %f", rx, ry, rz, x1, y1, z1);
sprintf(oapiDebugString(), "%f, %f, %f >> %f, %f, %f", rx, ry, rz, V3ARGS(deltaRot), x1, y1, z1);
}
rposCurrent = _V(BT3ARGS(v));
rot = _V(x1, y1, z1);
---------- Post added at 01:43 PM ---------- Previous post was at 01:12 PM ---------- ok Now I have modified the code to not add/subtract PI. The rotations seems smooth with no sudden 180 deg turn arounds, but the orientation is still wrong. I have negated each angle for converting from right to left handed. Code:
rbSimple->getMotionState()->getWorldTransform(trans);
//trans.getOpenGLMatrix(m);
v = trans.getOrigin();
VECTOR3 delta = _V(BT3ARGS(v)) - rposCurrent;
trans.getBasis().getEulerYPR(ry, rx, rz);
x1 = - ry;
y1 = - rx;
z1 = - rz;
VECTOR3 deltaRot = _V(x1, y1, z1) - rot;
VISHANDLE hvisCar = *oapiObjectVisualPtr (oapiGetObjectByName("Brighton Beach"));
if(hvisCar != NULL){
MESHGROUP_TRANSFORM mt;
float angle;
// Undo translation
mt.P.transparam.shift = -rposCurrent;
mt.transform = mt.TRANSLATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);
//ry
mt.P.rotparam.angle = deltaRot.y ;
mt.P.rotparam.ref = _V(0.f, 0.f, 0.f);
mt.P.rotparam.axis = _V(0, 1, 0);
mt.transform = mt.ROTATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);
//rz
mt.P.rotparam.angle = deltaRot.z;
mt.P.rotparam.ref = _V(0, 0, 0);
mt.P.rotparam.axis = _V(0, 0, 1);
mt.transform = mt.ROTATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);
//rx
mt.P.rotparam.angle = deltaRot.x;
mt.P.rotparam.ref = _V(0, 0, 0);
mt.P.rotparam.axis = _V(1, 0, 0);
mt.transform = mt.ROTATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);
//translation
mt.P.transparam.shift = _V(BT3ARGS(v));
mt.transform = mt.TRANSLATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);
oapiWriteLogV("phy:%f, %f, %f, delta: %f, %f, %f >> %f, %f, %f", rx, ry, rz, V3ARGS(deltaRot), x1, y1, z1);
sprintf(oapiDebugString(), "%f, %f, %f >> %f, %f, %f", rx, ry, rz, x1, y1, z1);
}
rposCurrent = _V(BT3ARGS(v));
rot = _V(x1, y1, z1);
Last edited by dumbo2007; 06-20-2012 at 04:21 PM. |
|
|
|
|
|
#2 |
|
Crazy about real time sims
|
Well I have reduced the issue down to more manageable proportions:
So I have decided not to use the change in rotation and supply that to MeshgroupTransform(). Instead I will be undo-ing the previous rotation and thus rotating the mesh back to 0. Then doing the rotation for the current iteration. At least till I have rotation working smoothly. Also, I am concentrating on only 1 axis now, the Y-axis or the Yaw-axis. Here is a video as usual of how things appear now : It seems to be a classic Euler angles to [0, 360] angle range conversion problem which I am sure many people have seen and solved before. I have got loads of data on the angles of course : Previous Angle : The angle as in the previous iteration. This is 1st undone Current Angle : This is the angle calculated from the angle given to me by Bullet (the Bullet Angle) Bullet Angle : This is the angle which Bullet is giving me from a function called getEulerYPR() : http://bulletphysics.com/Bullet/Bull...d5804d5cf31343 I do think the angle returned by this function is correct as far as Euler angles go. Bullet is after all used by many professional quality games. Angle Applied : This is the angle which I give to Bullet to rotate the body(its probably using quaternions or something similar inside to apply and store the angle, it doesnt matter.). You will see this angle cycle from 0 ->360->0 in 5 degree increments. Code:
Previous Angle | Current Angle | Bullet Angle | Angle Applied -24728977613.06772 | -0.00000 | -0.00000 | 0.00000 -0.00000 | 5.00000 | 5.00000 | 5.00000 5.00000 | 10.00000 | 10.00000 | 10.00000 10.00000 | 15.00000 | 15.00000 | 15.00000 15.00000 | 20.00000 | 20.00000 | 20.00000 20.00000 | 25.00000 | 25.00000 | 25.00000 25.00000 | 30.00000 | 30.00000 | 30.00000 30.00000 | 35.00000 | 35.00000 | 35.00000 35.00000 | 40.00000 | 40.00000 | 40.00000 40.00000 | 45.00000 | 45.00000 | 45.00000 45.00000 | 50.00000 | 50.00000 | 50.00000 50.00000 | 55.00000 | 55.00000 | 55.00000 55.00000 | 59.99999 | 59.99999 | 59.99999 59.99999 | 64.99999 | 64.99999 | 64.99999 64.99999 | 70.00001 | 70.00001 | 69.99999 70.00001 | 74.99999 | 74.99999 | 74.99999 74.99999 | 80.00001 | 80.00001 | 79.99999 80.00001 | 85.00002 | 85.00002 | 84.99999 85.00002 | 89.98022 | 89.98022 | 89.99999 <------------ increasing 89.98022 | 85.00002 | 85.00002 | 94.99999 <------------ dropping !! 85.00002 | 80.00001 | 80.00001 | 99.99999 80.00001 | 75.00003 | 75.00003 | 104.99999 75.00003 | 70.00001 | 70.00001 | 109.99998 70.00001 | 65.00001 | 65.00001 | 114.99999 65.00001 | 59.99999 | 59.99999 | 119.99999 59.99999 | 55.00001 | 55.00001 | 124.99999 55.00001 | 50.00001 | 50.00001 | 129.99999 50.00001 | 45.00001 | 45.00001 | 134.99999 45.00001 | 40.00002 | 40.00002 | 139.99999 40.00002 | 35.00001 | 35.00001 | 144.99998 35.00001 | 30.00002 | 30.00002 | 149.99998 30.00002 | 25.00002 | 25.00002 | 154.99998 25.00002 | 20.00002 | 20.00002 | 159.99998 20.00002 | 15.00002 | 15.00002 | 164.99998 15.00002 | 10.00002 | 10.00002 | 169.99998 10.00002 | 5.00002 | 5.00002 | 174.99998 5.00002 | 0.00002 | 0.00002 | 179.99998 0.00002 | 355.00001 | -4.99998 | 184.99998 355.00001 | 350.00001 | -9.99998 | 189.99998 350.00001 | 345.00001 | -14.99997 | 194.99997 345.00001 | 340.00001 | -19.99997 | 199.99997 340.00001 | 335.00002 | -24.99997 | 204.99997 335.00002 | 330.00002 | -29.99997 | 209.99997 330.00002 | 325.00004 | -34.99997 | 214.99997 325.00004 | 320.00002 | -39.99997 | 219.99997 320.00002 | 315.00002 | -44.99997 | 224.99997 315.00002 | 310.00002 | -49.99998 | 229.99998 310.00002 | 305.00002 | -54.99998 | 234.99998 305.00002 | 300.00002 | -59.99998 | 239.99998 300.00002 | 295.00002 | -64.99998 | 244.99998 295.00002 | 290.00002 | -69.99998 | 249.99998 290.00002 | 285.00000 | -75.00000 | 254.99998 285.00000 | 280.00000 | -80.00001 | 259.99998 280.00000 | 275.00003 | -84.99998 | 264.99997 275.00003 | 270.00000 | -90.00000 | 269.99997 270.00000 | 274.99997 | -85.00002 | 274.99997 274.99997 | 279.99997 | -80.00003 | 279.99997 279.99997 | 284.99997 | -75.00003 | 284.99997 284.99997 | 289.99997 | -70.00004 | 289.99997 289.99997 | 294.99997 | -65.00003 | 294.99997 294.99997 | 299.99997 | -60.00003 | 299.99997 299.99997 | 304.99997 | -55.00003 | 304.99997 304.99997 | 309.99997 | -50.00004 | 309.99997 309.99997 | 314.99996 | -45.00004 | 314.99996 314.99996 | 319.99996 | -40.00004 | 319.99996 319.99996 | 324.99996 | -35.00004 | 324.99996 324.99996 | 329.99996 | -30.00004 | 329.99996 329.99996 | 334.99996 | -25.00004 | 334.99996 334.99996 | 339.99996 | -20.00004 | 339.99996 339.99996 | 344.99996 | -15.00004 | 344.99996 344.99996 | 349.99996 | -10.00004 | 349.99996 349.99996 | 354.99996 | -5.00004 | 354.99996 354.99996 | 359.99996 | -0.00004 | 359.99996 359.99996 | -0.00000 | -0.00000 | 0.00000 -0.00000 | 5.00000 | 5.00000 | 5.00000 5.00000 | 10.00000 | 10.00000 | 10.00000 10.00000 | 15.00000 | 15.00000 | 15.00000 15.00000 | 20.00000 | 20.00000 | 20.00000 20.00000 | 25.00000 | 25.00000 | 25.00000 25.00000 | 30.00000 | 30.00000 | 30.00000 30.00000 | 35.00000 | 35.00000 | 35.00000 35.00000 | 40.00000 | 40.00000 | 40.00000 40.00000 | 45.00000 | 45.00000 | 45.00000 45.00000 | 50.00000 | 50.00000 | 50.00000 50.00000 | 55.00000 | 55.00000 | 55.00000 55.00000 | 59.99999 | 59.99999 | 59.99999 59.99999 | 64.99999 | 64.99999 | 64.99999 64.99999 | 70.00001 | 70.00001 | 69.99999 70.00001 | 74.99999 | 74.99999 | 74.99999 74.99999 | 80.00001 | 80.00001 | 79.99999 80.00001 | 85.00002 | 85.00002 | 84.99999 85.00002 | 89.98022 | 89.98022 | 89.99999 89.98022 | 85.00002 | 85.00002 | 94.99999 85.00002 | 80.00001 | 80.00001 | 99.99999 80.00001 | 75.00003 | 75.00003 | 104.99999 75.00003 | 70.00001 | 70.00001 | 109.99998 70.00001 | 65.00001 | 65.00001 | 114.99999 65.00001 | 59.99999 | 59.99999 | 119.99999 59.99999 | 55.00001 | 55.00001 | 124.99999 55.00001 | 50.00001 | 50.00001 | 129.99999 50.00001 | 45.00001 | 45.00001 | 134.99999 45.00001 | 40.00002 | 40.00002 | 139.99999 40.00002 | 35.00001 | 35.00001 | 144.99998 35.00001 | 30.00002 | 30.00002 | 149.99998 30.00002 | 25.00002 | 25.00002 | 154.99998 25.00002 | 20.00002 | 20.00002 | 159.99998 20.00002 | 15.00002 | 15.00002 | 164.99998 15.00002 | 10.00002 | 10.00002 | 169.99998 10.00002 | 5.00002 | 5.00002 | 174.99998 5.00002 | 0.00002 | 0.00002 | 179.99998 0.00002 | 355.00001 | -4.99998 | 184.99998 355.00001 | 350.00001 | -9.99998 | 189.99998 350.00001 | 345.00001 | -14.99997 | 194.99997 345.00001 | 340.00001 | -19.99997 | 199.99997 340.00001 | 335.00002 | -24.99997 | 204.99997 335.00002 | 330.00002 | -29.99997 | 209.99997 330.00002 | 325.00004 | -34.99997 | 214.99997 325.00004 | 320.00002 | -39.99997 | 219.99997 320.00002 | 315.00002 | -44.99997 | 224.99997 315.00002 | 310.00002 | -49.99998 | 229.99998 310.00002 | 305.00002 | -54.99998 | 234.99998 305.00002 | 300.00002 | -59.99998 | 239.99998 300.00002 | 295.00002 | -64.99998 | 244.99998 295.00002 | 290.00002 | -69.99998 | 249.99998 290.00002 | 285.00000 | -75.00000 | 254.99998 285.00000 | 280.00000 | -80.00001 | 259.99998 280.00000 | 275.00003 | -84.99998 | 264.99997 275.00003 | 270.00000 | -90.00000 | 269.99997 270.00000 | 274.99997 | -85.00002 | 274.99997 274.99997 | 279.99997 | -80.00003 | 279.99997 279.99997 | 284.99997 | -75.00003 | 284.99997 284.99997 | 289.99997 | -70.00004 | 289.99997 289.99997 | 294.99997 | -65.00003 | 294.99997 294.99997 | 299.99997 | -60.00003 | 299.99997 299.99997 | 304.99997 | -55.00003 | 304.99997 304.99997 | 309.99997 | -50.00004 | 309.99997 309.99997 | 314.99996 | -45.00004 | 314.99996 314.99996 | 319.99996 | -40.00004 | 319.99996 319.99996 | 324.99996 | -35.00004 | 324.99996 324.99996 | 329.99996 | -30.00004 | 329.99996 329.99996 | 334.99996 | -25.00004 | 334.99996 334.99996 | 339.99996 | -20.00004 | 339.99996 339.99996 | 344.99996 | -15.00004 | 344.99996 344.99996 | 349.99996 | -10.00004 | 349.99996 349.99996 | 354.99996 | -5.00004 | 354.99996 354.99996 | 359.99996 | -0.00004 | 359.99996 359.99996 | -0.00000 | -0.00000 | 0.00000 -0.00000 | 5.00000 | 5.00000 | 5.00000 5.00000 | 10.00000 | 10.00000 | 10.00000 10.00000 | 15.00000 | 15.00000 | 15.00000 15.00000 | 20.00000 | 20.00000 | 20.00000 Code:
//Get the physics transform
rbSimple->getMotionState()->getWorldTransform(trans);
//trans.getOpenGLMatrix(m);
v = trans.getOrigin();
x = v.x();
y = v.y();
z = v.z();
VECTOR3 delta = _V(BT3ARGS(v)) - rposCurrent;
VISHANDLE hvisCar = *oapiObjectVisualPtr (oapiGetObjectByName("Brighton Beach"));
if(hvisCar != NULL){
MESHGROUP_TRANSFORM mt;
// Undo the previous translation
mt.P.transparam.shift = -rposCurrent;
mt.transform = mt.TRANSLATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);
// Undo angle
float y2 = (ry >= 0) ? ry : (PI2 + ry);
//negate previous ry
mt.P.rotparam.angle = -y2 ;
mt.P.rotparam.ref = _V(0.f, 0.f, 0.f);
mt.P.rotparam.axis = _V(0, 1, 0);
mt.transform = mt.ROTATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);
trans.getBasis().getEulerYPR(rx, ry, rz);
y1 = (ry >= 0) ? ry : (PI2 + ry);
//ry
mt.P.rotparam.angle = y1 ;
mt.P.rotparam.ref = _V(0.f, 0.f, 0.f);
mt.P.rotparam.axis = _V(0, 1, 0);
mt.transform = mt.ROTATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);
//translation
mt.P.transparam.shift = _V(BT3ARGS(v));
mt.transform = mt.TRANSLATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);
oapiWriteLogV("%3.5f | %3.5f | %3.5f | %3.5f", y2*DEG, y1*DEG, ry*DEG, ry1*DEG);
sprintf(oapiDebugString(), "%3.5f >> %3.5f | %3.5f | %3.5f", y2*DEG, y1*DEG, ry*DEG, ry1*DEG);
}
rposCurrent = _V(BT3ARGS(v));
// Apply a rotation
trans.setIdentity();
trans.setOrigin(v);
ry1 += 5.f * RAD;
if(ry1 > PI2)
ry1 = 0.;
q.setEuler( ry1, 0, 0);
trans.setRotation(q);
rbSimple->getMotionState()->setWorldTransform(trans);
rbSimple->setActivationState(DISABLE_DEACTIVATION); //so bullet gets transform from body
15.00002 | 10.00002 | 10.00002 | 169.99998 10.00002 | 5.00002 | 5.00002 | 174.99998 5.00002 | 0.00002 | 0.00002 | 179.99998 0.00002 | 355.00001 | -4.99998 | 184.99998 355.00001 | 350.00001 | -9.99998 | 189.99998 350.00001 | 345.00001 | -14.99997 | 194.99997 when the euler angle reported by Bullet suddenly goes negative. I start adding 360 deg to the angle to bring it in the [0, 360] range : y1 = (ry >= 0) ? ry : (PI2 + ry); I assumed the Euler angles would go from 0->180 and then -180 -> 0 (continuing rotation along the same direction). Apparently this is not the case. The angles go from 0->90->0 then 0->-90->0 to complete a 360 deg rotation. ---------------------- Got some info, seems if I directly apply the angles then the mesh will rotate back and forth from 0->90 and then back to 0. How to convert it to tell Orbiter that this is actually 0->180 http://www.gamedev.net/topic/479130-...ation-matrix-/ and tblaxland's post here : http://orbiter-forum.com/showthread....9&postcount=13 Apparently yaw has the range [-90, 90] while pitch and roll the range of [-180, +180] That however still doesnt help me with the fact that I need to convert the yaw angle range of 0->90->0-> -90 -> 0 to 0->90->180->270->0 for 1 360 deg rotation around y-axis starting from 0 deg. Note: I cant just add 90 and translate the angles as then I get 90->180->90.... when the angle starts to drop again I have to detect that this is due to the Euler angle values and not the body suddenly rotating the other way.....which is weird ! ------------------------ I think I ll use the rotation matrix, get it into Orbiter and then calculate the angle using Orbiter's function for getting angle between 2 vectors (mesh y axis and vessel y-axis) ---------- Post added at 11:20 AM ---------- Previous post was at 02:30 AM ---------- Nope the above is a stupid idea, somehow I thought the angle between the y-axis of the mesh and the vessel in Bullet would give me the right angle. Back to the original functions. Almost there now : Code:
if(physicsInited){
//Get the physics transform
btTransform trans;
rbSimple->getMotionState()->getWorldTransform(trans);
btVector3 v = trans.getOrigin();
VISHANDLE hvisCar = *oapiObjectVisualPtr (oapiGetObjectByName("Brighton Beach"));
if(hvisCar != NULL){
MESHGROUP_TRANSFORM mt;
//-txyz
mt.P.transparam.shift = -rposCurrent;
mt.transform = mt.TRANSLATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);
//-rx
mt.P.rotparam.angle = -rx ;
mt.P.rotparam.ref = _V(0.f, 0.f, 0.f);
mt.P.rotparam.axis = _V(1, 0, 0);
mt.transform = mt.ROTATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);
//-ry
mt.P.rotparam.angle = -ry ;
mt.P.rotparam.ref = _V(0.f, 0.f, 0.f);
mt.P.rotparam.axis = _V(0, 1, 0);
mt.transform = mt.ROTATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);
//-rz
mt.P.rotparam.angle = -rz ;
mt.P.rotparam.ref = _V(0.f, 0.f, 0.f);
mt.P.rotparam.axis = _V(0, 0, 1);
mt.transform = mt.ROTATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);
//--------------------------------------------------------------------
btMatrix3x3 m_el = trans.getBasis();
ry = btAtan2( m_el[0].z(), m_el[0].x() );
if(ry < 0)
ry += SIMD_PI;
float yaw, pitch, roll;
trans.getBasis().getEulerYPR(yaw, pitch, roll);
;
rz = yaw;
if(rz < 0)
rz += SIMD_PI;
rx = roll;
if(rx < 0)
rx += SIMD_PI;
//rz
mt.P.rotparam.angle = rz ;
mt.P.rotparam.ref = _V(0.f, 0.f, 0.f);
mt.P.rotparam.axis = _V(0, 0, 1);
mt.transform = mt.ROTATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);;
//ry
mt.P.rotparam.angle = ry ;
mt.P.rotparam.ref = _V(0.f, 0.f, 0.f);
mt.P.rotparam.axis = _V(0, 1, 0);
mt.transform = mt.ROTATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);
//rx
mt.P.rotparam.angle = rx ;
mt.P.rotparam.ref = _V(0.f, 0.f, 0.f);
mt.P.rotparam.axis = _V(1, 0, 0);
mt.transform = mt.ROTATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);
//txyz
rposCurrent = _V(BT3ARGS(v));
mt.P.transparam.shift = rposCurrent;
mt.transform = mt.TRANSLATE;
mt.ngrp = 0;
mt.nmesh = mshIndex;
bumpBase->bb->MeshgroupTransform(hvisCar, mt);
oapiWriteLogV("%3.5f | (%3.5f, %3.5f, %3.5f) + (%3.5f, %3.5f, %3.5f)| (%3.5f, %3.5f, %3.5f)",
angle*DEG, rx*DEG, ry*DEG, rz*DEG, V3ARGS(rposCurrent), yaw*DEG, pitch*DEG, roll*DEG);
/*sprintf(oapiDebugString(), "%3.5f | %3.5f | (%3.5f, %3.5f, %3.5f) | %3.5f",
y2*DEG, y1*DEG, yaw*DEG, pitch*DEG, roll*DEG, angle*DEG);*/
}
Only the pitch, which strangely corresponds to rotation about Y axis, needed dealing directly with the rotation matrix to bring the range to [-180, 180] and not [-90, +90] Now I have to get the order of axes correct somehow. Only 6 combinations possible - probably will try all ![]() ---------- Post added at 10:46 PM ---------- Previous post was at 11:20 AM ---------- ------------------------ ok the experiment to get rid of animations for mesh transformations was an epic fail at the last step where none of the 6 combinations of axis rotations gave me the correct behavior. It does not seem like a workable solution till the API itself supports Euler angles for meshes. Meanwhile using animations works so darn smooth...it almost dark magic ...and with the same Euler angles !!Code:
double state = 0.0f;
//sprintf(boutput, "Bump_Plate::update: The next sim step will advance the sim by %f secs", SimDT);
//oapiWriteLog(boutput);
if(physicsInited){
//Get the physics transform
btTransform transComponent;
btVector3 originComponent;
rbSimple->getMotionState()->getWorldTransform(transComponent);
//trans.getOpenGLMatrix(m);
originComponent = transComponent.getOrigin();
x = originComponent.x();
y = originComponent.y();
z = originComponent.z();
transComponent.getBasis().getEulerYPR(rz, ry, rx);
//sprintf(output,"Sphere height: %f, rx=%f, ry=%f, rz=%f\n", trans.getOrigin().getY(), rx*180/PI, ry*180/PI, rz*180/PI);
//oapiWriteLog(output);
//Update the Orbiter mesh
state = fabs(x/Bump_BulletBase::BULLET_WORLD_SIZE);
state *= 0.5; //reduce range to within 0 to 0.5 or 0.5 to 1
state = (x > 0) ? 0.5+state : 0.5-state ; //-ve or +ve direction
bumpBase->bb->SetAnimation(animTX, state);
state = fabs(y/Bump_BulletBase::BULLET_WORLD_SIZE);
state *= 0.5; //reduce range to within 0 to 0.5 or 0.5 to 1
state = (y > 0) ? 0.5+state : 0.5-state ; //-ve or +ve direction
bumpBase->bb->SetAnimation(animTY, state);
state = fabs(z/Bump_BulletBase::BULLET_WORLD_SIZE);
state *= 0.5; //reduce range to within 0 to 0.5 or 0.5 to 1
state = (z > 0) ? 0.5+state : 0.5-state ; //-ve or +ve direction
bumpBase->bb->SetAnimation(animTZ, state);
state = fabs((rz+PI)/(2*PI) );
bumpBase->bb->SetAnimation(animRZ, state);
state = fabs((-ry+PI)/(2*PI)); //Very important to negate RY
bumpBase->bb->SetAnimation(animRY, state);
state = fabs((rx+PI)/(2*PI));
bumpBase->bb->SetAnimation(animRX, state);
rposCurrent = _V(x, y, z);
//Update terrain
if(ground){
//oapiEquToGlobal(base->hObjRefBody, lng, lat, base->rad, &gposSurfPoint);
//oapiLocalToEqu(bumpBase->hObjRefBody, _V(m[12], m[13], m[14]), &lng, &lat, &rad);
bumpBase->bb->Local2Global(rposCurrent, gposCurrent);
oapiGlobalToEqu(bumpBase->hObjRefBody, gposCurrent, &lng, &lat, &rad);
/*oapiWriteLogV("Bump_SimpleRigidBody::poststep: Converted (%f,%f,%f) to lolara(%f,%f,%f)",
m[12], m[13], m[14], lng, lat, rad);
*/
int t = ground->updatePatch(lng, lat, rad);
}
}//physics inited
Last edited by dumbo2007; 06-23-2012 at 05:22 PM. |
|
|
|
|
|
#3 |
|
shoemaker without legs
![]() |
Quote:
What I do not quite understand is why you would transform the mesh vertices themselves for what should be a rotation of the mesh in the gobal frame, but I'm probably missing something. |
|
|
|
|
|
#4 |
|
Crazy about real time sims
|
Thanks for the reply. Well I am not transforming the mesh vertices in my code above. I simply rotate the mesh using animations. No vertices at all
![]() I am yet to look at the function that manipulates the mesh directly in Dx11. It would be a welcome break if such a function has been added . At this point I am waiting for the terrain rendering to work and then I ll start testing with the client
|
|
|
|
|
|
#5 |
|
shoemaker without legs
![]() |
Quote:
|
|
|
|
| Thanked by: |
|
|
#6 |
|
Crazy about real time sims
|
Ah I see, well anyway, I am using only animations now and that seems to work well. Currently I approximate vessels like the DG with simple collision meshes consisting of basic shapes like cuboids, spheres and cylinders, all placed and scaled correctly in a kind of compound shape(list of simple shapes). For accurate collision detection I plan to support triangle meshes later which follow the curves of the ship but are at a lower triangle count. However the triangle meshes themselves will of course need to be made in a separate editor and then imported into Orbiter while it runs. These shapes are drawn by scaling their unit shapes and transforming them into positions according to their physics counterparts. That is where animations come in and do a pretty job... so far.
Since making vessels will now require a simple collision mesh as well, I guess it will be easier to edit the mesh inside Orbiter itself. So I am planning on superimposing the collision mesh on a vessel mesh when the user presses a key and open a kind of property editor panel. Here the translation, rotation and scale can be typed in to change the shape and sync it with the vessel mesh (no triangle level mesh editing) Has anyone had any success in extending the Orbiter in-sim(while simulation is running) interface with panels etc ? I would ultimately like to setup a kind of toolbar in a separate window(like the vessel selector). The toolbar will have icons for various objects/vessels that can be created and these will appear immediately in a basic form inside the Orbiter window. Like say a vehicle. Then the property editor opens which lets the user customize the vessel. How does all this sound ? Would it be a desirable workflow for vessel developers
Last edited by dumbo2007; 06-23-2012 at 10:03 PM. |
|
|
|
|
|
#7 |
|
shoemaker without legs
![]() |
Quote:
Quote:
|
|
|
|
|
|
#8 |
|
Crazy about real time sims
|
Well right now my system does not depend on touchdown points. For the DG for example, I just treat it like a 3 wheeled vehicle with similar suspension characteristics(very rigid suspension). Once the physics model is aligned with the Orbiter model, touchdown points do not make a big difference. When the DG's wheels are rolled up then the wheels in the physics vehicle are also rolled up, so when the vehicle chassis is touching the ground so is the DG chassis. There should be no difference I think.
The ground collision behavior of Orbiter will be overridden with Bullet's response as otherwise I cannot provide collisions with terrain. However the end results will be exactly the same
Last edited by dumbo2007; 06-23-2012 at 11:08 PM. |
|
|
|
![]() |
|
| Thread Tools | |
|
|
|||||
| Quick Links | Need Help? |