Page 1 of 1

[v3.6.1] Preventing aircraft "Sticking" using Torque Script

Posted: Wed Mar 04, 2015 10:21 pm
by WaxyChicken
In this version of Torque3D MIT (v3.6.1) there is still the problem of aircraft getting stuck in terrain or other objects.
such as when you land an aircraft at low speeds and it slowly drifts into a wall and "Gets Stuck".

These code tweaks will help to automatically "UNSTICK" your stuck aircraft.

using your editor add these dynamic values into your vehicle datablock:
lastColVec = 0 0 0 
lastColVecB = 1 1 1
unstickMeter = 0

in your scripts:

scripts / server / vehicle.cs
function VehicleData::onAdd(%this, %obj)
{
   %obj.setRechargeRate(%this.rechargeRate);
   %obj.setEnergyLevel(%this.MaxEnergy);
   %obj.setRepairRate(0);

   if (%obj.mountable || %obj.mountable $= "")
      %this.isMountable(%obj, true);
   else
      %this.isMountable(%obj, false);

   if (%this.nameTag !$= "")
      %obj.setShapeName(%this.nameTag);
	     
	if (%obj.getClassName() $= "FlyingVehicle")
		%this.CheckForStuck(%obj);
}
because it tends to occur with only flying vehicles, adding in
if (%obj.getClassName() == "FlyingVehcile")
will make it apply only to flying vehicles.
%this.CheckForStuck(%obj);
is the call that will start it's routine checking for getting stuck, and pushing the vehicle back when a sticky situation is detected.

these values are managed by the onCollision and onImapct functions:
function VehicleData::onCollision(%this, %obj, %sourceObject, %position, %len)
{
	%tempPosition = %obj.getPosition();
	if (%obj.lastColVec !$= %tempPosition)
	{
		%obj.lastColVecB = %obj.lastColVec;
		%obj.lastColVec = %tempPosition;
	}
}
function VehicleData::onImpact(%this, %obj, %sourceObject, %position, %len)
{
	%tempPosition = %obj.getPosition();
	if (%obj.lastColVec !$= %tempPosition)
	{
		%obj.lastColVecB = %obj.lastColVec;
		%obj.lastColVec = %tempPosition;
	}
}
during any contact with another object - collision or full impact speed - the position the the craft will now be stored in the datablock.
this will provide "Rewind" values. We will get to that later.

For now, add in the function that does the actual hard work:
function VehicleData::CheckForStuck(%this,%obj)
{
	//Make sure this vehicle still exists. return if it doesn't.
	if(!isObject(%obj) ) 
	{
		return;
	}	

	%Vehiclepos = %obj.getPosition(); 
	if (%Vehiclepos $= %obj.UnstickPosition)
	{
	        // the vehicle is stuck!?!
               // let it check a couple more times on our sticky meeter to make sure.
		%obj.unstickMeter = %obj.unstickMeter + 1;
		if (%obj.unstickMeter > 2)
		{
			// echo (" ==============     ATTEMPTING TO UNSTICK! ---");
			if (%obj.unstickMeter > 5)
			{
				// UNSTICK IS NOT WORKING!
				// you may wish to add code to destroy the vehicle or kill the player at this point.
				%obj.unstickMeter = 5;
			}

			// let's check our two history variables for a previous nearby collision 
			// and set vehicle back to that position.
			// it will either bump lose quickly or "Shake" loose.
			if (%vehiclepos $= %obj.lastColVec)
			{
				%newPosition = %obj.lastColVecB; 
			}
			else
			{
				%newPosition = %obj.lastColVec;
			}

			// echo ("Unstick Attempt - change " @ %vehiclepos @ " to " @ %newPosition);
			%obj.setTransform(%newPosition));
		}
	}
	else
	{
		%obj.unstickMeter = 0;
		%obj.unstickPosition = %VehiclePos;
	}
	
	if ( isObject(%obj) )
	{
		// decrease the 250 to a lower number for a faster response to sticking but more burden on the server / hosting client.
		%this.schedule(250,CheckForStuck,%obj); 	
	}
	else
	{
		// at some point during this function the vehicle was removed or destroyed.
		// echo("\c1 Vehicle::: DESTROYED!");
	}
}
i find this working on aircraft datablocks with the following values:
bodyRestitution = 1
bodyFriction = 0.1
collisionTol = 1
contactTol = 1

this is intended only for vehicles that have a minimum speed > 0 (even if they are just wiggling in place)

this is not a "TRUE" solution or a perfect fix, but it does make getting stuck MUCH more rare and with
some tweaking you may get better results.

Re: [v3.6.1] Preventing aircraft "Sticking" using Torque Script

Posted: Wed Mar 04, 2015 11:52 pm
by cybore
Handy information. Thanks!

Re: [v3.6.1] Preventing aircraft "Sticking" using Torque Script

Posted: Thu Mar 05, 2015 4:53 pm
by Gibby
taming the collisions between vehicles and terrain in T3D can be a downward spiral. The same problems affect space, water, hover and vtol vehicles as well - adding this change to vehicle.cpp around line 1212 solves most of these issues:

Code: Select all

//---------------------------------------------------------------------------- /** Update the physics */ void Vehicle::updatePos(F32 dt) { PROFILE_SCOPE( Vehicle_UpdatePos ); Point3F origVelocity = mRigid.linVelocity; //-->>[HNG] Vehicles // Update internal forces acting on the body. mRigid.clearForces(); updateForces(dt); if (!mRigid.atRest) mRigid.integrate(dt); //<<--[HNG] Vehicles // Update collision information based on our current pos. bool collided = false; if (!mRigid.atRest) { collided = updateCollision(dt); // Now that all the forces have been processed, lets // see if we're at rest. Basically, if the kinetic energy of // the vehicles is less than some percentage of the energy added // by gravity for a short period, we're considered at rest. // This should really be part of the rigid class... if (mCollisionList.getCount()) { F32 k = mRigid.getKineticEnergy(); F32 G = sVehicleGravity * dt; F32 Kg = 0.5 * mRigid.mass * G * G; if (k < sRestTol * Kg && ++restCount > sRestCount) mRigid.setAtRest(); } else restCount = 0; } //-->>[HNG] Vehicles // Integrate forward //if (!mRigid.atRest) // mRigid.integrate(dt); //<<--[HNG] Vehicles // Deal with client and server scripting, sounds, etc.

Re: [v3.6.1] Preventing aircraft "Sticking" using Torque Script

Posted: Tue Jun 02, 2015 12:40 pm
by TorqueFan
Nice, this is useful. Thanks!