make_face.c
上传用户:xk288cn
上传日期:2007-05-28
资源大小:4876k
文件大小:14k
- /* ==========================================================================
- 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 datastructure.
- 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.
- 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 )
- DESCRIPTION
- This module is where the face data structures are created.
- T his module comes as is with no warranties.
- HISTORY
- 16-Dec-94 Keith Waters (waters) at DEC's Cambridge Research Lab
- Created.
- Modified 22-Nov-96 Sing Bing Kang (sbk@crl.dec.com)
- Added function expressions() to enable changing facial expression
- ============================================================================ */
- #include <math.h> /* C header for any math functions */
- #include <stdio.h> /* C header for standard I/O */
- #include <string.h> /* For String compare */
- #include <stdlib.h>
- #ifndef _WIN32
- #include <sys/types.h>
- #include <sys/file.h>
- #endif
- #include "memory.h" /* Local memory allocation macros */
- #include "head.h" /* local header for the face */
- void reflect_polygon ( POLYGON *poly, HEAD *face );
- void add_polygon_to_face ( POLYGON *p, HEAD *face );
- void make_face ( HEAD *face );
- /* ========================================================================= */
- /* 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] ;
- }
- }
- }
- }
- /* =========================================================================
- expressions
- Written by: Sing Bing Kang
- Date: 11/22/96
- ========================================================================= */
- /*
- ** Produces the facial expressions as indicated by the muscle contraction
- ** vector
- **
- */
- void
- expressions ( HEAD *face, int e )
- {
- int m;
- fprintf( stderr, "Expression: %sn", face->expression[e]->name );
- for (m=0; m<face->nmuscles; m++) {
- float m_val = face->expression[e]->m[m],
- m_diff = m_val - face->muscle[m]->mstat;
- face->muscle[m]->mstat = m_val;
- activate_muscle ( face,
- face->muscle[m]->head,
- face->muscle[m]->tail,
- face->muscle[m]->fs,
- face->muscle[m]->fe,
- face->muscle[m]->zone,
- m_diff ) ;
- }
- }
- /* ========================================================================= */
- /* 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 ) ;
-
- h->npolygons = 0 ;
- h->npindices = 0 ;
- h->npolylinenodes = 0 ;
- h->nmuscles = 0 ;
- read_polygon_indices ( f1, h ) ;
- read_polygon_line ( f2, h ) ;
- make_face ( h ) ;
-
- return ( h ) ;
- }
- /* ========================================================================= */
- /* make_face */
- /* ========================================================================= */
- /*
- ** makes the face from the two input files.
- **
- */
- void
- make_face ( HEAD *face )
- {
- POLYGON *p ;
- int i, ii, j, k,
- p1, p2, p3, p4 ;
- int parray[4] ;
- for ( i=0, ii=0; i < face->npindices; i++,ii+=4 ) {
- p1 = face->indexlist[ii] -1 ;
- p2 = face->indexlist[ii+1] -1 ;
- p3 = face->indexlist[ii+2] -1 ;
- p4 = face->indexlist[ii+3] -1 ;
- for (j=0; j<4; j++)
- parray[j] = face->indexlist[ii+j] -1;
- if ( p1 == 999 ) {
- p = _new ( POLYGON ) ;
- for (j=0; j<3; j++) {
- p->vertex[j] = _new ( VERTEX ) ;
- p->vertex[j]->np = 0 ;
- }
- for (j=0; j<3; j++)
- p->vertex[0]->nxyz[j] =
- p->vertex[0]->xyz[j] = face->polyline[ p2*3 + j ] ;
-
- for (j=0; j<3; j++)
- p->vertex[1]->nxyz[j] =
- p->vertex[1]->xyz[j] = face->polyline[ p3*3 + j ] ;
-
- for (j=0; j<3; j++)
- p->vertex[2]->nxyz[j] =
- p->vertex[2]->xyz[j] = face->polyline[ p4*3 + j ] ;
- add_polygon_to_face ( p, face ) ;
- reflect_polygon ( p, face ) ;
- }
- else {
- p = _new ( POLYGON ) ;
- for (j=0; j<3; j++) {
- p->vertex[j] = _new ( VERTEX ) ;
- p->vertex[j]->np = 0 ;
- }
- for (k=0; k<3; k++) {
- for (j=0; j<3; j++)
- p->vertex[k]->nxyz[j] =
- p->vertex[k]->xyz[j] = face->polyline[ parray[k]*3 + j ] ;
- }
- add_polygon_to_face ( p, face ) ;
- reflect_polygon ( p, face ) ;
- p = _new ( POLYGON ) ;
- for (j=0; j<3; j++) {
- p->vertex[j] = _new ( VERTEX ) ;
- p->vertex[j]->np = 0 ;
- }
- for (j=0; j<3; j++)
- p->vertex[0]->nxyz[j] =
- p->vertex[0]->xyz[j] = face->polyline[ p1*3 + j ] ;
-
- for (j=0; j<3; j++)
- p->vertex[1]->nxyz[j] =
- p->vertex[1]->xyz[j] = face->polyline[ p3*3 + j ] ;
-
- for (j=0; j<3; j++)
- p->vertex[2]->nxyz[j] =
- p->vertex[2]->xyz[j] = face->polyline[ p4*3 + j ] ;
- add_polygon_to_face ( p, face ) ;
- reflect_polygon ( p, face ) ;
- }
- }
- }
- /* ========================================================================= */
- /* add_polygon_to_face */
- /* ========================================================================= */
- /*
- ** add a polygon to the face structure.
- **
- */
- void
- add_polygon_to_face ( POLYGON *p, HEAD *face )
- {
- int nn ;
- if(face->npolygons == 0)
- face->polygon = _new_array(POLYGON *, 500) ;
- else if(face->npolygons % 500 == 0)
- face->polygon = _resize_array(face->polygon,POLYGON *,face->npolygons+500) ;
- nn = face->npolygons ;
- face->polygon[nn] = p ;
- face->npolygons++ ;
- }
- /* ========================================================================= */
- /* reflect_polygon */
- /* ========================================================================= */
- /*
- ** Reflects all the polygons in the half-face and adds them to
- ** the data structure.
- **
- */
- void
- reflect_polygon ( POLYGON *poly, HEAD *face )
- {
- POLYGON *newp ;
- float temp[3] ;
- int i, j ;
-
- /*
- * Allocate memory for the new polygon.
- */
- newp = _new ( POLYGON ) ;
- for (j=0; j<3; j++) {
- newp->vertex[j] = _new ( VERTEX ) ;
- newp->vertex[j]->np = 0 ;
- }
- /*
- * Load the old polygon values.
- */
- for (i=0; i<3; i++)
- for (j=0; j<3; j++)
- newp->vertex[i]->nxyz[j] =
- newp->vertex[i]->xyz[j] = poly->vertex[i]->xyz[j] ;
- /*
- * flip the X component.
- */
- for (i=0; i<3; i++)
- newp->vertex[i]->nxyz[0] =
- newp->vertex[i]->xyz[0] = -newp->vertex[i]->xyz[0] ;
-
- /*
- * Re-order the vertices, flip 0 and 1.
- */
- for (j=0; j<3; j++)
- temp[j] = newp->vertex[0]->xyz[j] ;
- for (j=0; j<3; j++)
- newp->vertex[0]->nxyz[j] =
- newp->vertex[0]->xyz[j] = newp->vertex[1]->xyz[j];
- for (j=0; j<3; j++)
- newp->vertex[1]->nxyz[j] =
- newp->vertex[1]->xyz[j] = temp[j] ;
- add_polygon_to_face ( newp, face ) ;
- }
- /* ========================================================================= */
- /* averaged_vertex_normals */
- /* ========================================================================= */
- /*
- ** Caculates the averaged polygon normal.
- */
- void averaged_vertex_normals ( HEAD *face, int p, float *n1, float *n2, float *n3 )
- {
- int i,j,np, pt ;
- float norm[3] ;
- for (i=0; i<3; i++)
- norm[i] = 0.0 ;
- np = face->polygon[p]->vertex[0]->np ;
- for ( i=0; i<np; i++) {
- pt = face->polygon[p]->vertex[0]->plist[i] ;
- for ( j=0; j<3; j++) {
- norm[j] += face->polygon[pt]->vertex[0]->norm[j] ;
- }
- }
- for (i=0; i<3; i++)
- norm[i] = norm[i] / (float)np ;
-
- for (i=0; i<3; i++)
- n1[i] = norm[i] ;
- for (i=0; i<3; i++)
- norm[i] = 0.0 ;
- np = face->polygon[p]->vertex[1]->np ;
- for ( i=0; i<np; i++) {
- pt = face->polygon[p]->vertex[1]->plist[i] ;
- for ( j=0; j<3; j++) {
- norm[j] += face->polygon[pt]->vertex[1]->norm[j] ;
- }
- }
- for (i=0; i<3; i++)
- norm[i] = norm[i] / (float) np ;
- for (i=0; i<3; i++)
- n2[i] = norm[i] ;
- for (i=0; i<3; i++)
- norm[i] = 0.0 ;
- np = face->polygon[p]->vertex[2]->np ;
- for ( i=0; i<np; i++) {
- pt = face->polygon[p]->vertex[2]->plist[i] ;
- for ( j=0; j<3; j++) {
- norm[j] += face->polygon[pt]->vertex[2]->norm[j] ;
- }
- }
- for (i=0; i<3; i++)
- norm[i] = norm[i]/ (float) np ;
-
- for (i=0; i<3; i++)
- n3[i] = norm[i] ;
-
- }
- /* ========================================================================= */
- /* data_struct */
- /* ========================================================================= */
- /*
- ** Create a new data structure for the polygons.
- **
- */
- #define DATA_STRUCT_DEBUG 0
- void
- data_struct ( HEAD *face )
- {
- int i,j, n ;
- int flag, cptr ;
- float x1,y1,z1, x2, y2, z2, x3, y3, z3 ;
- float tx1, ty1, tz1, tx2, ty2, tz2, tx3, ty3, tz3 ;
- for (i=0; i<face->npolygons; i++ ){
- x1 = face->polygon[i]->vertex[0]->xyz[0] ;
- y1 = face->polygon[i]->vertex[0]->xyz[1] ;
- z1 = face->polygon[i]->vertex[0]->xyz[2] ;
- x2 = face->polygon[i]->vertex[1]->xyz[0] ;
- y2 = face->polygon[i]->vertex[1]->xyz[1] ;
- z2 = face->polygon[i]->vertex[1]->xyz[2] ;
- x3 = face->polygon[i]->vertex[2]->xyz[0] ;
- y3 = face->polygon[i]->vertex[2]->xyz[1] ;
- z3 = face->polygon[i]->vertex[2]->xyz[2] ;
- #if DATA_STRUCT_DEBUG
- fprintf (stderr,"BASE polygon: %dn", i) ;
- fprintf (stderr,"x1: %f y1: %f z1: %fn", x1,y1,z1) ;
- fprintf (stderr,"x1: %f y1: %f z1: %fn", x2,y2,z2) ;
- fprintf (stderr,"x1: %f y1: %f z1: %fn", x3,y3,z3) ;
- #endif
- j = 0 ;
- flag = 0 ;
- while ( !flag &&
- j<face->npolygons ) {
- tx1 = face->polygon[j]->vertex[0]->xyz[0] ;
- ty1 = face->polygon[j]->vertex[0]->xyz[1] ;
- tz1 = face->polygon[j]->vertex[0]->xyz[2] ;
- tx2 = face->polygon[j]->vertex[1]->xyz[0] ;
- ty2 = face->polygon[j]->vertex[1]->xyz[1] ;
- tz2 = face->polygon[j]->vertex[1]->xyz[2] ;
- tx3 = face->polygon[j]->vertex[2]->xyz[0] ;
- ty3 = face->polygon[j]->vertex[2]->xyz[1] ;
- tz3 = face->polygon[j]->vertex[2]->xyz[2] ;
- #if DATA_STRUCT_DEBUG
- fprintf (stderr, "COMPARED TO polygon: %dn", j) ;
- fprintf (stderr,"tx1: %f ty1: %f tz1: %fn", tx1,ty1,tz1) ;
- fprintf (stderr,"tx1: %f ty1: %f tz1: %fn", tx2,ty2,tz2) ;
- fprintf (stderr,"tx1: %f ty1: %f tz1: %fn", tx3,ty3,tz3) ;
- #endif
- if ( (x1 == tx1 && y1 == ty1 && z1 == tz1) ||
- (x1 == tx2 && y1 == ty2 && z1 == tz2) ||
- (x1 == tx3 && y1 == ty3 && z1 == tz3)) {
- cptr = j ;
- #if DATA_STRUCT_DEBUG
- fprintf (stderr,"found a vertex match on polygon: %d and %dn", i,j);
- #endif
- n = face->polygon[i]->vertex[0]->np ;
- face->polygon[i]->vertex[0]->plist[n] = cptr ;
- face->polygon[i]->vertex[0]->np++ ;
- #if DATA_STRUCT_DEBUG
- fprintf (stderr,"loaded: %d onto polygon: %d vertex[0]n", cptr, i) ;
- fprintf (stderr,"total on vertex: %dn", face->polygon[i]->vertex[0]->np);
- #endif
- }
- j++ ;
- } /* end while */
- j = 0 ;
- flag = 0 ;
- while ( !flag &&
- j<face->npolygons ) {
- tx1 = face->polygon[j]->vertex[0]->xyz[0] ;
- ty1 = face->polygon[j]->vertex[0]->xyz[1] ;
- tz1 = face->polygon[j]->vertex[0]->xyz[2] ;
- tx2 = face->polygon[j]->vertex[1]->xyz[0] ;
- ty2 = face->polygon[j]->vertex[1]->xyz[1] ;
- tz2 = face->polygon[j]->vertex[1]->xyz[2] ;
- tx3 = face->polygon[j]->vertex[2]->xyz[0] ;
- ty3 = face->polygon[j]->vertex[2]->xyz[1] ;
- tz3 = face->polygon[j]->vertex[2]->xyz[2] ;
- if ( (x2 == tx1 && y2 == ty1 && z2 == tz1) ||
- (x2 == tx2 && y2 == ty2 && z2 == tz2) ||
- (x2 == tx3 && y2 == ty3 && z2 == tz3)) {
- cptr = j ;
- n = face->polygon[i]->vertex[1]->np ;
- face->polygon[i]->vertex[1]->plist[n] = j ;
- face->polygon[i]->vertex[1]->np++ ;
- }
- j++ ;
- } /* end while */
- j = 0 ;
- flag = 0 ;
- while ( !flag &&
- j<face->npolygons ) {
- tx1 = face->polygon[j]->vertex[0]->xyz[0] ;
- ty1 = face->polygon[j]->vertex[0]->xyz[1] ;
- tz1 = face->polygon[j]->vertex[0]->xyz[2] ;
- tx2 = face->polygon[j]->vertex[1]->xyz[0] ;
- ty2 = face->polygon[j]->vertex[1]->xyz[1] ;
- tz2 = face->polygon[j]->vertex[1]->xyz[2] ;
- tx3 = face->polygon[j]->vertex[2]->xyz[0] ;
- ty3 = face->polygon[j]->vertex[2]->xyz[1] ;
- tz3 = face->polygon[j]->vertex[2]->xyz[2] ;
- if ( x3 == tx1 && y3 == ty1 && z3 == tz1 ||
- x3 == tx2 && y3 == ty2 && z3 == tz2 ||
- x3 == tx3 && y3 == ty3 && z3 == tz3) {
- cptr = j ;
- n = face->polygon[i]->vertex[2]->np ;
- face->polygon[i]->vertex[2]->plist[n] = cptr ;
- face->polygon[i]->vertex[2]->np++ ;
- }
- j++ ;
- } /* end while */
- } /* end for i */
- }