AABB Creation and Camera to AABB Collisions

65eb966ad5022f5d1a74db72d434ff6e
0
AaronLLF 101 Nov 23, 2010 at 01:45

I would have seen this on the wiki but it’s been down for a while.

I’m developing a game and need AABB creating for terrains and collisions of the camera and AABB. Here is my current code (a lot is commented out in case I need it later):

import java.io.FileInputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.lwjgl.Sys;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.vector.Vector3f;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.util.glu.*;

import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;

import toxi.geom.Vec3D;
import toxi.geom.*;


//First Person Camera Controller
public class FPCameraController
{
    //GLImage sky;
    //the texture
    private Texture texture;
    //3d vector to store the camera's position in
    private Vector3f    position    = null;
    //the rotation around the Y axis of the camera
    private float       yaw         = 0.0f;
    //the rotation around the X axis of the camera
    private float       pitch       = 0.0f;
    //Constructor that takes the starting x, y, z location of the camera
    public FPCameraController(float x, float y, float z)
    {
        //instantiate position Vector3f to the x y z params.
        position = new Vector3f(x, y, z);
    }
    public FPCameraController() { // This is made so the line FPCameraController app = new FPCameraController(); will work
        // TODO Auto-generated constructor stub
    }
    //increment the camera's current yaw rotation
    public void yaw(float amount)
    {
        //increment the yaw by the amount param
        yaw += amount;
    }

    //increment the camera's current yaw rotation
    public void pitch(float amount)
    {
        //increment the pitch by the amount param
        pitch += amount;
    }
    //moves the camera forward relitive to its current rotation (yaw)
    public void walkForward(float distance)
    {
            position.x -= distance * (float)Math.sin(Math.toRadians(yaw));
            position.z += distance * (float)Math.cos(Math.toRadians(yaw));
    }

    //moves the camera backward relitive to its current rotation (yaw)
    public void walkBackwards(float distance)
    {       
            position.x += distance * (float)Math.sin(Math.toRadians(yaw));
            position.z -= distance * (float)Math.cos(Math.toRadians(yaw));
    }

    //strafes the camera left relitive to its current rotation (yaw)
    public void strafeLeft(float distance)
    {
            position.x -= distance * (float)Math.sin(Math.toRadians(yaw-90));
            position.z += distance * (float)Math.cos(Math.toRadians(yaw-90));
    }

    //strafes the camera right relitive to its current rotation (yaw)
    public void strafeRight(float distance)
    {
            position.x -= distance * (float)Math.sin(Math.toRadians(yaw+90));
            position.z += distance * (float)Math.cos(Math.toRadians(yaw+90));
    }
    public void playerJump(float distance)
    {
            position.y -= distance * (float)Math.sin(Math.toRadians(yaw+90));
    }
    public void playerFall(float distance)
    {
            position.y += distance * (float)Math.sin(Math.toRadians(yaw+90));
    }
    //translates and rotate the matrix so that it looks through the camera
    //this dose basic what gluLookAt() does
    public void lookThrough()
    {
        //roatate the pitch around the X axis
        GL11.glRotatef(pitch, 1.0f, 0.0f, 0.0f);
        //roatate the yaw around the Y axis
        GL11.glRotatef(yaw, 0.0f, 1.0f, 0.0f);
        //translate to the position vector's location
        GL11.glTranslatef(position.x, position.y, position.z);
    }
    private static boolean gameRunning=true;
    private static int targetWidth = 800;
    private static int targetHeight = 600;

