XNA 3D Collision Detection for Terrain - xna

I've been working on a basic 3D XNA game. So far I've managed to load various character models onto a larger level/world model. I've put in some basic controls which allows the user/player to move one of the characters around the world - and even implemented some collision detection using BoundingSphere/BoundingBox with other character models.
However, the character models (at the moment) are stuck in a fixed place on the Y-axis, and so my world is really just a flat plane for them to glide across.
What I want to do now is implement a gravity like force, which will allow characters to rise and fall with the flow of the terrain. I've spent a couple of hours on google searching (in vain) for some way of checking for a detailed collision between the bounding sphere of my character and the actual mesh of the world. The articles I have found all seem to explain how to use the sphere and box methods, or to implement some external physics engine (all of which seem really quite elaborate for what I want to achieve).
So my question is twofold -
Firstly, Am I approaching this in the best way? With a single large-ish model for my world?
Secondly, Is there a relatively simple way to check for the type of collision I need, using the XNA library itself, or some other library that doesn't require me to introduce an entirely new layer of physics.
NB. The models that I want to check for collisions are: Microsoft.Xna.Framework.Graphics.Model
EDIT:
I should also mention that I am not creating a single level, but a game engine which will work with various levels loaded from a Database. For this reason, I don't want to have to separately/manually define the constraints of the level. I would ideally like to load my single mesh from the database and be able to detect collisions with it as is, or alternatively automatically work out the constraints/bounding areas from the mesh data.

3d collision detection is more complex than it may seem at a glance, so using one of the prescribed methods (I.e. the BoundingSphere Object can help). Check http://msdn.microsoft.com/en-us/library/bb203906(v=xnagamestudio.10).aspx
Specifically this code block gives an idea:
static void CheckForCollisions( ref WorldObject c1, ref WorldObject c2 )
{
for (int i = 0; i < c1.model.Meshes.Count; i++)
{
// Check whether the bounding boxes of the two cubes intersect.
BoundingSphere c1BoundingSphere = c1.model.Meshes[i].BoundingSphere;
c1BoundingSphere.Center += c1.position;
for (int j = 0; j < c2.model.Meshes.Count; j++)
{
BoundingSphere c2BoundingSphere = c2.model.Meshes[j].BoundingSphere;
c2BoundingSphere.Center += c2.position;
if (c1BoundingSphere.Intersects( c2BoundingSphere ))
{
c2.ReverseVelocity();
c1.Backup();
c1.ReverseVelocity();
return;
}
}
}
}

The first answer gave you a first-pass test for detailed collision detection. You could refine that first-pass and use an AABB test. The second pass would then require a ray-triangle intersection test. Be careful since some of these will fail when the ray hits a triangle edge or vertex - so make sure that the tester code/algorithm you chose considers these. There are further modifications using quad-trees or other space-partitioning schemes to increase the speed of collision detection.

Here is a detailed description of a sphere/triangle technique I once adapted for 2D collision detection:
http://www.peroxide.dk/papers/collision/collision.pdf
I cannot say for certain that it will help you, but it may be useful for collisions with a terrain mesh and gravity. Combining that with collisions with other "characters" may be challenging, depending on exactly what it is you want to do. However, it does specifically describe how to implement gravity, and overall it is one of the simpler approaches you might take to collision detection and character physics in 3D.
As for the question of whether colliding with the entire terrain mesh is the "correct" way to go... if it is a simple mesh and you aren't resource-constrained, then sure. However, collision detection is computationally expensive, and applying it to all the triangles in your mesh may quickly become impossible. Generally, you may want to store your triangles in some efficiently searchable structure, like an octree or a k-d tree, and then do a rough search for triangles near your character which can then be tested more precisely for collisions in much less time than it would take to test every triangle in the mesh.

You could fake it. In other words, I'm assuming, at every update call you could just set the height of your player to the height of the terrain wherever the player happens to be. I imagine not the most professional way to handle things, but might work.

Related

Collision with objects

I am new to StackOverflow and my first question here is, how do I collide with objects in a game, removed them from scene and add 1 to the score .
To help you understand this question more here is an example: If the player collides with a coin, the coin will get removed from the scene and it will add 1 to the score
The only code I have is generating the diamonds and that't but I am not sure how to get round this question, I think I need to write the code in beginContact or something similar. I would be really glad if someone could help me with this issue. Thanks!
Object collision can be done in several ways depending on the complexity of the game.
The simplest method is to track the entire field in a 2d or 3d matrix and if the user moves into the same coordinates as an obtainable object remove the object and increment the score. This has obvious issues when it comes to large maps or complex systems that would run the hardware out of memory. So this works for something like a chess/checkers board but not a driving simulation.
The second method is to keep a linked list of objects visible on the field with it's central coordinates and it drawing directions. The objects might look like coords (1007.2053, 489.2111) shape (box). Where box is a function that generates all the border coordinates. Then detect collisions by checking if primary target overlaps any of the object in the list. You'll probably have to write a collision function for each shape. The simpler the shape the easier the collision function. For more complex object it's often easier just to simplify the shape to a box no mater what it looks like. This is why 3d games often have clipping errors and why you could shoot the edge of an object in a fps and still not be considered to hit it.
Your question is too broad for a better answer but Here is a very basic article that discusses the second method.
More Info. The game is apparently a 2d endless runner.
So you could set up a 2d matrix that acts as a queue. Say your board is 3 high so your character can walk, jump, or high jump.
highjump
jump
walk
This would be a simple matrix like board 10 X 3 (x, y)
With each frame the board removes the front column and adds a new column to the back. Think front of matix is left side, back is right side. When adding to back you randomly decide which box to put the coin in. In each frame the user must be in one of the 3 positions. if his position is the same as the object collect it and gain points. Or if the object is undesirable lose a life and start game over, etc.
more links
Information specific to endless runners here and another stack overflow question similar to yours here

How to create sprite surface like in "cham cham"

My question maybe a bit too broad but i am going for the concept. How can i create surface as they did in "Cham Cham" app
https://itunes.apple.com/il/app/cham-cham/id760567889?mt=8.
I got most of the stuff done in the app but the surface change with user touch is quite different. You can change its altitude and it grows and shrinks. How this can be done using sprite kit what is the concept behind that can anyone there explain it a bit.
Thanks
Here comes the answer from Cham Cham developers :)
Let me split the explanation into different parts:
Note: As the project started quite a while ago, it is implemented using pure OpenGL. The SpiteKit implementation might differ, but you just need to map the idea over to it.
Defining the ground
The ground is represented by a set of points, which are interpolated over using Hermite Spline. Basically, the game uses a bunch of points defining the surface, and a set of points between each control one, like the below:
The red dots are control points, and eveyrthing in between is computed used the metioned Hermite interpolation. The green points in the middle have nothing to do with it, but make the whole thing look like boobs :)
You can choose an arbitrary amount of steps to make your boobs look as smooth as possible, but this is more to do with performance.
Controlling the shape
All you need to do is to allow the user to move the control points (or some of them, like in Cham Cham; you can define which range every point could move in etc). Recomputing the interpolated values will yield you an changed shape, which remains smooth at all times (given you have picked enough intermediate points).
Texturing the thing
Again, it is up to you how would you apply the texture. In Cham Cham, we use one big texture to hold the background image and recompute the texture coordinates at every shape change. You could try a more sophisticated algorithm, like squeezing the texture or whatever you found appropriate.
As for the surface texture (the one that covers the ground – grass, ice, sand etc) – you can just use the thing called Triangle Strips, with "bottom" vertices sitting at every interpolated point of the surface and "top" vertices raised over (by offsetting them against "bottom" ones in the direction of the normal to that point).
Rendering it
The easiest way is to utilize some tesselation library, like libtess. What it will do it covert you boundary line (composed of interpolated points) into a set of triangles. It will preserve texture coordinates, so that you can just feed these triangles to the renderer.
SpriteKit note
Unfortunately, I am not really familiar with SpriteKit engine, so cannot guarantee you will be able to copy the idea over one-to-one, but please feel free to comment on the challenging aspects of the implementation and I will try to help.

Is there a way to create a CGPath matching outline of a SKSpriteNode?

