Game Development Community

dev|Pro Game Development Curriculum

Rigid Shape Class

by Thomas \"Man of Ice\" Lund · 04/07/2004 (9:57 am) · 256 comments

Download Code File

History
2005-09-08 Updated with performance fix from XoCluTch

What is this?
For my game I needed a boulder that rolls down a hill, and that one needs to evade. Initial attempts to use the existing classes (items, shapes and especially projectiles) fail because of too simple physics and/or lack of collision box support. I was faced with either implementing collision boxes in the projectile class, look into ODE or try to code my own rigid body class.

Thanks to Ben Garney I didnt have to do any of these (thanks ;-) ), as there already exists rigid physics in the engine. The rigid.cc/h files have everything needed, but they are only available as con/net objects using the vehicle classes.

So I simply took the base vehicle class and the hover vehicle class, merged them together and removed most of the unneeded code. The result is actually fantastic, and I cant believe this isnt standard part of Torque.

As the code basically is a hover vehicle there might be parts of the code that should be removed further. If you spot any of those, then post here and I'll update the codebase.

What does it look like?
No resource without a movie :-)
Here is the final result from a tech demo level in my upcomming action adventure game.

www.codejar.com/rigidshape4.wmv

I also did a few early tests and I've included the movies here. The lack of realism is totally due to way too much impulse applied with a large vertical factor + low mass for the chests.

www.codejar.com/rigidshape.wmv
www.codejar.com/rigidshape2.wmv
www.codejar.com/rigidshape3.wmv

All movies are approx 3 MB

How to add
First thing is to add the 2 attached files in the zip to your engine\game dir and to your project. Then open the shapebase.h and find this

class ShapeBaseConvex : public Convex
{
   typedef Convex Parent;
   friend class ShapeBase;
   friend class Vehicle;

and add

friend class RigidShape;

Also in the same file down the bottom find this

#define StaticShape_GenericShadowLevel 2.0f
#define StaticShape_NoShadowLevel 2.0f

and add

#define RigidShape_GenericShadowLevel 0.7f
#define RigidShape_NoShadowLevel 0.2f

Recompile your engine and thats it.

If you want to do this "for real", then one also needs to define a new objectType. I have reused the ShapeBaseObjectType - change that if you want or go through tons of code and add a RigidShapeObjectType.

How to use
From script you now got access to a RigidShapeData datablock and a RigidShape object type. Your DTS object is required to have a mass node, but nothing else. The code still includes dusttrail and splash emitters from the vehicle code, as well as impact + water sound. This example does not use any of those.

An example datablock for a rigid shape is included below

datablock RigidShapeData( BouncingBoulder )
{	

   category = "RigidShape";
	
   shapeFile = "~/data/shapes/boulder/boulder.dts";
   emap = true;

   // Rigid Body
   mass = 500;
   massCenter = "0 0 0";    // Center of mass for rigid body
   massBox = "0 0 0";         // Size of box used for moment of inertia,
                              // if zero it defaults to object bounding box
   drag = 0.2;                // Drag coefficient
   bodyFriction = 0.2;
   bodyRestitution = 0.1;
   minImpactSpeed = 5;        // Impacts over this invoke the script callback
   softImpactSpeed = 5;       // Play SoftImpact Sound
   hardImpactSpeed = 15;      // Play HardImpact Sound
   integration = 4;           // Physics integration: TickSec/Rate
   collisionTol = 0.1;        // Collision distance tolerance
   contactTol = 0.1;          // Contact velocity tolerance
   
   minRollSpeed = 10;
   
   maxDrag = 0.5;
   minDrag = 0.01;

   triggerDustHeight = 1;
   dustHeight = 10;

   dragForce = 0.05;
   vertFactor = 0.05;

   normalForce = 0.05;
   restorativeForce = 0.05;
   rollForce = 0.05;
   pitchForce = 0.05;
};

By including the category="" it now shows up in the world editor under the Shapes, and its fully working. Spawn the object on a hilltop and see it roll down :-)

For the mission editor to work you will need to add a create() function that hooks into the mission editor. You can either put this into a rigidShape.cs file (dont forget to load it from game.cs) or put it into any .cs file in the server\script

// Hook into the mission editor.