    private void init(){
        try {
            texture = TextureLoader.getTexture("PNG", new FileInputStream("C:/Game/Textures/Floor_002.png"));
        } catch (IOException ex) {
            Logger.getLogger(FPCameraController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private float xrot=0.1f;
    private float yrot=0.1f;
    private float zrot=0.1f;

    /** The texture that's been loaded */

    private static void initDisplay(boolean fullscreen){

        DisplayMode chosenMode = null;

        try {
                DisplayMode[] modes = Display.getAvailableDisplayModes();

                for (int i=0;i<modes.length;i++) {
                    if ((modes[i].getWidth() == targetWidth) && (modes[i].getHeight() == targetHeight)) {
                        chosenMode = modes[i];
                        break;
                    }
                }
            } catch (LWJGLException e) {
        Sys.alert("Error", "Unable to determine display modes.");
        System.exit(0);
    }

        // at this point if we have no mode there was no appropriate, let the user know
    // and give up
        if (chosenMode == null) {
            Sys.alert("Error", "Unable to find appropriate display mode.");
            System.exit(0);
        }

        try {
            Display.setDisplayMode(chosenMode);
            Display.setFullscreen(fullscreen);
            Display.setTitle("Secret Title from New Wave Games (Aaron Glazer) (ESC untimately will close it! Once you've pressed it, NO turning back! :P");
            Display.create();

        }
        catch (LWJGLException e) {
            Sys.alert("Error","Unable to create display.");
            System.exit(0);
        }

}

    private static boolean initGL(){
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();

//        Calculate the aspect ratio of the window
        GLU.gluPerspective(45.0f,((float)targetWidth)/((float)targetHeight),0.1f,50.0f);
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
        GL11.glLoadIdentity();

        GL11.glEnable(GL11.GL_TEXTURE_2D);                                    // Enable Texture Mapping ( NEW )
        GL11.glShadeModel(GL11.GL_SMOOTH);
        GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        GL11.glClearDepth(1.0f);
        GL11.glEnable(GL11.GL_DEPTH_TEST);
        GL11.glDepthFunc(GL11.GL_LEQUAL);
        GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);
        return true;
    }

    private void run(){
      FPCameraController camera = new FPCameraController(0, -7, 0);

            float dx        = 0.0f;
            float dy        = 0.0f;
            float dt        = 0.0f; //length of frame
            float lastTime  = 0.0f; // when the last frame was
            float time      = 0.0f;

            float mouseSensitivity = 0.15f;
            float movementSpeed = 20.0f;
            //hide the mouse
            Mouse.setGrabbed(true);
        while(gameRunning){
            update();
            renderGround();
            Display.update();

             //keep looping till the display window is closed the ESC key is down
            /*
            while (!Display.isCloseRequested() ||
             !Keyboard.isKeyDown(Keyboard.KEY_ESCAPE))
                {
                */
                time = Sys.getTime();
                dt = (time - lastTime)/1000.0f;
                lastTime = time;


                //distance in mouse movement from the last getDX() call.
                dx = Mouse.getDX();
                //distance in mouse movement from the last getDY() call.
                dy = Mouse.getDY();

                //control camera yaw from x movement from the mouse
                camera.yaw(dx * mouseSensitivity);
                //control camera pitch from y movement from the mouse
                camera.pitch(-dy * mouseSensitivity);


                //when passing in the distrance to move
                //we times the movementSpeed with dt this is a time scale
                //so if its a slow frame u move more then a fast frame
                //so on a slow computer you move just as fast as on a fast computer
                //OVER HERE! What do I do to make the boolean canWalk actually work the right way?
                if (Keyboard.isKeyDown(Keyboard.KEY_W))//move forward
                {
                    camera.walkForward(movementSpeed*dt);
                }
                if (Keyboard.isKeyDown(Keyboard.KEY_S))//move backwards
                {
                    camera.walkBackwards(movementSpeed*dt);
                }
                if (Keyboard.isKeyDown(Keyboard.KEY_A))//strafe left
                {
                    camera.strafeLeft(movementSpeed*dt);
                }
                if (Keyboard.isKeyDown(Keyboard.KEY_D))//strafe right
                {
                    camera.strafeRight(movementSpeed*dt);
                }
                

                //set the modelview matrix back to the identity
                GL11.glLoadIdentity();
                //look through the camera before you draw anything
                camera.lookThrough();
                //you would draw your scene here.

                //draw the buffer to the screen
                //Display.update();
            //}

            // finally check if the user has requested that the display be
            // shutdown
            if (Display.isCloseRequested()) {
                    gameRunning = false;
                    Display.destroy();
                    System.exit(0);
                }
            if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE))
            {
                Sys.alert("Close","To continue, press ESCAPE on your keyboard or OK on the screen.");
                System.exit(0);
                
            }
        }
    }

