Orbiter-Forum  

Go Back   Orbiter-Forum > Orbiter Space Flight Simulator > Orbiter SDK
Register Blogs Orbinauts List Social Groups FAQ Projects Mark Forums Read

Orbiter SDK Orbiter software developers post your questions and answers about the SDK, the API interface, LUA, meshing, etc.

Reply
 
Thread Tools
Old 06-20-2012, 08:13 AM   #1
dumbo2007
Crazy about real time sims
Default How to use MeshgroupTransform()

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));
These are the times I wish Orbiter has a matrix based transform method for meshes.

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.
dumbo2007 is offline   Reply With Quote
Old 06-23-2012, 05:16 PM   #2
dumbo2007
Crazy about real time sims
Default

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
Here is how the code looks :

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
The problem seems to be in the data points :

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);*/


        }
Got rid of the Euler angle conversion issues. Roll and Yaw are actually rotations around X and Z respectively and are in the range [-180, +180]

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
My primary purpose is to provide a simple way to display the collision mesh on top of the Orbiter mesh in the Orbiter window, so they can be aligned or adjusted in real time using manipulators. Seems I ll stick with animations for mesh transformations for now since it would also be supported in the clients.

Last edited by dumbo2007; 06-23-2012 at 05:22 PM.
dumbo2007 is offline   Reply With Quote
Old 06-23-2012, 05:32 PM   #3
jedidia
shoemaker without legs
 
jedidia's Avatar
Default

Quote:
I am trying to use meshgroup tranform to translate and orient a mesh.
Sorry for the late reply, although I'm afraid I can't help much with the issue at hand. All That comes to mind is that to transform the whole mesh, MeshTransform would probably be better suited than MeshGroupTransform. However, there's the problem of MeshTransform not yet being supported by graphics clients. Someone posted a function to do the same by manipulating the mesh directly in the DX11 thread.

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.
jedidia is offline   Reply With Quote
Old 06-23-2012, 05:43 PM   #4
dumbo2007
Crazy about real time sims
Default

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
dumbo2007 is offline   Reply With Quote
Old 06-23-2012, 08:03 PM   #5
jedidia
shoemaker without legs
 
jedidia's Avatar
Default

Quote:
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
Well, as far as I know, that's what MeshgroupTransform does... might be mistaken, though. In any case, it will transform the mesh, but not the mesh orientation, so the axes will still point n the same direction. Might get a bit confusing to propagate movement this way...
jedidia is offline   Reply With Quote
Thanked by:
Old 06-23-2012, 09:50 PM   #6
dumbo2007
Crazy about real time sims
Default

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.
dumbo2007 is offline   Reply With Quote
Old 06-23-2012, 10:25 PM   #7
jedidia
shoemaker without legs
 
jedidia's Avatar
Default

Quote:
I would ultimately like to setup a kind of toolbar in a separate window(like the vessel selector).
You can make a dialog box for that purpose, no problem at all. Do you know if your system will get in a dogfight with Martins upcomming "convex hull" dynamics using touchdown points? Well, we probably have to wait for the next Beta to come out to say that...

Quote:
How does all this sound ? Would it be a desirable workflow for vessel developers
It sounds good. Just give me a programming interface with the thing, so I can make IMS compatible with it...
jedidia is offline   Reply With Quote
Old 06-23-2012, 11:01 PM   #8
dumbo2007
Crazy about real time sims
Default

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.
dumbo2007 is offline   Reply With Quote
Reply

  Orbiter-Forum > Orbiter Space Flight Simulator > Orbiter SDK


Thread Tools

Posting Rules
BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
Forum Jump


All times are GMT. The time now is 08:52 PM.

Quick Links Need Help?


About Us | Rules & Guidelines | TOS Policy | Privacy Policy

Orbiter-Forum is hosted at Orbithangar.com
Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Copyright ©2007 - 2012, Orbiter-Forum.com. All rights reserved.