Skip to main content
GameDev.net gamedev.net
🔒 Locked 🎮 Unity

Collision Problem

Started by mguneskou Jul 13, 2006 at 7:46 AM 6 replies 1.6k views
Original Post
mguneskou
mguneskou
I wrote some code with C# and MDX for a simple game engine. I'm trying to check whether two objects are collide or not. I know methods such mesh.intersect, Geometry.Boxboundprobe, Geometry.Sphereboundprobe but all of them look working incorrect. There's something wrong with my code. I'm loading x files from a different class and i derive a different instance from class for every mesh. So every mesh has it's own object space(Device.Transform.World). I have a cube which moves with camera and i'm checking the collision between this cube and other objects. The cube and other objects in the space have min and max points calculated with the Geometry.ComputeBoundingBox method. when i try to use Geometry.BoxBoundProbe method to check collision between them the cube collide anything but other objects. The points that cube collides are not on the other objects. I'm confused because i tried mesh.intersect too... here is my code http://rapidshare.de/files/25731442/carp_deneme.rar.html
Supernat02
Supernat02
I don't have time to read your code, but it sounds like maybe you aren't transforming everything properly.

If you have a cube in model space (center 0,0,0) and you move that cube around in world space through the transform that you have stored in your class, then you need to be sure that transform is also being applied to the cube prior to the collision tests. There are a couple of ways of doing this. One is to lock the vertex buffer and multiple every vertex by the world transform, then set the world transform to Identity and don't use it anymore. The other way is to temporarily create a new cube, one that has every vertex transformed by the world matrix, and pass that cube into the collision routines.

To check collision between two cubes (let's say one is 10 units out in the x direction and the other is -5 units out), but both cubes are stored as (0,0,0) for their center (model coords), then you need to move each cube to its respective point in space, and then call the collision routines. What I mean is that you can't just pass in the untransformed model coordinates to the collision routines. You may have called the SetTransform(WORLD, cubeTransform) function, but that only moves the cube in the graphics pipeline, not in your cube class. I hope that makes sense.

Good luck,
Chris
Chris ByersMicrosoft DirectX MVP - 2005
mguneskou
mguneskou
thanks for your interest, i read your reply carefully. you say lock the vertex buffer of the mesh then multiply every vertex by the Matrix(World) here is my cube class. i derive two cubes from same class...

public class mesh_load
{
Mesh mesh = null;
Texture[] meshtextures = null;
Material[] meshmaterials = null;
public Vector3 min, max;

public Mesh Mesh_Load(Device device, string xfile)
{
ExtendedMaterial[] mtrl = null;
mesh = Mesh.FromFile(xfile, MeshFlags.Managed, device, out mtrl);
if(mtrl != null)
{
meshtextures = new Texture[mtrl.Length];
meshmaterials = new Material[mtrl.Length];
for(int i = 0; i < mtrl.Length; i++)
{
meshmaterials = mtrl.Material3D;
if(mtrl.TextureFilename != null)
{
meshtextures = TextureLoader.FromFile(device, mtrl.TextureFilename);
}
}
}
return mesh;
}

public void render(Device device, Vector3 position)
{
for(int i = 0; i < meshmaterials.Length; i++)
{
device.Material = meshmaterials;
device.SetTexture(0, meshtextures);
device.Transform.World = Matrix.Translation(position);//i set world transfrom to Matrix.Translation(position) because i move my cube. position is used as a different Vector3 in the other class. This different Vector3 takes value by keyboard entries.
mesh.DrawSubset(i);
}
collision(device);
}

void collision(Device device)
{
VertexBuffer vb = mesh.VertexBuffer;
try
{
GraphicsStream stm = vb.Lock(0, 0, LockFlags.None);
Geometry.ComputeBoundingBox(stm, mesh.NumberVertices, mesh.VertexFormat, out min, out max);
min.TransformCoordinate(device.Transform.World);
max.TransformCoordinate(device.Transform.World);
}
finally
{
vb.Unlock();
vb.Dispose();
}
}
}

Where and how should i multiply every vertex with world transform?
Thanks Murat...
coolshamim
coolshamim
u can use
Matrix.transfromcoordinate(vertices, worldtranformMatrix)

vertices shows the vertices of the bounding cube of the object
world transform represents the transformation u have applied on your object

the above api returns u the updated position of ur cube position as well

next perform your calculation to find the collision
hope it will work because i am using the same technique and its working
deathkrush
deathkrush
I think it's too slow to transform all the coordinates of an object and re-calculate the bounding sphere or the bounding box. If you are not doing any scaling, it's much faster to calculate a bounding sphere or a bounding box when the object is at (0,0,0) and then just transform the bounding sphere or the bounding box, not the object's vertices.

Think about it, a bounding sphere has just one vertex! (the center) so you only need to transform one vertex. A bounding box has more vertices and it probably needs to be rotated too, but it's still faster to transform a box than it is to transform hundreds of vertices.

In my game, I totally dumped the built-in DirectX Geometry.Boxboundprobe and Geometry.Sphereboundprobe methods and used my own calculatiuons, but I guess you can still use my method and the built-in DirectX functions.
deathkrushPS3/Xbox360 Graphics Programmer, Mass Media.Completed Projects: Stuntman Ignition (PS3), Saints Row 2 (PS3), Darksiders(PS3, 360)
coolshamim
coolshamim
if ur object is in motion which is normal case in all the games then transformations of all the vertices of ur mesh is the must case and in that case u must need to update the postions of ur bounding box or bounding sphere because the all the DirectX geometry related APIs return the result based on ur loaded mesh and not wrt to the transformed mesh position so must need to transform the coordinates of ur mesh as object is in motion
mguneskou
mguneskou
thanx all for your answers but i guess we misunderstood eachother...
i have two cubes, both derived from same class, in this class i make translation transformation to them via a Vector3 parameter in a mathod. now i have two cubes with different translations(model spaces) and i have a world space. i use Geometry.ComputeBoundingBox method for to get the min and max values for cubes in the same class. i want to collide these two cubes using Geometry.BoxBoundProbe method. i need to take both cubes in the same model space or in world space. i understood this. but how? any C# code for this? because when i tried to find some code i only found mouse picking examples, they're not same. i don't use mouse. i use just keyboard entries.

By the way for BoxBoundProbe method i need two vectors: rayposition and raydirection. my camera moves with the first cube, just behind it. i attached camera to it. i check whether this cube collides the other one.

please help...

Thanx

Murat
mguneskou
mguneskou
I solve the problem. Here's the solution: I said i have a class that my cubes are derived from. I added a Matrix struct to this class named "world". thus every object that is derived from this class had a Matrix struct named world. And i used this "world" in other class for the Vector3.TransfromCoordinate method. so my ray is transformed to my obstacle's world transform.

Thanx for everyone who replied my message.

Murat...

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.