LWJGL 3 Mouse 3rd person

Started by andrei, June 12, 2015, 08:54:57

Previous topic - Next topic

andrei

Hello,

I started making a 3D game using this library and everything worked till now.
The problem is that lwjgl 3 doesn't have a mouse class that get dx and dy so I implemented one but it doesn't seem to work properly.
When I click anywhere on the screen ( only the first time ) the whole world rotates a couple of degrees, but if I click again on the same "spot" it doesn't.

package input;

import org.lwjgl.glfw.GLFWCursorPosCallback;

public class MouseCursorPos extends GLFWCursorPosCallback {

	public static double mouseX = 0;
	private static double mouseY = 0;
	private static double mouseDX = 0;
	private static double mouseDY = 0;

	@Override
	public void invoke(long window, double xpos, double ypos) {
		// Add delta of x and y mouse coordinates
		mouseDX += xpos - mouseX;
		mouseDY += ypos - mouseY;
		// Set new positions of x and y
		mouseX = xpos;
		mouseY = ypos;

		// System.out.println(mouseDX + " - " + mouseDY);
	}

	public static double getMouseDX() {
		double result = mouseDX;
		mouseDX = 0;
		return result;
	}

	public static double getMouseDY() {
		double result = mouseDY;
		mouseDY = 0;
		return result;
	}

}

Kai

Your problem is probably, that with the first mouse input, the difference between your initialization of 0.0 for mouseX and mouseY and the coordinates reported by GLFW are very large, because the first time the callback is invoked, you will get the difference between that large x and y values (probably around 500-900 or so, depending on your window size and cursor position).

For the next invocations of the callback, you will get small differences, because your mouseX and mouseY values have then been set.

You probably need to differentiate in the invoke() method whether it is the first invocation, like so:
import org.lwjgl.glfw.GLFWCursorPosCallback;
 
public class MouseCursorPos extends GLFWCursorPosCallback {
    private double mouseX;
    private double mouseY;
    private double mouseDX;
    private double mouseDY;
    private boolean wasFirst;

    @Override
    public void invoke(long window, double xpos, double ypos) {
        if (!wasFirst) {
            wasFirst = true;
        } else {
            mouseDX += xpos - mouseX;
            mouseDY += ypos - mouseY;
        }
        mouseX = xpos;
        mouseY = ypos;
    }

    public double getMouseDX() {
        double result = mouseDX;
        mouseDX = 0;
        return result;
    }

    public double getMouseDY() {
        double result = mouseDY;
        mouseDY = 0;
        return result;
    }
}


There, we only compute the difference if it was not the first invocation. Also I made your fields non-static since they rather belong to that instanceof GLFWCursorPosCallback.

andrei

I tried this before and it is not working, getMouseDX and getMouseDY is always 0.

Kai

getMouseDX and getMouseDY are always zero between samples/frames where you do not move the mouse.
But once you move the mouse and then sample the delta position, getMouseDX and/or getMouseDY should report the number of pixels the mouse has moved relative to its position at the previous sample.
Because a mouse gives absolute coordinates in GLFW, we need to define what a "delta" value then means for us.
And you did this by introducing state into the MouseCursorPos class which on every invocation accumulates the difference between the last invocation's absolute mouse coordinates and the new coordinates into mouseDX/mouseDY.
This is fine.
Then you invoke getMouseDX/getMouseDY which then samples the stored delta values at this point and resets the accumulated mouseDX/mouseDY to zero, which also is fine.
You just must make sure that you sample getMouseDX/getMouseDY not too often but only once in your sample interval (which probably is a single render frame).

andrei

I understand the process and already did that. I think the error is that I am adding the class (as new object ) to the callback and after that I instantiate it again ( new object ) and that is why I am gettinh 0 values.
But still the mouse clicking isn't correct, or I am doing something else wrong. When I click on the screen it shouldn't rotate the camera, but it does. Should I check the mouse down on GLFW_REPEAT and not on click?

Kai

I have obviously no idea what camera you are talking about and how that camera's movement/rotation is related in any way to the mouse input.
GLFW_REPEAT is for keyboard input. GLFW_PRESS and GLFW_RELEASE are for mouse (and keyboard) inputs. So if you want to figure out a mouse "down", you would check if the action was GLFW_PRESS. Correspondingly, for a mouse "up" use GLFW_RELEASE.

andrei

What I am trying to achieve is when I click and drag the "camera" should move around the player. If I only click, no drag, the "camera" should not move around the player but now it does.