Mouse position in world space

#1

This is an old topic,I know, but I did not find any clear explanation in the forum. I want to implement a ray caster that shoots a ray from the camera to the mouse position, in order to check if a ray intersects or not with some meshes.

I was reading this:

But I can not understand the solution proposed, and it looks a bit hacky to me. I am looking at the moment at this tutorial http://antongerdelan.net/opengl/raycasting.html where things are explained clearly, but my implementation does not work.

This is my code:

void ofApp::setFromCamera(const glm::vec2 coords, const ofCamera camera){
    // 2d Viewport Coordinates
    float x = (2.0f * coords.x) / ofGetWidth() - 1.0f;
    float y = 1.0f - (2.0f * coords.y) / ofGetHeight();

    // 3D Normalised Device Coordinates
    float z = -1.0f; // the camera looks on the negative z axis
    glm::vec3 rayNds = glm::vec3(x, y, z);

    // 4D Homogeneous Clip Coordinates
    glm::vec4 rayClip = glm::vec4(rayNds, 1.0);

    // 4D Eye (Camera) Coordinates
    glm::vec4 rayEye = glm::inverse(camera.getProjectionMatrix()) * rayClip;

    // Now, we only needed to un-project the x,y part, so let's manually set the z,w part to mean "forwards, and not a point". From http://antongerdelan.net/opengl/raycasting.html
    rayEye = glm::vec4(rayEye.x,rayEye.y, -1.0, 0.0);

    // 4D World Coordinates
    glm::vec3 rayWorld = glm::vec3(glm::inverse(camera.getModelViewMatrix()) * rayEye);

    rayWorld = glm::normalize(rayWorld);


};

I think it could be something related to the order in which OF is applying the transformation, that it should be vertex * matrix instead matrix * vertex as it happens in GLSL.

Any hints is much appreciated.

#2

My bad, it works. I was debugging it wrong

#3

Hi @edapx,
Have you tried ofxRay?
it does exactly what you describe.
or even easier, just use this

	glm::vec3 screenMouse (ofGetMouseX(),ofGetMouseY(),0);
	auto worldMouse = camera.screenToWorld(screenMouse);
	auto worldMouseEnd = camera.screenToWorld(glm::vec3(screenMouse.x, screenMouse.y, 1.0f));
	
	auto worldMouseTransmissionVector = worldMouseEnd - worldMouse;
	
	// worldMouse is the start of the ray
       // worldMouseTransmissionVector is the transmision vector or direction vector of the ray

The code you posted is very similar to the one in ofCamera::screenToWorld

#4

Thanks! I will use this code, it works the same and it is shorter.