Game Development Community

Returning the Angular Velocity of Vehicles

by Matthew Genge · in Torque 3D Professional · 02/19/2012 (3:46 pm) · 2 replies

Dear All,

I've been working on a boat using a flying vehicle. I've managed to get it to float nicely, simply by applying gravity and bouyancy as an impulse in a scheduled function. I've managed to get it to move forwards nicely simply by adding an impulse and friction in the same function. The issue I am having is with rotations.

I can turn, roll and pitch the vehicle with impulses applied as torques around an axis, however, the issue is there doesn't seem to be a way in script to return the angular velocity of a vehicle. Only linear velocity is returned by getVelocity(). This means there is no way to damp out rotations or limit rotational speed apart from the built in rotationaldrag, rollforce etc. These seem to me worse than useless, often causing oscillation of a vehicle with increasing amplitude. I've managed to control yaw by keeping track of the turning speed manually (just in case you are interested code is below...it requires setting all rotational drags to zero), however, as soon as this is changed by the physics engine (e.g. a collision, bouyant rise) it can no longer be controlled. If only I can get the angular velocity in script....I can make it work manually. Anyone know of a way? My search of the forums suggests there isn't....otherwise the dark day I start learning C++ gets closer.

function setAngularTurn(%obj, %axis, %currspeed, %targetSpeed){

   //Calculates the force required to increase the angular velocity around the specified axis
   %torque = %obj.getDatablock().momentofInertia*(%targetspeed - %currspeed);
   %obj.applyTrueRadialImpulse(%axis, %obj.getRightVector(), %torque/2.0);
   return %torque;
     
}


function SceneObject::applyTrueRadialImpulse(%obj, %axis, %leverarm, %force){
   
      //Applies a balanced torque around any axis, where leverarm is a vector
   
      %origin = getWords(%obj.getTransform(),0,2);
      %impVec = VectorCross(%axis,%leverarm);     
      
      //Apply first impulse
      %impposition = VectorAdd(%origin, %leverarm);
      %impulse = VectorScale(%impVec,%force);
      %obj.applyImpulse(%impposition, %impulse);

      //Apply second impulse
      %impposition = VectorSub(%origin, %leverarm);
      %impulse1 = VectorScale(%impulse, -1.0);
      %obj.applyImpulse(%impposition, %impulse1);
   
}

Best,
Matt


#1
02/20/2012 (7:51 pm)
Maybe you could keep track of the up and direction vectors of your boat and then calculate the angular velocity from the change in their direction over a frame?
#2
04/25/2012 (12:52 pm)
The rigid object for the vehicle should have the angular velocity. What you'll need to do is set up a new console method in Vehicle to return the angular velocity from the rigid object.

So you'd have a new function for Vehicle called getAngularVelocity() which returns a VectorF. Then you'd need to set up a corresponding console method which calls your getAngularVelocity (you should be able to just copy the current console method for getVelocity). The relevant member variable of Rigid is called angVelocity (so in getAngularVelocity, you'd return mRigid.angVelocity).