Translate objects relative to the camera view - c++

I'm trying to translate objects via matrices in OpenGL and I know how to rotate/translate/scale objects in model coordinates.
However, I want to make a callback to translate objects relative to the camera view (so, the z-axis always looks at the camera):
I'm operating with objects using the MVP matrix. Does somebody know how to translate objects on the screen coordinates, not world ones?

So you have this sequence of matrices: project * view * model * <vertices>.
Going right-to-left:
model converts the model from model space to world space.
view converts it from world space to camera space.
project converts it from camera space to clip space.
You have your offset in camera space, and want to convert it to model space, so you need to apply:
view.inverse() to transform from camera space to world space.
model.inverse() to transform from world space to model space.
Those are too ordered right-to-left, so:
modelspace_offset = model.inverse() * view.inverse() * cameraspace_offset

Related

Finding world position of element in screen space

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;
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!
If you render an object with standard model M, view V and P matrices, you get the P*V*M as the overall transformation. If you draw a model without the view transform, you're placing the object directly in view space. However, conceptually, that will be the same as first placing your object in world space (by applying a modified model matrix M'), and rendering that with the full P*V*M' pipline.
Since V transforms from world to view space, inverse(V) will transform from view space to world space, and therefore M' = inverse(V) * M will get you P*V*M' = P*V*inverse(V)*M = P*M, and M' is exactly the transformation you are looking for. Note that the projection matrix has nothing to do with that at all, and you are not unprojecting any positions back from screen space as the question title suggests.

How can OpenGL transform multiple objects to world space with a single model matrix?

A few OpenGL tutorials teach the role of each matrix (model, view and projection matrices). They all agree that the model matrix transforms an object to world space, the view matrix then transforms it to camera space and the projection matrix handles the perspective elements.
What isn't explained is how a single model matrix can transform many objects to different world spaces.
Different objects have different positions in world space and therefore a different modelling transformation must be applied - so how can a single model matrix be used?

What is world space and eye space in game development?

I am reading a book about 3D concepts and OpenGL. The book always talks about world space, eye space, and so on.
What exactly is a world inside the computer monitor screen?
What is the world space?
What is eye space? Is it synonymous to projection?
World space
World space is the (arbitrarily chosen) frame of reference in which everything within the world is located in absolute coordinates.
Local space
Local space is space relative to another local frame of reference, in coordinates relative to the local frame.
For example, the mesh of a model will be constructed in relation to a coordinate system local to the model. When you move around the model in the world, the relative positions to each other of the points making up the model don't change. But they change within the world.
Hence there exists a model-to-world transformation from local to world space.
Eye (or view) space
Eye (or view) space is the world as seen by the viewer, i.e. all the positions of things in the world are no longer in relation to the (arbitrary) world coordinate system, but in relation to the viewer.
View space is somewhat special, because it not arbitrarily chosen. The coordinate (0, 0, 0) in view space is the position of the viewer and a certain direction (usually parallel to Z) is the direction of viewing.
So there exists a transformation world-to-view. Now because the viewer is always at the origin of the view space, setting the viewpoint is done by defining the world-to-view transformation.
Since for the purposes of rendering the graphics world space is of little use, you normally coalesce model-to-world and world-to-view transformations into a single model-to-view transformation.
Note that eye (or view) space is not the projection. Projection happens by a separate projection transform that transforms view-to-clip space.
You should read this: http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/
That tutorial uses term "camera space" instead of "eye space" but they are the same.

Why do you use camera space instead of model space for normals?

I am learning OpenGL graphics, and am getting into shadows. The tutorials that I am reading are telling me to transform my normals and light vector to camera space. Why is this? Why can't you just keep the coords in model space?
A follow up question to this is how to handle model transformations. I am unable to find a definitive answer. I currently have this code:
vec3 normCamSpace = normalize(mat3(V) * normal);"
vec3 dirToLight = (V*vec4(lightPos, 0.0)).xyz;"
float cosTheta = clamp(dot(normCamSpace, dirToLight),0,1);"
V is the view matrix, or the camera matrix. I am unsure how to move or edit the light when the model changes in position, rotation, and scale.
The main reason is, that usually your light positions will not be given in model space, but world space. However for illumination to work efficiently all calculations must happen in a common space. In your usual transformation chain, model local coordinates are transformed by the modelview matrix directly into view space
p_view = MV · p_local
Since you normally have only one modelview matrix it would be cumbersome to separate this steap into something like
p_world = M · p_local
p_view = V · p_world
For that you required MV to be separated.
Since the projection transformation traditionally happens as a separate step, view space is the natural "common lower ground" on which illumination calculation to base on. It just involves transforming transforming your light positions from world to view space, and since light positions are not very complex, this is done on the CPU and the pretransformed light positions given as shader.
Note that nothing is stopping you from performing illumination calculations in world space, or model local space. It just takes transforming the light positions correctly.
I am learning OpenGL graphics, and am getting into shadows. The tutorials that I am reading are telling me to transform my normals and light vector to camera space. Why is this? Why can't you just keep the coords in model space?
Actually if you're the one writing the shader, you can use whatever coordinate space you want. IMO calculating lighting in world space feels more "natural", but that's matter of taste.
However, there are two small details:
You cannot "naturally" calculate lighting in object space, if your object is a skinned mesh (character model animated by bones). Such model will require world space or view space. If your object can be only translated and rotated (affine transforms only), then lighting can be easily calculated in model/object space. I think some game engines actualy worked this way.
If you use camera space, you can drop one subtraction when calculating specular highlights. Blinn/phong specular models require vector to(or from) eye to calculate specular factor. In camera space vector from eye to point is equal to point position. This is a very small optimization and it probably isn't worth the effort.

orientation in openGl

Could someone explain to me what are the up front and right vectors of an object and how are they used ?
Are you referring to how vectors in Object or Model space are used? Each object or model has its own coordinate space. This is necessary since the points in the model will be relative to the models origin. This makes it possible to work with arbitrary models in larger worlds. You would perform certain operations on the model (like Rotation) before moving the model in the World (translation). If I understand your question correctly, you are referring to a set of vectors that define the models position in the world. These up, front and right vectors would be what you would use to possibly determine which way the model was facing or moving.
I hope this helps if anything to formulate your question a bit more.
This Gamedev question might be of help glMultMatrix, how does it work?
Those vectors usually refer to world-space transformations of the local body axes of the model in question.
Usually a model is defined with respect to some local coordinate system whose origin is at the center of mass, centroid, or some other convenient location from which to construct the object's geometry. This local coordinate system has its own x, y, and z axes with x = [1, 0, 0]', y = [0, 1, 0]', and z = [0, 0, 1]'. The coordinates of each vertex in the model are then defined with respect to this local frame. Usually the origin is chosen so that the "forward" direction of the model is aligned with this local x, the "left" direction is aligned with local y, and "up" is aligned with local z (though any right-handed system will do.
The model is placed into the world via the modelview matrix in OpenGL. When the model's vertices are sent to the GPU, they are transformed from their local space (aka "object" space or "model space" or "body space") to world space by multiplying them by the modelview matrix. Ignoring scaling, the upper left 3x3 block in the modelview matrix is an orthonormal rotation matrix that defines the projection of the body axes into the world frame, assuming the model is placed at the world origin. The modelview matrix is augmented into a 4x4 by adding the translation between the model and world origins in the upper right 3x1 block of the modelview matrix.