XNA 3D Collision matrices not working

2019-07-18 03:21发布

I previously asked a question about why my collision was not working. I got a good answer which makes sense: Apply the same transforms that I did in the DrawModel method to the isCollision method. This however, did not work. I was unable to figure out how to make the same transformations in the isCollision method. If anyone could help me, that would be great. Thanks! Here are the methods:

private bool checkPlayerCollision(Model model1, Matrix world1)
{
    //Make floor matrix
    Matrix floorMatrix = Matrix.CreateTranslation(new Vector3(0, 0, 0));
    //Make ship1 matrix
    Matrix ship1WorldMatrix = Matrix.CreateTranslation(ship1loc);
    //Make ship2 matrix
    Matrix ship2WorldMatrix = Matrix.CreateTranslation(ship2loc);
    //Check for collision with floor
    if (IsCollision(model1, world1, floor, floorMatrix)) return true;
    //Check for collision with ship1
    if (IsCollision(model1, world1, model, ship1WorldMatrix)) return true;
    //Check for collision with ship2
    if (IsCollision(model1, world1, model, ship2WorldMatrix)) return true;
    return false;
}

That was the check player collision where I check all the models for collision with the player model.

private bool IsCollision(Model model1, Matrix world1, Model model2, Matrix world2)
{
    for (int meshIndex1 = 0; meshIndex1 < model1.Meshes.Count; meshIndex1++)
    {
        BoundingSphere sphere1 = model1.Meshes[meshIndex1].BoundingSphere;
        sphere1 = sphere1.Transform(world1);

        for (int meshIndex2 = 0; meshIndex2 < model2.Meshes.Count; meshIndex2++)
        {
            BoundingSphere sphere2 = model2.Meshes[meshIndex2].BoundingSphere;
            sphere2 = sphere2.Transform(world2);

            if (sphere1.Intersects(sphere2))
                return true;
        }
    }
    return false;
}

That was the method where I actually check the collision.

private void DrawModel(Model model, Matrix world, Matrix view, Matrix projection, Vector3 loc)
{
    Matrix gameWorldRotation = Matrix.CreateRotationX(MathHelper.ToRadians(RotationX)) * Matrix.CreateRotationY(MathHelper.ToRadians(RotationY));
    Matrix[] transforms = new Matrix[model.Bones.Count];
    model.CopyAbsoluteBoneTransformsTo(transforms);
    foreach (ModelMesh mesh in model.Meshes)
    {
        foreach (BasicEffect effect in mesh.Effects)
        {
            effect.World = gameWorldRotation * transforms[mesh.ParentBone.Index] * Matrix.CreateTranslation(loc);
            GraphicsDevice.RenderState.DepthBufferEnable = true;
            effect.EnableDefaultLighting();

            //effect.World = world;
            effect.View = view;
            effect.Projection = projection;
        }

        mesh.Draw();
    }
}

And that was the method where I draw the models and make the matrix transformations. More code is available upon request along with any more information.

2条回答
祖国的老花朵
2楼-- · 2019-07-18 03:58

I was unable to figure out how to make the same transformations in the isCollision method. If anyone could help me, that would be great

You do this by building the transformation matrix in the Update method after you've applied any movement or rotation. Then save that built matrix and pass it for use in both collision test method and draw method.

Matrix TransformationMatrix;   
void Update()
        {
        TransformationMatrix = Matrix.Create...X(RotationX) * Matrix.Create...Y(RotationY) * transforms[mesh.ParentBone.Index] * Matrix.CreateTranslation(loc);
        }

then

(IsCollision(TransformationMatrix )
{
sphere.Transform(TransformationMatrix );
} 

and

DrawModel(TransformationMatrix )
{
 effect.World = TransformationMatrix ;
}
查看更多
小情绪 Triste *
3楼-- · 2019-07-18 04:05

You should build your world matrices from all three transformations (scale, rotation, translation, in that order). If you used only translation in your game then your method should work fine. Maybe your model is messed up. Try rendering bounding spheres to see if they truly intersect. Here is a really good BoundingSphereRenderer class.

查看更多
登录 后发表回答