function RigidShapeData::create(%data)
{
   // The mission editor invokes this method when it wants to create
   // an object of the given datablock type.
   %obj = new RigidShape() {
      dataBlock = %data;
   };
   return %obj;
}

If you want to have a little fun pushing things around then add this to your player onCollision:

function Armor::onCollision(%this,%obj,%col)
{

...

if (%col.getDataBlock().getName() $= "BouncingBoulder") {
	 // Apply an impulse to the object we collided with
	 %eye = %obj.getEyeVector();
         %vec = vectorScale(%eye, 10);
	 
        // Add a vertical component to give the item a better arc
	%dot = vectorDot("0 0 1",%eye);
	if (%dot < 0)
		%dot = -%dot;
	%vec = vectorAdd(%vec,vectorScale("0 0 2",1 - %dot));

	// Set the object's position and initial velocity
	%trans = %col.getTransform();
   
   // Heres the position and rotation.
   %pos = getWords(%trans, 0, 2);
	%col.applyImpulse(%pos,%vec);	 
}

...

}

I've done a few tests with forces, masses and such - and as you saw from my movies with varying results.

The objects are fully network aware, and I bet this code can replace ODE for most purposes if you dont need total realism.

As I wrote earlier, the code can be stripped down further. There are various pieces of the physics that I do not understand fully and left in. I would be very happy if someone could run through those parts and see if any of it can be taken out.

Regarding performance, I've tried to add approx 20 shapes to a scene and then letting all collide with each other (its in one of the movies actually). I noticed no performance degradation at all with those simple shapes (they had a 6 sided box as collision mesh.

The boulders in the last movie have an approx 25 faced hedra inside it as a collision mesh. I think I had 15 of those in an scene without performance degradation.

These shapes do have 1 problem though, and that is the collision detection that sometimes fails - exactly as vehicles. If they gain too much speed they will dip into the terrain or go through it. I think a lot of people are looking into that problem at the moment here www.garagegames.com/mg/forums/result.thread.php?qt=17384

Enjoy ;-)
#61
04/10/2005 (1:57 am)
I did it for a prototype game I'm developing

You can do it 2 ways - either code it for real using C++ updateMovement() or whatever just like the e.g. player class, or you can apply impulses from script when someone clicks the control buttons
#62
04/10/2005 (9:34 am)
I have been trying to get the first way to work for days, so I think you second method sounds like something I should look into. Thanks for the tip.
#63
04/14/2005 (11:21 am)
How do you apply an impulse to the ball to make it roll instead of slide? When I apply an impulse it just moves in a given direction, but never actually rolls over.
#64
04/19/2005 (8:35 am)
@Thomas, I just saw your video for this... What might be more fun is if you actually flattened the player when they get run over by the object.
I have managed to flatten a player by integrating a large part of the custom shape mod code, and then just setting all the players z values to .1 :) Just a thought.
#65
04/19/2005 (12:27 pm)
Fixed the rolling problem, but now I'm wondering if there's anyway to modify the RigidShape class to use bounding sphere vs poly collision instead of poly vs poly collision. The frame rate really goes to hell if you want to have a smooth sphere.
#66
04/26/2005 (10:16 pm)
I'm getting this error:

/server/scripts/rigidShape.cs (0): Unable to instantiate non-conobject class RigidShapeData.
#67
04/27/2005 (6:23 am)
Most likely you forgot to add the C++ files to your project, and thus RigidShapeData is not defined.
#68
05/20/2005 (4:44 pm)
Hi Thomas, I came across your resource here after I'd hacked away and came up with something very similar on my own. What I did was use the WheeledVehicle.cc & .h and replaced all the references with PhysicsObject, then modified the WheeledVehicle.cs to Barrel.cs and replaced out all of the references to the WheeledVehicle with PhysicsObject Recompiled and came up with this. I have a link here:

http://www.reallyreallygoodthings.com/barrel_physics9.mpg

