Mouse position projected in game...

Started by Hellekin, February 05, 2008, 02:07:46

Previous topic - Next topic

Hellekin

I'm making a real time strategy game, like age of empires and that sort of stuff, and I'm having problems in finding the mouse position in the terrain. The screen show uses the rotations:
GL11.glRotatef (45.0f, 0.0f, 1.0f, 0.0f);	   
GL11.glRotatef (45.0f, 1.0f, 0.0f, 1.0f);


I need to get the position of the mouse in the x z plane, in which my units move, and I can't figure a way to that. Does anyone know a way of doing that?

wolf_m

There are different ways to figure out which polygon is under the mouse cursor. You could go into GL_SELECT mode, use gluPickMatrix(..), do object selection using the back buffer, project a ray from mouse cursor into infinity and make collision ray-poly collision tests...

The Redbook has some material on this, see Chapter 13 and 14. The internet also has extensive material, see NeHe Lesson 32, the Lighthouse3D Picking Tutorial, look at the OpenGL Picking and Selection FAQ or fire up your favorite internet search site with smart search strings.


bobjob

WARNING: i dont use matricies :D

If you would like some code that doesnt use opengl functions, and you would like to do the math yourself, here is 1 way of doing it.

this is the selection code i use in this app http://users.on.net/~bobjob/TD.jnlp

hopefully you use GLU to setup your screen, these values passed to gluPerspective are used in my code
GLU.gluPerspective(FOV, ASPECT_RATIO, NEAR_DISTANCE, FAR_DISTANCE);//Aspect Ratio Of The Window

pre-process (after selecting your FOV and aspect ratio)
cot = (float)(Math.cos(Math.toRadians(FOV/2.0)) / Math.sin(Math.toRadians(FOV/2.0)));


work out the pointers angle from its ortho position.
xRadAng  = (float)Math.toRadians(((Pointer.yPos - (screenHeight/2.0f)) / (screenHeight/2.0f)) * (-(FOV/2.0f)));
yRadAng =  (float)(Math.atan(1f/((cot/ASPECT_RATIO)  / ((Pointer.xPos - (screenWidth/2.0)) / (screenWidth/2.0)))));


I know you said that the camera is angled at 45, 45, 0. but this code works for a dynamic angle as well as camera position
you can tweek the code to go faster for a static angle like your own.
once you have ur xRadAng, and yRadAng the actual selection code is as follows
assuming Entity is just a class that holds an xPos, yPos, and zPos value...
double distance = FAR_DISTANCE;

//start loop through entities

double x = currentEntity.xPos - Camera.xPos;
double y = currentEntity.yPos + (currentEntity.type.height * currentEntity.scale)  - Camera.yPos;
double z = currentEntity.zPos - Camera.zPos;
	
double temp1 = (x * Math.cos(-Math.toRadians(Camera.yRot))) - (z * Math.sin(-Math.toRadians(Camera.yRot)));
double temp2 = (x * Math.sin(-Math.toRadians(Camera.yRot))) + (z * Math.cos(-Math.toRadians(Camera.yRot)));
x = temp1;
z = temp2;

temp1 = (z * Math.sin(-Math.toRadians(Camera.xRot))) + (y * Math.cos(-Math.toRadians(Camera.xRot)));
temp2 = (z * Math.cos(-Math.toRadians(Camera.xRot))) - (y * Math.sin(-Math.toRadians(Camera.xRot)));
y = temp1;
z = temp2;
				

temp1 = (x * Math.cos(-Pointer.yRadAng)) - (z * Math.sin(-Pointer.yRadAng));
x = temp1;
temp1 = (z * Math.sin(-Pointer.xRadAng)) + (y * Math.cos(-Pointer.xRadAng));
temp2 = (z * Math.cos(-Pointer.xRadAng)) - (y * Math.sin(-Pointer.xRadAng));
y = temp1;
z = temp2;
	
   
        		
if (z <= 0) {
   double temp = Math.sqrt((x*x) + (y*y));
   if (temp-1  > currentEntity.type.height * currentEntity.scale) continue;
   else if (temp < distance) {
      collision = currentEntity;
      type = currentEntity.type;
      distance = temp;
   }
}
//end loop through entities

if (collision != null) System.out.println("hit entity positioned at: " + collision.x + " " + collision.y + " " + collision.z);


Oh almost forgot
When placing camera the order is important in relation to the selection code

GL11.glRotatef(xRot,1.0f,0.0f,0.0f);
GL11.glRotatef(yRot,0.0f,1.0f,0.0f);
GL11.glTranslated(-xPos,-yPos,-zPos); //translate the screen to the position of our camera