0
\$\begingroup\$

I am currently working on a Minecraft like game with OpenGL and C++. I've gotten as far as abstracting a Camera object and setting up movement and even defining basic gravity like simulations, but I am stuck on collision detection and resolution.

Movement is defined by a function which adds an 'x' and 'z' velocity depending on the key pressed. I finally get a velocity vector which may look like (-2.0, 0.0, 2.5). The Velocity vector is then added to the camera's Position vector in a Move function. Then, I look for collisions and try to resolve them (currently only with the y-axis but even that does not work). The code for the Move function looks like:

void Camera::Move(const std::vector<glm::vec3>& cubePositions)
{
  glm::vec3 nPos = glm::vec3((int)(round(Position.x)), (int)(round(Position.y)), (int)(round(Position.z)));
  Position += Velocity;

  // Collision resolution
  for (float i = -2.0f; i <= 2.0f; i++)
  {
    for (float j = -2.0f; j <= 2.0f; j++)
    {
      for (float k = -2.0f; k <= 2.0f; k++)
      {
        if (std::find(cubePositions.begin(), cubePositions.end(), glm::vec3(nPos.x - i, nPos.y - j, nPos.z - k)) == cubePositions.end())
          continue;

        glm::vec3 box = glm::vec3(nPos.x - i, nPos.y - j, nPos.z - k);

        if
        (((Position.x - 0.5f <= box.x + 0.5f) || (Position.x + 0.5f >= box.x - 0.5f)) &&
         ((Position.y - 2.0f <= box.y + 0.5f) || (Position.y + 0.5f >= box.y - 0.5f)) &&
         ((Position.z - 0.5f <= box.z + 0.5f) || (Position.z + 0.5f >= box.z - 0.5f)))
        {
          LOG("Collision check with box " << box.x << " " << box.y << " " << box.z);
          Position.y -= Velocity.y;
          LOG("Position.y:  " << Position.y);
        }
      }
    }
  }

  LOG("Position: " << Position.x << " " << Position.y << " " << Position.z);
  Velocity = glm::vec3(0.0f);
}

(LOG is just a macro which prints to the screen). Right now, when a collision with a block is detected, it causes this sort of jumpy motion. This is the output:

...
[LOG] Position: 2.10997 -12.1245 3.19591
[LOG] Position: 2.10997 -12.1899 3.19591
[LOG] Position: 2.10997 -12.2546 3.19591
[LOG] Position: 2.10997 -12.3261 3.19591
[LOG] Position: 2.10997 -12.3952 3.19591
[LOG] Position: 2.10997 -12.4618 3.19591
[LOG] Position: 2.10997 -12.5288 3.19591
[LOG] Collision check with box 4 -15 5
[LOG] Position.y:  -12.5288
[LOG] Collision check with box 4 -15 4
[LOG] Position.y:  -12.4595
[LOG] Collision check with box 4 -15 3
[LOG] Position.y:  -12.3903
[LOG] Collision check with box 4 -15 2
[LOG] Position.y:  -12.321
[LOG] Collision check with box 4 -15 1
[LOG] Position.y:  -12.2518
[LOG] Collision check with box 3 -15 5
[LOG] Position.y:  -12.1825
[LOG] Collision check with box 3 -15 4
[LOG] Position.y:  -12.1133
[LOG] Collision check with box 3 -15 3
[LOG] Position.y:  -12.044
[LOG] Collision check with box 3 -15 2
[LOG] Position.y:  -11.9748
[LOG] Collision check with box 3 -15 1
[LOG] Position.y:  -11.9055
[LOG] Collision check with box 2 -15 5
[LOG] Position.y:  -11.8363
[LOG] Collision check with box 2 -15 4
[LOG] Position.y:  -11.767
[LOG] Collision check with box 2 -15 3
[LOG] Position.y:  -11.6978
[LOG] Collision check with box 2 -15 2
[LOG] Position.y:  -11.6285
[LOG] Collision check with box 2 -15 1
[LOG] Position.y:  -11.5593
[LOG] Collision check with box 1 -15 5
[LOG] Position.y:  -11.49
[LOG] Collision check with box 1 -15 4
[LOG] Position.y:  -11.4208
[LOG] Collision check with box 1 -15 3
[LOG] Position.y:  -11.3515
[LOG] Collision check with box 1 -15 2
[LOG] Position.y:  -11.2823
[LOG] Collision check with box 1 -15 1
[LOG] Position.y:  -11.213
[LOG] Collision check with box 0 -15 5
[LOG] Position.y:  -11.1437
[LOG] Collision check with box 0 -15 4
[LOG] Position.y:  -11.0745
[LOG] Collision check with box 0 -15 3
[LOG] Position.y:  -11.0052
[LOG] Collision check with box 0 -15 2
[LOG] Position.y:  -10.936
[LOG] Collision check with box 0 -15 1
[LOG] Position.y:  -10.8667
[LOG] Position: 2.10997 -10.8667 3.19591
[LOG] Position: 2.10997 -10.9176 3.19591
...

(here, when I say with box x y z, x y z refers to the box's co-ordinates, which are just transformations applied to a defined set of vertices when each box is drawn)

I have been working on this for a while, and looked for a while for a solution, but could not find any. I appreciate any help :)

Edit: I changed the if-condition since I found out it was, wrong. But the bouncing motion still exists, only to a lesser scale. The correct if-condition:

if
        (((Position.x - 0.5f <= box.x + 0.5f) && (Position.x + 0.5f >= box.x - 0.5f)) &&
         ((Position.y - 2.0f <= box.y + 0.5f) && (Position.y + 0.5f >= box.y - 0.5f)) &&
         ((Position.z - 0.5f <= box.z + 0.5f) && (Position.z + 0.5f >= box.z - 0.5f)))

The output:

...
[LOG] Position: 5.43324 -12.5657 6.24592
[LOG] Collision check with box 6 -15 7
[LOG] Position.y:  -12.5657
[LOG] Collision check with box 6 -15 6
[LOG] Position.y:  -12.5014
[LOG] Collision check with box 5 -15 7
[LOG] Position.y:  -12.4371
[LOG] Position: 5.43324 -12.4371 6.24592
[LOG] Position: 5.43324 -12.5011 6.24592
[LOG] Collision check with box 6 -15 7
[LOG] Position.y:  -12.5011
[LOG] Collision check with box 6 -15 6
[LOG] Position.y:  -12.4362
[LOG] Position: 5.43324 -12.4362 6.24592
[LOG] Position: 5.43324 -12.5246 6.24592
[LOG] Collision check with box 6 -15 7
[LOG] Position.y:  -12.5246
[LOG] Collision check with box 6 -15 6
[LOG] Position.y:  -12.4312
[LOG] Position: 5.43324 -12.4312 6.24592
...
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.