// ==========================================================================
// MAKE_FACE_C
// =============================================================================
//
// FUNCTION NAMES
//
// face_reset -- reset the face to neutral.
// create_face -- creates the face data
// create_face -- returns a pointer to the head data structure.
// make_face -- makes a face from the two input files.
// add_polygon_to_face -- adds a polygon to the face data structure.
// reflect_polygon -- reflect a polygon in the Y axis.
// void averaged_vertex_normals -- compute the average vertex normals.
// data_struct -- create the datastructure for the face.
// calculate_minmax -- calculates the geometry min maxes
// calculate_texture_coords -- calculates the texture coordinates
// fix_eyelids -- fix the eyelids so they fit to the cornea
// make_jawpointers -- create explicit pointers to the jaw nodes.
// add_jaw_tag -- add a tag/pointer to a the list of jaw tags
// rotate_jaw -- rotate the jaw by a specified angle.
// C SPECIFICATIONS
//
// void face_reset ( HEAD *face )
// HEAD *create_face ( char *f1, char *f2 )
// HEAD *create_face ( f1, f2 )
// make_face ( HEAD *face )
// add_polygon_to_face ( POLYGON *p, HEAD *face )
// reflect_polygon ( POLYGON *poly, HEAD *face )
// void averaged_vertex_normals ( HEAD *face, int p,
// float *n1, float *n2, float *n3 )
// data_struct ( HEAD *face )
// calculate_minmax ( HEAD *face )
// calculate_texture_coords ( HEAD *face )
// fix_eyelids ( HEAD *face, float, float, float )
// make_jawpointers ( HEAD *face, int start, int end )
// add_jaw_tag ( HEAD *face, TAG *t, int p, int v )
// rotate_jaw ( HEAD *face, float angle )
// DESCRIPTION
//
// This module is where the face data structures are created.
// This module comes as is with no warranties.
//
// HISTORY
// 16-Dec-94 Keith Waters (waters@crl.dec.com) Created at Digital Equipment
// Cambridge Research Labatory
// 10-Aug-98 Keith Waters (waters@crl.dec.com) Modified for OpenGL on W95 and
// WNT at Compaq Cambridge Research Laboratory
// 02-Dec-98 Keith Waters (waters@crl.dec.com) Added eyes, texture mapping and
// basic jaw articulation.
//
//============================================================================
#include <math.h> // C header for any math functions
#include <stdio.h> // C header for standard I/O
#include "memory.h" // Local memory allocation macros
#include "head.h" // local header for the face
void read_polygon_line ( char*, HEAD* ) ;
void read_polygon_indices ( char*, HEAD* ) ;
void make_face ( HEAD* ) ;
void add_polygon_to_face ( POLYGON*, HEAD* ) ;
void reflect_polygon ( POLYGON*, HEAD* ) ;
void data_struct ( HEAD* );
void activate_muscle ( HEAD*, float*, float*, float, float, float, float ) ;
void calculate_minmax ( HEAD * ) ;
void calculate_texture_coords ( HEAD * ) ;
void calculate_eye_texture_coords ( HEAD * ) ;
void make_eyes ( HEAD *, float, float, float ) ;
void fix_eyelids ( HEAD *, float, float, float ) ;
void make_jawpointers ( HEAD *face, int start, int end ) ;
void add_jaw_tag ( HEAD *face, TAG *t, int p, int v ) ;
void rotate_jaw ( HEAD *face, float angle ) ;
#define DTOR(deg) ((deg)*0.017453292) // degrees to radians Opps! defined in muscle.c as well.
// =========================================================================
// face_reset
// =========================================================================
//
// Resets the geometry of the face to neutral.
//
void face_reset ( HEAD *face )
{
int i,j,k ;
for ( i=0; i<face->npolygons; i++ ) {
for ( j=0; j<3; j++ ) {
for ( k=0; k<3; k++ ) {
face->polygon[i]->vertex[j]->xyz[k] = face->polygon[i]->vertex[j]->nxyz[k] ;
}
}
}
// Reset the jaw.
face->absjawang = 0.0 ;
}
// =========================================================================
// calculate_minmax
// =========================================================================
//
// Calculates the minmax for the face geometry.
//
void calculate_minmax ( HEAD *face )
{
int i,j ;
// Set the min max values
face->minx = face->miny = 10000.0f;
face->maxx = face->maxy = -10000.0f ;
for ( i=0; i<face->npolygons; i++ ) {
for ( j=0; j<3; j++ ) {
// Check the min maxes
if ( face->polygon[i]->vertex[j]->xyz[0] < face->minx ) face->minx = face->polygon[i]->vertex[j]->xyz[0] ;
if ( face->polygon[i]->vertex[j]->xyz[0] > face->maxx ) face->maxx = face->polygon[i]->vertex[j]->xyz[0] ;
if ( face->polygon[i]->vertex[j]->xyz[1] < face->miny ) face->miny = face->polygon[i]->vertex[j]->xyz[1] ;
if ( face->polygon[i]->vertex[j]->xyz[1] > face->maxy ) face->maxy = face->polygon[i]->vertex[j]->xyz[1] ;
}
}
fprintf ( stderr, "Minx: %2.2f Maxx: %2.2f Miny: %2.2f Maxy: %2.2f\n", face->minx, face->maxx, face->miny, face->maxy ) ;
}
// =========================================================================
// create_face
// =========================================================================
//
// create the default structures for the face and retrun a pointer.
//
HEAD *create_face ( char *f1, char *f2 )
{
HEAD *h ;
h = _new ( HEAD ) ;
// Initialization
h->npolygons = 0 ;
h->npindices = 0 ;
h->npolylinenodes = 0 ;
h->nmuscles = 0 ;
h->current_muscle = 0 ;
h->current_exp = 0 ;
h->rendermode = 0 ;
h->currentnode = 0 ;
h->nleyepolygons = 0 ;
h->nreyepolygons = 0 ;
h->jawang = 0.0 ;
h->absjawang = 0.0 ;
read_polygon_indices ( f1, h ) ;
read_polygon_line ( f2, h ) ;
// Set the eye radius
h->eyeradius = 1.35 ;
make_eyes ( h, 0.0, 0.0, 0.0 ) ;
fix_eyelids ( h, 2.0, 2.8, 6.5 ) ;
make_face ( h ) ;
make_jawpointers ( h, 0, 58 ) ;
calculate_minmax ( h ) ;
calculate_texture_coords ( h ) ;
calculate_eye_texture_coords ( h ) ;
return ( h ) ;
}
// =========================================================================
// fix_eyelids
// =========================================================================
//
// Fix the eyelids so the fit the cornea.
//
#define EYELIDSTARTNODE 244
#define EYELIDENDNODE 251
void fix_eyelids ( HEAD *face, float eyex, float eyey, float eyez )
{
int i ;
float erad, xval ;
erad = face->eyeradius * face->eyeradius ;
// Yeah, yeah I know. Fixed constants in the code! Bar humbug!
// This is face->npolylinenodes because it's the last nodes in
// the face ployline that represent the face.
for ( i= EYELIDSTARTNODE; i< face->npolylinenodes; i++ ) {
// grab the x component. eyex is the x displacement of the eyeballs
xval = eyex - ((fabs)(face->polyline[i*3])) ;
// Fix up the Z coordinate only
face->polyline[i*3+2] = sqrt ((double)
( (fabs) (erad - (xval * xval)) )) ;
// This is the Z displacement for the eyeballs
face->polyline[i*3+2] += eyez ;
// Close the top eyelid some
if (i >= EYELIDSTARTNODE && i < EYELIDENDNODE )
face->polyline[i*3+1] -= 0.15 ;
}
}
// ================================
- 1
- 2
- 3
- 4
前往页