How to use hierarchy on openGL - opengl

How to create some kind of "arm", using sphere as joint (shoulder, elbow, wrist) and ellipsoid as bone (forearm, arm, fingers)?
the shoulder is the root, it all can move like real life arms..

Related

Gimbal Locking when projecting 3D System onto Sphere

I'm making a skybox in my game. The game has a solar system with some things in it (to start, the sun and the earth, with stars in the background). The player is on one planet in this solar system. The solar system is represented to the player using a skybox, with 2D sprites projected onto the skybox in the corresponding positions. The Skybox is rendered with OpenGL (actually, Java's LWJGL) [1]
First things first, all of the bodies are being tracked in 3D space. I can obtain their coordinates, relative directions, etc. All orbits are defined independently (aka, occur on arbitrary planes). In addition, planets have Quaternion rotations. Rendering the system in full 3D, there are no problems.
Projecting the system to the skybox is another matter entirely. In theory, I figure that I should be able to do it like this;
1. Calculate direction vector of where the player is looking (full rotations are not relevant - the vector just has to point in the right direction).
2. Multiply this direction vector with their planet's orientation (Quaternion) to calculate the "view direction"
3. Calculate direction vector from the planet to the object being viewed
4. Find the rotation between the vectors, and rotate the skybox accordingly.
However, when I feed OpenGL my angles, Gimbal Locking occurs and orbits that should be straight: go all bendy (although rotations around one single axis work fine). In what ways can I attempt to prevent this from happening? I'm at a loss.
[1]: My terrain is actually a flat square voxel grid, and I scale the player's coordinates onto it, then pretend that it is a 3D planet.

Modifying 3D coordinates in C++

I'm attempting to animate a skeleton in C++. I currently have the coordinates of all the joints and which joints connect to which.
Does anyone know how I would go about, say, raising the arm up by 90 degrees and then calculate the new coordinates for all the joints further down the arm?
I'm guessing I'd have to get the vectors for each bone and rotate those and take it from there, but I'm not sure how to go about doing that.
(I'm using openGL to display them)
Calculate the point and axis you wish to rotate around. The axis is perpendicular to the rotation plane. The point is the shoulder in your case. You would rotate all points in the arm hierarchy the same amount. There are many examples on the web for rotation about an arbitrary axis. Here's one: http://paulbourke.net/geometry/rotate/
Another way to go about it is to reinterpret your skeleton using local transformations: ie each new bone has a transformation from its parent bone's world space. This is useful for forward kinematics (FK) where you simply pose a skeleton based on local rotations. Most motion capture data is stored in this way. To calculate the world co-ordinates of each joint, you must multiply all local matrices up the hierarchy.
If you currently only have skeleton joint positions in world space it is a pain to generate the local transformation matrices, because you don't necessarily know the local matrix of each joint. This is a bigger topic. I did it years ago when I worked on the motion capture retargetting module in a 3dsmax plugin called CAT.
I worked with two popular formats: BVH and HTR. From memory, BVH uses global positions (and is a pain), whereas HTR uses local joint matrices and is much easier to import.

How to implement joints and bones in openGL?

I am in the process of rolling my own openGL framework, and know how to draw 3d objects ... etc...
But how do you define relationships between 3d objects that may have a joint?
Or how do you define the 3d object as being a "bone"?
Are there any good resources?
As OpenGL is only a graphics library and not a 3D modeling framework the task of defining and using "bones" falls onto you.
There are different ways of actually implementing it, but the general idea is:
You treat each part of your model as a bone (e.g. head, torso, lower legs, upper legs, etc).
Each bone has a parent which it is connected to (e.g. the parent of the lower left leg is the upper left leg).
Thus each bone has a number of children.
Now you define each bone's position as a relative position to the parent bone. When displaying a bone you now multiply it's relative position with the parent bone's relative position to get the absolute position.
To visualize:
Think of it as a doll. When you grab the doll's arm and move it around, the relative position (and rotation) of the hand won't change. Its absolute position WILL change because you've moved one of its parents around.
When tried skeletal animations I learnt most of it from this link:
http://content.gpwiki.org/index.php/OpenGL:Tutorials:Basic_Bones_System
But how do you define relationships between 3d objects that may have a joint?
OpenGL does not care about these things. I't a pure drawing API. So it's upon you to unleash your creativity and define such structures yourself. The usual approach to skeletal animatio is having a bone/rig system, where each bone has an orientation (represented by a quaternion or a 3×3 matrix) a length and a list of bones attached to it further, i.e. some kind of tree.
I'd define this structure as
typedef float quaternion[4];
struct Bone {
quaternion orientation;
float length;
int n_subbones;
Bone *subbones;
};
In addition to that you need a pivot from where the rig starts. I'd do it like this
typedef float vec3[3];
struct GeomObjectBase {
vec3 position;
quaternion orientation;
};
struct BoneRig {
struct GeomObjectBase gob;
struct Bone pivot_bone;
}
Next you need some functions that iterate through this structure, generate the matrix palette out of it, so that it can be applied to the model mesh.
note: I'm using freeglut
Totally irrelevant

How do I implement basic camera operations in OpenGL?

I'm trying to implement an application using OpenGL and I need to implement the basic camera movements: orbit, pan and zoom.
To make it a little clearer, I need Maya-like camera control. Due to the nature of the application, I can't use the good ol' "transform the scene to make it look like the camera moves". So I'm stuck using transform matrices, gluLookAt, and such.
Zoom I know is dead easy, I just have to hook to the depth component of the eye vector (gluLookAt), but I'm not quite sure how to implement the other two, pan and orbit. Has anyone ever done this?
I can't use the good ol' "transform the scene to make it look like the camera moves"
OpenGL has no camera. So you'll end up doing exactly this.
Zoom I know is dead easy, I just have to hook to the depth component of the eye vector (gluLookAt),
This is not a Zoom, this is a Dolly. Zooming means varying the limits of the projection volume, i.e. the extents of a ortho projection, or the field of view of a perspective.
gluLookAt, which you've already run into, is your solution. First three arguments are the camera's position (x,y,z), next three are the camera's center (the point it's looking at), and the final three are the up vector (usually (0,1,0)), which defines the camera's y-z plane.*
It's pretty simple: you just glLoadIdentity();, call gluLookAt(...), and then draw your scene as normally. Personally, I always do all the calculations in the CPU myself. I find that orbiting a point is an extremely common task. My template C/C++ code uses spherical coordinates and looks like:
double camera_center[3] = {0.0,0.0,0.0};
double camera_radius = 4.0;
double camera_rot[2] = {0.0,0.0};
double camera_pos[3] = {
camera_center[0] + camera_radius*cos(radians(camera_rot[0]))*cos(radians(camera_rot[1])),
camera_center[1] + camera_radius* sin(radians(camera_rot[1])),
camera_center[2] + camera_radius*sin(radians(camera_rot[0]))*cos(radians(camera_rot[1]))
};
gluLookAt(
camera_pos[0], camera_pos[1], camera_pos[2],
camera_center[0],camera_center[1],camera_center[2],
0,1,0
);
Clearly you can adjust camera_radius, which will change the "zoom" of the camera, camera_rot, which will change the rotation of the camera about its axes, or camera_center, which will change the point about which the camera orbits.
*The only other tricky bit is learning exactly what all that means. To clarify, because the internet is lacking:
The position is the (x,y,z) position of the camera. Pretty straightforward.
The center is the (x,y,z) point the camera is focusing at. You're basically looking along an imaginary ray from the position to the center.
Now, your camera could still be looking any direction around this vector (e.g., it could be upsidedown, but still looking along the same direction). The up vector is a vector, not a position. It, along with that imaginary vector from the position to the center, form a plane. This is the camera's y-z plane.

