Computer Graphics: Strategy for inheriting rotations in an animation tree - opengl

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.

Related

Tree to optimize OpenGL Pointcloud

I would like to optimize my OpenGL program.
It consists in loading a vector of 3D points then applying shaders to them.
But I have billions of points, and my FPS drop to 2 when I try to see the points.
Actually I'm sending every points, and I believe this is what is too much for my computer.
Is making a KD-tree (for example) to store my points and then send to my shaders only the points contained in the viewing frustum an efficient way to optimize my program?
And, since my goal isn't to do research of points, but only use points in the viewing frustum, which tree would be better? Octree? KD-tree?
using trees is definitely a good way to deal with large point clouds. i worked on a point cloud rendering software for a while and we used kd-trees for rendering, and regular voxel grids for analysis.
i don't exactly remember the reasons for/against using an octree, but i guess it depends on the density distribution of your clouds: if you have large point clouds with some small high-density areas, you would have lots of empty cells in the octree, whether for evenly-distributed point clouds, octrees might be simpler. We also had 2.5D maps (from aerial scans: several square kilometers of terrain but only little devation in height) where we used quad trees for some tasks.
also we did not render all the points that were in the frustum, because that degenerates e.g. when you zoom all the way out so the whole point cloud is in the frustum again.
instead, all the inner (non-leaf) nodes in the kd-tree contained a "representative" selection of the points in their children, and we rendered the tree only up to a depth that seemed appropriate depending on the distance from the camera to the bounding volume of each node. this way, for areas that are far away from the camera, you render a thinned out version of the point cloud, an LOD of sorts.
if you want to go fancy: we actually maintained a "front-line" of nodes, that is a line or cut from left to right through the tree up to which all nodes should be rendered. this way we did not need to check each node but only the ones in the cut whether their status ("rendered" or "not rendered") should change. additionally, we had out-of-core point clouds which where larger that the (V)RAM, where we allowed the front to only move farther down the tree if the parent node had been loaded from disk.
kd-trees are a bit harder to build because you need to determine where the split plane is located. for this we used a first pass where we read the locations of all the points in the node, determining the split plane, and then a second pass doing the actual split.
i think we had 4096 points per node (i think we experimented with more and 8k or 16k were fine as well), and did one draw call per node. as long as your point cloud fits in VRAM you can simply put all of it in one large buffer and do draw calls with offsets into that buffer.

Movement of a surgical robot's arm OpenGL

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 .

How to group multiple objects for purpose of rotating them as a unit?

I need some pointers on the best approach for a rotation task in OpenGL. I know how to rotate objects in 3D space using quaternions, I can translate them, all well and good.
But I want to know the best way to treat a collection of different objects as a single entity for the purpose of rotation. For example, suppose you have a desk with objects on it. Each has its own translation and rotation, but now I want to rotate the entire desk and everything on it, while keeping other objects in the room in place. This means objects on the outer edge of the desk will rotate and also translate around the center of the desk, while objects at the center might just rotate but otherwise stay in place, or simply not translate by as much, depending on their distance from the axis of rotation.
It seems that a rather inelegant way to do this is to individually rotate and translate each object on the desk, as well as the desk itself, knowing where the axis of rotation is. Perhaps this is the only good way to do it, but is there a technique to "group" disparate objects for this purpose?
What you're looking for are transformation hierachies. The objects on your desk are positioned relative to the desk, or in other words in the coordinate system of the desk. So lets designate M_Desk as the transformation defining the placement of the desk and the local coordinate system of it. Next let be M_Pencilbox the transformation of the pencil box standing on the desk in relation to the desk. And a pencil in the pencil box would be placed in relation to the pencil box.
So the pencil goes through a hierachy of transformations. Remember that in the column major notation used by OpenGL things "flow" through the transformation chain from last transformation to first (or right to left when written down).
Each transformation, like M_Desk for example, is a 4×4 matrix that can be constructed the usual way: Rotations, translations, scalings, etc.
So to transform the vertices of a pencil you'd apply the following transformation
… · M_Desk · M_Pencilbox · v_Pencil
Of course the desk itself may be in relation to something different, like a room. At the very beginning of that transformation chain would be the view transformation. So effectively we're building a modelview matrix here.
In terms of modern OpenGL, everytime you encounter a branch in the transformation hierachy (think of directories in a file system), you'd create a copy of the transformation chain built so far, so that you don't have to restart from scratch for each branch.
Let me know if you need further clearification.
This is generally accomplished by using some kind of scene-graph which incorporates a transform hierarchy.
A simple minimal version would be to have a tree where each node contains an object, a transform, and a list of child nodes. The transform is relative to the parent node.
So the objects on the desk would be children of the desk itself.
The transform for any given object is the concatenation of that object's transform with all its parents in the tree. There are many ways to accomplish that, but the 'old school' GL functionality provides a matrix stack for this purpose. You multiply in the local matrix for a node, draw the geometry for that node, recursively draw all the child nodes, and then pop the matrix back off.