    private void update(){
        xrot+=0.1f;
        yrot+=0.1f;
        zrot+=0.1f;
    }

    private void renderGround() {
        //sky = loadImage("C:/Game/Textures/Sky.png");
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT|GL11.GL_DEPTH_BUFFER_BIT);
        //GL11.glLoadIdentity();
        GL11.glTranslatef(0.0f,0.0f,0.0f);
        GL11.glBegin(GL11.GL_QUADS);
        texture.bind(); // or GL11.glBind(texture.getTextureID());
        /*
                // Front Face
                GL11.glTexCoord2f(0.0f, 0.0f);
                GL11.glVertex3f(-50.0f, -1.0f,  50.0f);   // Bottom Left Of The Texture and Quad
                GL11.glTexCoord2f(1.0f, 0.0f);
                GL11.glVertex3f( 50.0f, -1.0f,  50.0f);   // Bottom Right Of The Texture and Quad
                GL11.glTexCoord2f(1.0f, 1.0f);
                GL11.glVertex3f( 50.0f,  1.0f,  50.0f);   // Top Right Of The Texture and Quad
                GL11.glTexCoord2f(0.0f, 1.0f);
                GL11.glVertex3f(-50.0f,  1.0f,  50.0f);   // Top Left Of The Texture and Quad
                
                // Back Face
                GL11.glTexCoord2f(1.0f, 0.0f);
                GL11.glVertex3f(-50.0f, -1.0f, -50.0f);   // Bottom Right Of The Texture and Quad
                GL11.glTexCoord2f(1.0f, 1.0f);
                GL11.glVertex3f(-50.0f,  1.0f, -50.0f);   // Top Right Of The Texture and Quad
                GL11.glTexCoord2f(0.0f, 1.0f);
                GL11.glVertex3f( 50.0f,  1.0f, -50.0f);   // Top Left Of The Texture and Quad
                GL11.glTexCoord2f(0.0f, 0.0f);
                GL11.glVertex3f( 50.0f, -1.0f, -50.0f);   // Bottom Left Of The Texture and Quad
                */
                // Top Face
                GL11.glTexCoord2f(0.0f, 1.0f);
                GL11.glVertex3f(-50.0f,  0.0f, -50.0f);   // Top Left Of The Texture and Quad
                GL11.glTexCoord2f(0.0f, 0.0f);
                GL11.glVertex3f(-50.0f,  1.0f,  50.0f);   // Bottom Left Of The Texture and Quad
                GL11.glTexCoord2f(1.0f, 0.0f);
                GL11.glVertex3f( 50.0f,  1.0f,  50.0f);   // Bottom Right Of The Texture and Quad
                GL11.glTexCoord2f(1.0f, 1.0f);
                GL11.glVertex3f( 50.0f,  1.0f, -50.0f);   // Top Right Of The Texture and Quad
                /*
                // Bottom Face
                GL11.glTexCoord2f(1.0f, 1.0f);
                GL11.glVertex3f(-50.0f, -1.0f, -50.0f);   // Top Right Of The Texture and Quad
                GL11.glTexCoord2f(0.0f, 1.0f);
                GL11.glVertex3f( 50.0f, -1.0f, -50.0f);   // Top Left Of The Texture and Quad
                GL11.glTexCoord2f(0.0f, 0.0f);
                GL11.glVertex3f( 50.0f, -1.0f,  50.0f);   // Bottom Left Of The Texture and Quad
                GL11.glTexCoord2f(1.0f, 0.0f);
                GL11.glVertex3f(-50.0f, -1.0f,  50.0f);   // Bottom Right Of The Texture and Quad

                // Right face
                GL11.glTexCoord2f(1.0f, 0.0f);
                GL11.glVertex3f( 50.0f, -1.0f, -50.0f);   // Bottom Right Of The Texture and Quad
                GL11.glTexCoord2f(1.0f, 1.0f);
                GL11.glVertex3f( 50.0f,  1.0f, -50.0f);   // Top Right Of The Texture and Quad
                GL11.glTexCoord2f(0.0f, 1.0f);
                GL11.glVertex3f( 50.0f,  1.0f,  50.0f);   // Top Left Of The Texture and Quad
                GL11.glTexCoord2f(0.0f, 0.0f);
                GL11.glVertex3f( 50.0f, -1.0f,  50.0f);   // Bottom Left Of The Texture and Quad

                // Left Face
                GL11.glTexCoord2f(0.0f, 0.0f);
                GL11.glVertex3f(-010.0f, -1.0f, -50.0f);   // Bottom Left Of The Texture and Quad
                GL11.glTexCoord2f(1.0f, 0.0f);
                GL11.glVertex3f(-50.0f, -1.0f,  50.0f);   // Bottom Right Of The Texture and Quad
                GL11.glTexCoord2f(1.0f, 1.0f);
                GL11.glVertex3f(-50.0f,  1.0f,  50.0f);   // Top Right Of The Texture and Quad
                GL11.glTexCoord2f(0.0f, 1.0f);
                GL11.glVertex3f(-50.0f,  1.0f, -50.0f);   // Top Left Of The Texture and Quad
                */
        GL11.glEnd();
    }

    public static void main(String[] args)
{
        FPCameraController app = new FPCameraController();
        initDisplay(false);
        initGL();
        app.init();
        app.run();




    }
}