Now the question, the collision is working great with projectiles, i.e. shotguns, rifles, etc. but I don't think it is working at all with the player. I tried modifying your code above and plugging in various things to the "BouncingBoulder". I tried "PBarrel" which is the name of the PhysicsObjectData, and I've tried using the OnCollision call from the shotgun.cs script, but nothing seems to make the player able to budge the barrels. They collide, but the player doesn't seem to affect the object. I was wondering if it is an impulse strength issue, or perhaps something else? I would have posted the scripts, but right now I'm at work and not able to do so, but though I'd get the barrel rolling...so to speak. Any ideas would be appreciated.
#69
05/21/2005 (12:33 am)
It does work for player vs rigid shape - but as you guessed you need to fiddle a lot with impulse strenght. Beware that too high values crash the engine.

One thing that gives strange results is rigid vs rigid - because the collision is registered on both rigid shapes.

Good luck!!
#70
06/05/2005 (9:13 am)
I can't seem to figure out how to "mount" a Rigid Shape object. Any thoughts?
#71
06/29/2005 (8:18 pm)
Has anyone managed to throw a rigidshape object?
I have managed to pick them up and throw them a small distance foward when I am stationary. When I am running however the object just ends up going behind me and not propelling foward. Has anyone else had this issue?
I have also noticed that Bryan Edds has implemented an equivalent of the set collision timeout. How do I call this?
#72
07/06/2005 (6:08 am)
I need to create ball shape with arkanoid physics:
- moving on the plane (not jumping)
- speed not decreasing on collision
- perfectly rigid body
- etc.

I tried RigidShape, but have a problems: ball jumping on collision, speed descreasing and etc.
#73
07/06/2005 (2:16 pm)
You will need to modify the updatePhysics method of this class to match the physics you describe. This means you have to insert the correct formula's and calculations for your required result.
#74
07/06/2005 (2:20 pm)
@ Tim Muenstermann

I know it's a month late, but you need to add a "mountpoint" node to the shape you are using. Check some tuts on creating weapons etc. Same rules should apply here.
#75
08/19/2005 (11:52 am)
I've added a little bit of code to this resource in my game.. I can now add basicly as many rigid shapes as i want with no lag. Just took a little bit of code so it doesn't do any movement calculations when its not moving... its only triggered on when its collidied with... Which might not be what most people want to use it for. But I added a flag to turn this feature on and off for certin objects. For the most part it works, there is a bug that rarely happens that im trying fix, and ill post the changes here once its working the way i like it.
#76
08/29/2005 (8:20 am)
Has anyone got sound to work with this? Rocks rolling down a hill should have sound.
I created an audio profile and set these values but no sound.

softImpactSound = RockImpactSound ;
hardImpactSound = RockImpactSound ;

minImpactSpeed = 0.1; // Impacts over this invoke the script callback
softImpactSpeed = 0.5// Play SoftImpact Sound
hardImpactSpeed = 0.75// Play HardImpact Sound
#77
09/06/2005 (6:44 pm)
I'm having some *SERIOUS* performance issues with the rigid shape class. In one of the movies, it looks like there are a whole bunch of boxes being kicked around..

But if I put 5 object on my mission, it grinds to a halt.

2 of the objects are spheres and they perform OK on their own.

Then I added 3 cars. The cars have got VERY simple collision meshes and no moving parts, just wanted them to be blown around by a radius explosion.. but it chuggs.

(Recompiled for Release... was using Debug build)

OK, Now I can have 13 before there's any major performance drop

Is there any way to speed up the Rigid shape class or should I just limit the number of objects to something more sensible or should I find another way to throw little cars around?
#78
09/07/2005 (4:10 am)
You should wait approx 1-2 days. Then I'll release a new code

XoCluTch has made some modifications to the code, so that the physics are only calculated per object while in motion. When at rest, it skips the calculations and thus you can have more shapes in your scene.

Also the number of polys in the collision mesh is what pulls teeth. So simplify your collision meshes down to absolute minimum
#79
09/07/2005 (8:50 am)
Ooh.. I can't wait. <>

I'll be patient :-)

The collision meshes I'm using for my cars are extremely simple. 12 faces of a cube which has been tapered at the top to form a crude car shape.

I could simplify it further by making a pyramid collision mesh, only 6 faces. Would that make much of a difference?

Thanks Thomas.
#80
09/07/2005 (11:27 am)
I've actually been having some problems with only calculating physics while objects are in motion. It makes it very hard to apply impulses to static objects, or have them react to objects that are in-motion, hitting them.

How did you resolve those issues?

Gary (-;