Fastest way to perform rotational transformations on a chain of dependent, attached objects

Suppose I have two (two for the example, it will actually be some n > 1) sort of rectangular prisms "attached to each other" such that the 4 vertices on their adjacent faces are the same vertex in memory. So like two wooden blocks, one stacked on the other, with 4 vertices on the bottom, 4 in the middle that are shared between the two, and 4 on the top. Now, I want to be able to first do a specific rotation on the "top" wooden block, as if it were on a hinge that has a centerpoint of those 4 shared vertices.
So like an elbow, let's say it can only flex up to 45 degrees at a specific angle, and to perform the rotation I rotate the 8 vertices that make up the object around that invisible hinge center point. In the process, the 4 shared vertices of the other block get somewhat moved, but since the hinge is the center point among them they aren't getting "translated" away from the bottom block. I guess calling them wooden is counter-intuitive, since they will morph in specific ways, but I was trying to set it up to visualize. Anyway, let's say I want to be able to rotate this bottom block in a different manner, but have the top block act like it is attached. Thus, if the bottom block moves, the top block is swung around with it, but also with whatever flex it has on the hinge between them.
I was considering incrementally doing the transformations either via axis angle or quaternions, starting with the "top most" block and working my way down the dependency chain, performing the rotation on the current block and every vertex on blocks "above" it. However, this would require messing with offsetting all the vertices to put the current hinge as the origin, performing the rotation, then reversing the previous offset, for each step in this chain. Is there a more efficient way of handling this? I mean efficiency in speed, having extra preprocessed data in memory isn't a big deal. There may also come a time when I can't count on having such a linear dependency chain (such as the top block ends up being attached to the bottom block to form a ring, perhaps). What would be the proper way to handle this for these kind of possibilities?
Sounds to me from your description that you basically want something like a long piece of "jello", i.e., if the top section of the block/prism moves, then there is some secondary movement in the rest of the segments of the block/prism-chain, sort of like how moving a chain or some soft-body will create secondary-movements in the rest of the segments that make-up the chain or ring.
If that is the case, then I suggest actually constructing some "bones", where each bone segment starts and ends at the center-point of the 4-vertices that make-up each start and end-face of the prism/blocks. Then you can calculate when you move one segment of the bone-chain, how much the other bones in the chain should move relative to the bone that was moved. From there, you can weight the rest of the vertices in the prism/block against this central "bone" so that they move the appropriate amount as the bone moves. You may also want to average the vertices attached to one "bone" against another bone segment as well so that there is a fall-off in the weight of the attached vertices, creating a smoother movement if you end up with too much pinching at each "joint".
Using bones with the vertices weighed against the bones should reduce the number of rotational transforms you need to calculate. Only the movement of the bone-joints needs the heavy-lifting calculations ... the vertices themselves are simply interpolated from the location of the bones in the chain.
Consider using an existing tool. Have a look at this question about linking rigid bodies:
https://physics.stackexchange.com/questions/19724/how-to-represent-the-effect-of-linking-rigid-bodies-together
The standard way to handle an articulated, single-ended chain is skeletal animation -- using a chain of "bone" elements (defined by a relative translation/rotation relation), with the option of doing linear interpolation based on the bones to determine the position of the "skin" vertices. (Note that you will need to determine the rotation angle of each "joint" to fully define the pose.)
A ring of elements is more difficult to handle, because you can no longer define the rotation of each joint independently of all others. To solve this problem, set up a physical simulation or other solver which includes all the constraints. Exactly what to do depends on how you need to manipulate the object -- if it's part of a game engine, physical simulation makes sense, but if it's to be hand-animated, you have a wide range of possibilities for semi-automated rigging (keyword: reverse-kinematic).

Modern OpenGL Question

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.