Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!swrinde!elroy.jpl.nasa.gov!decwrl!sgi!shinobu!odin!horus.esd.sgi.com!thant From: thant@horus.esd.sgi.com (Thant Tessman) Newsgroups: comp.sys.sgi Subject: Re: Have a better lookat() ? Message-ID: <1991Apr3.172853.7947@odin.corp.sgi.com> Date: 3 Apr 91 17:28:53 GMT References: <9103232036.AA05543@karron.med.nyu.edu> <1991Mar30.135724.21424@mintaka.lcs.mit.edu> Sender: news@odin.corp.sgi.com (Net News) Reply-To: thant@horus.esd.sgi.com (Thant Tessman) Organization: sgi Lines: 226 Here is my twice-yearly posting of an alternative to the lookat command: To compile: cc example.c upat.c -lgl_s -lm -o example ----------------------cut here-------------------------- #!/bin/sh -v # this is a shell archive (once) named upat.mail # created by thant@horus at Thu Jan 17 08:59:48 PST 1991 # # The rest of this file is a shell script which will extract: # example.c # upat.c # # to use, type sh upat.mail # echo x - example.c cat > example.c << 'EndOfRecord' #include #include extern void upat(float vx, float vy, float vz, float px, float py, float pz, float ux, float uy, float uz); main() { int dev; short val; float i, j, k; initialize(); /* first flyby */ printf("Y is up. (Just like lookat.)\n"); j = 2.0; for (i = -8.0, k=12.0; i<12.0; i+=0.05, k-=0.05) { color(BLACK); clear(); perspective(400, 5.0/4.0, 1.0, 50.0); upat(i, j, k, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); draw_axes(); swapbuffers(); } /* second flyby */ printf("Z is up, but same path.\n"); j = 2.0; for (i = -8.0, k=12.0; i<12.0; i+=0.05, k-=0.05) { color(BLACK); clear(); perspective(400, 5.0/4.0, 1.0, 50.0); upat(i, j, k, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0); draw_axes(); swapbuffers(); } /* third flyby */ printf("(1, 1, 1) is up. Different path.\n"); for (i = -8.0, j=10.0, k=12.0; i<12.0; i+=0.05, k-=0.05, j-=0.05) { color(BLACK); clear(); perspective(400, 5.0/4.0, 1.0, 50.0); upat(i, j, k, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0); draw_axes(); swapbuffers(); } } initialize() { keepaspect(5, 4); winopen(""); doublebuffer(); gconfig(); qdevice(ESCKEY); } draw_axes() { color(RED); move(0.0, 0.0, 0.0); draw(1.0, 0.0, 0.0); cmov(1.2, 0.0, 0.0); charstr("x"); color(GREEN); move(0.0, 0.0, 0.0); draw(0.0, 1.0, 0.0); cmov(0.0, 1.2, 0.0); charstr("y"); color(BLUE); move(0.0, 0.0, 0.0); draw(0.0, 0.0, 1.0); cmov(0.0, 0.0, 1.2); charstr("z"); color(WHITE); move(0.5, 0.5, 0.5); draw(0.5, 0.5, 0.0); move(0.5, 0.0, 0.0); draw(0.5, 0.5, 0.0); draw(0.0, 0.5, 0.0); move(0.5, 0.5, 0.5); draw(0.0, 0.5, 0.5); move(0.0, 0.5, 0.0); draw(0.0, 0.5, 0.5); draw(0.0, 0.0, 0.5); move(0.5, 0.5, 0.5); draw(0.5, 0.0, 0.5); move(0.5, 0.0, 0.0); draw(0.5, 0.0, 0.5); draw(0.0, 0.0, 0.5); } EndOfRecord len=`wc -c < example.c ` if [ $len != 1993 ] ; then echo error: example.c was $len bytes long, should have been 1993 fi echo x - upat.c cat > upat.c << 'EndOfRecord' #include "math.h" #include "gl.h" #include "stdio.h" #define X 0 #define Y 1 #define Z 2 void normalize(float *); void cross(float *result, float *v1, float *v2); void upat(float vx, float vy, float vz, float px, float py, float pz, float ux, float uy, float uz) { int i; float forward[3], side[3], up[3]; float m[4][4]; forward[X] = px - vx; forward[Y] = py - vy; forward[Z] = pz - vz; up[X] = ux; /* temporarily use view-up to hold world-up */ up[Y] = uy; up[Z] = uz; normalize(forward); /* make side from view forward and world up */ cross(side, forward, up); normalize(side); /* make view up from view forward and view side */ cross(up, side, forward); m[0][0] = side[X]; m[1][0] = side[Y]; m[2][0] = side[Z]; m[3][0] = 0.0; m[0][1] = up[X]; m[1][1] = up[Y]; m[2][1] = up[Z]; m[3][1] = 0.0; m[0][2] = -forward[X]; m[1][2] = -forward[Y]; m[2][2] = -forward[Z]; m[3][2] = 0.0; m[0][3] = 0.0; m[1][3] = 0.0; m[2][3] = 0.0; m[3][3] = 1.0; multmatrix(m); translate(-vx, -vy, -vz); } void normalize(float *v) { float r; r = sqrt( v[X]*v[X] + v[Y]*v[Y] + v[Z]*v[Z] ); v[X] /= r; v[Y] /= r; v[Z] /= r; } void cross(float *result, float *v1, float *v2) { result[X] = v1[Y]*v2[Z] - v1[Z]*v2[Y]; result[Y] = v1[Z]*v2[X] - v1[X]*v2[Z]; result[Z] = v1[X]*v2[Y] - v1[Y]*v2[X]; } EndOfRecord len=`wc -c < upat.c ` if [ $len != 1480 ] ; then echo error: upat.c was $len bytes long, should have been 1480 fi