About Store Forum Documentation Contact



Post Reply 
Rotating object: Phys and Mesh out of sync
Author Message
SONB Offline
Member

Post: #1
Rotating object: Phys and Mesh out of sync
Hi, Esenthel!

As I said before, I made a class for my ship, which extends the Item class. Now I'm trying to rotate the ship with this code:
Code:
Bool Ship::update()
{
    if(Kb.b(KB_NP4)) {
        T.pos(T.matrix().pos - T.matrix().x*0.2);
    }else if(Kb.b(KB_NP6)) {
        T.pos(T.matrix().pos + T.matrix().x*0.2);
    }
    if(Kb.b(KB_NP8)) {
        T.pos(T.matrix().pos - T.matrix().z*0.2);
    }else if(Kb.b(KB_NP2)) {
        T.pos(T.matrix().pos + T.matrix().z*0.2);
    }
    if(Kb.b(KB_NP7)) {
        Matrix m = T.matrix();
        m.orn.rotateY(DegToRad(-5));
        T.matrix(m);
    }else if(Kb.b(KB_NP9)) {
        Matrix m = T.matrix();
        m.orn.rotateY(DegToRad(5));
        T.matrix(m);
    }
    
    if(__super::update()) {
        part.set(Vec(T.pos().x, T.pos().y, T.pos().z+1.2));   // Updating particles of the ship engines - position is not right yet!
        part.update();

        return true;
    }

    return false;
}

I don't know if I'm using the matrix transformations correctly. I can move and rotate the ship, so that it always flies along its Z axis and rotates around its local Y axis.
But there is a problem with physics synchronization. The physical body of the ship seems to rotate slower than the ship itself. After 2 or 3 full rotations the angle between the body and the ship grows up to ~45 degrees. After that the physical body scales along X and Z axis and gets so large that I always get an exception.
Does it happen because of wrong matrix transformation? Or is it a bug?


Thank you in advance!


SONB
04-15-2009 12:09 AM
Find all posts by this user Quote this message in a reply
Esenthel Offline
Administrator

Post: #2
Re: Rotating object: Phys and Mesh out of sync
Hello,

instead of modifying the position and matrix manually each frame, you should more like apply forces to the actor.

check the various methods in the Actor.h header file for applying forces/velocities, methods such as addVel addForce addTorque and so on
04-15-2009 12:41 AM
Find all posts by this user Quote this message in a reply
Esenthel Offline
Administrator

Post: #3
Re: Rotating object: Phys and Mesh out of sync
and for the scaling issue, you could try normalizing the matrix after applying the rotation

m.orn.rotateY(..);
m.normalize();
04-15-2009 12:44 AM
Find all posts by this user Quote this message in a reply
SONB Offline
Member

Post: #4
Re: Rotating object: Phys and Mesh out of sync
Yeah, I just wanted to see my brand new ship in 'action' without getting dirty with physics, you know smile

Ok, I'll take a look at the Actor.h now.

Thanx for fast reply, Esenthel!
04-15-2009 12:53 AM
Find all posts by this user Quote this message in a reply
SONB Offline
Member

Post: #5
Re: Rotating object: Phys and Mesh out of sync
Great! Normalizing solved the problem grin
There is no scaling, and the body rotates in sync with the ship.

Thanx a lot, Esenthel!
04-15-2009 12:57 AM
Find all posts by this user Quote this message in a reply
SONB Offline
Member

Post: #6
Re: Rotating object: Phys and Mesh out of sync
I was wrong, the normalization doesn't work. The body keeps on scaling.
Never mind, I'm going to add forces right now.
04-15-2009 01:21 AM
Find all posts by this user Quote this message in a reply
Esenthel Offline
Administrator

Post: #7
Re: Rotating object: Phys and Mesh out of sync
that's weird, the cpu precission issues shouldnt be that big.

you should check the length of the axes in debug mode

Flt x_length=matrix.x.length(),
y_length=matrix.y.length(),
z_length=matrix.z.length();

and see if they're near 1.0
04-15-2009 09:37 AM
Find all posts by this user Quote this message in a reply
SONB Offline
Member

Post: #8
Re: Rotating object: Phys and Mesh out of sync
Yes, they are exactly 1.000 long.
04-15-2009 02:00 PM
Find all posts by this user Quote this message in a reply
Esenthel Offline
Administrator

Post: #9
Re: Rotating object: Phys and Mesh out of sync
so the scaling problem should lay somewhere else, are you using default drawing method or a custom one?
04-15-2009 02:03 PM
Find all posts by this user Quote this message in a reply
SONB Offline
Member

