/***********************************************************
/* A program to generate symbolic walkers as dynamic, three dimensional /* color graphic displays. We, the viewers, move into the seen in a
/* straight line, while our "gaze" is on this walker
/*
/*
/* The basis for this code was a program written by James E. Cutting,
/* published in Behavior Research Methods & Instrumentation (1978, Vol. /* 10 (1), 91-94), under the * title of "A program to generate synthetic /* walkers as * dynamic point-light displays." The orginal program was * /* written in FORTAN 77 on a 32K Hewlett-Packard HP-100 * L-Series P /* for a Tektronix 604 monitor display driven by a Data General Nova.
/*
/* Modifications by J.E.C. beginning 23 Sept 91
/* latest 18 Mar 92, Laurence Kaplan adaptation
/*
/***********************************************************/
/* attach the code to the 'C' libraries it requires */ #include <stdio.h>
/* standard input & output */
#include <values.h>
#include <gl.h> /* graphics library */
#include <math.h> /* math functions */
#include <device.h> /* interactive device */
#include <time.h>
#include <sys/types.h> /* } */
#include <sys/times.h>
#include <sys/time.h> /* } time/timing functions */
#include <sys/param.h> /* } */
#include <fmclient.h>
/* define the global constants */
/* math */
#define PI 3.1415926
#define RAD 0.017453292 /* degree to radian conversion constant */
#define DEG 57.29577951 /* radian to degree conversion constant */
/* body */
#define TORSO 85.0 /* height or length of torso */
#define SW 25.0 /* shoulder width */
#define HW 15.0 /* hip width */
/* walker object */
#define NUM_STEPS 6 /* number of steps to be taken by walker */
#define Z1 0.0 /* where in z-plane walker is to walk */
/* colors */
#define GROUND 1 /* color of ground plane in bkgnd scenery */
#define FIXTREE 9
#define TREECOLOR 10
/* viewing */
#define VISANG 300 /* cone of vision */
#define EYE_HT 255.0
/* forest */
#define NUMTR 60
#define NTRI 9 /* 8 plus 1 */
/* declare global variables */
/* the coords for cube object from which walker is created */
long side[6][4][3] ={{-1,-1,1}, {1,-1,1}, {1,1,1}, {-1,1,1},
{1,-1,1}, {1,-1,-1}, {1,1,-1}, {1,1,1},
{1,-1,-1}, {-1,-1,-1}, {-1,1,-1}, {1,1,-1},
{-1,-1,-1}, {-1,-1,1}, {-1,1,1}, {-1,1,-1},
{-1,1,1}, {1,1,1}, {1,1,-1}, {-1,1,-1},
{-1,-1,-1}, {1,-1,-1}, {1,-1,1}, {-1,-1,1}};
/* variables used by time functions */
struct tms t1;
long time1,time2;
double tim, starttim;
struct timeval tp;
struct timezone tzp;
float x,y,z,xx,zz,xx1,zz1;
int REDO,TRI,RESP,SDIR,SX,SZ,GRID,TREES,INCR,t,tt,tmod,j,OUT; char fname[20];
FILE *fp,*fopen();
Coord rno[NUMTR][3];
int afile[NTRI][6];
int tord[NTRI];
int tinfo[NTRI][3] ={0,0,0,
/* x z angle */
-4943, 0, 0,
/* in front and behind */
4943, 0, 180,
0, -4943, 90,
/*on either side*/
0, 4943, 270,
3445, -3445, 135,
/*in front and to the side*/
3445, 3445, 225,
-3445, -3445, 45,
/*behind and to the side*/
-3445, 3445, 315};
/* the graphical objects that make up the walker and scenery */ Object cube,Groundplane,Floorgrid,Tree1,Cylinder;
/***************************************************************************
* MAIN function/procedure of the program *
***************************************************************************/ main () {
/* declare functions */
void initialize_variables (),
setup_windows_graphics_devices (),
setup_underdraw(),
make_objects (),
ankle_table (),
get_hips (),
get_ankles (),
get_shoulders (),
get_wrists (),
get_knees (),
get_elbows (),
get_midpoint (),
clear_screen (),
draw_corpse (),
draw_head (),
draw_part (),
draw_torso (),
get_angle (),
locomotion (),
stop_and_wait (),
clean_up ();
/* declare variables */
float humor,ulna,tibia,femur,leg, /* lengths of body parts */
step, hstep, /* length of step, half-step */ hex, hey, /* hip ellipses, x&y axes */
sex, sey, /* shoulder ellipses,x&y-axes*/
sher, /* shoulder excursion as multiple of hip */
time, /* cmsec per frame */
bounce, /* up & down mvt of body */
swf, /* femur swing */
swh, /* humor swing, f(sholder swing&step */
swu, /* ulna swing */
swt, /* tibia swing, 25=atan(foot/tibia) */
femfo, /* forward tilt of femur pendulum */
delay, /* degrees pre- and post-femur swing that tibia
swings due to foot & to compound pendulum */
cosff, /* y correction for hip */
xlean, ylean, /* upper body lean, f(speed), 2 deg modal */ xinit, yinit, /* initial x & y values in screen units */ falfo, /* mvt falling forwards w/in overlay period
due to tibia swing and foot */
sia[541]; /* ankle table, broad w-shaped, 0-540 deg. */
int ip, ist; /* used for SWAPINTERVAL */
char ss[10];
int c,k;
fmfonthandle f;
fmfonthandle fsized;
/* printf("filename = ");
scanf("%s",fname);
*/
/* main routines */
/* initialize the variables */
initialize_variables (&humor,&ulna,&femur,&tibia,&leg,&step,
&sher,&time,&hex,&hey,&sex,&sey,&swf,&swh, &swu,&swt,&hstep,&bounce,&delay,&xlean,&ylean, &xinit,&yinit,&falfo,&femfo,&cosff,&ip,&ist);
/* set up the windows, the graphics configuration, objects, etc. */ setup_windows_graphics_devices ();
/* generate the ankle table */
ankle_table (delay,sia);
rnorder();
/*for (t=1; t<NTRI; t++) printf("%5d",tord[t]);*/ color(BLACK);
clear();
swapbuffers();
for (TRI=1; TRI<NTRI; TRI++){
frontbuffer(TRUE);
color(WHITE);
ortho2 (0,1280,0,1009);
cmov2i(520,530);
sprintf(ss,"%d",TRI);
fminit();
f = fmfindfont("Times-Roman");
fsized = fmscalefont(f,36);
fmsetfont(fsized);
fmprstr("TRIAL");
cmov2i(700,530);
fmprstr(ss);
sleep(1);
frontbuffer(FALSE);
if (REDO == 0)
generatecoords();
qreset();
/* main loop(s) for the walker(s) */
t=tord[TRI];
xx=tinfo[t][0];
zz=tinfo[t][1];
SDIR=tinfo[t][2];
setup_underdraw();
locomotion (humor,ulna,femur,tibia,leg,step,
sher,time,hex,hey,sex,sey,swf,swh,
swu,swt,hstep,bounce,delay,xlean,ylean,
xinit,yinit,falfo,femfo,cosff,sia,ip,ist);
/* clean up the underlay plane so desktop/workspace isn't messed up */
qreset ();
while(qtest()) {}
processinput();
clean_up ();
clearscreen();
swapbuffers();
qreset();
sleep(1);
if (OUT == 1)
break;
afile[t][0]=xx;
afile[t][1]=zz;
afile[t][2]=SDIR;
afile[t][3]=RESP;
afile[t][4]=1;
if(t%2==(RESP-1)) afile[t][4]=0;
/* printf("%3d %3d ",TRI,t);
for (j=0; j<5; j++)
printf("%6d",afile[t][j]);
printf("\n");
*/
}
fp=fopen(fname,"w");
for (TRI=1; TRI<NTRI; TRI++){
for (j=0; j<5; j++)
fprintf(fp,"%6d",afile[TRI][j]);
fprintf(fp,"\n");
}
fclose(fp);
clearscreen ();
clear ();
}
/*********************************************************************
/* initialize the variables *
**********************************************************************void initialize_variables (humor,ulna,femur,tibia,leg,step,
sher,time,hex,hey,sex,sey,swf,swh,
swu,swt,hstep,bounce,delay,xlean,ylean,
xinit,yinit,falfo,femfo,cosff,ip,ist)
/* all of these values are R/W, and are explained in declarations above */
float *humor,*ulna,*femur,*tibia,*leg,*step,*sher,
*time,*hex,*hey,*sex,*sey,*swf,*swh,*swu,*swt, *hstep,*bounce,*delay,*xlean,*ylean,*xinit,*yinit, *falfo,*femfo,*cosff;
int *ip,*ist;
{
float a, temp; /* for temporary storage */
*step=TORSO*0.975;
*hex=1.0;
*sher=3.0;
*hex=(*hex)*0.03*(*step);
*hey=(*hex)/1.5;
*sex=(*sher)*(*hex);
*sey=(*sex)/5.0;
*humor=TORSO*0.59; /* length of upper arm */
*ulna=TORSO*0.56; /* length of forearm */
*femur=TORSO*0.77; /* length of upper leg */
*tibia=TORSO*0.77; /* length lower leg */
*leg=(*femur)+(*tibia)+0.3*TORSO; /* adjust for ankle to heel length */
/* half step without torso torque */
*hstep=(*step)/2.0-(*hex);
/* up & down mvt of body due to step size and hip roll */ *bounce=((*leg)-sqrt((*leg)*(*leg)-(*hstep)*(*hstep))-(*hey))/2.0;
temp=(*hstep)/sqrt((*leg)*(*leg)-(*hstep)*(*hstep)); *swf=atan(temp);
*swh=0.24*((*step)-4.0*(*sex))*RAD;
*swu=1.65*(*swh);
*swt=25.0*RAD+(*swf)+5.0*(*hey)*RAD;
*femfo=RAD*0.04*(*step);
*cosff= (*leg)*(cos((*swf)-(*femfo))-cos((*swf)+(*femfo)))/2.0;
*xlean=TORSO*sin(-.0*RAD); /* no lean */ *ylean=TORSO*cos(-.0*RAD);
*xinit= -1060.0; /*changed*/
*yinit=130.0; /*changed from Laurence's program*/
*falfo=0.0;
REDO=0; /* to repeat a trial */
OUT=0; /* to break out of system */
}
/*********************************************************************
* create the objects from which the sequence is to be made *
/********************************************************************* void make_objects ()
{
int i,j; /* used in "Floorgrid" object */
makeobj (cube=genobj());
/* 1.05-1.07 s/cyc w/ polygons only
1.06-1.10 s/cyc w/ closedlines only
1.08-1.40 s/cyc w/ both */
color (YELLOW);
for (j=0;j<6;j++)
{
bgnpolygon ();
v3i (side[j][0]);
v3i (side[j][1]);
v3i (side[j][2]);
v3i (side[j][3]);
endpolygon ();
}
color (BLACK);
for (j=0;j<6;j++)
{
bgnclosedline ();
v3i (side[j][0]);
v3i (side[j][1]);
v3i (side[j][2]);
v3i (side[j][3]);
endclosedline ();
}
closeobj ();
makeobj (Groundplane=genobj());
pmv(-20000.0,0.0,-20000.0);
pdr(-20000.0,0.0,20000.0);
pdr(20000.0,0.0,20000.0);
pdr(20000.0,0.0,-20000.0);
pclos();
closeobj ();
makeobj (Floorgrid=genobj());
for (i= -13000;i<=13000;i+=1500)
{
movei (i,0.0,13500);
drawi (i,0.0,-13500);
movei (13500,0.0,i);
drawi (-13500,0.0,i);
}
closeobj ();
makeobj(Cylinder=genobj());
move(0.0,0.0,0.0);
draw(0.0,20.0,0.0);
closeobj();
makeobj(Tree1);
move(0.0,0.0,0.0);
scale(1.6,1.6,1.6);
callobj(Cylinder);
translate(0.0,20.0,0.0);
rotate(250,'z');
scale(0.8,0.8,0.8);
callobj(Cylinder);
rotate(-400,'z');
rotate(250,'x');
scale(0.9,0.9,0.9);
callobj(Cylinder);
translate(0.0,15.0,0.0);
scale(0.8,0.8,0.8);
rotate(-850,'x');
callobj(Cylinder);
translate(0.0,8.0,0.0);
scale(0.8,0.8,0.8);
rotate(500,'z');
callobj(Cylinder);/**/
translate(-10.0,-8.0,-25.0);
rotate(1800,'x');
rotate(1400,'z');
callobj(Cylinder);
translate(0.0,15.0,0.0);
rotate(1200,'z');
scale(0.5,0.5,0.5);
callobj(Cylinder);/**/
translate(21.0,17.0,-46.0);
rotate(-1350,'z');
scale(2.0,2.0,2.0);
callobj(Cylinder);
translate(0.0,18.0,0.0);
rotate(-400,'z');/*b*/
rotate(-600,'x');
scale(0.6,0.6,0.6);
callobj(Cylinder);/*e*/
move(0.0,0.0,0.0);
closeobj();
}
/*********************************************************************
* setup windows, graphical configurations, devices, and call objects *
*********************************************************************/ void setup_windows_graphics_devices ()
{
prefposition (0,1280,0,1009); /* define window size and placement */ winopen ("walker in a forest"); /* call and name the window */
underlay (2);
doublebuffer (); /* double buffer mode for animation */
gconfig ();
/*swapinterval (7);*/
backface (TRUE); /* Remove counter-clockwise drawn */
zbuffer (TRUE); /* backfacing characters & activate */
zclear (); /* z-buffering for speed & acuracy */
qdevice (ESCKEY); /* queue the ESC key */
qdevice (LEFTMOUSE);
qdevice (MIDDLEMOUSE);
qdevice (RIGHTMOUSE);
make_objects (); /* generate the graphical objects */
mapcolor (TREECOLOR,227,128,101);
mapcolor (FIXTREE,227,144,67);
drawmode(UNDERDRAW); /*added by Peter to fix ground plane*/
mapcolor (GROUND,90,73,47); /*added by Peter to fix ground plane*/
drawmode(NORMALDRAW); /*added by Peter to fix ground plane*/
}
/*********************************************************************
* set up underdraw *
*********************************************************************/ void setup_underdraw ()
{
drawmode (UNDERDRAW);
perspective (VISANG,1.0,0.1,20000.0);
lookat (0.0,EYE_HT,0.0,0.0,0.0,20000.0,0.0); color(GROUND);
callobj (Groundplane);
drawmode (NORMALDRAW);
}
/*********************************************************************
* generate the ankle table, broad w-shaped, 0-540 degrees *
*********************************************************************/ void ankle_table (delay,sia)
float delay, /* R/W pre- and post- femur swing of tibia */
sia[]; /* R/W ankle table */
{
int i,j; /* counters */
float n, a, z; /* for temporary storage */
for (i=0;i<=180;i++)
{
sia[i]=0.0;
sia[i+360]=0.0;
}
n=360.0+delay;
i=0;
/* symmetric about 270 degrees */
for (j=270;j<=n;j++)
{
z=(float)i;
a=(2.0*z-2.0*delay*z/(90.0+delay))*RAD;
a=(cos(a)+1.0)/2.0;
sia[j]=a;
sia[j-2*i]=a;
i++;
}
for (i=360;i<=n;i++)
sia[i-360]=sia[i];
n=180.0-delay;
for (i=n;i<=180;i++)
sia[i+360]=sia[i];
}
/*********************************************************************
* determine the right and left hip locations in the x and y axes *
*********************************************************************/ void get_hips (x,y,cosa,sina,cosff,hex,hey,xhipr,yhipr,xhipl,yhipl) float x,y,cosa,sina,cosff,hex,hey,*xhipr,*yhipr,*xhipl,*yhipl; {
float hx,hy;
hx=hex*cosa;
hy=hey*sina-cosff*sina;
*xhipr=x+hx;
*yhipr=y+hy;
*xhipl=x-hx;
*yhipl=y-hy;
}
/*********************************************************************
* determine the right and left knee locations in the x and y axes *
*********************************************************************/ void get_knees (swf,cosa,femfo,femur,xhipr,yhipr,xhipl,yhipl,
xkner,ykner,xknel,yknel)
float swf,cosa,femfo,femur,xhipr,yhipr,xhipl,yhipl,
*xkner,*ykner,*xknel,*yknel;
{
float a,z;
a=swf*cosa+femfo;
z=swf*cosa-femfo;
*xkner=xhipr+femur*sin(a);
*ykner=yhipr-femur*cos(a);
*xknel=xhipl-femur*sin(z);
*yknel=yhipl-femur*cos(z);
}
/*********************************************************************
* determine the right and left shoulder locations in the x and y axes *
*********************************************************************/ void get_shoulders (x,y,sex,sey,cosa,sina,xlean,ylean,
xshor,yshor,xshol,yshol)
float x,y,sex,sey,cosa,sina,xlean,ylean,
*xshor,*yshor,*xshol,*yshol;
{
float hx,hy;
hx=sex*cosa;
hy=sey*sina;
*xshor=x+xlean-hx;
*yshor=y+ylean-hy;
*xshol=x+xlean+hx;
*yshol=y+ylean+hy;
}
/*********************************************************************
* determine the right and left elbows locations in the x and y axes *
*********************************************************************/ void get_elbows (humor,cosa,swh,xshor,yshor,xshol,yshol,
xelbr,yelbr,xelbl,yelbl)
float humor,cosa,swh,xshor,yshor,xshol,yshol,
*xelbr,*yelbr,*xelbl,*yelbl;
{
float hx,hy;
hx=humor*sin(swh*cosa);
hy=humor*cos(swh*cosa);
*xelbr=xshor-hx;
*yelbr=yshor-hy;
*xelbl=xshol+hx;
*yelbl=yshol-hy;
}
/*********************************************************************
* determine the right and left ankles locations in the x and y axes *
*********************************************************************/ void get_ankles (swf,swt,cosa,sina1,sina2,femfo,tibia,
xkner,ykner,xknel,yknel,
xankr,yankr,xankl,yankl)
float swf,swt,cosa,sina1,sina2,femfo,tibia,xkner,ykner,xknel,yknel,
*xankr,*yankr,*xankl,*yankl;
{
float a,z;
a=swf*cosa+femfo-swt*sina1;
z= -swf*cosa+femfo-swt*sina2;
*xankr=xkner+tibia*sin(a);
*yankr=ykner-tibia*cos(a);
*xankl=xknel+tibia*sin(z);
*yankl=yknel-tibia*cos(z);
}
/*********************************************************************
* determine the right and left wrists locations in the x and y axes *
*********************************************************************/ void get_wrists (swh,swu,cosa,cos2a,ulna,xelbr,yelbr,xelbl,yelbl,
xwrir,ywrir,xwril,ywril)
float swh,swu,cosa,cos2a,ulna,xelbr,yelbr,xelbl,yelbl,
*xwrir,*ywrir,*xwril,*ywril;
{
float hx,hy,a,z;
hx=swh*cosa;
hy=swh*(cos2a+1.0)/2.0;
a=swu*(cosa-1.0)/2.0;
z=swu*(cosa+1.0)/2.0;
*xwrir=xelbr-ulna*sin(hx+a);
*ywrir=yelbr-ulna*cos(hy-a);
*xwril=xelbl+ulna*sin(hx+z);
*ywril=yelbl-ulna*cos(hy+z);
}
/********************************************************************
* render the walker to the buffering being drawn to *
*********************************************************************/ void draw_corpse (xhead,yhead,xshor,yshor,xshol,yshol,
xelbr,yelbr,xelbl,yelbl,xwrir,ywrir,
xwril,ywril,xhipr,yhipr,xhipl,yhipl,
xkner,ykner,xknel,yknel,xankr,yankr,
xankl,yankl,
ulna,humor,femur,tibia,
beta,shape,z)
float xhead,yhead,
xshor,yshor,xshol,yshol,
xelbr,yelbr,xelbl,yelbl,
xwrir,ywrir,xwril,ywril,
xhipr,yhipr,xhipl,yhipl,
xkner,ykner,xknel,yknel,
xankr,yankr,xankl,yankl,
ulna,humor,femur,tibia;
Angle beta;
Object shape;
float z;
{
/* bones lengths added --get_part_length omitted */ draw_part (xshor,yshor,z+SW,xelbr,yelbr,z+SW,ulna,8.0,8.0,beta,shape); draw_part (xelbr,yelbr,z+SW,xwrir,ywrir,z+SW,humor,7.0,7.0,beta,shape); draw_part (xshol,yshol,z-SW,xelbl,yelbl,z-SW,ulna,8.0,8.0,beta,shape); draw_part (xelbl,yelbl,z-SW,xwril,ywril,z-SW,humor,7.0,7.0,beta,shape);
/* legs changed */
draw_part
(xhipr,yhipr,z+HW-4.0,xkner,ykner,z+HW-4.0,femur,12.0,12.0,beta,shape);
draw_part
(xkner,ykner,z+HW-4.0,xankr,yankr,z+HW-4.0,tibia,11.0,11.0,beta,shape);
draw_part
(xhipl,yhipl,z-HW+4.0,xknel,yknel,z-HW+4.0,femur,12.0,12.0,beta,shape);
draw_part
(xknel,yknel,z-HW+4.0,xankl,yankl,z-HW+4.0,tibia,11.0,11.0,beta,shape);
draw_torso ((xshor+xshol)/2.0,(yshor+yshol)/2.0,z,
(xhipr+xhipl)/2.0,(yhipr+yhipl)/2.0,z,beta,shape); draw_head (xhead-5.0,yhead-19.0,z,10.0,beta,shape); draw_head (xhead-9.0,yhead-40.0,z,5.0,beta,shape); /* neck added */ }
/*********************************************************************
* This is the main loop, in which the walker walks and the viewer moves * * through the "scenery" *
*********************************************************************/ void locomotion (humor,ulna,femur,tibia,leg,step,
sher,time,hex,hey,sex,sey,swf,swh,
swu,swt,hstep,bounce,delay,xlean,ylean,
xinit,yinit,falfo,femfo,cosff,sia,ip,ist) float humor,ulna,femur,tibia,leg,step,
sher,time,hex,hey,sex,sey,swf,swh,
swu,swt,hstep,bounce,delay,xlean,ylean,
xinit,yinit,falfo,femfo,cosff,sia[];
int ip,ist;
{
int i,j,k,it,gridrot,tt,tmod;
float sina, sina1, sina2, cosa, cos2a, cosi, dum,
x, y, xf, zf,
xhead, yhead, /* } */
xhipr, yhipr, xhipl, yhipl, /* } */
xelbr, yelbr, xelbl, yelbl, /* } */
xkner, ykner, xknel, yknel, /* }x&y coords of body parts */
xshor, yshor, xshol, yshol, /* } */
xankr, yankr, xankl, yankl, /* } */
xwrir, ywrir, xwril, ywril, /* } */
n, /* a counter */
a1, /* for temporary storage */
yy, /* eyeheight of looker */
speed; /* time in secs. of each step cycle */
/* n is the counter used in the subject walker movement loop.
The subject walker starts walking at xx,zz=0.0 */
gridrot=(float)rand()*3600.0;
time1=times(&t1);
gettimeofday(&tp,&tzp);
tt=0;
tmod=0;
INCR=30;
xx1=xx;
zz1=zz;
/* This is the main loop for both walkers. Each step-cycle (j) is
two steps */
for (j=1;j<=NUM_STEPS;j++)
{
for (k=tmod;k<359;k+=INCR)
{
tim = starttim = ((double)tp.tv_sec) +
((double)tp.tv_usec)*0.000001;
/*n=step*2.0*INCR/360.0;*/
i=k+12.0*sin(2.0*k*RAD); /* surge factor */
sina=sin(i*RAD);
cosa=sin((i+90)*RAD);
cos2a=sin((i*2+90)*RAD);
sina1=sia[i];
sina2=sia[i+180];
if (i <= 180) cosi=cosa;
if (i > 180) cosi=sin((i-90)*RAD);
if ((i >= (180-delay)) & (i <= (180+delay)))
falfo=falfo+step*0.02/12;
if ((i >= (360-delay)) || (i <= delay))
falfo=falfo+step*0.02/12;
/* depends on increment in i */
x=xinit-cosi*step/2.0+falfo;
y=yinit-bounce*cos2a;
/* generate the coords of the walker object */
xhead=x+1.6*xlean+TORSO/15.0;
yhead=y+1.6*ylean;
get_hips (x,y,cosa,sina,cosff,hex,hey,&xhipr,&yhipr,
&xhipl,&yhipl);
get_knees (swf,cosa,femfo,femur,xhipr,yhipr,xhipl,
yhipl,&xkner,&ykner,&xknel,&yknel);
get_shoulders (x,y,sex,sey,cosa,sina,xlean,ylean,
&xshor,&yshor,&xshol,&yshol);
get_elbows (humor,cosa,swh,xshor,yshor,xshol,yshol,
&xelbr,&yelbr,&xelbl,&yelbl);
get_ankles (swf,swt,cosa,sina1,sina2,femfo,tibia,
xkner,ykner,xknel,yknel,
&xankr,&yankr,&xankl,&yankl);
get_wrists (swh,swu,cosa,cos2a,ulna,
xelbr,yelbr,xelbl,yelbl,
&xwrir,&ywrir,&xwril,&ywril);
/* draw the grid, walker object, then trees */
clearscreen ();
perspective (VISANG,1.0,0.1,30000.0);
lookat (xx1,EYE_HT,zz1,0.0,EYE_HT,0.0,0.0);
linewidth(1);
color (WHITE);
pushmatrix();
rotate(gridrot,'y');
callobj(Floorgrid);
popmatrix();
draw_corpse (xhead,yhead,xshor,yshor,xshol,yshol,
xelbr,yelbr,xelbl,yelbl,xwrir,ywrir,
xwril,ywril,xhipr,yhipr,xhipl,yhipl,
xkner,ykner,xknel,yknel,xankr,yankr,
xankl,yankl,
ulna,humor,femur,tibia,
0,cube,Z1);
drawtrees(xx,zz);
swapbuffers ();
gettimeofday(&tp,&tzp);
tim = ((double)tp.tv_sec) +
((double)tp.tv_usec)*0.000001;
tt=(float)(tim-starttim)*100*3;
/* printf ("frame %d = %d %f\n",k,tt,x);
*/
INCR = tt;
if((k+tt)>359) tmod=(k+tt)%360;
if ((k>=140) & (k<=180)){
xinit=xinit+step+falfo;
xx=xx+(step+falfo)*cos(SDIR*RAD);
zz=zz+(step+falfo)*sin(SDIR*RAD);
falfo=0;
if(k<(181-INCR)) k=181-INCR;}
}
xinit=xinit+step+falfo;
xx=xx+(step+falfo)*cos(SDIR*RAD);
zz=zz+(step+falfo)*sin(SDIR*RAD);
falfo=0;
}
time2=times(&t1);
/* printf (" duration = %d\n",(time2-time1));
*/
}
/*********************************************************************
* calculate the midpoint between two points in three dimensional space * *********************************************************************/ void get_midpoint (x1,y1,z1,x2,y2,z2,xm,ym,zm) float x1,y1,z1,x2,y2,z2,*xm,*ym,*zm;
{
*xm=(x1+x2)/2.0;
*ym=(y1+y2)/2.0;
*zm=(z1+z2)/2.0;
}
/*********************************************************************
* render a single body part *
*********************************************************************/ void draw_part (x1,y1,z1,x2,y2,z2,length,w,t,beta,shape) float x1,y1,z1,x2,y2,z2, /* R/O coords of joints of this body part */
w,t, /* R/O width and thickness of this body part */
length; /* from bone */
Angle beta; /* R/O Angle of walker's change of direction */
Object shape; /* R/O object used to make this body part */
{
float alpha, /* angle to which the object that the body
part is made freom is rotated */
xm,ym,zm; /* midpoint of the body part (midpoint
between the joints */
get_midpoint (x1,y1,z1,x2,y2,z2,&xm,&ym,&zm); get_angle (x1,y1,x2,y2,&alpha);
pushmatrix ();
rotate (beta*10,'Y'); /* change of direction */
translate (xm,ym,zm);
rotate (alpha*10,'Z');
scale (length/2.0,t/2.0,w/2.0); /* make the part the correct length,
width and thickness */
callobj (shape);
popmatrix ();
}
/*********************************************************************
* calculate the angle that a body part needs to be rotated *