2
\$\begingroup\$

I'm writing a 2d game, but decided to make some 3d objects that my 2d character can pick up.

I've got them displaying on the screen - but can't work out how to get the 2d area that the 3d object is displayed at (so I can do 2d collision detection).

Here's the code that draws my 3D objects - I can see that there's a projection object and have been poking around in there. But no luck so far ...

    foreach (var mesh in Model.Meshes)
    {
        foreach (BasicEffect currentEffect in mesh.Effects)
        {
            currentEffect.EnableDefaultLighting();
            currentEffect.World = (transforms[mesh.ParentBone.Index] * GetMatrix());
            currentEffect.View = viewMatrix;
            currentEffect.Projection = projectionMatrix;


        }
        mesh.Draw();
    }
\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

you could use a BoundingSphere, initialized with the mesh of your 3d object (see here how), and then use your it to collide in 2d environment.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Thanks - this pretty much got me what I needed. I struggled a bit as I didn't realise that I needed to apply transforms to the bounding sphere. Anyone else struggling in this area might benefit from gamedev.stackexchange.com/questions/71737/… which is a similar problem, working out the click of a mouse in a 3D world. You need to use a Ray (i.e a thin point through the 3D world). \$\endgroup\$ Sep 8, 2014 at 11:30
1
\$\begingroup\$

There are roads to solving this you can go down, project the 3D geometry in 2 dimensions or project the 2D geometry into 3 dimensions. The later is far simpler as the former requires you to define a plane on which your sprites lie and then detect where each triangle defining the mesh intersects with that plane.

2D to 3D

Projecting the 2D geometry into 3 dimensions is fairly trivial. 2D geometry is, after all, just two triangles stuck together with one axis constrained to a constant value. So turn your sprites into a 3D quad of two triangles and use 3D collision detection techniques instead.

3D to 2D

Making 3D geometry into 2D requires you to project the geometry onto a plane. In this case the plane you need is the plane on which the 2D geometry lies.

It's probably and XY plane which intersects the origin so can be defined by the vectors (1, 0, 0) and (0, 1, 0) making the normal (0, 0, 1).

If you can define the plane you need, all you really have to do is to move each vertex along the plane's normal until it's at a point on the plane. If the plane above is correct, just set the z coordinate of every vertex to 0.

For a general plane you do this by finding the distance from the plane to the point then moving the point by that result. The distance should conform to the plane's normal. This question might help you do this.

Alternately use a projection matrix to do this operation. This is exactly what your rendering pipeline will do to project the 3D geometry into screen space (which is the camera's near clipping plane). Specifically, it multiplies each vertex by the world (to get it relative to the origin), view (to get that relative to the camera) and projection (to get it in screen space).

Once projected onto the plane you have to construct triangles from the points. This will depend on how the mesh is defined; i.e. does it use a triangle list/strip/fan or is there an index array?. Each of those triangles can then be used in your 2D collision detection.

You could also apply a convex hull algorithm 2d give you an acceptable shape to use (you might need to triangulate it first though)

Note: You might want to consider the plane in use as being the near clipping plane of the camera so the player collides exactly with the shape drawn to the screen. This could be achieved by multiplying the vertices by the world, view and then projection matrix as that's how you project them into screen space and you should already have that information defined somewhere.

One more problem

Projecting the 3D geometry in this way will probably suit, even if it is expensive. But, you might need to consider the case where the geometry drawn to the camera isn't what you'd want to collide with. For example, if it was some wheels on an axel you might want to collide only with the axel and not the wheel. Collapsing the geometry to the plane will meen you collide with the wheel.

To avoid this you would actually have to define a plane and find the geometry defined by the mesh intersecting the plane. However, I doubt this is what you want since generally in 2D games you collide with the edges of what you see or not at all (foreground/background items).

Conclusion / Long story short

Create 2 3D triangles for the 2D resources or some better fitting collision mesh and just use 3D collision detection for these problems. It's the easiest way. If you really need it to be more 2D collision then project the 3D geometry onto the draw plane (probably done by just zeroing the z component or multiplying verts by world, view and projection matrices) and do 2D collision detection with the cloud of triangles that defines.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .