Example 23

Example 23

Shows an animated robot arm using a simple scene graph implementation.

ex_23/robot_arm.png

Source Code

robot_arm.c:

/* Peter Bui
 * CSE 40166 Computer Graphics (Fall 2010)
 * Example 23: robot arm
 */

#include "ssg.h"
 
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif

#include <stdio.h>

/* Custom render functions -------------------------------------------------- */

void
cylinder_render(SSG_Node *n)
{
    static GLUquadric *quadric = NULL;

    if (!quadric) 
        quadric = gluNewQuadric();

    glPushMatrix();
    glRotatef(90, 1.0, 0.0, 0.0);
    gluCylinder(quadric, 1.0, 1.0, 1.0, 32, 32);
    glPopMatrix();
}

void
cube_render(SSG_Node *n)
{
    glPushMatrix();
    glTranslatef(0.0, 1.0, 0.0);
    glScalef(0.5, 2.0, 0.5);
    glutSolidCube(1.0);
    glPopMatrix();
}

void
animation_render(SSG_Node *n)
{
    SSG_Node *dn   = (SSG_Node *)ssg_node_data(n);
    double   *data = (double *)ssg_node_data(dn);

    data[1] += data[2];

    if (data[1] >= 90.0) {
        data[1] = 90.0;
        data[2] *= -1.0;
    }
    
    if (data[1] <= 0.0) {
        data[1] = 0.0;
        data[2] *= -1.0;
    }
}

void
transform_render(SSG_Node *n)
{
    double *data = (double *)ssg_node_data(n);

    glTranslatef(0.0, data[0], 0.0);
    glRotatef(data[1], 0.0, 0.0, 1.0);
}

/* Main execution ----------------------------------------------------------- */

int 
main(int argc, char *argv[])
{
    SSG_Node *root = NULL;
    SSG_Node *base = NULL;
    SSG_Node *lower_transform = NULL;
    SSG_Node *lower_animation = NULL;
    SSG_Node *lower_arm = NULL;
    SSG_Node *upper_transform = NULL;
    SSG_Node *upper_animation = NULL;
    SSG_Node *upper_arm = NULL;
    SSG_Viewer *viewer = NULL;

    double lower_data[] = { 0.0, 0.0,  2.0 };
    double upper_data[] = { 2.0, 90.0, 16.0 };

    /* Create nodes */
    root = ssg_node_create(NULL, NULL);
    base = ssg_node_create(cylinder_render, NULL);
    lower_transform = ssg_node_create(transform_render, lower_data);
    lower_animation = ssg_node_create(animation_render, lower_transform);
    lower_arm = ssg_node_create(cube_render, NULL);
    upper_transform = ssg_node_create(transform_render, upper_data);
    upper_animation = ssg_node_create(animation_render, upper_transform);
    upper_arm = ssg_node_create(cube_render, NULL);

    /* Organize graph */
    ssg_node_connect(root, base);
    ssg_node_connect(base, lower_animation);
    ssg_node_connect(lower_animation, lower_transform);
    ssg_node_connect(lower_transform, lower_arm);
    ssg_node_connect(lower_arm, upper_animation);
    ssg_node_connect(upper_animation, upper_transform);
    ssg_node_connect(upper_transform, upper_arm);

    /* Create viewer and run */
    viewer = ssg_viewer_create("robot arm", 640, 480);
    ssg_viewer_initialize(viewer, &argc, argv);
    ssg_viewer_show(viewer, root); 

    return (EXIT_SUCCESS);
}

/* vim: set sts=4 sw=4 ts=8 ft=cpp: ----------------------------------------- */

Files