Best way to calculate projection

Hi guys,

I am implementing input where I want character to rotate to the direction of the mouse pointer.
What I have so far:

  1. I get projection direction from the camera near and far clipping planes.
  2. I calculate projection angle and calculate projection length, so that if projection with given direction is starting at camera position, it should end at y=0.

Problem:
I do not know how to calculate the end position Vector of where the mouse pointer is at y= 0.
It should be really easy, as there is direction vector, start position vector and float length.

I went already through Math for dummies and searched on forum - could not find solution.
Do you have an idea?

P.D. Thanks guys, you are really the best community I have ever met. Thank you for being so open and quick :slightly_smiling_face: :sunny:

This depends very highly on what kind of scene you have. Is this a FPS camera, a top down view, etc.? Where is the mouse pointer? Is it centered, does it move around freely?

This is third person view,
the camera is looking top-down around 30 degrees (later probably there would be controls to rotate it around character or change inclination degree).

I see. You have some sort of terrain under the character right? There must be something for the mouse pointer to reference. Especially if you want to do camera rotations later.

I would suggest getting the mouse pointer coords, making a raycast from there and onto the terrain and then using that location to calculate the direction vector with the character’s position.

CollisionResults data = new CollisionResults();

Vector2f mau5pos = Main.app.getInputManager().getCursorPosition().clone();
Vector3f click3d = Main.app.getCamera().getWorldCoordinates(new Vector2f(mau5pos.x, mau5pos.y), 0f).clone();
Vector3f dir = Main.app.getCamera().getWorldCoordinates(new Vector2f(mau5pos.x, mau5pos.y), 1f).subtractLocal(click3d).normalizeLocal();

Ray ray = new Ray(click3d, dir);
yourterrain.collideWith(ray, data);

CollisionResult closest = data.getClosestCollision();

if(closest == null)
	return;
	
Vector3f dir = closest.getContactPoint().subtract(yourcharacter.getWorldTranslation());

//TODO ask character politely to rotate to face dir

You may or may not want to set the y component of the dir vector to zero.

1 Like

Even if you don’t want to do a picking operation just to figure out where the mouse is pointing. You can imagine finding the location of where the mouse would intersect on the plane at the character’s feet.

Basically, take that ray dir vector as MoffKalast has it and project it along the hypotenus of a triangle where one leg is the distance from the camera to the character. (Which can be found easily.)

Vector3f camLoc =…
Vector3f charLoc = …
Vector3f charDir = charLoc.subtract(camLoc);

Presuming the character may not be directly in front of the camera, find the camera-dir projected distance:
float charDistance = cam.getDirection().dot(charDir);

Vector3f cursorDir = … (see post above only he called it just ‘dir’)

Calculate how many times we’d have to travel down cursorDir before we intersected with character’s plane:
float projection = cursorDir.dot(charDir); (cosine leg of a triangle from camera to char to imaginary intersection point)
float scale = charDistance / projection;
Vector3f point = cam.getLocation().add(cursorDir.mult(scale));

Then make the character look at point.

Note: that’s camera direction based. If you want strictly ground plane based then you can skip the ‘projection’ part and just divide char distance by charDir.y.

3 Likes

btw I’m pretty sure there is something build in where at least you can get the screen position of an obeject in space and then it shouldn’t be very complicated to achieve what you want with that info.

1 Like

Yeah, it’s the reverse of getWorldCoordinates() (getScreenCoordinates())… the issue is once you have that 2D screen vector, projecting it back into 3D space.

1 Like