[SOLVED] Camera Node and Spot Light and Mouse Cursor - How?

Are You native english speaker? Sry but I didn’t understand half of what You wrote… Could You please give complete example of what goes where?

Also for the B point…

Are you a Java coder? If you were you’d have understood what he said. Learning Java while learning how to write a game is an almost impossible task and will only lead to frustration.

1 Like

Not as long as there are people willing to help with that. Code snippets here code snippets there and it works… That’s how I learn! Now can You please help me finish those last things? :smile:

I didn’t say the frustration would necessarily be on your side…

3 Likes

That was subtle… And nice…

Could You please at least follow up on the B point and help me fix this light so it moves exactly as mouse cursor does? Not slower, not faster just identical as if my mouse cursor and flashlight were one entity…

While I take my sweet time to google around to found a way to pass this goddamn cam to my appstate…
[EDIT] Did it like this… Is it proper way to do stuff (I mean it works but dunno if it’s best solution)? I believe cam itself belongs to another (default) appstate so no idea how to reach those directly.

//Inside MyAppState constructor
this.theapp = app;
//And the vector stuff in update loop in MyAppState
Vector3f click3d = theapp.getCamera().getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 0f).clone();
Vector3f dir = theapp.getCamera().getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 1f).subtractLocal(click3d).normalizeLocal();

Anyway I can’t deal with B point alone :frowning: It’s not just googling…

I still not sure on what you need.
Take a look on my old thread :

http://hub.jmonkeyengine.org/t/solved-it-seens-quaternions-got-me-again/

You may find some answers.

I said what you could do to keep the light direction at z. Changing the direction of the light doesn’t change its speed so you obviously did something wrong.

CODE IN NEXT POST - DIDN’T FIT HERE!!

Probably I did but sure as hell I have no idea what. This is whole code relating to my mouse and light. Just uncomment “dir” parts and comment “UNIT_Z” part to see difference.

And (probably a wild guess) I maybe learning java but I’m pretty good at math and I have an idea why things don’t work as expected (sadly don’t have the solution). Image below, please study it cause it’s the best way I can elaborate on the problem.

public void initialize(AppStateManager stateManager, Application app) {
super.initialize(stateManager, app);
spotty = new SpotLight();
spotty.setSpotRange(40f);                           // distance
spotty.setSpotInnerAngle(1f * FastMath.DEG_TO_RAD); // inner light cone (central beam)
spotty.setSpotOuterAngle(1.5f * FastMath.DEG_TO_RAD); // outer light cone (edge of the light)
spotty.setColor(ColorRGBA.Red.mult(1f));         // light color and strength
rootNode.addLight(spotty);

public void update(float tpf) {
Vector2f click2d = inputManager.getCursorPosition();
Vector3f click3d = theapp.getCamera().getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 0f).clone();
//Vector3f dir = theapp.getCamera().getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 1f).subtractLocal(click3d).normalizeLocal();

spotty.setPosition(click3d);
spotty.setDirection(Vector3f.UNIT_Z);
//spotty.setDirection(dir)

“Screen level” (or rather the normal of that) is the camera direction so the code you have in your previous post should be fine.

I needed several edits to make image work. You responded too fast :stuck_out_tongue: Check image please - it shows the effect of different solutions. Situation B is potential explanation of the speed issue (not the solution though).

No, image 3 is what you get when you do

Vector3f click3d = theapp.getCamera().getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 0f).clone();
Vector3f dir = theapp.getCamera().getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 1f).subtractLocal(click3d).normalizeLocal();

Situation B might be what you get when your screen isn’t looking in z direction any you use UNIT_Z. I only gave that solution because you asked for it. Play around a bit, you have all information, now its time to do your homework.

The thing with DIR is situation A and I can prove it. In my code I can move a camera in drag’n’drop fashion (in only one plane - no rotation so the distance from camera to the plane is constant). When I do so mouse stays in “grab” place (above some object for example) while I move my camera around.

If it were situation C my light shouldn’t change at all because mouse didn’t change position relative to the object that is lighted. But it does. It acts exactly as if the light were cast from the middle of my window (meaning: the light gets “bigger” when the distance from the middle of my window becomes larger - and it shouldn’t if it were cast from the mouse cursor).

You get the click position and a direction vector that is from the camera through the click location to 1f behind it. Use the cam direction if you don’t want the actual perspective of the ray from the camera.

Ok I know what’s the issue now (and yes Vector3f.UNIT_Z is the only way to keep the 90 degrees angle between my plane of objects and spotlight - which in turn is the only way to avoid light being distorted).

The reason things moves so “slow” on my plane of objects is the effect of the perspective (field of view). So to calculate point to which I should REALLY move spotlight castpoint (even though it would make an illusion of being on cursor) I need to first calculate mouse collision point, and then move my spotlight to the point above this one (in Z dimension).

The only question left is: how can I get collision point between ray and some arbitrary plane (for example Z = 5 plane) and not with an object?

Found the plane object. Created it using:

colli = new Plane();
colli.setPlanePoints(new Vector3f(1, 1, 3), new Vector3f(2, 2, 3), new Vector3f(2, 1, 3));

Now I need a way to find intersection of a ray and this plane. But by default ray have 2 parameters: position (in my case click3d) and direction (in my case dir). How to find intersection point between this ray and my plane colli?

[EDIT] Enough dying for today. I hope someone will tell me a way to find ray collision point with either plane I created or some arbitrary plane in general.

Assuming no obstacle geometries are there between ray origin and the plane:

CollisionResults results = new CollisionResults();
yourNode.collideWith(ray, results);
CollisionResult c = results.getClosestCollision();
float distance = c.getDistance();

Then using your perspective-whatever-correction you can easily get your point in scene coordinates.

I thought you were good at math…? Just look at the javadoc of Plane.

Plane isn’t even necessary. It can all be done with simple vector math given the camera location, the direction vector, and the click location… all in 3D space.

But I’m not clear on whether or not it’s some fixed distance that the light should shine on or only intersected objects or something. Because for trying to remove the ‘perspective’ part of the light it matters.

Let’s say for the sake of argument that it’s desirable for the spotlight to shine parallel to the camera direction as if it’s shining on a plane 100 meters away.

float distance = 100;
Vector3f farMousePoint = camera.getWorldCoordinates(click2D, camera.getViewToProjectionZ(distance));

/// then go backwards
Vector3f lightLoc = farMousePoint.subtract(camera.getDirection().mult(distance));

Note: physically, this is like holding a spot light way out of view.

As I’m still not sure what exactly he wants to do - Plane will work for all situations :wink: But sure, all that Plane does can be done with Vectors alone.