GLFW - disabled cursor not recentering automatically ?

Started by
0 comments, last by Green_Baron 5 years, 10 months ago

Hi,

i am self teaching me graphics and oo programming and came upon this:

My Window class creates an input handler instance, the glfw user pointer is redirected to that object and methods there do the input handling for keyboard and mouse. That works. Now as part of the input handling i have an orbiting camera that is controlled by mouse movement. GLFW_CURSOR_DISABLED is set as proposed in the glfw manual. The manual says that in this case the cursor is automagically reset to the window's center. But if i don't reset it manually with glfwSetCursorPos( center ) mouse values seem to add up until the scene is locked up.

Here are some code snippets, mostly standard from tutorials:


// EventHandler
	m_eventHandler = new EventHandler( this, glm::vec3( 0.0f, 5.0f, 0.0f ), glm::vec3( 0.0f, 1.0f, 0.0f ) );
	glfwSetWindowUserPointer( m_window, m_eventHandler );
	m_eventHandler->setCallbacks();

Creation of the input handler during window creation. For now, the camera is part of the input handler, hence the two vectors (position, up-vector).  In future i'll take that functionally out into an own class that inherits from the event handler.


void EventHandler::setCallbacks() {
	glfwSetCursorPosCallback( m_window->getWindow(), cursorPosCallback );
	glfwSetKeyCallback( m_window->getWindow(), keyCallback );
	glfwSetScrollCallback( m_window->getWindow(), scrollCallback );
	glfwSetMouseButtonCallback( m_window->getWindow(), mouseButtonCallback );
}

Set callbacks in the input handler.


// static
void EventHandler::cursorPosCallback( GLFWwindow *w, double x, double y ) {
	EventHandler *c = reinterpret_cast<EventHandler *>( glfwGetWindowUserPointer( w ) );
	c->onMouseMove( (float)x, (float)y );
}

Example for the cursor pos callback redirection to a class method.


// virtual
void EventHandler::onMouseMove( float x, float y ) {
	if( x != 0 || y != 0 ) {
		// @todo cursor should be set automatically, according to doc
		if( m_window->isCursorDisabled() )
			glfwSetCursorPos( m_window->getWindow(), m_center.x, m_center.y );
		// switch up/down because its more intuitive
		m_yaw += m_mouseSensitivity * ( m_center.x - x );
		m_pitch += m_mouseSensitivity * ( m_center.y - y );
		// to avoid locking
		if( m_pitch > 89.0f )
			m_pitch = 89.0f;
		if( m_pitch < -89.0f )
			m_pitch = -89.0f;
		// Update Front, Right and Up Vectors
		updateCameraVectors();
	}
}	// onMouseMove()

Mouse movement processor method. The interesting part is the manual reset of the mouse position that made the thing work ...


// straight line distance between the camera and look at point, here (0,0,0)
float distance = glm::length( m_target - m_position );
// Calculate the camera position using the distance and angles
float camX = distance * -std::sin( glm::radians( m_yaw ) ) * std::cos( glm::radians( m_pitch) );
float camY = distance * -std::sin( glm::radians( m_pitch) );
float camZ = -distance * std::cos( glm::radians( m_yaw ) ) * std::cos( glm::radians( m_pitch) );
// Set the camera position and perspective vectors
m_position = glm::vec3( camX, camY, camZ );
m_front = glm::vec3( 0.0, 0.0, 0.0 ) - m_position;
m_up = m_worldUp;
m_right = glm::normalize( glm::cross( m_front, m_worldUp ) );
glm::lookAt( m_position, m_front, m_up );

Orbiting camera vectors calculation in updateCameraVectors().

Now, for my understanding, as the glfw manual explicitly states that if cursor is disabled then it is reset to the center, but my code only works if it is reset manually, i fear i am doing something wrong. It is not world moving (only if there is a world to render :-)), but somehow i am curious what i am missing.

 

I am not a professional programmer, just a hobbyist, so it may well be that i got something principally wrong :-)

And thanks for any hints and so ...

 

This topic is closed to new replies.

Advertisement