My goal is to create a CGPath that matches the outline of a SKSpriteNode.
This would be useful in creating glows/outlines of SKSpriteNodes as well as a path for physics.
One thought I have had, but I have not really worked much at all with CIImage, so I don't know if there is a way to access/modify images on a pixel level.
Then maybe I would be able to port something like this to Objective-C :
http://www.sakri.net/blog/2009/05/28/detecting-edge-pixels-with-marching-squares-algorithm/
Also very open to other approaches that make this process automated as opposed to me creating shape paths for every sprite I make for physics or outline/glow effects.
What you're looking for is called a contour tracing algorithm. Moore neighbor tracing is popular and works well for images and tilemaps. But do check out the alternatives because they may better fit your purposes.
AFAIK marching squares and contour tracing are closely related, if not the same (class of) algorithms.
An implementation for tilemaps (to create physics shapes from tiles) is included in Kobold Kit. The body of the algorithm is in the traceContours method of KKTilemapLayerContourTracer.m.
It looks more complex than it really is, on the other hand it takes a while to wrap your head around it because it is a "walking" algorithm, meaning the results of prior steps is used in the current step to make decisions.
The KK implementation also includes a few minor fixes specifically for tilemaps (ie two or more horizontally or vertically connected tiles become a single line instead of dividing the line into tile-sized segments). It was also created with a custom point array structure, and when I ported it to SK I decided it would be easier to continue with that and only at the end convert the point arrays to CGPath objects.
You can make certain optimizations if you can safely assume that the shape you're trying to trace is not going to touch the borders, and there can not be any tiles that are only connected diagonally. All of this becomes clearer when you're actually implementing the algorithm for your own purposes.
But as far as a ready-made, fits-all-purposes solution goes: there ain't none.

Collision detect with iterative sampling - should I use an engine (box2d) or roll my own?

