SONB
Member
|
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 |
|
Esenthel
Administrator
|
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 |
|
Esenthel
Administrator
|
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 |
|
SONB
Member
|
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
Ok, I'll take a look at the Actor.h now.
Thanx for fast reply, Esenthel!
|
|
04-15-2009 12:53 AM |
|
SONB
Member
|
Re: Rotating object: Phys and Mesh out of sync
Great! Normalizing solved the problem
There is no scaling, and the body rotates in sync with the ship.
Thanx a lot, Esenthel!
|
|
04-15-2009 12:57 AM |
|
SONB
Member
|
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 |
|
Esenthel
Administrator
|
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 |
|
SONB
Member
|
Re: Rotating object: Phys and Mesh out of sync
Yes, they are exactly 1.000 long.
|
|
04-15-2009 02:00 PM |
|
Esenthel
Administrator
|
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 |
|
SONB
Member
|
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 |
|
Esenthel
Administrator
|
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 |
|
Esenthel
Administrator
|
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 |
|
SONB
Member
|
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 |
|
xzessmedia
Member
|
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 |
|
Rubeus
Member
|
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 |
|