Jump to content
SubSpace Forum Network

Recommended Posts

Posted

Having tried out a number of physics engines for Subspace2 none of them quite meet the performance demands I require. The biggest issue is that many of the engines support alot of features that I'm not interested in at the moment such as collisions with rotating objects. I want a much more simpler system (arcade style). Unfortunately this whole area I'm woefully lacking knowledge in in.

 

Fortunately after ALOT of research I found a tutorial http://gafferongames.com/game-physics/ that started to make some sence to me. and from the knowledge i've learnt in the tutorial i have begun to build my own engine based on the work of many others. I still have plans to use other physics engines for other game modes.

 

The subspace world only contains AABB (squares or rectangles) collision objects.

 

Collision handling and physics are usually done separately. In my engine I move all the objects first using numerical integration and process the collisions afterwards by looking for intersecting objects (this is a pretty standard way of doing things). So there are 2 district phases. That are repeated around 60times/second

 

while (GameLoop)
  Integrate
  CollisionCheckResponse
end

 

1. Physics

 

As objects in subspace have no mass there are only 2 equations governing the movement of objects.

position = velocity * time

velocity = acceleration * time

 

A simple Eular Integrator can be used to calculate your new position for a change in time.

public void EularIntergrate(float deltaTime)
 {
   position += velocity * deltaTime;
   velocity += acceleration * deltaTime;
 }

the problem with Eular Integration is its horrible inaccurate which can lead to nasty quirks appearing in the game. Therefore after reading this article http://gafferongames.com/game-physics/integration-basics/ I managed to implement a RK4 (Runge-Kutta Integration) integrator.

 

Thus the Physics part of the engine is now complete, we have a decent integrator which is producing the accurate simulation we require.

 

1. Collisions

 

The First step in a collision detection is to detect if an object has collided with another (wow big surpise)

In the example i'm using I test every object against each other, which is very inefficient, though the use of spacial partitioning and/or broad phase the number of tests can be minimised. ( http://stackoverflow.com/questions/414553/broad-phase-collision-detection-quadtrees-bsp-etc)

 

The test if two AABB bodies intersect is pretty simple: Min refers to the top left corner, Max refers to the bottom right corner.

 

        
public bool Intersects(aabb other)
       {
           if (this.Max.X < other.Min.X || 
               this.Max.Y < other.Min.Y || 
               this.Min.X > other.Max.X || 
               this.Min.Y > other.Max.Y) 
           {
               return false;
           }
   return true;
}

 

Following testing for intersections we will have a list of objects that are colliding, we are now ready to create responses to the collisions.

In order to create accurate responses we need to find the collision vector, which can be obtained from the Minimum Translation Distance or MTD Vector.

 

This is more complex to calculate:

 

public Vector2 minimumTranslation(aabb other)
       {
           Vector2 amin = this.Min;
           Vector2 amax = this.Max;
           Vector2 bmin = other.Min;
           Vector2 bmax = other.Max;

           Vector2 mtd = new Vector2();

           float left = (bmin.X - amax.X);
           float right = (bmax.X - amin.X);
           float top = (bmin.Y - amax.Y);
           float bottom = (bmax.Y - amin.Y);

           // box dont intersect   
           if (left > 0 || right < 0) throw new Exception("no intersection");
           if (top > 0 || bottom < 0) throw new Exception("no intersection");

           // box intersect. work out the mtd on both x and y axes.
           if (Math.Abs(left) < right)
               mtd.X = left;
           else
               mtd.X = right;

           if (Math.Abs(top) < bottom)
               mtd.Y = top;
           else
               mtd.Y = bottom;

           // 0 the axis with the largest mtd value.
           if (Math.Abs(mtd.X) < Math.Abs(mtd.Y))
               mtd.Y = 0;
           else
               mtd.X = 0; 
           return mtd;
       }

 

Now we have the MTD we can use it to move our objects out of collision, and correct there velocities to ensure they should not collide next time

mtd = this.minimumTranslation(ab);
this.position += mtd ;
if (interv.X != 0)
{
this.velocity.X = -this.velocity.X ; //* bounce factor\
}
else if (interv.Y != 0)
{
this.velocity.Y = -this.velocity.Y;//* bounce factor
}

 

This is more a reminder to myself than a particularly useful tutorial, but maybe it will help someone somewhere blum.gif

 

References

http://gafferongames.com/game-physics/

http://www.gamedev.net/community/forums/topic.asp?topic_id=531478

http://www.gamedev.net/community/forums/topic.asp?topic_id=520224

http://www.deannolan.co.uk/pt/blog/default.aspx?id=23&t=2D-Collision-Detection-and-Response

 

Any quite a few other random pages, that I can't remember

 

I've attached my C# source code to a test project I created.

 

Keys AWSD

Mouse clicks create another object.

 

Its quick and messy but gives you enough to play with happy.png

physics2.zip

Posted

And if you collide horizontally at the same time as you collide vertically, are both speeds inverted?

And if so, if you collide horizontally with 2 objects at the same time, is the speed inverted twice? blum.gif

Posted
Nice, but you have to watch out for rounding errors here, if you add up a lot of small delta's the sum of the rounding errors could get pretty nasty which lead to the inaccuracies you speak of
Posted (edited)

And if you collide horizontally at the same time as you collide vertically, are both speeds inverted?

And if so, if you collide horizontally with 2 objects at the same time, is the speed inverted twice? blum.gif

Hmm i hadn't thought of that looks like theres more I need to work on blum.gif

 

Edit: found something here that looks useful http://games.fourtwo.se/xna/2d_collision_response_xna/

Edited by doc flabby
Posted

From what I seen in your code (a quick look), it looks like what we have in the Test Map of DCME, and the horizontal+vertical collisions are not handled correctly.

 

In fact, you also have to be aware of a diagonal collision... If you just check if (pos.x+vel.x, pos.y) intersects something, then if (pos.x, pos.y+vel.y) intersects something, you could go through a tile diagonally, that is if (pos.x+vel.x, pos.y+vel.y) intersects something; then you have to figure out which way to make it actually bounce.

 

Did you take a look at Discretion's code for its collision handling?

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...