E, Robot
The E, Robot project was an experiment in modeling and animation. As a basis, the robots from the movie I, Robot were used. It was written using C++ and Microsoft Visual Studio 2003 for Professor Wood's CSC 471: Intro to Computer Graphics class at Cal Poly, San Luis Obispo. Further information about the project is organized as follows:
[ Use Instructions ] [ Modeling ] [ Animation ] [ Other Graphic Concepts ]
Use Instructions
E-Robot is capable of many different actions, all of which are controllable via either the keyboard or the mouse.
Movement
E-Robot is moved in a variety of ways:
- Walking via the arrow keys. Using the keyboard's arrow keys will allow the user to navigate E-Robot at a walking pace. The UP arrow moves E-Robot forward, the DOWN arrow moves him backward, and the LEFT and RIGHT arrow keys rotate him counter-clockwise and clockwise, respectively. Characteristics of walking include a moderate traversal speed, moderate limb angles, and open palms.
- Walking via click-move mode. When in click-move mode (which can be toggled with rotate mode using the 'G' key), E-Robot can be told to walk to a desired location by clicking a location on the floor. Upon clicking, E-Robot will rotate toward the point and make the appropriate number of steps. Note that E-Robot may under- or over-step the spot slightly depending on where his final stride ends.
- Running via the 'R' key. Using the 'R' key will cause E-Robot to run. Characteristics of running include a faster traversal speed, larger swing angles of limbs, and clenched fists.
All movement is attenuated based on how much movement is requested. Thus if four steps are requested, the first step will be at single speed until the second step is requested, at which point it will move to double speed. If three steps are queued, then triple speed will be used. The final step (in this case the fourth step) will always be at single speed again because nothing else is queued.
Character Animations
E-Robot can perform other animations as well:
- Jump via the spacebar. E-Robot is capable of jumping in place. This is initiated using the spacebar.
- Clenching/unclenching of fists via 'C'/'F'. Pressing the 'C' key will cause E-Robot to clench his fists (if they are not already clenched), and pressing 'F' will cause him to unclench his fists (if they are not already open).
- Flashlight mode via 'L'. Pressing the 'L' key will switch the scene to flashlight mode. In this mode, the lights are dimmed and E-Robot's left hand is converted to a flashlight. This is a bit crude because since all the walls are a single polygon and thus can only reflect one color. Because of this, a directional light was used rather than a spotlight. Pressing 'L' again will exit flashlight mode.
- Waving via idling. If E-Robot is left idle for an extended period of time he will wave to anything in front of him. This behavior is repetitive based on a set time interval of inactivity.
- Walk collision. By using one of the walk mechanisms and colliding E-Robot with a wall, he will raise his arm to stop the collision.
- Run collision. By using 'R' to run E-Robot into a wall, he will be thrown to the ground and then return to his feet.
Camera Movement
The camera is capable of both lateral (i.e. along latitude lines) and horizontal (longitude lines) movement around an invisible sphere in the scene. The sphere is effectively enlarged via zooming the camera in and out. Camera movement is achieved as follows:
- Horizontal movement via 'A' and 'S'. Pressing 'A' will rotate the camera clockwise around the invisible sphere, while pressing 'S' will rotate the camera counter-clockwise around the invisible sphere.
- Vertical movement via 'W' and 'Z'. Pressing 'W' will rotate the camera in the direction that is initially towards the north pole of the invisible sphere. Pressing 'Z' moves the camera in the opposite direction.
- Zooming via 'D' and 'X'. Pressing 'X' will zoom the camera in, pressing 'D' will zoom it out.
- Orthographic mode via 'V' key. By pressing 'V', the user can toggle the scene between orthographic and perspective viewings. Orthographic viewing can provide a good viewing perspective, especially if the camera is zoomed such that the near wall is clipped off.
Modeling
E-Robot is a compilation of 115 cone and sphere models and 19 other containing modules (to more easily manipulate a group of primitive models). He is fully hierarchical, and is laid out as follows (an item designated as (C) is a container only):
-
DGuy (C)
- Head (C)
- Dome
- Jaw (2 pieces)
- Nose (2 pieces)
- Eyes (2 pieces)
- Arms (C) (2)
- Shoulder
- Upper Arm
- Elbow
- Lower Arm
- Wrist
- Hand (C)
- Palm
- Fingers (C) (10)
- Joints (3 pieces)
- Digits (3 pieces)
- Chest (3 pieces)
- Torso (4 pieces)
- Spine (6 pieces)
- Legs (C) (2)
- Rods (3 pieces)
- Upper Leg
- Knee Rods (C)
- rods (2 pieces)
- Knee
- Lower Leg
- Foot
- Head (C)
This is in fact even a simplified diagram of the actual model, as only containers have been expanded as hierarchical. In the actual model, almost all things are a child of their predecessor. As an example, the hand is not at the same level as the elbow in the arm, but the hand is actually a child of the wrist, who is a child of the lower arm, who is a child of elbow, who is a child of the upper arm, who is a child of the shoulder (...I know, it's like a bible verse...), who finally is a child of the base figure. All this hierarchy allows for easy modeling since a rotation or translation applied to any one object is then also applied appropriately to its children object. Scaling is applied somewhat differently in that scaling is applied only to a single object (not its children), unless that object is a container, in which case the scaling is applied to the children as well (thus the convenience of using containers).
Overall, I'm quite pleased with the results of the model. It is sufficiently flexible for animations and such, and does in fact resemble the I, Robot animations. For comparison, a picture is available here.
Animation
Animation was done using a two-dimensional vector and a timer function. The animations vector was composed, at the top level, of more vectors, with each second level vector representing a queue of animations in a certain group which were in the process of being acted out. As an example, the top level vector held vectors for groups such as stepping (which included walking steps, both forward and back, and running steps), falling down, and raising E-Robot's arm. Each group has its own queue, and as animations are required, they are pushed onto the appropriate queue. By having separate groups (as opposed to one single vector of pending animations), the character could then perform multiple animations simultaneously, adding an additional element of timing.
The actions which are to be performed for each animation are dictated in a number of functions, one for each action to be performed. A pointer to that function is placed on the queue and when required the timer function calls the function using the pointer and an integer value representing the step to perform for that animation. The step number is decremented each call, and thus the function being called generally consists of a switch statement, with each case representing a step in the animation.
There is also an aspect of attenuation to the animations. Rather than simple suddenly walking full speed, then stopping suddenly, E-Robot's first and last steps will be slower than the middle steps because the speed of the animation is based on the number of items in the group's queue. For the first and last steps, only one item would be in the queue, so it would be at its slowest. The speed is a linear relation to the number of items in the queue. Thus, with a max queue of five items (the value used in the demo), and a max frame rate of 50 FPS, if three items were queued, then they would run at (3 / 5 * 50) = 30 FPS for the first one, then 20 FPS for the second, and finally 10 FPS for the final one (in reality the fastest frame rates are generally lower than expected because the hardware can't keep up).
Other Graphics Concepts
This project makes use of a large variety of the concepts prevalent in computer graphics today, besides animation and hierarchical modeling, which are described in detail above, some of the more important concepts are described below.
Collision Detection
E-Robot is capable of colliding with the walls of his room. This is observed in a variety of instances, such as when he raises his hand to stop a walking advance into a wall, when he falls down from a running advance, or when he simply backs into a wall and is unable to go through it. The form of collision detection used was very basic, in that, for two objects, it used two orthonormal aligned bounding boxes and tested that for all three dimensions the maximum value of one object was less than the minimum value of the other or vice versa. If this was not true then a collision had occurred. This sufficed quite well for this project. The bounding box of the robot was padded considerably to keep any flying limbs from reaching through the walls, and so that when he outstretched his arm it reached to the wall (and not through it).
Pixel to Object Coordinate Conversion
The click-move feature of E-Robot was done using a mapping of the 2D pixel coordinates to 3D object coordinates on the floor of E-Robot's room. This was achieved with two calls to gluUnProject(), which provided the world coordinates corresponding to the 2D click point at the near and far clipping planes. Using these coordinates and the known height (y-value) of the floor, it was simple algebra to scale the x- and z-range given by gluUnProject() and get a point on the floor in 3D space. E-Robot is then rotated towards the point (he is facing the right direction when the normalized vector from the point to E-Robot's center, dotted with E-Robot's forward facing unit vector, is approximately one), and told to step the necessary steps in that direction.
Lighting
Three different lights are used for the E, Robot project: an overhead point light, that same point light dimmed for flashlight mode, and a directional light which is used for the flashlight. As described above, a spot light would have been preferable for the flashlight, however it did not interact well with the single-polygon walls, and thus a directional light was chosen. The directional light is manipulated such that it follows E-Robot's movement, illuminating the wall in front of him.
Texture Mapping
Texture maps were created and applied for E-Robot's eyes. They are loaded from a 24-bit 512 x 512 pixel bitmap image using file reads, and mapped to gluQuadric spheres using glBindTexture().
Materials
Three custom materials were created to finish E-Robot: a shiny plastic, a silver metal, and a black metal. The combination of reflective attributes of these materials, mixed with the lights created for the scene, allow for a reflection appropriate for a metallic material, but not so bright as to obscure the features of E-Robot. Originally it was planned that The plastic pieces (such as his chest, head, and lower legs) were to be translucent with a solid white version scaled slightly smaller inside of them. This however was foiled by OpenGL's hidden surface removal and depth buffer, which doesn't compensate for translucency when deciding if one object obscures another. Because of this, the inner object was never rendered because OpenGL didn't think it would be visible.