CAVEActors:  A Human Actor Library For The CAVETM    Darren R. Thompson

Appendix A:  Class Definitions



 
CLASS:  Vectors
Public Functions:
    Vectors();

    /* CalculateUnitNormal computes a normal vector from 3 vertices. */
    void CalculateNormal(float Origin[3], float Vertex1[3], float Vertex2[3], float Result[3]); 

    /* CalculateUnitNormal computes a normal vector first and then calculates a normal vector from the 
     * result. 
     */ 
    void CalculateUnitNormal(float Origin[3], float Vertex1[3], float Vertex2[3], float Result[3]);

    /* AverageNormals takes a list of normal vectors and averages them. */ 
    void AverageNormals(float NormalMatrix[][3], short NumberOfNormals, float Result[3]); 

    /* Normalize normalizes the vector passed. */
    void Normalize(float Vector[3], float Result[3]);

    /* DotProd computes the dotproduct of two vectors. */
    float DotProd(float Vector1[3], float Vector2[3]); 

    /* MultiplyLengths multiplies the lengths of two vectors.  */
    float MultiplyLengths(float Vector1[3], float Vector2[3]);

    /* CalculateAngle calculates the angle between two vectors.  NOTE:  0 <= angle <= 180. */
    float CalculateAngle(float Vector1[3], float Vector2[3]);

    /* Length returns the length of the vector passed.  */ 
    float Length(float Vector[3]);
 


 
 
CLASS:  Point<Type>
Protected VarsType X, Type Y, Type Z

Public Functions:
    /* Default Constructor */
    Point();

    /* Initializes the point */
    Point(Type x, Type y, Type z);

    /* Changes the X-, Y-, and Z-values of this point to the values passed. */ 
    void Change(Type x, Type y, Type z);

    /* Returns the X-value of the point */
    Type x();

    /* Returns the Y-value of the point */
    Type y() ;

    /* Returns the Z-value of the point */
    Type z();

    Point& operator=(const Point &);

    /* Returns 1 if the two points are equal. */
    short operator==(const Point &);
 


 
 
CLASS:  Curve<Type>
Inherited: public Point<Type>

Protected VarsPoint<Type> Start, Point<Type> End, Type t, Type StartT, Type EndT

Public Functions:
   /* Default Constructor */
   Curve();

   /* Initializes the Start and End points of the Curve. */
   Curve(Point<Type> &Start, Point<Type> &End, Type startT, Type endT);

   /* Returns 1 if t equals the Maximum t-value for the curve, else 0 is returned. */
   unsigned char AtEnd();

    /* Returns the Start point of the Curve */ 
    Point<Type> StartPt();

    /* Returns the End point of the Curve */ 
    Point<Type> EndPt();

    /* Returns StartT's value.  */ 
    Type GetStartT();

   /* Returns EndT's value.  */ 
   Type GetEndT();

   /* Returns t's value.  */ 
   Type GetT();

   /* Sets  t's value  to T.  */
   void SetT(Type T); 

   Curve<Type>& operator=(const Curve &c);
 


 
 
CLASS:  TimeLinearCurve<Type>
Inherited: public Curve<Type>

Private Vars: Point<Type> A, Point<Type> B 

Public Functions:
    /* Default Constructor */
    TimeLinearCurve();

    /* This constructor only assigns the variables, it doesn't construct the curve.  Call Construct below to 
     *  construct the curve.
     */ 
    TimeLinearCurve(Point<Type> &startPt, Point<Type> &endPt, Type StartTime, Type EndTime);

    /* This fn is called to construct the curve.  0 is returned if there is a problem with the times passed.  One of 
     * the times may cause a division by 0.  If there is a problem with one of the times, try assigning a different 
     * time for one of the control points. 1 is returned if the curve was constructed successfully.  NOTE: You 
     * must call this function first if you used the Constructor above which takes the points and times to 
     * describe the curve.
     */
    unsigned char Construct();

    /* Change is used to change one or more of the control points or Times on the curve or to create a curve if 
     * you used the default constructor.This fn automatically recalculates the equations for the curve.This fn 
     * also returns 0 or 1 as does the  fn Construct.
     */
     unsigned char Change(Point<Type> &StartPt, Point<Type> &EndPt,  Type StartTime, Type EndTime); 

    /* CalcPoint uses its own class variable to calculate the point on the curve and stores the result into 
     * Result 
     */ 
    void CalcPoint(Point<Type> &Result);

    /* CalcPoint uses the Time passed to calculate the point on the curve and stores the result into Result.
     * If 1 is passed for SetT, then the class' t-variable will be changed, else if you pass 0, it won't.
     */ 
    void CalcPoint(Type Time, unsigned char SetT, Point<Type> &Result); 

    /* Speed returns the speed of the object.  This speed will of course be constant since the derivative 
     * doesn't contain the parameter T. 
     */ 
    Type Speed();

    /* Length takes 2 values [t1,t2] and calculates the length between these two times on the curve.
     * OF course, T1 <= t1 < t2 <= T2.
     */
    Type Length(Type t1, Type  t2);

    /* This Length fn calculates the length of this curve.  */
    Type Length();


 
 
CLASS:  TimeCubicCurve<Type>
Inherited: publicCurve<Type>

Private Vars: Point<Type> CP2, Point<Type> CP3, Point<Type> A, Point<Type> B, Point<Type> C, 
    Point<Type> D, Type CPTime2, Type CPTime3 

Public Functions:
    /* Default Constructor */
    TimeCubicCurve();

    /* This constructor only assigns the variables, it doesn't construct the curve.  Call Construct below to 
     * construct the curve.
     */ 
    TimeCubicCurve(Point<Type> &cp1, Point<Type> &cp2, Point<Type> &cp3, Point<Type> &cp4, 
                                  Type cpTimes[4]);

    /* This fn is called to construct the curve.  0 is returned if there is a problem with the times passed.  One 
     * of the times may cause a division by 0.  If there is a problem with one of the times, try assigning a 
     * different time for one of the control points. 1 is returned if the curve was constructed successfully. 
     * NOTE: You must call this function first if you used the Constructor above which takes the points 
     * and times to describe the curve.
     */
    unsigned char Construct();

    /* Change is used to change one or more of the control points or Times on the curve or to create a curve 
     * if you used the default constructor.This fn automatically recalculates the equations for the curve.This 
     * fn also returns 0 or 1 as does the fn Construct.
     */
    unsigned char Change(Point<Type> &cp1, Point<Type> &cp2, Point<Type> &cp3, Point<Type> &cp4, 
                                            Type cpTimes[4]); 

    void GetPoint(unsigned char WhichPt, Point<Type> &Result);

    void GetAllPoints(Point<Type>  &p1, Point<Type> &p2, Point<Type> &p3, Point<Type> &p4); 

    /* CalcPoint uses its own class variable to calculate the point on the curve and stores the result into 
     * Result 
     */ 
    void CalcPoint(Point<Type> &Result);

    /* CalcPoint uses the Time passed to calculate the point on the curve and stores the result into Result.
     * If 1 is passed for SetT, then the class' t-variable will be changed, else if you pass 0, it won't.
     */ 
    void CalcPoint(Type Time, unsigned char SetT, Point<Type> &Result); 

    /* Speed returns the speed of the object at position T.  */ 
    Type Speed(Type T);

    /* Speed returns the speed of the object at the class' position  t.  */ 
    Type Speed();

    /* Acceleration returns the acceleration of the object at the class' position  t.  */ 
    Type Acceleration();

    /* Acceleration returns the acceleration of the object at position T.  */ 
    Type Acceleration(Type T); 

    /* Length takes 3 values [t1, t2] and and NumberOfIntervals and calculates the length between these  two 
     * times on the curve.  OF course, T1 <= t1< t2 <= T4.
     */
    Type Length(Type t1, Type  t2,  unsigned  int NumberOfIntervals);

    /* This Length fn calculates the length of this curve based on the number of intervals passed.  */
    Type Length(unsigned  int NumberOfIntervals); 
 


 
 
CLASS:  TranslationCtrl
Inherited: public TimeLinearCurve<GLfloat>, public TimeCubicCurve<GLfloat>

Defined TypesPathType {NONE, LINEAR_TIME, CUBIC_TIME}

Private Vars: Point<GLfloat> Current, PathType pathType 

Public Functions:
   TranslationCtrl();

   /* Gets the current position of the object. */
   void tcGetCurrent(Point<GLfloat> &Position);

   /* Sets the current position of the object. */ 
   void tcSetCurrent(Point<GLfloat> &Position);

   /* Returns the current path type of the object. */
    PathType CurrentPathType();

   /* Calls glTranslate() to translate the object.  glPushMatrix() and glPopMatrix() are not called. */
   void tcTranslate();

    /* MoveFromTo constructs the curve on which the object is to move and then calls Update.  This movement 
     * will be a straight line. Use the function SetPath below to create a non-linear path. GL_TRUE is returned 
     * if the curve wascreated successfully, else GL_FALSE is returned. 
     */
    GLboolean MoveFromTo(Point<GLfloat> &StartPt, Point<GLfloat> &EndPt, GLfloat StartTime, 
                                                              GLfloat EndTime, GLfloat CurrentTime);

    /* MoveFromCurrentTo constructs the curve on which the object is to move from its current position to
     * the position provided and then calls Update.  This movement will be a straight line. Use the function 
     * SetPath below to create a non-linear path. GL_TRUE is returned if the curve wascreated successfully, 
     * else GL_FALSE  is returned. 
     */
    GLboolean MoveFromCurrentTo(Point<GLfloat> &EndPt, GLfloat StartTime, GLfloat EndTime, 
                                                                                 GLfloat CurrentTime);

    /* SetPath constructs the curve on which the object is to move and then calls Update.  This fn returns 
     * GL_TRUE  if the path was set properly, else it returns GL_FALSE. 
     * REMEMBER: Time1 < Time2 < Time3 < Time4.
     */
    GLboolean SetPath(Point<float> &CP1, Point<float> &CP2, Point<float> &CP3, Point<float> &CP4, 
                                                 GLfloat TimesToArrive[4], GLfloat CurrentTime);

    /*  Will update the primitive's position along a time curve.  A value of GL_TRUE is returned if the 
     * object is still moving along  the path, else GL_FALSE is returned if the object has reached the end of 
     * its path.
     */
    GLboolean tcUpdate(GLfloat CurrentTime);
 


 
 
CLASS:  RotationCtrl
Inherited: public TimeLinearCurve<GLfloat>

Private Vars: Point<GLfloat> Current

Public Functions:
   RotationCtrl();

   /* Calls glRotate() to rotate the object.  glPushMatrix() and glPopMatrix() are not called */
   void rcRotate();

   /* Sets the current angle of the object. */
   void rcSetCurrent(Point<GLfloat> angle);

   /* Gets the current angle of the object.  */ 
   void rcGetCurrentAngle(Point<GLfloat> &angle);

    /* Update will update the object's angle.  GL_TRUE is returned if the object is still rotating,  else 
     * GL_FALSE  is returned  if the object has finished rotating.
    */
    GLboolean rcUpdate(GLfloat CurrentTime);

    /* RotateFromTo will rotate the object from StartAngle to EndAngle given the times provided. 
     * GL_TRUE is returned if the curve was constructed successfully, else GL_FALSE is returned. 
     */
    GLboolean rcRotateFromTo(Point<GLfloat> &StartAngle, Point<GLfloat> &EndAngle, 
                                                                      GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* RotateFromTo will rotate the object from the Current angle to the EndAngle during the given the times 
     * provided.  GL_TRUE is returned if the curve was constructed successfully, else GL_FALSE is returned. 
     */
    GLboolean rcRotateFromCurrentTo(Point<GLfloat> &EndAngle, GLfloat StartTime, 
                                                                                        GLfloat EndTime, GLfloat CurrentTime);

    /* RotateFromCurrent will rotate the object from Current to the angle Current+NumberOfDegrees 
     * during the given the times provided.  GL_TRUE is returned if the curve was constructed 
     * successfully, else GL_FALSE is returned. 
     */
    GLboolean rcRotateFromCurrent(Point<GLfloat> &NumberOfDegrees, GLfloat StartTime, 
                                                                                  GLfloat EndTime, GLfloat CurrentTime);
 


 
 
CLASS:  ActorCommon
Inherited: public RotationCtrl

Defined Types: Direction {LEFT=0, RIGHT, LEFT_S, RIGHT_S, FRONT, 
                                                         BACK, UP, DOWN, IN, OUT},
     Side {S_LEFT=0, S_RIGHT}

Public Functions:
   ActorCommon();
 


 
CLASS:  ActorGlobal
Inherited: public ActorCommon
 

Defined TypesParts {HEAD=0, EYE, NECK, TORSO, U_ARM, L_ARM, HAND,THUMB_1, THUMB_2, 
                                                   FFINGER_1, FFINGER_2, FFINGER_3, SFINGER_1,SFINGER_2, 
                                                   SFINGER_3, TFINGER_1, TFINGER_2, TFINGER_3, PFINGER_1, 
                                                   PFINGER_2, PFINGER_3, THIGH, CALF, FOOT, TOE, WHOLE_BODY};
 


 
CLASS:  PartCommon
Inherited: public ActorCommon

Uses Point<GLfloat>

Defined TypesWhichAngles  {MIN, MAX, REST, CURRENT}, 
    MaterialProperty {COLOR, AMBIENT,  DIFFUSE, SPECULAR, SHININESS, 
                                         EMISSION}

Protected Vars: Point<GLfloat> MinAngle, Point<GLfloat> MaxAngle, 
    Point<GLfloat> RestAngle, Point<GLfloat> Offset

Public Functions:
   PartCommon();

    /* GetMin gets the Min rotation angles for this part. */
    void GetMin(Point<GLfloat> &minAngle);

    /* SetMin sets the Min rotation angles for this part. */
    void SetMin(Point<GLfloat> &minAngle);

    /* GetMax gets the Max rotation angles for this part. */
    void GetMax(Point<GLfloat> &maxAngle);

    /* SetMax sets the Max rotation angles for this part */
    void SetMax(Point<GLfloat> &maxAngle);

    /* GetRest gets the Rest rotation angles for this part. */
    void GetRest(Point<GLfloat> &restAngle);

    /* SetRest sets the Rest rotation angles for this part. */
    void SetRest(Point<GLfloat> &restAngle);

    /* GetOffset gets the offset for this part. */
    void GetOffset(Point<GLfloat> &offset);

    /* SetOffset sets the offset for this part. */
    void SetOffset(Point<GLfloat> &offset);

    /* Rest is used to rotate the corresponding part to its rest position.  */
    GLboolean Rest(GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* Rotate rotates this part about 1 or more axes to an angle of Current + DegreesToRotate.  It is assumed 
     * that a value < 0.0 for DegreesToRotate is moving towards the corresponding MinAngle.
     */
    GLboolean Rotate(Point<GLfloat> &DegreesToRotate, GLfloat StartTime, GLfloat EndTime, 
                                                GLfloat CurrentTime);

    /* RotateTo rotates this part about 1 or more axes to the Angle provided.  It is assumed that a 
     * value  < 0.0 for Angle  is moving towards the corresponding MinAngle.
     */
    GLboolean  RotateTo(Point<GLfloat> &Angle, GLfloat StartTime, GLfloat EndTime, 
                                                      GLfloat CurrentTime);

    /* Rotate rotates this part about 1 axis to an angle of Current + DegreesToRotate.  It is assumed that a 
     * value  < 0.0 forDegreesToRotate is moving towards the corresponding MinAngle.
     */
    GLboolean Rotate(unsigned char axis, GLfloat DegreesToRotate, GLfloat StartTime, GLfloat EndTime, 
                                                GLfloat CurrentTime);

    /* RotateTo rotates this primitive about 1 axis to the Angle provided.  It is assumed that a value  < 0.0 for 
     * Angle  is moving  towards the corresponding MinAngle.
     */
    GLboolean RotateTo(unsigned char Axis, GLfloat Angle, GLfloat StartTime, GLfloat EndTime, 
                                                      GLfloat CurrentTime);
 


 
 
CLASS:  ActorPrimitive
Inherited: public PartCommon

UsesVectors

Defined TypesPrimitivePart {TOP, MIDDLE, BOTTOM}

Protected Vars: Glfloat Verts[18][3], Glfloat Normals[18][3], Glfloat TopColor[4], 
    Glfloat TopAmbient[4],  Glfloat TopDiffuse[4], Glfloat TopSpecular[4], Glfloat TopShininess, 
    Glfloat TopEmission[4], Glfloat MiddleColor[4], Glfloat MiddleAmbient[4], 
    Glfloat MiddleDiffuse[4], Glfloat MiddleSpecular[4], Glfloat MiddleShininess, 
    Glfloat MiddleEmission[4], Glfloat BottomColor[4], Glfloat BottomAmbient[4], 
    Glfloat BottomDiffuse[4], Glfloat BottomSpecular[4], Glfloat BottomShininess, 
    Glfloat BottomEmission[4]

Public Functions:
   ActorPrimitive();

    /* GetVertex gets the designated vertex. */
    void GetVertex(unsigned char index, Point<Glfloat> &vertex);

    /* SetVertex sets the designated vertex. */
    void SetVertex(unsigned char index, Point<Glfloat> &vertex);

    /* GetNormal gets the designated normal. */
    void GetNormal(unsigned char index, Point<Glfloat> &normal);

    /* SetNormal sets the designated normal. */
    void SetNormal(unsigned char index, Point<Glfloat> &normal);

    /* Draw draws the primitive.  If CallTransformationFns is true, then the glTranslate() and glRotate 
     * functions are called.  But, glPushMatris() and glPopMatrix are not called.  The vars DrawTop and 
     * DrawBottom are for drawing the top and bottom of the primitive.
     */
    void Draw(Glboolean CallTransformationFns=GL_TRUE, Glboolean DrawTop=GL_TRUE, 
                             Glboolean DrawBottom=GL_TRUE);

    /* GetProperty gets the Color or one of the Material properties of the primitive.  If you're getting the 
     * shininess property, just pass the address.
     */
    void GetProperty(ActorPrimitive WhichPart, PartCommon::MaterialProperty WhichProperty, 
                                            Glfloat *PropertyValue);

    /* SetProperty sets the Color or one of the Material properties of the primitive. */
    void SetProperty(ActorPrimitive WhichPart, PartCommon::MaterialProperty WhichProperty, 
                                            Glfloat *PropertyValue);

    /* Initialize will read the data from the file pointer to initialize the attributes of this primitive.  The value
     * for ComputeNormals decides whether or not the normals read in from the file are valid.  If they aren't,
     * then CalcNormals will be called within this function.  GL_FALSE will be returned if there is a problem.
     */
    Glboolean Initialize(FILE *InitFilePtr, Glboolean ComputeNormals=GL_TRUE);

    /* This function will write the primitive data (vertices, normals, color, material, and transformation info) 
     * to the file pointed to by the file pointer.  The variable PrimitiveName is the descriptive name for this
     * primitive - e.g., "Neck."  GL_FALSE will be returned if there is a problem.
     */
    Glboolean WriteDataToFile(FILE *OutFilePtr, char *PrimitiveName);

    /* CalcNormals will calculate the normals for this primitive */
    void CalcNormals();

    /* NegateNormals is used to change the sign of the normals.  This may be useful since CalcNormals may
     * cause the normals to point in the wrong direction.
     */
    void NegateNormals();
 


 
 
CLASS:  Eye
UsesVectors

Defined TypesEyePart  {PUPIL, IRIS, MAIN}

Protected Vars: GLfloat Verts[49][3], GLfloat Normals[49][3], GLfloat PupilColor[4], 
    GLfloat  PupilAmbient[4], GLfloat PupilDiffuse[4], GLfloat PupilSpecular[4], GLfloat PupilShininess, 
    GLfloat PupilEmission[4], GLfloat IrisColor[4], GLfloat IrisAmbient[4], GLfloat IrisDiffuse[4], 
    GLfloat IrisSpecular[4], GLfloat IrisShininess, GLfloat IrisEmission[4], GLfloat MainColor[4], 
    GLfloat MainAmbient[4], GLfloat MainDiffuse[4], GLfloat MainSpecular[4], GLfloat MainShininess, 
    GLfloat MainEmission[4],  GLfloat BlinkColor[4], GLfloat BlinkAmbient[4], GLfloat BlinkDiffuse[4], 
    GLfloat BlinkSpecular[4], GLfloat BlinkShininess, GLfloat BlinkEmission[4], GLboolean Blinking

Public Functions:
    Eye();

    /* SetBlinking sets the Blinking variable to GL_TRUE.  */
    void SetBlinking();

    /* SetNotBlinking sets the Blinking variable to GL_FALSE.  */
    void SetNotBlinking();

    /* EyeIsBlinking queries the Blinking variable.  */
    GLboolean EyeIsBlinking();

    /* GetVertex gets the designated vertex */
    void GetVertex(unsigned char index, Point<GLfloat> &vertex);

    /* SetVertex sets the designated vertex.  */
    void SetVertex(unsigned char index, const Point<GLfloat> &vertex);

    /* GetNormal gets the designated normal.  */
    void GetNormal(unsigned short index, Point<GLfloat> &normal);

    /* SetNormal sets the designated normal.  */
    void SetNormal(unsigned short index, const Point<GLfloat> &normal);

    /* Draw draws the Eye. */
    void Draw();

     /* SetBlinkMaterials sets up the eye blinking material properties. */
    void SetBlinkMaterials(GLfloat [4] blinkColor, GLfloat blinkAmbient[4], GLfloat [4] blinkSpecular, 
                                                         GLfloat blinkShininess, GLfloat blinkEmission[4]);

    /* Initializewill read the data from the file pointer to initialize the attributes of the eye.  The value for 
     * ComputeNormals decides whether or not the normals read in from the file are valid.  If they aren't, then 
     * CalcNormals will be called within  this function.  GL_FALSE will be returned if there is a problem.
     */
    GLboolean Initialize(FILE *InitFilePtr, GLboolean ComputeNormals=GL_TRUE);

    /* CalcNormals will calculate the normals for the eye. */ 
    void CalcNormals();

    /* NegateNormals is used to change the sign of the normals.  This may be useful since CalcNormals may 
     * cause the normals to point in the wrong direction.
    */ 
    void NegateNormals();
 


 
 
CLASS:  Eyes
Inherited: public Eye

UsesPartCommon

Protected Vars: PartCommon EyeControl[2]

Public Functions:
   Eyes();

    void GetEyesOffset(ActorCommon::Side Which, Point<GLfloat> &offset);

    void SetEyesOffset(ActorCommon::Side Which, Point<GLfloat> &offset)

    /* RotateEyes will rotate the designated eye in the direction provied.   Degrees > 0.0 */ 
    GLboolean RotateEyes(ActorCommon::Side WhichSide, ActorCommon::Direction WhchDirection, 
                                                    GLfloat DegreesToRotate, GLfloat StartTime, GLfloat EndTime, 
                                                    GLfloat CurrentTime);

    /* RotateEyesTo will rotate the eyes to the angle provided. */ 
    GLboolean RotateEyesTo(const Point<GLfloat> &Angle, GLfloat StartTime, GLfloat EndTime, 
                                                         GLfloat CurrentTime);

    /* RestEyes will construct the curve to place the eyes at rest . */ 
    GLboolean RestEyes(GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* UpdateEyes will update the angle of rotation . */ 
    unsigned char UpdateEyes(GLfloat CurrentTime);

    /* DrawEyes draws both Eyes.  */
    void DrawEyes();

    /* This fn is used to get the angle for one of the eyes. */
    void GetAngle(PartCommon::WhichAngles whichAngle, ActorCommon::Side whichSide, 
                                  Point<GLfloat> &Angle);

    /* This fn is used to set the angle for one of the eyes. */
    void SetAngle(PartCommon::WhichAngles whichAngle, ActorCommon::Side whichSide, 
                                 Point<GLfloat> &Angle);

    /* GetEyeProperty gets the Color, or one of the Material properties for the Pupil, Iris, or Main part of 
     * the eye. 
     */
    void GetEyeProperty(Eye::EyePart WhichPart, PartCommon::MaterialProperty WhichProperty, 
                                                GLfloat *PropertyValue);

    /* SetEyeProperty sets the Color, or one of the Material properties for the Pupil, Iris, or Main part of the 
     * eye. 
     */
    void SetEyeProperty(Eye::EyePart WhichPart, PartCommon::MaterialProperty WhichProperty, 
                                               GLfloat *PropertyValue);

    /* InitializeEyes will read the data from the file pointer to initialize the attributes of this primitive.  The 
     * value for ComputeNormals decides whether or not the normals read in from the file are valid.  If they 
     * aren't, then CalcNormals will be called within this function.
     */
    GLboolean InitializeEyes(FILE *InitFilePtr, GLboolean ComputeNormals=GL_TRUE);

    /* This fn will write the primitive data (vertices, normals, color, material, and transformation info) to 
     *  the file pointed to by the file ptr.
     */
    short WriteDataToFile(FILE *OutFilePtr);
 


 
 
CLASS:  Head
Inherited: public PartCommon, public Eyes

UsesVectors

Defined TypesHeadPart {SKIN_FACE, LIP, NOSTRIL, EYEBROW, HAIR}, 
    LidState {BLINKING, LIDS_CLOSED, LIDS_OPEN}, 
    MouthState {MOUTH_OPEN, MOUTH_CLOSED}

Protected Vars: Glfloat Verts[328][3], Glfloat Normals[3289][3], Glfloat FaceColor[4], 
    Glfloat FaceAmbient[4], Glfloat FaceDiffuse[4], Glfloat FaceSpecular[4], Glfloat FaceShininess, 
    Glfloat FaceEmission[4], Glfloat LipColor[4], Glfloat LipAmbient[4], Glfloat LipDiffuse[4], 
    Glfloat LipSpecular[4], Glfloat LipShininess, Glfloat LipEmission[4], Glfloat NostrilColor[4], 
    Glfloat NostrilAmbient[4], Glfloat NostriDiffuse[4], Glfloat NostrilSpecular[4], Glfloat NostrilShininess, 
    Glfloat NostrilEmission[4], Glfloat EyebrowColor[4], Glfloat EyebrowAmbient[4], 
    Glfloat EyebrowDiffuse[4], Glfloat EyebrowSpecular[4], Glfloat EyebrowShininess, 
    Glfloat EyebrowEmission[4], Glfloat HairColor[4], Glfloat HairAmbient[4], Glfloat HairDiffuse[4], 
    Glfloat HairSpecular[4], Glfloat HairShininess, Glfloat HairEmission[4]

Private VarsLidState lidState, MouthState mouthState

Public Functions:
   Head();

    /* GetVertex gets the designated vertex. */
    void GetVertex(unsigned short index, Point<Glfloat> &vertex);

    /* SetVertex sets the designated vertex. */
    void SetVertex(unsigned short index, Point<Glfloat> &vertex);

    /* GetNormal gets the designated normal. */
    void GetNormal(unsigned short index, Point<Glfloat> &normal);

    /* SetNormal sets the designated normal. */
    void SetNormal(unsigned short index, Point<Glfloat> &normal);

    /* OpenMouth will open the mouth the percent provided within the amount of time provided, where 
     * 0.0 < PercentToOpen <= 1.0. 
     */
    void OpenMouth(Glfloat PercentToOpen, Glfloat StartTime, Glfloat EndTime, Glfloat CurrentTime);

    /* CloseMouth will close the mouth the percent provided within the amount of time provided, where 
     * 0.0 < PercentToClose <= 1.0. 
     */
    void CloseMouth(Glfloat PercentToClose, Glfloat StartTime, Glfloat EndTime, Glfloat CurrentTime);

    /* Blink causes the eyes to blink.  The eyelids will stay closed for (EndTime-StartTime) seconds. */
    void Blink(Glfloat StartTime, Glfloat EndTime, Glfloat CurrentTime);

    /* CloseEyelids causes the lids to close and stay closed at the time provided and to stay closed until 
     * EndTime. 
     */
    void CloseEyelids(Glfloat StartTime, Glfloat EndTime, Glfloat CurrentTime);

    /* Rotate will rotate the head in the direction provided.  Degrees > 0.0. */
    void Rotate(ActorCommon::Direction WhichDirection, Glfloat Degrees, Glfloat StartTime, 
                                Glfloat EndTime, Glfloat CurrentTime);

    /* Update calls RotationCtrl::Update for both the head and eyes. */
    void Update(Glfloat CurrentTime);

    /* Draw draws the head and eyes. */
    void Draw(Glboolean CallTransformationFns=GL_TRUE);

    /* GetProperty gets the Color or one of the Material properties of the head. */
    void GetProperty(Head::HeadPart WhichPart, PartCommon::MaterialProperty WhichProperty, 
                                            Glfloat *PropertyValue);

    /* SetProperty sets the Color or one of the Material properties of the head. */
    void SetProperty(Head::HeadPart WhichPart, PartCommon::MaterialProperty WhichProperty, 
                                           Glfloat *PropertyValue);

    /* Initialize will read the data from the file pointer to initialize the attributes of  the head and eyes.  The 
     * value for ComputeNormals decides whether or not the normals read in from the file are valid.  If  they 
     * aren't, then CalcNormals will be called within this function.
     */
    Glboolean Initialize(FILE *InitFilePtr, Glboolean ComputeNormals=GL_TRUE);

    /* GetProperty gets the Color, or one of the Material properties for the head. */
    void GetProperty(Head::HeadPart WhichPart, PartCommon::MaterialProperty WhichProperty, 
                                            GLfloat *PropertyValue);

    /* SetProperty sets the Color, or one of the Material properties for the head . */
    void SetProperty(Head::HeadPart WhichPart, PartCommon::MaterialProperty WhichProperty, 
                                           GLfloat *PropertyValue);

    /* Initialize will read the data from the file pointer to initialize the attributes of this primitive.  The value 
     * for ComputeNormals decides whether or not the normals read in from the file are valid.  If they aren't,
     *  then CalcNormals will be called within this function.
     */
    GLboolean Initialize(FILE *InitFilePtr, GLboolean ComputeNormals=GL_TRUE);

    /* This fn will write the head data (vertices, normals, color, material, and transformation info) to the file 
     * pointed to by the file ptr.
     */
    GLboolean WriteDataToFile(FILE *OutFilePtr, GLboolean WriteEyeData=GL_TRUE);

    /* CalcNormals calculates the normals for the  head only, and not the eyes.  */
    void CalcNormals();

    /* NegateNormals is used to change the sign of the normals.  This may be useful since CalcNormals may 
     * cause the normals to point in the wrong direction.
     */ 
    void NegateNormals();

Private Functions:
    /* CalcEarNormals calculates the normals for one of the ears. */
    void CalcEarNormals(ActorCommon::Side WhichSide);
 


 
 
CLASS:  Neck
Inherited: public ActorPrimitive

Public Functions:
    Neck();

    /* Rotate will rotate the neck Current+Degrees in the direction provied, where  Degrees > 0.0.  */ 
    GLboolean Rotate(ActorCommon::Direction WhichDirection, GLfloat Degrees, GLfloat StartTime, 
                                               GLfloat EndTime, GLfloat CurrentTime);
 


 
 
CLASS:  Torso
Inherited: public ActorPrimitive

Uses Vectors

Protected Vars: GLfloat BreastVerts[33][3], GLfloat BreastNormals[33][3], Point<Glfloat> BreastOffset,
    Point<Glfloat> StoopAngle

Private Vars: GLboolean IsFemale

Public Functions:
   Torso(GLboolean isFemale);

    /* Rotate will rotate the torso in the direction provied.  Degrees > 0.0.  */ 
    GLboolean Rotate(ActorCommon::Direction WhichDirection, GLfloat Degrees, GLfloat TimeToComplete, 
                                               GLfloat CurrentTime);

    /* Draw draws the Torso and Bust if this is a female.  If CallTransformationFns is true, then the glTranslate() 
     * and glRotate()  functions are called.  But, glPushMatrix() and glPopMatrix() are not called.   The vars 
     * DrawTop and DrawBottom are for drawing the top and bottom of the Torso. 
     */
    void Draw(GLboolean CallTransformationFns=GL_TRUE, GLboolean DrawTop=GL_TRUE, 
                            GLboolean DrawBottom=GL_TRUE);

    /* GetVertex gets the designated vertex.  */
    void GetVertex(unsigned char index, Point<GLfloat> &vertex, GLboolean BustVertex=GL_FALSE);

    /* SetVertex sets the designated vertex.  */
    void SetVertex(unsigned char index, Point<GLfloat> &vertex, GLboolean BustVertex=GL_FALSE);

    /* GetNormal gets the designated normal.  */
    void GetNormal(unsigned char index, Point<GLfloat> &normal, GLboolean BustNormal=GL_FALSE);

    /* SetNormal sets the designated normal.  */
    void SetNormal(unsigned char index, Point<GLfloat> &normal, GLboolean BustNormal=GL_FALSE);

    /* Initialize will read the data from the file pointer to initialize the attributes of this primitive.  The value for 
     * ComputeNormals decides whether or not the normals read in from the file are valid.  If they aren't, then 
     * CalcNormals will be called within this function.  This function will also read in the Bust normals and 
     * calculate them ifCalculateNormals is set to GL_TRUE and this is a female.
     */
    GLboolean Initialize(FILE *InitFilePtr, GLboolean ComputeNormals=GL_TRUE);

    /* This fn will write the primitive data (vertices, normals, color, material, and transformation info) to the 
     * file pointed to by the file ptr.  The variable PrimitiveName is the descriptive name for this primitive - 
     * e.g., "Neck".
     */
    GLboolean WriteDataToFile(FILE *OutFilePtr);

    /* CalcNormals will calculate the normals for the Torso and Breast (if this is a female). */ 
    void CalcNormals();

    /* NegateNormals is used to change the sign of the Torso or Bust normals.  This may be useful since 
     * CalcNormals may cause the normals to point in the wrong direction.
     */ 
    void NegateNormals(GLboolean BustNormals=GL_FALSE);

Protected Functions:
    void DrawBreast();
    void CalcBreastNormals();
    void NegateBreastNormals();
 


 
 
CLASS:  Hands
Uses: ActorPrimitive

Protected Vars: ActorPrimitive MainHand[2], ActorPrimitive ThumbPart1[2], 
    ActorPrimitive ThumbPart2[2], ActorPrimitive FFingerPart1[2], ActorPrimitive FFingerPart2[2], 
    ActorPrimitive FFingerPart3[2], ActorPrimitive SFingerPart1[2], ActorPrimitive SFingerPart2[2], 
    ActorPrimitive SFingerPart3[2], ActorPrimitive TFingerPart1[2], ActorPrimitive TFingerPart2[2], 
    ActorPrimitive TFingerPart3[2], ActorPrimitive PFingerPart1[2], ActorPrimitive PFingerPart2[2], 
    ActorPrimitive PFingerPart3[2], Point<GLfloat> ThumbPart1PP[2], Point<GLfloat> ThumbPart2PP[2], 
    Point<GLfloat> FFingerPart1PP[2], Point<GLfloat> FFingerPart2PP[2], Point<GLfloat> FFingerPart3PP[2], 
    Point<GLfloat> SFingerPart1PP[2], Point<GLfloat> SFingerPart2PP[2], Point<GLfloat> SFingerPart3PP[2], 
    Point<GLfloat> TFingerPart1PP[2], Point<GLfloat> TFingerPart2PP[2], Point<GLfloat> TFingerPart3PP[2], 
    Point<GLfloat> PFingerPart1PP[2], Point<GLfloat> PFingerPart2PP[2], Point<GLfloat> PFingerPart3PP[2], 
    Point<GLfloat> ThumbPart1FP[2], Point<GLfloat> ThumbPart2FP[2], Point<GLfloat> FFingerPart1FP[2], 
    Point<GLfloat> FFingerPart2FP[2], Point<GLfloat> FFingerPart3FP[2], Point<GLfloat> SFingerPart1FP[2], 
    Point<GLfloat> SFingerPart2FP[2], Point<GLfloat> SFingerPart3FP[2], Point<GLfloat> TFingerPart1FP[2], 
    Point<GLfloat> TFingerPart2FP[2], Point<GLfloat> TFingerPart3FP[2], Point<GLfloat> PFingerPart1FP[2], 
    Point<GLfloat> PFingerPart2FP[2], Point<GLfloat> PFingerPart3FP[2], 
    Point<Glfloat> MainHandStoopAngle[2]

Public Functions:
   Hands();

    /* SetToWalkingPosition places the hands in the walking position. */
    GLboolean SetToWalkingPosition(GLfloat CurrentTime);

    /* SetToJoggingPosition places the hands in the jogging position. */
    GLboolean SetToJoggingPosition(GLfloat CurrentTime);

    /* SetToRunningPosition placess the hands in the running position. */
    GLboolean SetToRunningPosition(GLfloat CurrentTime);

    /* Point places the designated hand in the pointing position. */
    GLboolean SetToPoint(ActorCommon::Side WhichSide, GLfloat StartTime, GLfloat EndTime, 
                                                          GLfloat CurrentTime);

    /* MakeFist places the designated hand in the fist position. */
    GLboolean MakeFist(ActorCommon::Side WhichSide, GLfloat StartTime, GLfloat EndTime, 
                                                      GLfloat CurrentTime);

    /* AssumeStoopPos places the hands in the stoop position. */
    GLboolean AssumeStoopPos( GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* RotateMain will rotate the designated main part of the hand in the direction provied.  Degrees > 0.0.  */ 
    GLboolean RotateMain(ActorCommon::Side WhichSide, ActorCommon::Direction WhichDirection, 
                                                           GLfloat Degrees, GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

     /* RotateMain will rotate the designated main part of the hand to the Angle provided.  */ 
    GLboolean RotateMain(ActorCommon::Side WhichSide, Point<GLfloat> &Angle, GLfloat StartTime,
                                                           GLfloat CurrentTime);

     /* RotateThumbPart1 will rotate the designated ThumbPart1 in the direction provied.  Degrees > 0.0.  */ 
    GLboolean RotateThumbPart1(ActorCommon::Side WhichSide, 
                                                                          ActorCommon::Direction WhichDirection, GLfloat Degrees, 
                                                                          GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

     /* RotateThumbPart1 will rotate the designated ThumbPart1 to the Angle provied..  */ 
    GLboolean RotateThumbPart1(ActorCommon::Side WhichSide, const Point<GLfloat> &Angle, 
                                                                          GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* RotateThumbPart2 will rotate the designated ThumbPart2 in the direction provied.  Degrees > 0.0.  */ 
    GLboolean RotateThumbPart2(ActorCommon::Side WhichSide, 
                                                                          ActorCommon::Direction WhichDirection, GLfloat Degrees, 
                                                                          GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

     /* RotateThumbPart2 will rotate the designated ThumbPart2 to the Angle provied..  */ 
    GLboolean RotateThumbPart2(ActorCommon::Side WhichSide, const Point<GLfloat> &Angle, 
                                                                          GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* RotateFFingerPart1 will rotate the designated FFingerPart1 in the direction provied.  Degrees > 0.0.  */ 
    GLboolean RotateFFingerPart1(ActorCommon::Side WhichSide, 
                                                                              ActorCommon::Direction WhichDirection, GLfloat Degrees, 
                                                                              GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* RotateFFingerPart1 will rotate the designated FFingerPart1 to the Angle provied..  */ 
    GLboolean RotateFFingerPart1(ActorCommon::Side WhichSide, const Point<GLfloat> &Angle, 
                                                                             GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* RotateFFingerPart2 will rotate the designated FFingerPart2 in the direction provied.  Degrees > 0.0.  */ 
    GLboolean RotateFFingerPart2(ActorCommon::Side WhichSide, 
                                                                              ActorCommon::Direction WhichDirection, GLfloat Degrees, 
                                                                             GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

     /* RotateFFingerPart2 will rotate the designated FFingerPart2 to the Angle provied..  */ 
    GLboolean RotateFFingerPart2(ActorCommon::Side WhichSide, const Point<GLfloat> &Angle, 
                                                                             GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* RotateFFingerPart3 will rotate the designated FFingerPart3 in the direction provied.  Degrees > 0.0.  */ 
    GLboolean RotateFFingerPart3(ActorCommon::Side WhichSide, 
                                                                              ActorCommon::Direction WhichDirection, GLfloat Degrees, 
                                                                              GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

     /* RotateFFingerPart3 will rotate the designated FFingerPart3 to the Angle provied..  */ 
    GLboolean RotateFFingerPart3(ActorCommon::Side WhichSide, const Point<GLfloat> &Angle, 
                                                                             GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* RotateSFingerPart1 will rotate the designated SFingerPart1 in the direction provied.  Degrees > 0.0.  */ 
    GLboolean RotateSFingerPart1(ActorCommon::Side WhichSide, 
                                                                             ActorCommon::Direction WhichDirection, GLfloat Degrees, 
                                                                             GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

     /* RotateSFingerPart1 will rotate the designated SFingerPart1 to the Angle provied..  */ 
    GLboolean RotateSFingerPart1(ActorCommon::Side WhichSide, const Point<GLfloat> &Angle, 
                                                                             GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* RotateSFingerPart2 will rotate the designated SFingerPart2 in the direction provied.  Degrees > 0.0.  */ 
    GLboolean RotateSFingerPart2(ActorCommon::Side WhichSide, 
                                                                             ActorCommon::Direction WhichDirection, GLfloat Degrees, 
                                                                              GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

     /* RotateSFingerPart2 will rotate the designated SFingerPart2 to the Angle provied..  */ 
    GLboolean RotateSFingerPart2(ActorCommon::Side WhichSide, const Point<GLfloat> &Angle, 
                                                                             GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* RotateSFingerPart3 will rotate the designated SFingerPart3 in the direction provied.  Degrees > 0.0.  */ 
    GLboolean RotateSFingerPart3(ActorCommon::Side WhichSide, 
                                                                              ActorCommon::Direction WhichDirection, GLfloat Degrees, 
                                                                             GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

     /* RotateSFingerPart3 will rotate the designated SFingerPart3 to the Angle provied..  */ 
    GLboolean RotateSFingerPart3(ActorCommon::Side WhichSide, const Point<GLfloat> &Angle, 
                                                                             GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* RotateTFingerPart1 will rotate the designated TFingerPart1 in the direction provied.  Degrees > 0.0.  */ 
    GLboolean RotateTFingerPart1(ActorCommon::Side WhichSide, 
                                                                              ActorCommon::Direction WhichDirection, GLfloat Degrees, 
                                                                              GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

     /* RotateTFingerPart1 will rotate the designated TFingerPart1 to the Angle provied..  */ 
    GLboolean RotateTFingerPart1(ActorCommon::Side WhichSide, const Point<GLfloat> &Angle, 
                                                                             GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* RotateTFingerPart2 will rotate the designated TFingerPart2 in the direction provied.  Degrees > 0.0.  */ 
    GLboolean RotateTFingerPart2(ActorCommon::Side WhichSide, 
                                                                              ActorCommon::Direction WhichDirection, GLfloat Degrees, 
                                                                             GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

     /* RotateTFingerPart2 will rotate the designated TFingerPart2 to the Angle provied..  */ 
    GLboolean RotateTFingerPart2(ActorCommon::Side WhichSide, const Point<GLfloat> &Angle, 
                                                                              GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* RotateTFingerPart3 will rotate the designated TFingerPart3 in the direction provied.  Degrees > 0.0.  */ 
    GLboolean RotateTFingerPart3(ActorCommon::Side WhichSide, 
                                                                              ActorCommon::Direction WhichDirection, GLfloat Degrees, 
                                                                             GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* RotateTFingerPart3 will rotate the designated TFingerPart3 to the Angle provied..  */ 
    GLboolean RotateTFingerPart3(ActorCommon::Side WhichSide, const Point<GLfloat> &Angle, 
                                                                             GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* RotatePFingerPart1 will rotate the designated PFingerPart1 in the direction provied.  Degrees > 0.0.  */ 
    GLboolean RotatePFingerPart1(ActorCommon::Side WhichSide, 
                                                                             ActorCommon::Direction WhichDirection, GLfloat Degrees, 
                                                                             GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

     /* RotatePFingerPart1 will rotate the designated PFingerPart1 to the Angle provied..  */ 
    GLboolean RotatePFingerPart1(ActorCommon::Side WhichSide, const Point<GLfloat> &Angle, 
                                                                             GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* RotatePFingerPart2 will rotate the designated PFingerPart2 in the direction provied.  Degrees > 0.0.  */ 
    GLboolean RotatePFingerPart2(ActorCommon::Side WhichSide, 
                                                                              ActorCommon::Direction WhichDirection, GLfloat Degrees, 
                                                                              GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

     /* RotatePFingerPart2 will rotate the designated PFingerPart2 to the Angle provied..  */ 
    GLboolean RotatePFingerPart2(ActorCommon::Side WhichSide, const Point<GLfloat> &Angle, 
                                                                              GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* RotatePFingerPart3 will rotate the designated PFingerPart3 in the direction provied.  Degrees > 0.0.  */ 
    GLboolean RotatePFingerPart3(ActorCommon::Side WhichSide, 
                                                                             ActorCommon::Direction WhichDirection, GLfloat Degrees, 
                                                                             GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

     /* RotatePFingerPart3 will rotate the designated PFingerPart3 to the Angle provied..  */ 
    GLboolean RotatePFingerPart3(ActorCommon::Side WhichSide, const Point<GLfloat> &Angle, 
                                                                              GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* Rest calls Hands::Rest below for both hands. */
    GLboolean Rest(GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* Rest calls PartCommon::Rest for all parts of the designated  hand. */
    GLboolean Rest(ActorCommon::Side WhichSide, GLfloat StartTime, GLfloat EndTime, 
                                      GLfloat CurrentTime);

    /* Update calls RotationCtrl::Update for all parts of both hands. */
    GLboolean Update(GLfloat CurrentTime);

    /* Draw draws both hands.  */
    void Draw();

    /* GetProperty gets the Color, or one of the Material properties for the designated part of the hand. */
    void GetProperty(ActorGlobal::Parts WhichPart, ActorCommon::Side WhichSide, 
                                             PartCommon::MaterialProperty WhichProperty, GLfloat *PropertyValue);

    /* SetProperty sets the Color, or one of the Material properties for the designated part of the hand. */
    void SetProperty(ActorGlobal::Parts WhichPart, ActorCommon::Side WhichSide, 
                                            PartCommon::MaterialProperty WhichProperty, GLfloat *PropertyValue);

    /* GetAngle is used to get the MIN, MAX, REST or CURRENT angle for the specified part of the hand. */
    void GetAngle(PartCommon::WhichAngles WhichAngle, ActorGlobal::Parts WhichPart, 
                                      ActorCommon::Side WhichSide, Point<GLfloat> &Angle);

    /* SetAngle is used to set the MIN, MAX, REST or CURRENT angle for the specified part of the hand. */
    void SetAngle(PartCommon::WhichAngles WhichAngle, ActorGlobal::Parts WhichPart, 
                                     ActorCommon::Side WhichSide, Point<GLfloat> &Angle);

    /* GetOffset is used to get the offset for the specified part of the hand. */
    void GetOffset(ActorGlobal::Parts WhichPart, ActorCommon::Side WhichSide, Point<GLfloat> &offset);

    /* SetOffset is used to set the offset for the specified part of the hand. */
    void SetOffset(ActorGlobal::Parts WhichPart, ActorCommon::Side WhichSide, Point<GLfloat> &offset);

    /* GetVertex is used to get the vertex for the specified part of the hand. */
    void GetVertex(ActorGlobal::Parts WhichPart, ActorCommon::Side WhichSide, Point<GLfloat> &vertex);

    /* SetVertex is used to set the vertex for the specified part of the hand. */
    void SetVertex(ActorGlobal::Parts WhichPart, ActorCommon::Side WhichSide, Point<GLfloat> &vertex);

    /* GetNormal is used to get the normal for the specified part of the hand. */
    void GetNormal(ActorGlobal::Parts WhichPart, ActorCommon::Side WhichSide, Point<GLfloat> &normal);

    /* SetNormal is used to set the normal for the specified part of the hand. */
    void SetNormal(ActorGlobal::Parts WhichPart, ActorCommon::Side WhichSide, Point<GLfloat> &normal);

    /* Initialize will read the data from the file pointer to initialize the attributes of both hands.  The value for 
     * ComputeNormals decides whether or not the normals read in from the file are valid.  If they aren't, then 
     * CalcNormals will be called within this function.
     */
    GLboolean Initialize(FILE *InitFilePtr, GLboolean ComputeNormals, GLboolean InitFistAndPointAngles);

    /* This fn will write the data (vertices, normals, color, material, and transformation info) for both hands  to
     *  the file pointed to by the file ptr.
     */
    GLboolean WriteDataToFile(FILE *OutFilePtr);

    /* CalcNormals will calculate the normals for both hands. */ 
    void CalcNormals();

    /* NegateNormals is used to change the sign of the  normals for both hands.  This may be useful since 
     * CalcNormals may cause the normals to point in the wrong direction.
     */ 
    void NegateNormals();
 


 
 
CLASS:  Arms
Inherited: public Hands

Defined Types: ArmsMovingState {ARMS_STANDING, ARMS_WALKING, ARMS_JOGGING, 
    ARMS_RUNNING};

Protected Vars: ActorPrimitive UpperArm[2], ActorPrimitive LowerArm[2], 
    GLfloat UpperMaxWalkingFront, GLfloat UpperMaxWalkingFrontTime, 
    GLfloat UpperMaxWalkingBack, GLfloat UpperMaxWalkingBackTime,
    GLfloat LowerMaxWalkingFront, GLfloat LowerMaxWalkingFrontTime, 
    GLfloat LowerMaxWalkingBack, GLfloat LowerMaxWalkingBackTime, 
    GLboolean UpperFrontWalkSwitched, GLboolean UpperBackWalkSwitched,
    GLboolean LowerFrontWalkSwitched, GLboolean LowerBackWalkSwitched, 
    GLfloat UpperMaxJoggingFront, GLfloat UpperMaxJoggingFrontTime, 
    GLfloat UpperMaxJoggingBack, GLfloat UpperMaxJoggingBackTime,
    GLboolean UpperFrontJogSwitched, GLboolean UpperBackJogSwitched, 
    GLfloat UpperJogYZPos[2][2], GLfloat LowerJogXYZPos[2][3], GLfloat UpperMaxRunningFront, 
    GLfloat UpperMaxRunningFrontTime, GLfloat UpperMaxRunningBack, 
    GLfloat UpperMaxRunningBackTime, GLboolean UpperFrontRunSwitched,
    GLboolean UpperBackRunSwitched, GLfloat UpperRunYZPos[2][3], GLfloat LowerRunXYZPos[2][3],
    ArmsMovingState armsMovingState, Point<GLfloat> UpperStoopAngle[2], 
    Point<GLfloat> LowerStoopAngle[2]

Public Functions:
   Arms();

    /* Point. */
    GLboolean SetToPoint(ActorCommon::Side WhichSide, const Point<GLfloat> &Angle, 
                                                          GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* Rotate will rotate the designated UpperArm in the direction provied.  Degrees > 0.0.  */
    GLboolean RotateUpper(ActorCommon::Side WhichSide, ActorCommon::Direction WhichDirection, 
                                                             GLfloat Degrees, GLfloat TimeToComplete, GLfloat CurrentTime);

     /* Rotate will rotate the designated UpperArm to the Angle provied.  */ 
    GLboolean RotateUpper(ActorCommon::Side WhichSide, const Point<GLfloat> &Angle, 
                                                            GLfloat TimeToComplete, GLfloat CurrentTime);

    /* Rotate will rotate the designated LowerArm in the direction provied.  Degrees > 0.0.  */
    GLboolean RotateLower(ActorCommon::Side WhichSide, ActorCommon::Direction WhichDirection, 
                                                              GLfloat Degrees, GLfloat TimeToComplete, GLfloat CurrentTime);

    /* Rotate will rotate the designated LowerArm to the Angle provied.  */ 
    GLboolean RotateLower(ActorCommon::Side WhichSide, const Point<GLfloat> &Angle,
                                                              GLfloat TimeToComplete, GLfloat CurrentTime);

    /* Rest calls Arms::Rest below for both arms. */
    GLboolean Rest(GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* Rest calls PartCommon::Rest for both arms and hands. */
    GLboolean Rest(ActorCommon::Side WhichSide, GLfloat StartTime, GLfloat EndTime, 
                                          GLfloat CurrentTime);

    /* Update calls RotationCtrl::Update for all parts of both hands. */
    GLboolean Update(GLfloat CurrentTime);

    /* Draws both arms and hands. */
    void Draw();

    /* GetProperty gets the Color, or one of the Material properties for the designated part of the arm. */
    void GetProperty(ActorGlobal::Parts WhichPart, ActorCommon::Side WhichSide, 
                                             PartCommon::MaterialProperty WhichProperty, GLfloat *PropertyValue);

    /* SetProperty sets the Color, or one of the Material properties for the designated part of the arm. */
    void SetProperty(ActorGlobal::Parts WhichPart, ActorCommon::Side WhichSide, 
                                            PartCommon::MaterialProperty WhichProperty, GLfloat *PropertyValue);

    /* GetAngle is used to get the MIN, MAX, REST or CURRENT angle for the specified part of the arm. */
    void GetAngle(PartCommon::WhichAngles WhichAngle, ActorGlobal::Parts WhichPart, 
                                     ActorCommon::Side WhichSide, Point<GLfloat> &Angle);

    /* SetAngle is used to set the MIN, MAX, REST or CURRENT angle for the specified part of the arm. */
    void SetAngle(PartCommon::WhichAngles WhichAngle, ActorGlobal::Parts WhichPart, 
                                     ActorCommon::Side WhichSide, Point<GLfloat> &Angle);

    /* GetOffset is used to get the offset for the specified part of the arm. */
    void GetOffset(ActorGlobal::Parts WhichPart, ActorCommon::Side WhichSide, 
                                      Point<GLfloat> &offset);

    /* SetOffset is used to set the offset for the specified part of the arm. */
    void SetOffset(ActorGlobal::Parts WhichPart, ActorCommon::Side WhichSide, 
                                     Point<GLfloat> &offset);

    /* GetVertex is used to get the vertex for the specified part of the arm. */
    void GetVertex(ActorGlobal::Parts WhichPart, ActorCommon::Side WhichSide, 
                                         Point<GLfloat> &vertex);

    /* SetVertex is used to set the vertex for the specified part of the arm. */
    void SetVertex(ActorGlobal::Parts WhichPart, ActorCommon::Side WhichSide, 
                                        Point<GLfloat> &vertex);

    /* GetNormal is used to get the normal for the specified part of the arm. */
    void GetNormal(ActorGlobal::Parts WhichPart, ActorCommon::Side WhichSide, 
                                          Point<GLfloat> &normal);

    /* SetNormal is used to set the normal for the specified part of the arm. */
    void SetNormal(ActorGlobal::Parts WhichPart, ActorCommon::Side WhichSide, 
                                          Point<GLfloat> &normal);

    /* Initializewill read the data from the file pointer to initialize the attributes of the arms.  The value for
     * ComputeNormals decides whether or not the normals read in from the file are valid.  If they aren't, then 
     * CalcNormals will be called within this function. 
     */
    GLboolean Initialize(FILE *InitFilePtr, GLboolean ComputeNormals=GL_TRUE);

    /* This fn will write the primitive data (vertices, normals, color, material, and transformation info) to 
     * the file pointed to by the file ptr.  The variable PrimitiveName is the descriptive name for this primitive 
     * - e.g., "Neck".
     */
    GLboolean WriteDataToFile(FILE *OutFilePtr);

    /* CalcNormals will calculate the normals for the Torso and Bust (if this is a female). */ 
    void CalcNormals();

    /* NegateNormals is used to change the sign of the arms' and hands' normals.  This may be useful since
     * CalcNormals may cause the normals to point in the wrong direction.
    */ 
    void NegateNormals();

Protected Functions:
    GLboolean UpdateWalkingMovement(Glfloat CurrentTime);
    GLboolean UpdateJoggingMovement(Glfloat CurrentTime);
    GLboolean UpdateRunningMovement(Glfloat CurrentTime);
 


 
 
CLASS:  Legs
Defined Types: LegsMovingState {LEGS_STANDING, LEGS_WALKING, LEGS_JOGGING, 
    LEGS_RUNNING};

Protected Vars: ActorPrimitive Thigh[2], ActorPrimitive Calf[2], ActorPrimitive Foot[2], 
    ActorPrimitive Toe[2], GLfloat ThighMaxWalkingFront, GLfloat ThighMaxWalkingFrontTime, 
    GLfloat ThighMaxWalkingBack, GLfloat ThighMaxWalkingBackTime, GLfloat CalfMaxWalkingFront, 
    GLfloat CalfMaxWalkingFrontTime, GLfloat CalfMaxWalkingBack, GLfloat CalfMaxWalkingBackTime, 
    GLfloat FootMaxWalkingUp, GLfloat FootMaxWalkingUpTime, GLfloat FootMaxWalkingDown, 
    GLfloat FootMaxWalkingDownTime, GLfloat ToeMaxWalkingUp, GLfloat ToeMaxWalkingUpTime, 
    GLfloat ToeMaxWalkingDown, GLfloat ToeMaxWalkingDownTime, GLboolean ThighFrontWalkSwitched,
    GLboolean ThighBackWalkSwitched, GLboolean CalfFrontWalkSwitched, 
    GLboolean ThighBackWalkSwitched, Glboolean FootUpWalkSwitched,
    Glboolean FootDownWalkSwitched, Glboolean ToeUpWalkSwitched, GLbooleanToeDownWalkSwitched, 
    GLfloat ThighMaxJoggingFront, GLfloat ThighMaxJoggingFrontTime, GLfloat ThighMaxJoggingBack, 
    GLfloat ThighMaxJoggingBackTime, GLfloat CalfMaxJoggingFront, GLfloat CalfMaxJoggingFrontTime, 
    GLfloat CalfMaxJoggingBack, GLfloat CalfMaxJoggingBackTime, GLfloat FootMaxJoggingUp, 
    GLfloat FootMaxJoggingUpTime, GLfloat FootMaxJoggingDown, GLfloat FootMaxJoggingDownTime,
    GLfloat ToeMaxJoggingUp, GLfloat ToeMaxJoggingUpTime, GLfloat ToeMaxJoggingDown, 
    GLfloat ToeMaxJoggingDownTime, GLboolean ThighFrontJogSwitched, GLboolean ThighBackJogSwitched,
    GLboolean CalfFrontJogSwitched, GLboolean ThighBackJogSwitched, Glboolean FootUpJogSwitched, 
    Glboolean FootDownJogSwitched, Glboolean ToeUpJogSwitched, GLbooleanToeDownJogSwitched, 
    GLfloat ThighMaxRunningFront, GLfloat ThighMaxRunningFrontTime, GLfloat ThighMaxRunningBack, 
    GLfloat ThighMaxRunningBackTime, GLfloat CalfMaxRunningFront, GLfloat CalfMaxRunningFrontTime, 
    GLfloat CalfMaxRunningBack, GLfloat CalfMaxRunningBackTime, GLfloat FootMaxRunningUp, 
    GLfloat FootMaxRunningUpTime, GLfloat FootMaxRunningDown, GLfloat FootMaxRunningDownTime, 
    GLfloat ToeMaxRunningUp, GLfloat ToeMaxRunningUpTime, GLfloat ToeMaxRunningDown, 
    GLfloat ToeMaxRunningDownTime, GLboolean ThighFrontRunSwitched, 
    GLboolean ThighBackRunSwitched, GLboolean CalfFrontRunSwitched, 
    GLboolean ThighBackRunSwitched, Glboolean FootUpRunSwitched, 
    Glboolean FootDownRunSwitched, Glboolean ToeUpRunSwitched, GLbooleanToeDownRunSwitched, 
    LegsMovingState legsMovingState, Point<GLfloat> ThighStoopAngle[2], 
    Point<GLfloat> CalfStoopAngle[2], Point<GLfloat> FootStoopAngle[2], Point<GLfloat> ToeStoopAngle[2]

Public Functions:
   Legs();

    /* StartWalkJogRunMovement immediately starts moving the legs for the particular motion. */
    Glboolean StartWalkJogRunMovement(Glfloat CurrentTime, LegsMovingState WhichMovingState);

    /* StopWalkJogRunMovement immediately stops moving the legs for the particular motion. */
    Glboolean StopWalkJogRunMovement(Glfloat CurrentTime, LegsMovingState WhichMovingState);

    /* AssumeStoopPos places the legs in the stoop position during the times provided. */
    Glboolean AssumeStoopPos(Glfloat StartTime, Glfloat EndTime, Glfloat CurrentTime);

    /* Rotate will rotate the designated Thigh in the direction provied.  Degrees > 0.0.  */ 
    GLboolean RotateThigh(ActorCommon::Side WhichSide, ActorCommon::Direction WhichDirection, 
                                                           GLfloat Degrees, GLfloat TimeToComplete, GLfloat CurrentTime);

     /* Rotate will rotate the designated Thigh to the Angle provied.  Degrees > 0.0.  */ 
    GLboolean RotateThigh(ActorCommon::Side WhichSide, const Point<GLfloat> &Angle, 
                                                           GLfloat TimeToComplete, GLfloat CurrentTime);

    /* Rotate will rotate the designated Calf in the direction provied.  Degrees > 0.0.  */ 
    GLboolean RotateCalf(ActorCommon::Side WhichSide, ActorCommon::Direction WhichDirection, 
                                                         GLfloat Degrees, GLfloat TimeToComplete, GLfloat CurrentTime);

    /* Rotate will rotate the designated Calf to the Angle provied.  */ 
    GLboolean RotateCalf(ActorCommon::Side WhichSide, const Point<GLfloat> &Angle, 
                                                         GLfloat TimeToComplete, GLfloat CurrentTime);

    /* Rotate will rotate the designated Foot in the direction provied.  Degrees > 0.0.  */ 
    GLboolean RotateFoot(ActorCommon::Side WhichSide, ActorCommon::Direction WhichDirection, 
                                                          GLfloat Degrees, GLfloat TimeToComplete, GLfloat CurrentTime);

     /* Rotate will rotate the designated Foot to the Angle provied.  */ 
    GLboolean RotateFoot(ActorCommon::Side WhichSide, const Point<GLfloat> &Angle, 
                                                            GLfloat TimeToComplete, GLfloat CurrentTime);

    /* Rotate will rotate the designated Toe in the direction provied.  Degrees > 0.0.  */ 
    GLboolean RotateToe(ActorCommon::Side WhichSide, ActorCommon::Direction WhichDirection, 
                                                       GLfloat Degrees, GLfloat TimeToComplete, GLfloat CurrentTime);

    /* Rotate will rotate the designated Toe the Angle provied.  */ 
    GLboolean RotateToe(ActorCommon::Side WhichSide, const Point<GLfloat> &Angle, 
                                                        GLfloat TimeToComplete,  GLfloat CurrentTime);

    /* Rest calls Legs::Rest below for both legs. */
    GLboolean Rest(GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* Rest calls PartCommon::Rest for the designated leg. */
    GLboolean Rest(ActorCommon::Side WhichSide, GLfloat StartTime, GLfloat EndTime, 
                                          GLfloat CurrentTime);

    /* Update updates both legs. */
    GLboolean Update(GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* Draw draws both legs. */
    void Draw(GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* GetAngle is used to get the MIN, MAX, REST or CURRENT angle for the specified part of the leg. */
    void GetAngle(PartCommon::WhichAngles WhichAngle, ActorGlobal::Parts WhichPart, 
                                      ActorCommon::Side WhichSide, Point<GLfloat> &Angle);

    /* SetAngle is used to set the MIN, MAX, REST or CURRENT angle for the specified part of the leg. */
    void SetAngle(PartCommon::WhichAngles WhichAngle, ActorGlobal::Parts WhichPart, 
                                     ActorCommon::Side WhichSide, Point<GLfloat> &Angle);

    /* GetOffset is used to get the offset for the specified part of the leg. */
    void GetOffset(ActorGlobal::Parts WhichPart, ActorCommon::Side WhichSide, Point<GLfloat> &offset);

    /* SetOffset is used to set the offset for the specified part of the leg. */
    void SetOffset(ActorGlobal::Parts WhichPart, ActorCommon::Side WhichSide, Point<GLfloat> &offset);

    /* GetVertex is used to get the vertex for the specified part of the leg. */
    void GetVertex(ActorGlobal::Parts WhichPart, ActorCommon::Side WhichSide, Point<GLfloat> &vertex);

    /* SetVertex is used to set the vertex for the specified part of the leg. */
    void SetVertex(ActorGlobal::Parts WhichPart, ActorCommon::Side WhichSide, Point<GLfloat> &vertex);

    /* GetNormal is used to get the normal for the specified part of the leg. */
    void GetNormal(ActorGlobal::Parts WhichPart, ActorCommon::Side WhichSide, Point<GLfloat> &normal);

    /* SetNormal is used to set the normal for the specified part of the leg. */
    void SetNormal(ActorGlobal::Parts WhichPart, ActorCommon::Side WhichSide, Point<GLfloat> &normal);

    /* Initializewill read the data from the file pointer to initialize the attributes of the legs.  The value for
     * ComputeNormals decides whether or not the normals read in from the file are valid.  If they aren't, then 
     * CalcNormals will be called within this function. 
     */
    GLboolean Initialize(FILE *InitFilePtr, GLboolean ComputeNormals=GL_TRUE);

    /* This fn will write the primitive data (vertices, normals, color, material, and transformation info) 
     * to the file pointed to by the file ptr.  The variable PrimitiveName is the descriptive name for this 
     * primitive - e.g., "Thigh".
     */
    GLboolean WriteDataToFile(FILE *OutFilePtr);

    /* CalcNormals will calculate the normals for both legs. */ 
    void CalcNormals();

    /* NegateNormals is used to change the sign of the legs' normals.  This may be useful since
     * CalcNormals may cause the normals to point in the wrong direction.
    */ 
    void NegateNormals();

Protected Functions:
    GLboolean UpdateWalkJogRunMovement(Glfloat CurrentTime, LegsMovingState WhichMovingState);
 


 
 
CLASS:  CaveActor
Inherited: public Head, public Neck, public Torso, public Arms, public Legs, public ActorGlobal

Defined Types: CAMovingState {CA_STANDING, CA_WALKING, CA_JOGGING,  CA_RUNNING},
    CAStoopState {CA_ERECT, CA_STOOPING}

Private Vars: RotationCtrl ActorRC, TranslationCtrl ActorTC, CAMovingState MovingState, 
    CAVELOCK ActorUpdateLock, Point<Glfloat> StoopOffset, CAStoopState StoopState, 
    Glboolean MovingAlongCubicPath, Glboolean RestAtEndOfPath

Public Functions:
    CaveActor(Glboolean isFemale);

    /* GetCurrentAngle gets the current angle of the actor's body. */
    void GetCurrentAngle(Point<GLfloat> &Angle);

    /* SetCurrentAngle sets the current angle of the actor's body. */
    void SetCurrentAngle(Point<GLfloat> &Angle);

    /* GetCurrentPosition gets the current position of the actor's body. */
    void GetCurrentPosition(Point<GLfloat> &Position);

    /* SetCurrentPosition sets the current position of the actor's body. */
    void SetCurrentPosition(Point<GLfloat> &Position);

    /* GetStoopOffset gets the stoop offset for the actor. */
    void GetStoopOffset(Point<GLfloat> &offset);

    /* SetStoopOffset sets the stoop offset for the actor. */
    void SetStoopOffset(Point<GLfloat> &offset);

    /* RotateFromTo constructs a curve for the object to rotate from the  StartAngle to the EndAngle. 
     * The object will start rotating at StartTime and quit rotating at EndTime.  GL_TRUE will be returned 
     * if the curve was constructed successfully.
     */
    GLboolean RotateFromTo(Point<GLfloat> &StartAngle, Point<GLfloat> &EndAngle, 
                                                                  GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* RotateFromCurrentTo constructs a curve for the object to rotate from the Current.x,y,z() angle to the
     * EndAngle.x,y,z().  The object will start rotating at StartTime and quit rotating at EndTime. 
     * GL_TRUE will be returned if the curve was constructed successfully.
     */
    GLboolean RotateFromCurrentTo(Point<GLfloat> &EndAngle, GLfloat StartTime, GLfloat EndTime,
                                                                                   GLfloat CurrentTime);

    /* RotateFromCurrent constructs a curve for the object to rotate from the Current.x,y,z() to
     * Current.x,y,z()+NumberOfDegrees.x,y,z().  The object will start rotating at StartTime and quit 
     * rotating at EndTime. GL_TRUE will be returned if the curve was constructed successfully. 
     */
    GLboolean RotateFromCurrent(Point<GLfloat> &NumberOfDegrees, GLfloat StartTime, 
                                                                             GLfloat EndTime, GLfloat CurrentTime);

    /* WalkFromTo sets a linear path for the actor to walk.  GL_TRUE is returned if the path was set up 
     * correctly, else GL_FALSE is  returned.
     */
    GLboolean WalkFromTo(Point<GLfloat> &StartPoint, Point<GLfloat> &EndPoint, GLfloat StartTime, 
                                                               GLfloat EndTime, GLfloat CurrentTime);

    /* JogFromTo sets a linear path for the actor to jog.  GL_TRUE is returned if the path was set up 
     * correctly, else GL_FALSE is returned.
     */
    GLboolean JogFromTo(Point<GLfloat> &StartPoint, Point<GLfloat> &EndPoint, GLfloat StartTime, 
                                                           GLfloat EndTime,  GLfloat CurrentTime);

    /* RunFromTo sets a linear path for the actor to run.  GL_TRUE is returned if the path was set up 
     * correctly, else GL_FALSE is  returned.
     */
    GLboolean RunFromTo(Point<GLfloat> &StartPoint, Point<GLfloat> &EndPoint, GLfloat StartTime, 
                                                            GLfloat EndTime,  GLfloat CurrentTime);

    /* Walk sets up a cubic path for the actor to walk.  This fn returns GL_TRUE if the path was set 
     * properly, else it returns GL_FALSE.  REMEMBER: Time1 < Time2 < Time3 < Time4.
     */
    GLboolean WalkPath(Point<GLfloat> &CP1, Point<GLfloat> &CP2, Point<GLfloat> &CP3, 
                                                      Point<GLfloat> &CP4, GLfloat CPTimes[4], GLfloat CurrentTime);

    /* Jog sets up a cubic path for the actor to jog. This fn returns GL_TRUE if the path was set properly, 
     * else it returns GL_FALSE.  REMEMBER: Time1 < Time2 < Time3 < Time4.
     */
    GLboolean JogPath(Point<GLfloat> &CP1, Point<GLfloat> &CP2, Point<GLfloat> &CP3, 
                                                  Point<GLfloat> &CP4, GLfloat CPTimes[4], GLfloat CurrentTime);

    /* Run sets up a cubic path for the actor to run.  This fn returns GL_TRUE if the path was set properly, 
     * else it returns GL_FALSE.  REMEMBER: Time1 < Time2 < Time3 < Time4.
     */
    GLboolean RunPath(Point<GLfloat> &CP1, Point<GLfloat> &CP2, Point<GLfloat> &CP3, 
                                                   Point<GLfloat> &CP4, GLfloat CPTimes[4], GLfloat CurrentTime);

    /* PointAt makes the actor point at a point in space.  If the point is out of direct viewing range, then it 
     * will turn its body around to face the point.  GL_TRUE is returned if the path was set up correctly 
     * AND the actor can actually rotate to a position to see the point, else  GL_FALSE is returned.
     */
    GLboolean PointAt(Point<GLfloat> &Location, GLfloat StartTime, GLfloat EndTime, 
                                                  GLfloat CurrentTime);

    /* FacePt makes the actor look in a direction.  If the point is out of direct viewing range, then it will 
     * turn its body around  to face the point.  GL_TRUE is returned if the path was set up correctly AND 
     * the actor can actually  rotate to a position to see the point, else GL_FALSE is returned.
     */
    GLboolean FacePoint(Point<GLfloat> &Location, GLfloat StartTime, GLfloat EndTime, 
                                                       GLfloat CurrentTime);

    /* LookAt makes the actor look at a point in space.  If the point is out of direct viewing range, then it 
     * will turn its body around to face the point.  GL_TRUE is returned if the path was set up correctly 
     * AND the actor can actually rotate to a position to see the point, else  GL_FALSE is returned.
     */
    GLboolean LookAt(Point<GLfloat> &Location, GLfloat StartTime, GLfloat EndTime, 
                                                 GLfloat CurrentTime);

    /* LookAtTrackedUser makes the actor look at a point in space.  If the point is out of direct viewing 
     * range, then it will turn its body around to face the point.  GL_TRUE is returned if the path was set up 
     * correctly AND the actor can actually rotate to a position to see the point, else GL_FALSE is returned.
     */
    GLboolean LookAtTrackedUser(GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* Stoop places the actor in the stoop position. */
    GLboolean Stoop(GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* Rest places the whole body at rest. */
    GLboolean Rest(GLfloat StartTime, GLfloat EndTime, GLfloat CurrentTime);

    /* Calls Update for every part of the body. */
    void UpdateActor(Glfloat CurrentTime);

    /* Draws the entire body. */
    void DrawActor();

    /* This fn is used to compute the translation of the primitive from where it was created to where it 
     * should be for the body. 
     */
    void ComputeOffset(ActorGlobal::Parts WhichPart);

    /* This fn is used to set the translation of the primitive from where it was created to where it should be 
     * for the body. 
     */
    void ComputeOffset(ActorGlobal::Parts WhichPart, ActorCommon::Side WhichSide);

    /* Used to initialize the body by reading in a set of coords and colors for each part. Pass GL_TRUE 
     * if initializing just verts and colors. Passing GL_TRUE will calculate the normals for each part of 
     * the body.  Pass GL_FALSE if initializing  verts, normals, and colors.  NOTE: the file pointer must 
     * point to the appropriate file type (i.e., A file must contain just the information you're reading in.).
     */
    GLboolean Initialize(char *FilenameForBodyData, Glboolean DontCalcNormals);

    /* FreeMemory  frees all shared memory allocated for the actor. */
    void FreeMemory();

    /* This fn will write all actor data (vertices, normals, color, material, and transformation info) to the file. */
    GLboolean WriteDataToFile(char *Filename);