LWJGL ray picking

Started by
3 comments, last by Viped 11 years, 5 months ago
Hi, I am trying to make my first 3d game engine but cant implement shooting. I have read those few tuts what I could find but still cant do it. Any help would be appreciated.

Core.java
[source lang="java"]package net.viped.vengine;

import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.util.glu.GLU.*;

import java.awt.image.CropImageFilter;

import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Cursor;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;

public class Core {

public static final int WIDTH = 800;
public static final int HEIGHT = 600;
private Camera cam;
World world = new World();
Cursor emptyCursor;
Gun gun = new Gun();
boolean shooting = false;
long shootTime;

public Core() {
try {
Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));
Display.setTitle("vEngine 0.12");
Display.setVSyncEnabled(true);
Display.setResizable(false);

Display.create();
init();

world.createTestWorld();
long lastTime = System.nanoTime();
int frames = 0;
while (!Display.isCloseRequested()) {
tick();
render();
frames++;

if (System.nanoTime() - lastTime > 1000000000) {
System.out.println(frames + "FPS");
frames = 0;
lastTime = System.nanoTime();
}
Display.sync(60);
Display.update();
}

Display.destroy();
System.exit(0);
} catch (Exception e) {
e.printStackTrace();
Display.destroy();
System.exit(0);
}
}

public void init() {
Mouse.setGrabbed(true);
cam = new Camera(70, (float) (WIDTH / HEIGHT), 0.3f, 1000);
//Siirtää kameran alkupositiota
cam.move(0.0f, 1);

cam.setY(1.0f);

}

public void tick() {
input();
}

public void input() {
if (Keyboard.isKeyDown(Keyboard.KEY_W)) {
cam.move(0.1f, 1);
}
if (Keyboard.isKeyDown(Keyboard.KEY_S)) {
cam.move(-0.1f, 1);
}
if (Keyboard.isKeyDown(Keyboard.KEY_A)) {
cam.move(0.1f, 0);
}
if (Keyboard.isKeyDown(Keyboard.KEY_D)) {
cam.move(-0.1f, 0);
}
if (Keyboard.isKeyDown(Keyboard.KEY_SPACE) && collidingDown() && !cam.flymode) {
cam.jumping = true;
}
if (Keyboard.isKeyDown(Keyboard.KEY_SPACE) && cam.flymode) {
cam.fly(-0.1f);
}
if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) && cam.flymode) {
cam.fly(0.1f);
}
if (Keyboard.isKeyDown(Keyboard.KEY_F)) {
cam.flymode = !cam.flymode;
}
if (cam.jumping) {
cam.jump();
}
if (Mouse.isButtonDown(0)) {
renderAmmo();// shootTime = System.currentTimeMillis();
} else {
// shooting = false;
}
cam.rotateY(Mouse.getDX());
cam.rotateX(-Mouse.getDY());
}

public boolean collidingDown() {
for (int i = 0; i < world.walls.size(); i++) {
if ((-cam.getZ() > world.walls.get(i).z && (-cam.getZ() < world.walls.get(i).z + world.walls.get(i).length)) && (-cam.getX() > world.walls.get(i).x && -cam.getX() < world.walls.get(i).x + world.walls.get(i).width) && (-cam.getY() > world.walls.get(i).y - 0.5f)) {// && -cam.getY() < world.walls.get(i).y +2.5f)) {
return true;
}
}
return false;
}

// public boolean collidingDown() {
// for (int i = 0; i < world.walls.size(); i++) {
// if ((-cam.getZ() > world.walls.get(i).z && (-cam.getZ() < world.walls.get(i).z + world.walls.get(i).length)) && (-cam.getX() > world.walls.get(i).x && -cam.getX() < world.walls.get(i).x + world.walls.get(i).width) && (cam.getY() < -world.walls.get(i).y + 0.5f)) {
// return true;
// }
// }
// return false;
// }

public void renderCursor() {
glLoadIdentity();
glPushMatrix();
glLineWidth(1);
glBegin(GL_LINES);
glColor3f(0, 1, 0);
glVertex2f(WIDTH / 2 - 15, HEIGHT / 2);
glVertex2f(WIDTH / 2 + 15, HEIGHT / 2);
glVertex2f(WIDTH / 2, HEIGHT / 2 - 15);
glVertex2f(WIDTH / 2, HEIGHT / 2 + 15);
glEnd();

glPopMatrix();

}

public void render() {
cam.initProjection();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();
cam.useView();

glPushMatrix();

glTranslatef(0, -2, 0);

if (!collidingDown() && !cam.jumping && !cam.flymode) {
cam.implementGravity();
}

world.renderTestWorld();

// if (System.currentTimeMillis() - shootTime < 2000 && !shooting) {
// renderAmmo(cam.getRy(), cam.getY(), cam.getZ());
// }

glPopMatrix();

glPushMatrix();

glPopMatrix();

// glPushMatrix();
//
// System.out.println("x: " + cam.getX() + " , y: " + cam.getY() + " , z: " + cam.getZ());
//
// Vector3D from = new Vector3D(cam.getX(), -cam.getY(), -cam.getZ());
// glTranslatef(1, -10, -from.z);
// glColor3f(1f, 0.5f, 0.5f);
// glBegin(GL_QUADS);
// glVertex3f(from.x - 2, from.y, -from.z -2);
// glVertex3f(from.x + 2, from.y, -from.z -2);
// glVertex3f(from.x + 2, from.y, -from.z +2);
// glVertex3f(from.x - 2, from.y, -from.z +2);
// glEnd();
//
// glPopMatrix();

cam.init2D();
renderCursor();
gun.renderGun();
cam.initProjection();
}

public void renderAmmo(){//float x, float y, float z) {





}

public static void main(String[] args) {
new Core();
}

private class Vector3D {
float x, y, z;

public Vector3D(float x, float y, float z) {
this.x = x;
this.y = y;
this.z = z;
}
}
}
[/source]

Camera.java

[source lang="java"]package net.viped.vengine;

import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.util.glu.GLU.*;

public class Camera {
private float x, y, z;
private float rx, ry, rz;

private float fov;
private float aspect;
private float near;
private float far;

boolean flymode = false;

float speed = 0.05f;
float gravity = 0.5f;
float ogJumpGravity = 1.0f;
float jumpGravity = ogJumpGravity;
boolean jumping;

public Camera(float fov, float aspect, float near, float far) {
x = 0;
y = 0;
z = 0;
rx = 0;
ry = 0;
rz = 0;

this.fov = fov;
this.aspect = aspect;
this.near = near;
this.far = far;
initProjection();
}

public void initProjection() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(fov, aspect, near, far);
// glOrtho(0, Core.WIDTH, Core.HEIGHT, 0, 1, -1000);
glMatrixMode(GL_MODELVIEW);

glEnable(GL_DEPTH_TEST);
}

public void init2D() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, Core.WIDTH, Core.HEIGHT, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
}

public void useView() {
// gluLookAt(rx, ry, rz, x, y, z, 0, 1, 0);

glRotatef(rx, 1, 0, 0);
glRotatef(ry, 0, 1, 0);
glRotatef(rz, 0, 0, 1);
glTranslatef(x, y, z);
}

public void move(float amount, int dir) {
z += amount * Math.sin(Math.toRadians(ry + 90 * dir));
x += amount* Math.cos(Math.toRadians(ry + 90 * dir));
}

public void fly(float amount) {
if (flymode) {
y += amount;

}
}

public void jump() {
if (jumping) {
y -= jumpGravity;
jumpGravity -= speed;
if (y > 0) {
y = 0;
jumpGravity = ogJumpGravity;
jumping = false;
}
}

}

public void implementGravity() {

y += gravity;
}

public void rotateY(float amount) {
ry += amount;

}

public void rotateX(float amount) {
if (rx + amount >= -90 && rx + amount <= 90 ) {
rx += amount;
}
}

public float getX() {
return x;
}

public void setX(float x) {
this.x = x;
}

public float getY() {
return y;
}

public void setY(float y) {
this.y = y;
}

public float getZ() {
return z;
}

public void setZ(float z) {
this.z = z;
}

public float getRx() {
return rx;
}

public void setRx(float rx) {
this.rx = rx;
}

public float getRy() {
return ry;
}

public void setRy(float ry) {
this.ry = ry;
}

public float getRz() {
return rz;
}

public void setRz(float rz) {
this.rz = rz;
}

public boolean isFlymode() {
return flymode;
}

public void setFlymode(boolean flymode) {
this.flymode = flymode;
}

public float getSpeed() {
return speed;
}

public void setSpeed(float speed) {
this.speed = speed;
}
}[/source]

World.java

[source lang="java"]package net.viped.vengine;

import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.util.glu.GLU.gluPerspective;

import java.util.ArrayList;
import java.util.Random;

public class World {

public World() {

}

int stars = 10000;
Star[] starsA = new Star[stars];
int displayListHandle;
public ArrayList<pathToStars> walls = new ArrayList<World.pathToStars>();
public pathToStars path;
public pathToStars path2;
public pathToStars path3;

public void createTestWorld() {
for (int i = 0; i < stars; i++) {
Random rand = new Random();
starsA = new Star((rand.nextFloat() - 0.5f) * 100f, (rand.nextFloat() - 0.5f) * 100f, rand.nextInt(200) - 100);
}

path = new pathToStars(-1.0f, -1.0f, -9.0f, 2.0f, 30f);
path2 = new pathToStars(3.0f, -1.0f, 1.0f, 2.0f, 30f);
path3 = new pathToStars(-4.0f, -1.0f, 1.0f, 2.0f, 30f);
walls.add(path);
walls.add(path2);
walls.add(path3);


for (int i = 0; i < walls.size(); i++) {

glBegin(GL_QUADS);
glVertex3f(walls.get(i).x, walls.get(i).y, walls.get(i).z);
glVertex3f(walls.get(i).x + walls.get(i).width, walls.get(i).y, walls.get(i).z);
glVertex3f(walls.get(i).x + walls.get(i).width, walls.get(i).y, walls.get(i).z + walls.get(i).length);
glVertex3f(walls.get(i).x, walls.get(i).y, walls.get(i).z + walls.get(i).length);
glEnd();

}
}

public void renderTestWorld() {
glColor3d(1, 1, 1);
for (Star s : starsA) {
Random rand = new Random();
glBegin(GL_POINTS);
{
glVertex3f(s.x, s.y, s.z);
}
glEnd();

}

for (int i = 0; i < walls.size(); i++) {

glBegin(GL_QUADS);
glVertex3f(walls.get(i).x, walls.get(i).y, walls.get(i).z);
glVertex3f(walls.get(i).x + walls.get(i).width, walls.get(i).y, walls.get(i).z);
glVertex3f(walls.get(i).x + walls.get(i).width, walls.get(i).y, walls.get(i).z + walls.get(i).length);
glVertex3f(walls.get(i).x, walls.get(i).y, walls.get(i).z + walls.get(i).length);
glEnd();

}
}

private class Star {
float x, y, z;

public Star(float x, float y, float z) {
this.x = x;
this.y = y;
this.z = z;
}
}

class pathToStars {

float x, y, z;
float width, length;

public pathToStars(float x, float y, float z, float width, float length) {
super();
this.x = x;
this.y = y;
this.z = z;
this.width = width;
this.length = length;
}

}
}
[/source]

Gun.java

[source lang="java"]package net.viped.vengine;

import static org.lwjgl.opengl.GL11.*;

import org.lwjgl.Sys;

public class Gun {

public void renderGun() {

glPushMatrix();
glLineWidth(40);
glColor3f(1, 0, 0);
glBegin(GL_LINES);
glVertex2f(Core.WIDTH-80, Core.HEIGHT+20);
glVertex2f(Core.WIDTH-Core.WIDTH/4-50, Core.HEIGHT-Core.HEIGHT/4);
glEnd();
glPopMatrix();


}

}
[/source]
Advertisement
I know this doesn't help with your problem, but may I ask why you're developing an engine rather than making use of a community lib? (See signature links)
Main reason is that I want to learn. I want to be able to do everything by myself atleast at some level.
Before anyone goes randomly searching through your code for potential problems perhaps we could have some more information. What specifically are you trying to accomplish? What's going wrong? Are there any error messages or is it just not working as expected? What do you want to happen, and what does happen?

One quick comment on your code is that I'm seeing a lot of "magic numbers" -- these won't be the source of your problem, but they're bad practice.

- Jason Astle-Adams

Thanks for your comment. I know thats bad habit and I am trying to get rid of it.

What I am trying to accomplish is that if I press mouse button, player shoot ray wich when colliding to other object recognizes it. Theres nothing really going wrong because I dont even know where to start. I know that I have somehow change my screen coordinates to world coordinates, am I right? This just involves matrixes and I cant do the math, not yet atleast. Theres no flaw in that section of the code, because there isnt that section smile.png So the code is there just if someone needs to see how I have set up camera and so on to help me, or any other reason.

Edit. More accurately, I have aiming cross at center of the screen and I want to shoot ray to there and if it collides with something it could at this point just print something. All I think I need is to know how to do the conversion from x = WIDTH/2 y = HEIGHT/2 to my world coordinates. Atleast this is what I think I need for now.

This topic is closed to new replies.

Advertisement