I have been trying to get 3D collision detection working for a while and I think (hope) you people can help me.
For my project I have created a 'sprite3d' kinda class which is called ModelEntity
and there there is a function that is called intersects
.
intersects
gets another ModelEntity
as a parameter.
public bool intersects(ModelEntity entity)
{
BoundingSphere bs1 = CreateBoundingSphereForModel();
BoundingSphere bs2 = entity.CreateBoundingSphereForModel();
bs1.Center += position;
bs2.Center +=entity.position;
if (bs1.Intersects(bs2))
return true;
return false;
}
public BoundingSphere CreateBoundingSphereForModel()
{
Matrix[] boneTransforms = new Matrix[this.model.Bones.Count];
this.model.CopyAbsoluteBoneTransformsTo(boneTransforms);
BoundingSphere boundingSphere = new BoundingSphere();
BoundingSphere meshSphere;
for (int i = 0; i < model.Meshes.Count; i++)
{
meshSphere = model.Meshes[i].BoundingSphere.Transform(boneTransforms[i]);
boundingSphere = BoundingSphere.CreateMerged(boundingSphere, meshSphere);
}
return boundingSphere.Transform(getWorld());
}
public Matrix getWorld()
{
return Matrix.CreateTranslation(position) * Matrix.CreateRotationY(rotation.Y) * Matrix.CreateRotationZ(rotation.Z) * Matrix.CreateRotationX(rotation.X) ;
}
Those are the main parts of the collision in the ModelEntity
class and the place where I check collision is in the PlayState
class
if (model.intersects(player) || player.intersects(model1))
{
cam.returnToLastPosition();
}
cam.returnToLastPosition()
is just returning the camera to the last place it has been so you can't pass through the model.
In the update loop, I set the player's position to the camera position (I have created a first person camera class which takes care of mouse and keyboard movement).
If you want to see the draw function:
public void draw(FirstPersonCamera cam)
{
Matrix[] transforms = new Matrix[model.Bones.Count];
model.CopyAbsoluteBoneTransformsTo(transforms);
foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.World = transforms[mesh.ParentBone.Index] * getWorld();
effect.View = cam.getView();
effect.Projection = cam.projection;
}
mesh.Draw();
}
}
NOTE// in the intersects function I have tried to remove the part of
bs1.Center += position;
bs2.Center +=entity.position;
but it does not work anyways.