Post: #10
Re: Rotating object: Phys and Mesh out of sync
I'm using a custom method:
Code:
void Ship::draw()
{
    __super::draw();

    if(Renderer()==RM_PALETTE) {
        part.draw();                           // Ship engine particles
    }

    SetMatrix(); // reset drawing matrix

    T.matrix().pos.draw(GREY,0.02f);                    // draw matrix position with grey color
    D.line(RED  , T.matrix().pos, T.matrix().pos+T.matrix().x*2.5); // draw matrix 'x' (right  ) vector with red   color
    D.line(GREEN, T.matrix().pos, T.matrix().pos+T.matrix().y*2.5); // draw matrix 'y' (up     ) vector with green color
    D.line(BLUE , T.matrix().pos, T.matrix().pos+T.matrix().z*2.5); // draw matrix 'z' (forward) vector with blue  color

    D.text(0,0.5,S+"X: "+x_length+" Y: "+y_length+" Z: "+z_length);
}

Here I'm drawing some particles, matrix vectors for debugging and its axis length.
04-15-2009 02:11 PM
Find all posts by this user Quote this message in a reply
Esenthel Offline
Administrator

Post: #11
Re: Rotating object: Phys and Mesh out of sync
code looks ok, so does the matrix lines (red green and blue) are always of the same length?
and are perpendicular to each other?
04-15-2009 02:30 PM
Find all posts by this user Quote this message in a reply
Esenthel Offline
Administrator

Post: #12
Re: Rotating object: Phys and Mesh out of sync
I've made a quick test and everything works fine here

Code:
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Actor ground,
      box   ,
      ball  ;
/******************************************************************************/
void InitPre()
{
   App.name("Physics");
   App.flag=APP_MS_EXCLUSIVE|APP_NO_FX;
   PakAdd("../data/engine.pak");
   D.sync(true);
}
Bool Init()
{
   Cam.dist=4;

   // create physics
   Physics.create();

   // create actors
   ground.create(Box (15,1,15,Vec(0  ,-2, 0)), 0); // create ground actor from Box and density=0 (which means it's a static actor - will not move)
   box   .create(Box (0.3    ,Vec(0.1, 1, 0)));
   ball  .create(Ball(0.3    ,Vec(  0, 0, 0)));

   return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
   if(Kb.bp(KB_ESC))return false;
   CamHandle(0.1,10,CAMH_ZOOM|CAMH_ROT);

   Physics.sim(); // start frame simulation
   Physics.get(); // get results of frame simulation

   Matrix m=box.matrix(); m.orn.rotateY(Tm.d()*7);
   box.matrix(m); box.gravity(false);

   return true;
}
/******************************************************************************/
void Draw()
{
   D      .clear();
   Physics.draw (); // draw physical actors
}
/******************************************************************************/
04-15-2009 02:33 PM
Find all posts by this user Quote this message in a reply
SONB Offline
Member

Post: #13
Re: Rotating object: Phys and Mesh out of sync
Hmm.. yes the lines are always of the same length and perpendicular to each other.
04-15-2009 02:42 PM
Find all posts by this user Quote this message in a reply
xzessmedia Offline
Member

Post: #14
RE: Rotating object: Phys and Mesh out of sync
hi there, i have the problem that my mesh doesn't sync with my physmodel..

i created a physbody with the editor and i linked my class successfully

here is the code:
Code:
/********************************************************************************​***********
* Tauri Defense Ship Class
* written by Tim Koepsel <tim.koepsel@xzessmedia.de>
********************************************************************************​***********/
class Ship : public Game::Obj
{
  
public:
   Ship();
   ~Ship();
  
   void create(Game::ObjParams &obj);
   bool update();
  
   uint drawPrepare();
   void drawShadow();
  
   Actor getActor()     {   return actor;   }
  
  
   virtual Vec    pos         (                )   {     return _matrix.pos      ;}    // get position
   virtual Matrix matrix      (                )   {     return _matrix          ;}    // get matrix
           Matrix matrixscaled(                )   {     return _matrixscaled    ;}    // get matrix
   virtual void   pos   (C Vec    &pos   )         { _matrix.pos = pos; _matrixscaled.pos = pos; } // set position
   virtual void   matrix(C Matrix &matrix)         { _matrix     = matrix; _matrixscaled = _matrix; _matrixscaled.scaleOrn(scale); } // set matrix, for most classes 'matrix' should be normalized
  
private:
   Matrix _matrix;
   Matrix _matrixscaled;
  
   Vec         scale;
   MeshPtr     mesh;
   MaterialPtr material;
   PhysBodyPtr phys;
   Actor       actor;
  
   bool        isAlive;

   // Custom Parameters
   Str shipname;
   int hull;
   int shield;
   int attack;
   int defense;
   flt speed;
   flt angle;
  
  
}  

Ship::Ship()
{  
      // Read Custom Parameters
      shipname    = "Unbenannt";
      hull        = 10;
      shield      = 10;
      attack      = 10;
      defense     = 10;  
        
      angle       = 0;
      speed       = 5;
      
      isAlive     = true;
}

Ship::~Ship()
{
  
}

void Ship::create(Game.ObjParams &obj)
{
      scale          =  obj.scale3();
      mesh           =  obj.mesh();
      material       =  obj.material();
      phys           =  obj.phys();
      
      _matrix        =  obj.matrixFinal().normalize();
      _matrixscaled  =  _matrix;
      _matrixscaled.scaleOrn(scale);
      
      angle          = Angle(obj.matrixFinal().z.xz())-PI_2;
      speed          = 5;
      
      if(phys)
      {
         actor.create(*phys, 1, scale).matrix(_matrix);
         actor.obj(this);
         actor.group(AG_CONTROLLER);
      }
      
  
      // Read Custom Parameters
      if(Param *par=obj.findParam("schiffname" ))shipname =par.asText();
      if(Param *par=obj.findParam("huelle"))hull=par.asInt ();  
      if(Param *par=obj.findParam("angriff"))attack=par.asInt ();
      if(Param *par=obj.findParam("verteidigung"))defense=par.asInt ();  
      if(Param *par=obj.findParam("schild"))shield=par.asInt ();  
      if(Param *par=obj.findParam("maxspeed"))speed=par.asFlt();  


    
}

Bool Ship::update()
{
   Vec ThrusterForce;
  
   actor.matrix(_matrix);
  
   if(Touches.elms()>=1)
   {
      if(Touches[0].tappedFirst() == true || Kb.bp(KB_SPACE) == true)
      {
         float direction = actor.matrix().angle();
         Vec directionvec =  Vec(0, Sin(DegToRad(direction)), Cos(DegToRad(direction))).normalize();
         ThrusterForce = directionvec;
        
         flt sp = (speed*5) / 100;
         actor.addForce(ThrusterForce * sp);
         Str spstr = "Shipspeed: ";
         spstr += sp;
         Log(spstr);
      }
   }
  
   // Just for testing
   if(Kb.b(KB_Y)) actor.addTorque(Vec(0, 1, 0));
   if(Kb.b(KB_C)) actor.addTorque(Vec(0, -1, 0));
   if(Kb.b(KB_A)) _matrix.rotateY(0.1);
   if(Kb.b(KB_D)) _matrix.rotateY(-0.1);
  
   Log("Ship is getting updated...");
  
   return isAlive;
  

}


uint Ship::drawPrepare()
{
   if(mesh && Frustum(mesh->box, _matrixscaled))
   {
      MaterialLock = material();
      mesh->draw(_matrixscaled);
      
      MaterialLock = NULL;
   }
   return NULL;
}

void Ship::drawShadow()
{
   if(mesh && Frustum(mesh->box, _matrixscaled))
   {
      MaterialLock = material();
      mesh->drawShadow(_matrixscaled);
      MaterialLock = NULL;
   }
}

i attached a small vid to show what i mean...
Watch the video (Quicktime)
(please use rightclick and download as...)
in the video i press key_a and key_d and after that key_y and key_c
i know i do something wrong
can anybody tell me what i am doing wrong?
(This post was last modified: 06-11-2013 11:38 PM by xzessmedia.)
06-11-2013 10:32 PM
Find all posts by this user Quote this message in a reply
Rubeus Offline
Member

Post: #15
RE: Rotating object: Phys and Mesh out of sync
I had issues with the physics getting out of sync when I modified the matrix directly. Instead of
if(Kb.b(KB_A)) _matrix.rotateY(0.1);
if(Kb.b(KB_D)) _matrix.rotateY(-0.1);
try something like
if(Kb.b(KB_A)) actor.addAngVel(Vec(0, 0.1, 0));
if(Kb.b(KB_D)) actor.addAngVel(Vec(0, -0.1, 0));

I was able to get it working by playing with those values and actor.adamping(x)
See if that works for you.

Edit:
FYI, I don't have a quicktime codec installed, so I don't exactly know if you are having the same issue as me.
(This post was last modified: 06-12-2013 01:01 AM by Rubeus.)
06-12-2013 12:59 AM
Find all posts by this user Quote this message in a reply
Post Reply