0

I hope someone out there can answer my question. Currently I am doing some collision detection using D3DXVectors. I have the collision down, but what I need is what to do AFTER the collision has been made.

I have a player object and the object the player is being collided with and pass these into my function.

Basically, I have this so far (variables names have been changed for clarity):

D3DXVECTOR3 Collision::wallCol(D3DXVECTOR3 player, D3DXVECTOR3 object, float playerWidth, float playerDepth, float objectWidth, float objectDepth)
{
        //store the values of the objects into temps
        //left hand side of a box
        float minX = object.x - (objectWidth / 2);

        //right hand side of a box
        float maxX = object.x + (objectWidth / 2);

        //front of a box
        float minZ = object.z - (objectDepth / 2);

        //back of a box
        float maxZ = object.z + (objectDepth / 2);

        //store the players positions into temps
        float pminX = player.x - (playerWidth / 2);
        float pmaxX = player.x + (playerWidth / 2);
        float pminZ = player.z - (playerDepth / 2);
        float pmaxZ = player.z + (playerDepth / 2);


        //check to see if we are in the box at all
        if (pminX <= maxX && pmaxX >= minX &&
            pminZ <= maxZ && pmaxZ >= minZ)
        {

            //x collision for the left side of the block
            if (pmaxX >= minX && pmaxX <= maxX)
            {
                pmaxX = minX - 50;
                player.x = pmaxX;

                return player;
            }

            //x collision for the right side of the block
            if (pminX <= maxX && pminX >= minX)
            {
                pminX = maxX + 50;
                player.x = pminX;

                return player;
            }

            //z collision for the front
            if (pmaxZ >= minZ && pmaxZ <= maxZ)
            {
                pmaxZ = minZ - 20;
                player.z = pmaxZ;

                return player;
            }

            //z collision for the back
            if (pminZ <= maxZ && pminZ >= minZ)
            {
                pminZ = maxZ + 20;
                player.z = pminZ;

                return player;
            }
        }
        return player;
    }

As you can see, I would like to move my player object away from whatever it is that it is bumping into. The problem I am having is that no matter what, my player will always move either to the left or the right on the X axis because it accounts for the X first, it never has the chance to even get to the Z if statements.

I've considered making 2 Booleans to tell if the player makes contact with the X or the Z first, but since the first if statement is to even see if we are in the box, I believe it would trigger them both at the same time and there would be no way to tell which came first.

If anyone could offer some advice on this problem, it would be greatly appreciated! Thank you.

1 Answers1

2

In order to implement more or less realistic bouncing it is not enough to have only positions and bounding boxes of colliding objects. You need to have some kind of kinematic history: to be able to tell how objects move after collision you should also know how they were moving before the collision.

In simplest case, you want to have at least a velocity (speed) vector (direction and magnitude) and, probably, a mass for every object. When collision is detected you may simply invert the direction of the velocity vector of one of the objects (for example, smaller and lighter one).

The pseudocode will be something like:

if have_collided(object1, object2):
   if object1.mass > object2.mass:
      object2.velocity = -object2.velocity
   else:
      object1.velocity = -object1.velocity

This would not look very realistic, but is very simple to implement. For more realism you could use momentum conservation principle or elastic collisions. For even more realistic bouncing, implement acceleration vector and re-calculate both, velocity and acceleration after collision is detected. Having acceleration you may now add arbitrary forces influencing your objects (gravity, friction, maybe even electromagnetic forces etc.). Adding more attributes make it more interesting: for example adding elasticity and viscosity may be used to calculate deformations.

As you see there is more in object interactions involved than just positions.

Additionally, collision detection and bouncing code could (and should) be decoupled. That means that you would want to implement them in different parts of code (different set of functions and classes): collision subsystem will detect the collision event, providing information like: whether collision happened or not and if yes, by how far objects currently intersect with each other. After that, bouncing code, based on this information, will decide how to change objects traveling, while deformation code will decide how to change objects shapes etc. Thus, there will be no silly problems like which "if" statement in collision code came first decides the direction of bouncing.

Overall I would suggest you:

Finally, you should know that DirectX 9 API is wildly obsolete, not supported and should not be used for new projects. It is notoriously hard to port D3DX* stuff to modern APIs. You may want to take a look at DirectX 11 and OpenGL 4, along with their support library ecosystems, or maybe even a good rendering or game engine. Specifically you may want to use some good math library (with vectors, matrices, linear algebra, geometry).

Ivan Aksamentov - Drop
  • 12,860
  • 3
  • 34
  • 61
  • Thanks so much for the response! I'm about to sit down and work on implementing what you have suggested. On a side note, do you have any recommended books on using DirectX11? – Kayleigh Ekwall Apr 02 '18 at 17:08
  • @KayleighEkwall Frank Luna's books are good for starters, however tutorials on Rastertek and Braynzar have roughly equivalent content and are funnier and also free. Check [Practical Rendering and Computation with Direct3D 11](https://www.amazon.fr/Practical-Rendering-Computation-Direct3D-11-ebook/dp/B00918NNIS) for more advanced stuff. At all times, keep [Microsoft DirectX documentation](https://msdn.microsoft.com/en-us/library/windows/desktop/ff476080(v=vs.85).aspx) page open in a browser window on a side when you do coding (to quickly lookup functions, parameters, errors etc.). – Ivan Aksamentov - Drop Apr 02 '18 at 23:11
  • Also, stay away from DirectX 12 for some time until you will be comfortable with rendering complex scenes in DirectX 11. DirectX 12 is not a replacement for DirectX 11, but a different, low-lever API, mostly intended for experts. – Ivan Aksamentov - Drop Apr 02 '18 at 23:13
  • Thanks so much for the response. It's greatly appreciated! – Kayleigh Ekwall Apr 03 '18 at 19:04