thanks for taking the time to read my question.
I'm writing a 2d top-down shooter game. It is currently using Box2d as a physics engine. The thing is, it isn't really using Box2d to it's fullest potential, just for collision detection and the underlying velocity/rotation update loop. Any plans to add real physics would simply be eye-candy, not a game changer.
Now I chose Box2d because I went through 2 other physics engines, and they just couldn't handle the types of collisions I'm detecting. I'm creating several 'bullets' with very high velocities, and I do not want them to be instant hits on their targets. JigLib and Flixel both had the same problem - bullets were not overlapping enemies at the time of the frame update, and thus were not detected as collisions (i.e. the bullets passed through enemies because they moved to fast).
I moved to Box2d because of it's iterative collision sampling, as well as the SetAsBullet method on bodies. And it works great! But now Box2d is giving me troubles too - generating several bullets per second, or at the same time, is severely lowering my fps.
So I removed Box2d to confirm that it was not a rendering limitation... added my own velocity/rotation system, and I can fire hundreds of bullets per second. Great! But its lacking any sort of collision detection.
So the questions:
1) Should I write my own iterative collision engine?
2) Should I give Box2d a try again, perhaps with some tweaks to make adding new bodies faster?
3) Is there some other alternative, maybe a lightweight physics engine that specializes in this?
4) Do you know of any other techniques or design patterns that could be of use?
Thanks so much for your help!
Edit: I should note, there are not just bullets, but larger, slower projectiles as well. I considered ray casting a line segment to the projectile's previous position, and catching intersections, but that won't work for the larger objects :(
It depends on how complex your situation can become, If you are good at math and physics you can rollout a fast engine that can handle simple collisions more faster than you can learn using box2d, but why should anyone invent the bycicle if there are plenty of them already invented so choose one you like a try using it, i recommend using box2d

Surface Detection in 2d Game?

I'm working on a 2D Platform game, and I was wondering what's the best (performance-wise) way to implement Surface (Collision) Detection.
So far I'm thinking of constructing a list of level objects constructed of a list of lines, and I draw tiles along the lines.
alt text http://img375.imageshack.us/img375/1704/lines.png
I'm thinking every object holds the ID of the surface that he walks on, in order to easily manipulate his y position while walking up/downhill.
Something like this:
//Player/MovableObject class
MoveLeft()
{
this.Position.Y = Helper.GetSurfaceById(this.SurfaceId).GetYWhenXIs(this.Position.X)
}
So the logic I use to detect "droping/walking on surface" is a simple point (player's lower legs)-touches-line (surface) check
(with some safety approximation
- let`s say 1-2 pixels over the line).
Is this approach OK?
I`ve been having difficulty trying to find reading material for this problem, so feel free to drop links/advice.
Having worked with polygon-based 2D platformers for a long time, let me give you some advice:
Make a tile-based platformer.
Now, to directly answer your question about collision-detection:
You need to make your world geometry "solid" (you can get away with making your player object a point, but making it solid is better). By "solid" I mean - you need to detect if the player object is intersecting your world geometry.
I've tried "does the player cross the edge of this world geometry" and in practice is doesn't work (even though it might seem to work on paper - floating point precision issues will not be your only problem).
There are lots of instructions online on how to do intersection tests between various shapes. If you're just starting out I recommend using Axis-Aligned Bounding Boxes (AABBs).
It is much, much, much, much, much easier to make a tile-based platformer than one with arbitrary geometry. So start with tiles, detect intersections with AABBs, and then once you get that working you can add other shapes (such as slopes).
Once you detect an intersection, you have to perform collision response. Again a tile-based platformer is easiest - just move the player just outside the tile that was collided with (do you move above it, or to the side? - it will depend on the collision - I will leave how to do this is an exercise).
(PS: you can get terrific results with just square tiles - look at Knytt Stories, for example.)
Check out how it is done in the XNA's Platformer Starter Kit Project. Basically, the tiles have enum for determining if the tile is passable, impassable etc, then on your level you GetBounds of the tiles and then check for intersections with the player and determine what to do.
I've had wonderful fun times dealing with 2D collision detection. What seems like a simple problem can easily become a nightmare if you do not plan it out in advance.
The best way to do this in a OO-sense would be to make a generic object, e.g. classMapObject. This has a position coordinate and slope. From this, you can extend it to include other shapes, etc.
From that, let's work with collisions with a Solid object. Assuming just a block, say 32x32, you can hit it from the left, right, top and bottom. Or, depending on how you code, hit it from the top and from the left at the same time. So how do you determine which way the character should go? For instance, if the character hits the block from the top, to stand on, coded incorrectly you might inadvertently push the character off to the side instead.
So, what should you do? What I did for my 2D game, I looked at the person's prior positioning before deciding how to react to the collision. If the character's Y position + Height is above the block and moving west, then I would check for the top collision first and then the left collision. However, if the Character's Y position + height is below the top of the block, I would check the left collision.
Now let's say you have a block that has incline. The block is 32 pixels wide, 32 pixels tall at x=32, 0 pixels tall at x=0. With this, you MUST assume that the character can only hit and collide with this block from the top to stand on. With this block, you can return a FALSE collision if it is a left/right/bottom collision, but if it is a collision from the top, you can state that if the character is at X=0, return collision point Y=0. If X=16, Y=16 etc.
Of course, this is all relative. You'll be checking against multiple blocks, so what you should do is store all of the possible changes into the character's direction into a temporary variable. So, if the character overlaps a block by 5 in the X direction, subtract 5 from that variable. Accumulate all of the possible changes in the X and Y direction, apply them to the character's current position, and reset them to 0 for the next frame.
Good luck. I could provide more samples later, but I'm on my Mac (my code is on a WinPC) This is the same type of collision detection used in classic Mega Man games IIRC. Here's a video of this in action too : http://www.youtube.com/watch?v=uKQM8vCNUTM
You can try to use one of physics engines, like Box2D or Chipmunk. They have own advanced collision detection systems and a lot of different bonuses. Of course they don't accelerate your game, but they are suitable for most of games on any modern devices
It is not that easy to create your own collision detection algorithm. One easy example of a difficulty is: what if your character is moving at a high enough velocity that between two frames it will travel from one side of a line to the other? Then your algorithm won't have had time to run in between, and a collision will never be detected.
I would agree with Tiendil: use a library!
I'd recommend Farseer Physics. It's a great and powerful physics engine that should be able to take care of anything you need!
I would do it this way:
Strictly no lines for collision. Only solid shapes (boxes and triangles, maybe spheres)
2D BSP, 2D partitioning to store all level shapes, OR "sweep and prune" algorithm. Each of those will be very powerfull. Sweep and prune, combined with insertion sort, can easily thousands of potentially colliding objects (if not hundreds of thousands), and 2D space partitioning will allow to quickly get all nearby potentially colliding shapes on demand.
The easiest way to make objects walk on surfaces is to make then fall down few pixels every frame, then get the list of surfaces object collides with, and move object into direction of surface normal. In 2d it is a perpendicular. Such approach will cause objects to slide down on non-horizontal surfaces, but you can fix this by altering the normal slightly.
Also, you'll have to run collision detection and "push objects away" routine several times per frame, not just once. This is to handle situations if objects are in a heap, or if they contact multiple surfaces.
I have used a limited collision detection approach that worked on very different basis so I'll throw it out here in case it helps:
A secondary image that's black and white. Impassible pixels are white. Construct a mask of the character that's simply any pixels currently set. To evaluate a prospective move read the pixels of that mask from the secondary image and see if a white one comes back.
To detect collisions with other objects use the same sort of approach but instead of booleans use enough depth to cover all possible objects. Draw each object to the secondary entirely in the "color" of it's object number. When you read through the mask and get a non-zero pixel the "color" is the object number you hit.
This resolves all possible collisions in O(n) time rather than the O(n^2) of calculating interactions.

Resources