Jump to content


AABB Creation and Camera to AABB Collisions


6 replies to this topic

#1 AaronLLF

    New Member

  • Members
  • Pip
  • 4 posts

Posted 23 November 2010 - 01:45 AM

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();





	}

}


#2 Reedbeta

    DevMaster Staff

  • Administrators
  • 5307 posts
  • LocationBellevue, WA

Posted 23 November 2010 - 01:54 AM

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.
reedbeta.com - developer blog, OpenGL demos, and other projects

#3 AaronLLF

    New Member

  • Members
  • Pip
  • 4 posts

Posted 23 November 2010 - 01:57 AM

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

#4 Reedbeta

    DevMaster Staff

  • Administrators
  • 5307 posts
  • LocationBellevue, WA

Posted 23 November 2010 - 02:07 AM

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.
reedbeta.com - developer blog, OpenGL demos, and other projects

#5 AaronLLF

    New Member

  • Members
  • Pip
  • 4 posts

Posted 23 November 2010 - 04:10 PM

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

#6 .oisyn

    DevMaster Staff

  • Moderators
  • 1842 posts

Posted 23 November 2010 - 05:47 PM

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.
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#7 AaronLLF

    New Member

  • Members
  • Pip
  • 4 posts

Posted 23 November 2010 - 11:10 PM

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?





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users