-1


I've been trying to work on a 3d forward-runner game (like temple run) in XNA 4.0.
I'm hitting a bit of a brick wall, so any help would be much appreciated!
Currently, I'm using my own method for collision detection, which requires the dimensions for each model to be hard-coded into the collision method. I've tried using the code from Microsoft, directly below, but it always returns false:

  static bool CheckForCollisions(Entity c1, Entity c2)
    {
        for (int i = 0; i < c1.body.Meshes.Count; i++)
        {
            // Check whether the bounding boxes of the two cubes intersect.
            BoundingSphere c1BoundingSphere = c1.body.Meshes[i].BoundingSphere;
            c1BoundingSphere.Center += c1.position;

            for (int j = 0; j < c2.body.Meshes.Count; j++)
            {
                BoundingSphere c2BoundingSphere = c2.body.Meshes[j].BoundingSphere;
                c2BoundingSphere.Center += c2.position;

                if (c1BoundingSphere.Intersects(c2BoundingSphere))
                {
                    return true;
                }
            }
        }
        return false;
    }

This was taken and modified very slightly from, Here My Entity class goes as follows.

Code of mine which I think is relevant would be:

    public class Entity
    {
        public int rowID;
        public Model body;
        public Vector3 position;
        public float rotation = 0f;
        public float rotatePerFrame = 0f;
        protected internal float toRight = 0; 
        protected internal float toLeft = 0;
        protected internal float forward = 0;
        protected internal float back = 0;
        protected internal float bottom = 0;
        protected internal float top = 0;
        public void setDimensions(float right, float left, float front, float back, float top, float bottom)
        {
            this.toRight = right;
            this.toLeft = left;
            this.forward = front;
            this.back = back;
            this.top = top;
            this.bottom = bottom;
        }
        public Entity RotateEnt(Entity e,float degrees)//Psuedo-only accurate to 90 degrees.
        {
            float actual = MathHelper.ToDegrees(degrees);
            switch ((int)actual)
            {
                case 0:
                    break;
                case 90:
                  //  float temp = e.forward;
                  //  e.forward = e.toLeft;
                 //   e.toLeft =e.back ;
                 //   e.back = e.toRight;
                 //   e.toRight = temp;
                    float temp = e.forward;
                    e.forward = e.toRight;
                    e.toRight = e.back;
                    e.back = e.toLeft;
                       e.toLeft = temp;
                    break;
                case 180:
                    e.forward = e.back;
                    e.back = e.forward;
                    e.toRight = e.toLeft;
                    e.toLeft = e.toRight;
                    break;
                default: //case: 270

                    e.toRight = e.forward;
                    e.back = e.toRight;
                    e.toLeft = e.back;
                    e.forward = e.toLeft;
                    break;
            }


            return e;
        }
        public bool Collides(Entity e)
        {

            Entity c1 = RotateEnt(this, this.rotation);
            Entity c2 = RotateEnt(e, e.rotation);


            float myRightest = c1.position.X + c1.toRight;
            float myLeftest = c1.position.X - c1.toLeft;

             float hisRightest = c2.position.X + c2.toRight;
             float hisLeftest = c2.position.X - c2.toLeft;
            if(Collides1D(myLeftest, myRightest, hisLeftest, hisRightest))
            {

                float myTop = c1.position.Y + c1.top;
                float myBottom = c1.position.Y - c1.bottom;

                float hisTop = c2.position.Y + c2.top;
                float hisBottom = c2.position.Y - c2.bottom;
                if (Collides1D(myBottom, myTop, hisBottom, hisTop))
                {

                    float myBack = c1.position.Z - c1.forward;
                    float myForward = c1.position.Z + c1.back;

                    float hisBack = c2.position.Z - c2.forward;
                    float hisForward = c2.position.Z + c2.back;
                    if (Collides1D(myBack, myForward, hisBack, hisForward))
                    {

                        return true;
                    }
                }
            }
            return false;


        }
    }


    static bool Collides1D(float left1, float right1, float left2, float right2)
    {
        if (left1 >= left2 && left1 <= right2)
            return true;
        if (right1 >= left2 && right1 <= right2)
            return true;

        if (left2 >= left1 && left2 <= right1)
            return true;
        if (right2 >= left1 && right2 <= right1)
            return true;



        return false;
    }

My own method has been screwing up also, when trying to rotate models.
Ideally, it would be good to know what is wrong with the code from Microsoft, so that I can use it wherever, without worrying about hard-coding in object dimensions.
If anyone can see a fast fix to my own basic collision detection method, that would also be great.
I've looked at the Reimers tutorials, but I'm not getting them at the moment, maybe I've been staring at my own code for too long...
Any other information you want, I can try and supply. I can upload the models also, if that's the problem. I'm using models from Maya, exported as FBX. I'm using MSVS 2010. Thanks very much!
Jack

Jack
  • 472
  • 6
  • 13
  • How do you update the position of your models? – davidsbro Aug 09 '13 at 00:30
  • Here's the last section of code in my update method: if (kbstate.IsKeyDown(Keys.Up) || gpstate.DPad.Up == ButtonState.Pressed) { p1.position.Z -= speed; } cameraPos = p1.position; cameraPos.Y += 275; cameraPos.Z += 550; base.Update(gameTime); – Jack Aug 09 '13 at 02:33
  • My speed is a float which is currently 15f, and I also have gravity, which goes: Vector3 gravity = new Vector3(0f, -0.0017f, 0f); //later on... if (falling) { p1Velocity += (gravity * speed); } I've slowed things down to make sure that I don't 'jump past' anything I might collide with. – Jack Aug 09 '13 at 02:39
  • Have you tried putting breakpoints in your Collision check code? If you stop your game when you know two models are intersecting, then you could check the values of the boundingshperes and see why they aren't intersecting. – davidsbro Aug 09 '13 at 12:25

1 Answers1

0

I think the problem may not be in the collision code, but in how you are updating the position of your Entitys. I don't see any update code or MoveForward(), etc, type of code. First of all, though, I think it would be much easier for you to use a Matrix instead of a bunch of float values for rotation. For example, you could have:

public class Entity
{
    ...
    public Matrix RotationMatrix = Matrix.Identity;
    public Vector3 position;

    Public Entity(Vector3 FaceDirection, Vector3 UpDirection, Vector3 Position)
    {
        ...
        position = Position
        RotationMatrix  = Matrix.CreateWorld(Position, FaceDirection, UpDirection)  
    }
}

Then if you want to rotate, all you have to do is:

public Void RotateEnt(float Degrees)
{
    RotationMatrix *= Matrix.CreateFromAxisAngle(RotationMatrix.Up, MathHelper.ToRadians(Degrees));
}

And if you do all this, then you should easily be able to update your Entity's position, which I think is the problem

public Void Update(GameTime gametime)
{
    position += RotationMatrix.Forward * gametime.ElapsedRealTime.TotalMilliseconds * x; //x = some number to scale up or down velocity.
}

If you do this, I think your Entity's position will be updated, which then should fix your collision problem. But, not knowing how you update the position of your Entities, I am just speculating. HTH

davidsbro
  • 2,761
  • 4
  • 23
  • 33
  • My model moves and displays fine, so that's not really the problem I want to deal with here. Thanks for the suggestions, anyway. – Jack Aug 09 '13 at 02:05