In my OpenGL research (the OpenGL Red Book, I think) I came across an example of a model of an articulating robot arm consisting of an "upper arm", a "lower arm", a "hand", and five or more "fingers". Each of the sections should be able to move independently, but constrained by the "joints" (the upper and lower "arms" are always connected at the "elbow").
In immediate mode (glBegin/glEnd), they use one mesh of a cube, called "member", and use scaled copies of this single mesh for each of the parts of the arm, hand, etc. "Movements" were accomplished by pushing rotations onto the transformation matrix stack for each of the following joints: shoulder, elbow, wrist, knuckle - you get the picture.
Now, this solves problem, but since it's using old, deprecated immediate mode, I don't yet understand the solution to this problem in a modern OpenGL context. My question is: how to approach this problem using modern OpenGL? In particular, should each individual "member" keep track of its own current transformation matrix since matrix stacks are no longer kosher?
Pretty much. If you really need it, implementing your own stack-like interface is pretty simple. You would literally just store a stack, then implement whatever matrix operations you need using your preferred math library, and have some way to initialized your desired matrix uniform using the top element of the stack.
In your robot arm example, suppose that the linkage is represented as a tree (or even a graph if you prefer), with relative transformations specified between each body. To draw the robot arm, you just do a traversal of this data structure and set the transformation of whichever child body to be the parent body's transformation composed with its own. For example:
def draw_linkage(body, view):
//Draw the body using view matrix
for child, relative_xform in body.edges:
if visited[child]:
continue
draw_linkage(child, view * relative_xform)
In the case of rigid parts, connected by joints, one usually treats each part as a individial submesh, loading the appropriate matrix before drawing.
In the case of "connected"/"continous" meshes, like a face, animation usually happens through bones and deformation targets. Each of those defines a deformation and every vertex in the mesh is assigned a weight, how strong it is affected by each deformators. Technically this can be applied to a rigid limb model, too, giving each limb a single deformator nonzero weighting.
Any decent animation system keeps track of transformations (matrices) itself anyway, the OpenGL matrix stack functions are seldomly used in serious applications (since OpenGL had been invented). But usually the transformations are stored in a hierachy.
You generally do this at a level above openGL using a scenegraph.
The same matrix transforms at each node in the scenegraph tree just map simply onto the openGL matrices so it's pretty efficient.
Related
I'm developing a simple rendering engine as a pet project.
So far I'm able to load geometry data from Wavefront .obj files and render them onscreen separately. I know that vertex coordinates stored in these files are defined in Model space and to place them correctly in the scene I need to apply Model-to-world transform matrix to each vertex position (am I even correct here?).
But how do I define those matrices for each object? Do i need to develop a separate tool for scene composition, in which I will move objects around and the "tool" will calculate appropriate Model-to-world matrices based on translations, rotations an so on?
I would look into the "Scene Graph" data structure. It's essentially a tree, where nodes (may) define their transformations relative to their parent. Think of it this way. Each of your fingers moves relative to your hand. Moving your hand, rotating or scaling it also involves doing the same transformation on your fingers.
It is therefore beneficial to base all these relative transformations on one another as relative ones, and combine trhem to determine the overall transformation of each individual part of your model. As such you don't just define the direct model to view transformation, but rather a transformation from each part to its parent.
This saves having to define a whole bunch of transformations yourself, which are in the vast majority of cases similarly in the way I described anyway. As such you save yourself a lot of work by representing your models/scene in this manner.
Each of these relative transformations is usually a 4x4 affine transformation matrix. Combining these is just a matter of multiplying them together to obtain the combination of all of them.
A description of Scene Graphs
In order to animate objects within a scene graph, you need to specify transformations relative to their parent in the tree. For instance, spinning wheels of a car need to rotate relative to the car's chassis. These transformations largely depend on what kind of animations you'd like to show.
So I guess the answer to your question is "mostly yes". You do need to define transformations for every single object in your scene if things are going to look good. However, orgasnising the scene into a tree structure makes this process a lot easier to handle.
Regarding the creation of those matrices what you have to do is to export a scene from an authoring package.
That software can be the same you used to model the objects in the first place, Maya, Lightwave...
Right now you have your objects independent of each other.
So, using the package of your choice, either find a file format allowing you to export a scene you would have made by positioning each of your meshes where you want them, like FBX or GLTF or make your own.
Either way there is a scene structure, containing models, transforms, lights, cameras, everything you want in your engine.
After that you have to parse that structure.
You'll find here some explanations regarding how you could architect that:
https://nlguillemot.wordpress.com/2016/11/18/opengl-renderer-design/
Good luck,
When animations are organized as a tree, such that child shapes inherit rotations and translations from parent shapes, is there a common strategy for inheriting rotations?
Consider an arm that can rotate about the shoulder, elbow, and wrist. Each segment of the arm inherits some rotation from the segment above it and each segment might also have some independent rotation. It seems that the order of steps to determine the position of the hand is this:
1) Position the hand as though the wrist is at the origin and perform any rotation about the wrist that applies only to the hand.
2) Position the resulting hand as though the wrist is attached to the forearm, position the elbow at the origin, and perform any rotation about the elbow that applies only to the forearm.
3) Position the resulting hand as though the elbow is attached to the upper arm, position the shoulder at the origin, and perform any rotation about the shoulder that applies only to the upper arm.
4) Translate the resulting hand relative to the actual position of the shoulder.
Is there a more efficient strategy? If not, what is the best way to implement this in a tree?
This is also known as a scene graph, there are many API's with simply implement this paradigm.
Typically you can insert a mesh (and even have it animated) at a transformation node in said graph.
When designing one you do not have to go to that level of complexity (for example you may decide that there is no reason to move the wrist, hand or fingers programatically therefore you can simply attach them to the forearm group (or alternatively use a animated mesh and have a separate animation for fingers and hand moving which can be triggered based on some form of event.
This strategy is actually extremely efficient because it allows you to perform extremely complex operations on a large variety of shapes in a uniform and grouped manner.
When putting together a game typically one would create a mesh of characters and include all of the relevant animations for it, which in turn could be treated as a single object within a scene graph (with no smaller objects inside).
This is exactly what the classic OpenGL fixed pipeline matrix stack would achieve. Rendering would proceed as:
push matrix for shoulder;
draw shoulder;
call to draw elbow;
pop matrix for shoulder.
The elbow would push its matrix, draw, call to draw its children, pop its matrix and return. And so on, down your tree of local spaces.
That effectively reproduces your tree on the call stack. So if you prefer you can do the same thing by pushing an identity transformation from the root and having each node draw according to the transformation it receives, adding its transform and passing on to the children.
So the answer is, in short: no, there's no more efficient way to compose the transformations than walking around the tree composing the transformations.
I have a question concerning surgical robot arm's movements in OpenGL.
Our arm consists of 7 pieces that suppose to be the arm's joints and they are responsible for bending and twisting the arm. We draw the arm this way: first we create the element which is responsible for moving the shoulder like "up and down" and then we "move" using Translatef to the point in which we draw the next element, responsible for twisting the shoulder (we control the movement using Rotatef) and so on with the next joints (elbow, wrist).
The point is to create an arm that can make human-like movements. Our mechanism works, but now our tutor wants us to draw a line strip with the end of the arm. We put the code responsible for drawing and moving an arm between push and pop matrix, so it works like in real, I mean when we move the soulder, any other elements in arm also moves.
There is a lot of elements moving, rotating, we have a couple of rotate matrices that are attached to different elements which we can control and now we have no idea how to precisely find a new location of the end of an arm in space to be able to add a new point to a line strip. Anyone can help?
glGetFloatv(GL_MODELVIEW_MATRIX,mvm2);
x=mvm2[12];
y=mvm2[13];
z=mvm2[14];
glPointSize(5.0f);
glColor3f(1.0f, 0.0f, 0.0f);
glBegin(GL_POINTS);
glVertex3f(x,y,z);
glEnd();
When I checked using watch what are the x,y,z values, I got (0,-1.16-12e,17.222222), what can't be true, as my arm has length about 9.0 (on z-axis). I think only the last column of modelview matrix is important and I don't have to muliply it by local coordinates of the vertex, as the they are (0,0,0) since I finish my drawning here.
we have no idea how to precisely find a new location of the end of an arm in space to be able to add a new point to a line strip.
You do this by performing the matrix math and transformations yourself.
(from comment)
To do this we are suppose to multiply the matrices and get some information out of glGetFloatv
Please don't do this. Especially not if you're supposed to build a pretransformed line strip geometry yourself. OpenGL is not a matrix math library and there's absolutely no benefit to use OpenGL's fixed function pipeline matrix functions. But it has a lot of drawbacks. Better use a real matrix math library.
Your robot arm technically consists of a number of connected segments where each segment is transformed by the composition of transformations of the segments upward in the transformation hierachy.
M_i = M_{i-1} · (R_i · T_i)
where R_i and T_i are the respective rotation and translation of each segment. So for each segment you need the individual transform matrix to retrieve the point of the line segment.
Since you'll place each segment's origin at the tip of the previous segment you'd transform the homogenous point (0,0,0,1) with the segment's transformation matrix, which has the nice property of being just the 4th column of the transformation matrix.
This leaves you with the task of creating the transformation matrix chain. Doing this with OpenGL is tedious. Use a real math library for this. If your tutor insists on you using the OpenGL fixed function pipeline please ask him to show you the reference for the functions in the specicifications of a current OpenGL version (OpenGL-3 and later); he won't find them because all the matrix math functions have been removed entirely from modern OpenGL.
For math libraries I can recommend GLM, Eigen (with the OpenGL extra module) and linmath.h (self advertisement). With each of these libraries building transformation hierachies is simple, because you can create copies of each intermediary matrix without much effort.
If you're supposed to use glGetFloatv, then this refers to calling it with the GL_MODELVIEW_MATRIX argument, which returns the current model view matrix. You can then use this matrix to transform a point from the coordinate system of the hand to the world space CS.
However, calling glGetFloatv is bad practice, as it will probably result in reduced rendering performance. I think you should talk to your tutor about teaching outdated and even deprecated functionality, maybe he can get the prof to update the materials.
Edit: Your code for retrieving the translation is correct. However, you can't draw the point with the same model view matrix applied. Before drawing it, you have to reset the model view matrix with glLoadIdentity or by popping .
I've been following the GPU Gems 3 tutorial on how to blur based on camera movement. However I'm wanting to implement a blur based on object movement too. The solution is presented in the article (see quote below), however I'm curious as to how exactly to implement this.
At the moment I'm multiplying the object's matrix by the view-projection, then separately again for the previous-view-projection and then passing them into the pixel shader to calculate the velocity instead of just the view-projections.
If that is in fact the correct method, then why am I not simply able to pass in the model-view-projection? I would have assumed they would be the same value?
GPU Gems 3 Motion Blur
To generate a velocity texture for rigid dynamic objects, transform the object by using the current frame's view-projection matrix and the last frame's view-projection matrix, and then compute the difference in viewport positions the same way as for the post-processing pass. This velocity should be computed per-pixel by passing both transformed positions into the pixel shader and computing the velocity there.
Check out my research I did a few months ago on this topic: https://slu-files.s3.us-east-1.amazonaws.com/Fragment_shader_dynamic_blur.pdf
(source: stevenlu.net)
(source: stevenlu.net)
Sadly I did not implement textured objects when producing this material, but do use your imagination. I am working on a game engine so when that finally sees the light of day in the form of a game, you can be sure that I'll come and post breadcrumbs here.
It primarily addresses how to implement this effect in 2D, and in cases where objects do not overlap. There is not really a good way to handle using a fragment shader to "sweep" samples in order to generate "accurate" blur. While the effect approaches pixel-perfection as the sample count is cranked up, the geometry that must be generated to cover the sweep area has to be manually assembled using some "ugly" techniques.
In full 3D it's a rather difficult problem to know which pixels a dynamic object will sweep over during the course of a frame. Even with static geometry and a moving camera the solution proposed by the GPU Gems article is incorrect when moving past things quickly because it is unable to address that issue of requiring blending of the area swept out by something moving...
That said, if this approximation which neglects the sweep is sufficient (and it may be) then what you can do to extend to dynamic objects is to take their motion into account. You'll need to work out the details of course but look at lines 2 and 5 in the second code block on the article you linked: They are the current and previous screen space "positions" of the pixel. You simply have to somehow pass in the matrices that will allow you to compute the previous position of each pixel, taking into account the dynamic motion of your object.
It shouldn't be too bad. In the pass where you render your dynamic object you send in an extra matrix that represents its motion over the last frame.
Update:
I found that this paper describes an elegant and performant approach that provides somewhat high quality physically correct blurring for a 3D pipeline. It'll be hard to do much better than this within the constraint of rendering the full scene no more than one time for performance reasons.
I noticed with some of the examples the quality of the velocity buffer could be better. for example a rotating wheel should have some curves in the velocity space. I believe if they can be set properly (may require custom fragment shaders to render the velocity out...) they will look intuitively correct like the spinning cube seen above from my 2D exploration into dynamic motion blurring.
I want to create a 2D game with monsters build as a custom vertex mesh and a texture map. I want to use this mesh to provide smooth vector animations. I'm using opengl es 2.0.
For now the best idea i have is to write a simple editor, where i can create a mesh and make key-frame based animation by changing position of each vertex and specifying the key-frames interpolation technics ( linear, quadric and so on).
I also have some understanding of bone animation (and skin based on bones), but i'm not sure i will be able to provide a good skeletons for my monsters.
I'm not sure it is a good way to go. Can you suggest some better ideas and / or editors, libraries for such mesh animations ?
PS: i'm using C++ now and so c++ libraries are the most welcome
You said this is a 2D game, so I'm going to assume your characters are flat polygons on to which you apply a texture map. Please add more detail to your question if this is not the case.
As far as the C++ part I think the same principles used for 3D blend shape animation can be applied to this case. For each character you will have a list of possible 'morph targets' or poses, each being a different polygon shape with same number of vertices. The character's AI will determine when to change from one to another, and how long a transition takes. So at any given point time your character can be either at a fixed state, matching one of your morph targets, or it can be in a transition state between two poses. The first has no trouble, the second case is handled by interpolating the vertices of the two polygons one by one to arrive to a morphed polygon. You can start with linear interpolation and see if that is sufficient, I suspect you may want to at least apply an easing function to the start and end of the transitions, maybe the smoothstep function.
As far as authoring these characters, have you considered using Blender? You can design and test your characters entirely within this package, then export the meshes as .obj files that you can easily import into your game.