opengl rotations for a human

I currently can rotate around a pivot point by first translating to the pivot point then performing the rotation and finally translating back to the origin. I do that easily enough for the shoulder in my example. However I cannot figure out how to also add in a rotation around the elbow for the forearm.
I've tried the following for the forearm rotation around the elbow:
translate to shoulder, rotate, translate to origin, translate to forearm, rotate, translate to origin
translate to shoulder, rotate, translate to forearm, rotate, translate to shoulder, translate to origin
Neither work for me. Any suggestions? I'm really stuck on this one.
I ran into a similar problem when I was doing some skeletal animation. It's very helpful to use recursion for this. Also, structure your bones hierarchically (e.g. shoulder is a parent of forearm which is a parent of hand, etc.). By doing that you can write your code as follows:
void drawBone(Bone *root) {
if (!root) return;
glPushMatrix();
glTranslatef(root->x,root->y,0);
glRotatef(root->a,0,0,1);
// insert code to actually draw bone here
int i;
glTranslatef(root->l,0,0);
for (i=0; i<root->childCount; i++)
drawBone(root->child[i]);
glPopMatrix();
}
My bone struct looked like this:
typedef struct _Bone {
float x,y,a,l; // position, angle, length of bone
int childCound; // number of children for this bone
struct _Bone *child[MAX_CHILD_COUNT], *parent;
} Bone;
This website is a great resource for skeletal animation.
The second approach should work.
I don't really know your model for the human body. Some similar task was
a first assignment in a computer vision course I took.
A helpful thing is to use a scene-graph to build parts that share a common
local coordinate system.
Then you can traverse it and rotate correctly.
It is helpful not to translate but to use
glPushMatrix() and glPopMatrix()
In this way you can think in a local coordinate system and affect all other elements.