Advertisement

Finding world position of element in screen space

Started by February 12, 2021 05:53 PM
1 comment, last by CDRZiltoid 3 years, 10 months ago

Thought this was going to be simple, but for some reason I appear to be struggling. I'm attempting to find the world position of an object that exists in screen space. For example in the below screenshot the pistol and hands are rendered without being translated into world space (using only projectionMatrix * modelMatrix), while the other objects in the scene exist in world space (translated via projectionMatrix * viewMatrix * modelMatrix):

I have added a "muzzle" bone to the end of the armature for this pistol, and I am attempting to convert the translation of the muzzle bone into world space so that I can cast a ray starting at this position.

I have this kind of working, but something isn't quite right. For example, note the closest green sphere in the above screenshot. That is the position which I come up with in world space for my muzzle bone. What I am expecting is below:

To obtain this position I am multiplying the position of the muzzle bone by the inverse of the projection and view matrixes of the world camera as follows:

glm::mat4 invMat = glm::inverse(worldStage.getCamera().value().getProjectionMatrix() * 
worldStage.getCamera().value().getViewMatrix());

glm::vec4 tmp = this->weapons[this->currentWeapon].actor->getTransform().getMatrix() * 
glm::vec4(this->weapons[this->currentWeapon].muzzleBone->translation, 1.0f);

glm::vec4 muzzleWorldTranslation = invMat * tmp;

muzzleWorldTranslation /= muzzleWorldTranslation.w;

One thing I noticed is that it is as if the `muzzleWorldTranslation` value that I'm coming up with is a mirror value of what it should be. For example if I swing the gun around the sphere is moving in the oposite direction of what it should be moving. I then calculated this value for other bones in the armature, just to see if they were in the correct location relative to the muzzle bone, and they are all also mirrored from what they should be.

It feels like I'm pretty close and there's just something that I'm missing or messed up slightly. If anyone is able to point out what that might be, I would be very grateful!

Looks like the issue was that I was including the projection matrix in `invMat`. Removing it has resolved the issue. Below is what I wound up with:

glm::mat4 invMat = glm::inverse(worldStage.getCamera().value().getViewMatrix());
glm::vec4 tmp = (this->weapons[this->currentWeapon].actor->getTransform().getMatrix() * this->weapons[this->currentWeapon].muzzleBone->matrix) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
glm::vec4 muzzleWorldTranslation = invMat * tmp;

This topic is closed to new replies.

Advertisement