6 Replies

Please log in or register to post a reply.

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Nov 23, 2010 at 01:54

Do you have a specific question? I don’t quite see what you need help with. Is your terrain a heightfield, or modeled polys? If it’s a heightfield, collision is quite easy by finding the point under the camera (or player, or whatever) and checking the height against the camera’s height, so there is not much need for AABBs. For modeled polys, a BSP tree would be the usual method for collision detection.

65eb966ad5022f5d1a74db72d434ff6e
0
AaronLLF 101 Nov 23, 2010 at 01:57

I’m trying to make a blocky-world like Minecraft. Not a GAME like Minecraft, just map.

I’m trying to make it so that once the camera hits the AABB, you can’t move in that direction.

Right now the map is just a plane made with GL11

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Nov 23, 2010 at 02:07

Okay. Minecraft terrains are made of a regular 3D grid of cells, also called voxels (you may want to google that).

Here’s what I’d suggest starting with. Each frame, when you update your camera, initially calculate its new position as if there were no collision. Then calculate which grid square the new position is in (divide by the grid spacing and use floor() to convert to integer grid coordinates). Look up whether that grid square is occupied, and if so disallow the move - that is, keep the camera at its old position.

The results will be dependent on movment speed and framerate - in particular, you’ll be able to “warp” through thin walls if the camera moves fast enough, or the framerate drops low enough. For more robust collision you’ll eventually want to trace a ray between the camera’s old and new position and find any intersections with terrain, then move the camera only as far as the nearest intersection point.

Hope this helps.

65eb966ad5022f5d1a74db72d434ff6e
0
AaronLLF 101 Nov 23, 2010 at 16:10

Uhhhh…

You see, the thing is, I have no idea how to create AABBs or pretty much anything… So I need the sample code from the Wiki if anyone has it, please :D

340bf64ac6abda6e40f7e860279823cb
0
_oisyn 101 Nov 23, 2010 at 17:47

Then maybe you should read up on AABBs. There are various ways to represent them. My personal favourite is using center and extent vectors, but you could also use min and max vectors, or the 8 corner vertices, or 6 planes, or whatever.

Creating a minimum fit AABB consists of simply getting the minimum and maximum of the object in X, Y and Z axes.

65eb966ad5022f5d1a74db72d434ff6e
0
AaronLLF 101 Nov 23, 2010 at 23:10

After a while of looking up AABBs none of them work/aren’t for Java/don’t give code examples. I’m using the toxiclibs download library for AABB. Is that the wrong one?