Crystal Space
Welcome, Guest. Please login or register.
September 02, 2014, 04:30:44 am

Login with username, password and session length
Search:     Advanced search
9009 Posts in 2043 Topics by 8373 Members
Latest Member: Msfilercarle03
* Home Help Search Login Register
+  Crystal Space
|-+  Associate Projects
| |-+  CEL Discussion
| | |-+  IPcMechanics and how to turn my object properly [SOLVED
« previous next »
Pages: [1] Print
Author Topic: IPcMechanics and how to turn my object properly [SOLVED  (Read 2805 times)
genjix
Jr. Member
**
Posts: 53


View Profile
« on: October 16, 2005, 01:51:11 pm »

Hi,

I am trying to code a behaviour for the main controllable object using CEL
Code:
if(strncmp(message , "pccommandinput_" , 15) == 0)
{
csRef<iPcMechanicsObject> pcmechobj = CEL_QUERY_PROPCLASS_ENT(entity , iPcMechanicsObject);
if(!pcmechobj)
return false;

// trying to compute actual force forwards based on transformation of body
if(!strcmp(message+15 , "forward1"))
pcmechobj->AddForceDuration(movement,false,csVector3(0,0,0),0.2);
else if(!strcmp(message+15 , "forward_"))
pcmechobj->AddForceDuration(csVector3(0,0,-2.5),false,csVector3(0,0,0),0.2);

else if(!strcmp(message+15 , "backward1"))
pcmechobj->AddForceDuration(csVector3(0,0,25),false,csVector3(0,0,0),0.2);
else if(!strcmp(message+15 , "backward_"))
pcmechobj->AddForceDuration(csVector3(0,0,2.5),false,csVector3(0,0,0),0.2);

else if(!strcmp(message+15 , "strafeleft1"))
pcmechobj->AddForceDuration(csVector3(25,0,0),false,csVector3(0,0,0),0.2);
else if(!strcmp(message+15 , "strafeleft_"))
pcmechobj->AddForceDuration(csVector3(2.5,0,0),false,csVector3(0,0,0),0.2);

else if(!strcmp(message+15 , "straferight1"))
pcmechobj->AddForceDuration(csVector3(-25,0,0),false,csVector3(0,0,0),0.2);
else if(!strcmp(message+15 , "straferight_"))
pcmechobj->AddForceDuration(csVector3(-2.5,0,0),false,csVector3(0,0,0),0.2);

else if(!strcmp(message+15 , "rotateleft1"))
pcmechobj->SetAngularVelocity(csVector3(0,-1,0));
else if(!strcmp(message+15 , "rotateleft0"))
pcmechobj->SetAngularVelocity(csVector3(0,0,0));

else if(!strcmp(message+15 , "rotateright1"))
pcmechobj->SetAngularVelocity(csVector3(0,1,0));
else if(!strcmp(message+15 , "rotateright0"))
pcmechobj->SetAngularVelocity(csVector3(0,0,0));

return true;
}
return false;

As you can see, I am using iPcMechanicsObject::SetAngularVelocity() to turn the object (since I am using the physics engine this is the only way of rotating the object I know of).

Code:
if(!strcmp(message+15 , "forward1"))
pcmechobj->AddForceDuration(movement,false,csVector3(0,0,0),0.2);

Like this the object moves fine, only rotating has no affect on the movement axis of the object (I can see the orientation of the mesh changing but it still always moves forwards relative to the world).
If I change the false to true (so it applies the force to the objects axis), the behaviour when I turn and go forwards is extremely strange... it will arc and spiral of just move in small circles on the spot... sometimes you can see if moving up and down in a sin wave as it moves forwards.

So, then I though something strange must be going on here so I tried this instead
Code:
if(!strcmp(message+15 , "forward1")) {
csVector3 movement(csVector3(0,0,-25) * pcmechobj->GetBody()->GetTransform());
pcmechobj->AddForceDuration(movement,false,csVector3(0,0,0),0.2);
                }
but now the behaviours just seem to have been reversed, so obviously Im missing something fundamentally important.

http://the-grid.sourceforge.net/rec.tar.gz   hopefully all you need to do is type 'make'

What can I do to make the object move in the direction I rotate it?

Thanks for your time.
« Last Edit: November 11, 2005, 01:52:08 pm by genjix » Logged
genjix
Jr. Member
**
Posts: 53


View Profile
« Reply #1 on: October 19, 2005, 04:33:49 pm »

after a conversation with Jorrit, he managed to explain to me I should transform the local vector to world space using Other2ThisRelative(csVector), so now I'm using something like:
Code:
void AddForce(csRef<iPcMechanicsObject> pcmechobj , csVector3 move)
{
move = pcmechobj->GetBody()->GetTransform().Other2ThisRelative(move);
pcmechobj->AddForceDuration(move,false,csVector3(0,0,0),0.2);
}

bool Behaviour::SendMessageV(const char *message , iCelPropertyClass *pc , celData &ret ,
iCelParameterBlock *params , va_list args)
{
if(strncmp(message , "pccommandinput_" , 15) == 0)
{
csRef<iPcMechanicsObject> pcmechobj = CEL_QUERY_PROPCLASS_ENT(entity , iPcMechanicsObject);
if(!pcmechobj)
return false;

if(!strcmp(message+15 , "forward1"))
AddForce(pcmechobj , csVector3(0,0,-25));
else if(!strcmp(message+15 , "forward_"))
AddForce(pcmechobj , csVector3(0,0,-2.5));

else if(!strcmp(message+15 , "backward1"))
AddForce(pcmechobj , csVector3(0,0,25));
else if(!strcmp(message+15 , "backward_"))
AddForce(pcmechobj , csVector3(0,0,2.5));

else if(!strcmp(message+15 , "strafeleft1"))
AddForce(pcmechobj , csVector3(25,0,0));
else if(!strcmp(message+15 , "strafeleft_"))
AddForce(pcmechobj , csVector3(2.5,0,0));

else if(!strcmp(message+15 , "straferight1"))
AddForce(pcmechobj , csVector3(-25,0,0));
else if(!strcmp(message+15 , "straferight_"))
AddForce(pcmechobj , csVector3(-2.5,0,0));

else if(!strcmp(message+15 , "rotateleft1"))
pcmechobj->SetAngularVelocity(csVector3(0,-1,0));
else if(!strcmp(message+15 , "rotateleft0"))
pcmechobj->SetAngularVelocity(csVector3(0,0,0));

else if(!strcmp(message+15 , "rotateright1"))
pcmechobj->SetAngularVelocity(csVector3(0,1,0));
else if(!strcmp(message+15 , "rotateright0"))
pcmechobj->SetAngularVelocity(csVector3(0,0,0));

return true;
}
return false;
}

But this still behaves weirdly! Albeit less so, it will sometimes take a leap into the air (at first I thought this was from the rotation being dirtied by other objects, but it turns out it is not), and when I rotate round sometimes the axis directions seem to change randomly in relation to each other (although usually remaining on the xz plane), sometimes I have occasionally caught it looping back round as per the previous behaviour.

It seems doing this is no different to using
Code:
pcmechobj->AddForceDuration(csVector3(0,0,-25),true,csVector3(0,0,0),0.2);
Since using true when I've calculated the local->world converted vector has the same effect as when I use the above case but with false (i.e without mesh rotation affecting force's direction), except in the odd case when I was moving back and I caught it leaping in the air.
Code:
if(!strcmp(message+15 , "forward1")) {
csVector3 move(pcmechobj->GetBody()->GetTransform().Other2ThisRelative(csVector3(0,0,-25)));
pcmechobj->AddForceDuration(move,false,csVector3(0,0,0),0.2);
}

// same as

if(!strcmp(message+15 , "forward1"))
pcmechobj->AddForceDuration(csVector3(0,0,-25),true,csVector3(0,0,0),0.2);
Logged
genjix
Jr. Member
**
Posts: 53


View Profile
« Reply #2 on: November 11, 2005, 01:53:38 pm »

solved now... turns out due to the big enough timesteps of ode and fairly uniform cube... it was being treated like a sphere (hence it was rolling about on point and spinning). making one dimension quite small compared to others solves this problem.
Logged
Pages: [1] Print 
« previous next »
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.2 | SMF © 2006-2007, Simple Machines LLC Valid XHTML 1.0! Valid CSS!
Page created in 4.279 seconds with 14 queries.