burdick@hpindda.HP.COM (Matt Burdick) (05/16/89)
I was asked to post this shar file to comp.sys.hp for Eric Haines, who was unable to. It contains a number of fractal graphics images in Neutral File Format (NFF), along with a viewer for displaying them under HP's Starbase product. This package by Eric Haines is for displaying scenes in NFF format, such as the SPD (Standard Procedural Databases) package. Mark VandeWettering has made the SPD package (and his ray tracer in "C" which uses the NFF format) available by anonymous FTP. Get it from drizzle.cs.uoregon.edu . If you don't have FTP capabilities but have UUCP, write to either of: alias arpa_netlib netlib@anl-mcs.arpa alias research_netlib ...hplabs!research!netlib and send the one line message "send Haines from Graphics". The mailers at the other end should automatically send you the SPD package. To contact Eric, write him at: alias eric_haines ...hplabs!hpfcla!hpfcrs!eye!erich To contact Mark, write him at: alias mark_vandewettering markv@cs.uoregon.edu Two polyhedra databases from Netlib's "polyhedra" section are also included in the NFF format in the following, along with a tetrahedron test scene. Enjoy! ---End Of Blurb Thanks much in advance, Eric Haines # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by Eric Haines <erich@spruce> on Wed May 10 10:01:30 1989 # # This archive contains: # README def.h lib.c lib.h # lookat.c makefile pol005.nff pol006.nff # tetra.nff # LANG=""; export LANG PATH=/bin:/usr/bin:$PATH; export PATH echo x - README cat >README <<'@EOF' unpack, cd into the new "SPD" directory, "make", then type "lookat tetra.nff" for a mouse controlled view. Note that input can be piped to lookat, e.g. "cat tetra.nff | lookat" is fine. Define OUTDEV, OUTDRIVER, INDEV and INDRIVER if another device than the SRX and the mouse is desired. These are the assumed defaults for each program: INDEV=/dev/hil2 INDRIVER=hp-hil OUTDEV=/dev/crt OUTDRIVER=hp98721 @EOF chmod 644 README echo x - def.h cat >def.h <<'@EOF' /* * def.h contains some useful definitions for "C" programs. * * Version: 2.2 (11/17/87) * Author: Eric Haines, 3D/Eye, Inc. */ #define EPSILON 5.0e-6 #ifndef FALSE #define FALSE 0 #endif #ifndef NULL #define NULL 0 #endif #ifndef TRUE #define TRUE 1 #endif #ifndef PI #define PI 3.141592653589793 #endif typedef double MATRIX[4][4] ; /* row major form */ typedef struct { double x ; double y ; double z ; double w ; } COORD4, *COORD4_P ; #define ABSOLUTE(A) ( (A) < 0 ? -(A) : (A) ) #define FRACTION(A) ( (A) - (long)(A) ) #define MAX(A,B) ( (A) > (B) ? (A) : (B) ) #define MAX3(A,B,C) ( MAX( MAX( A,B ), C ) ) #define MIN(A,B) ( (A) < (B) ? (A) : (B) ) #define MIN3(A,B,C) ( MIN( MIN( A,B ), C ) ) #define SQR(A) ( (A) * (A) ) #define ADD2_COORD(r,a) { (r).x += (a).x; (r).y += (a).y;\ (r).z += (a).z; } #define ADD3_COORD(r,a,b) { (r).x = (a).x + (b).x;\ (r).y = (a).y + (b).y;\ (r).z = (a).z + (b).z; } #define COPY_COORD(r,a) { (r).x = (a).x; (r).y = (a).y; (r).z = (a).z;} #define COPY_COORD4(r,a) { (r).x = (a).x; (r).y = (a).y; (r).z = (a).z;\ (r).w = (a).w; } #define CROSS(r,a,b) { (r).x = (a).y * (b).z - (a).z * (b).y;\ (r).y = (a).z * (b).x - (a).x * (b).z;\ (r).z = (a).x * (b).y - (a).y * (b).x; } #define DOT_PRODUCT(a,b) ( (a).x * (b).x +\ (a).y * (b).y +\ (a).z * (b).z ) #define SET_COORD(r,a,b,c) { (r).x = (a); (r).y = (b); (r).z = (c); } #define SET_COORD4(r,a,b,c,d) { (r).x = (a); (r).y = (b); (r).z = (c);\ (r).w = (d); } #define SUB2_COORD(r,a) { (r).x -= (a).x; (r).y -= (a).y;\ (r).z -= (a).z; } #define SUB3_COORD(r,a,b) { (r).x = (a).x - (b).x;\ (r).y = (a).y - (b).y;\ (r).z = (a).z - (b).z; } @EOF chmod 640 def.h echo x - lib.c cat >lib.c <<'@EOF' /* * lib.c - a library of vector operations, a random number generator, and * object output routines. * * Version: 2.2 (11/17/87) * Author: Eric Haines, 3D/Eye, Inc. */ #include <stdio.h> #include <math.h> #include <memory.h> #include "def.h" #include "lib.h" /* * Normalize the vector (X,Y,Z) so that X*X + Y*Y + Z*Z = 1. * * The normalization divisor is returned. If the divisor is zero, no * normalization occurs. * */ double lib_normalize_coord3( cvec ) COORD4 *cvec; { double divisor; divisor = sqrt( (double)DOT_PRODUCT( (*cvec), (*cvec) ) ) ; if ( divisor != 0.0 ) { cvec->x /= divisor; cvec->y /= divisor; cvec->z /= divisor; } return( divisor ); } /* * Set all matrix elements to zero. */ lib_zero_matrix( mx ) MATRIX mx ; { long i, j ; for ( i = 0 ; i < 4 ; ++i ) { for ( j = 0 ; j < 4 ; ++j ) { mx[i][j] = 0.0 ; } } } /* * Create identity matrix. */ lib_create_identity_matrix( mx ) MATRIX mx ; { long i ; lib_zero_matrix( mx ) ; for ( i = 0 ; i < 4 ; ++i ) { mx[i][i] = 1.0 ; } } /* * Create a rotation matrix along the given axis by the given angle in radians. */ lib_create_rotate_matrix( mx, axis, angle ) MATRIX mx ; long axis ; double angle ; { double cosine ; double sine ; lib_zero_matrix( mx ) ; cosine = cos( (double)angle ) ; sine = sin( (double)angle ) ; switch ( axis ) { case X_AXIS: mx[0][0] = 1.0 ; mx[1][1] = mx[2][2] = cosine ; mx[1][2] = sine ; mx[2][1] = -sine ; break ; case Y_AXIS: mx[1][1] = 1.0 ; mx[0][0] = mx[2][2] = cosine ; mx[2][0] = sine ; mx[0][2] = -sine ; break ; case Z_AXIS: mx[2][2] = 1.0 ; mx[0][0] = mx[1][1] = cosine ; mx[0][1] = sine ; mx[1][0] = -sine ; break ; } mx[3][3] = 1.0 ; } /* * Create a rotation matrix along the given axis by the given angle in radians. * The axis is a set of direction cosines. */ lib_create_axis_rotate_matrix( mx, rvec, angle ) MATRIX mx ; COORD4 *rvec ; double angle ; { COORD4 axis ; double cosine ; double one_minus_cosine ; double sine ; lib_zero_matrix( mx ) ; COPY_COORD( axis, (*rvec) ) ; cosine = cos( (double)angle ) ; sine = sin( (double)angle ) ; one_minus_cosine = 1.0 - cosine ; mx[0][0] = SQR(axis.x) + (1.0 - SQR(axis.x)) * cosine ; mx[0][1] = axis.x * axis.y * one_minus_cosine + axis.z * sine ; mx[0][2] = axis.x * axis.z * one_minus_cosine - axis.y * sine ; mx[1][0] = axis.x * axis.y * one_minus_cosine - axis.z * sine ; mx[1][1] = SQR(axis.y) + (1.0 - SQR(axis.y)) * cosine ; mx[1][2] = axis.y * axis.z * one_minus_cosine + axis.x * sine ; mx[2][0] = axis.x * axis.z * one_minus_cosine + axis.y * sine ; mx[2][1] = axis.y * axis.z * one_minus_cosine - axis.x * sine ; mx[2][2] = SQR(axis.z) + (1.0 - SQR(axis.z)) * cosine ; mx[3][3] = 1.0 ; } /* * Multiply a 4 element vector by a matrix. */ lib_transform_coord( vres, vec, mx ) COORD4 *vres ; COORD4 *vec ; MATRIX mx ; { vres->x = vec->x*mx[0][0] + vec->y*mx[1][0] + vec->z*mx[2][0] + vec->w*mx[3][0] ; vres->y = vec->x*mx[0][1] + vec->y*mx[1][1] + vec->z*mx[2][1] + vec->w*mx[3][1] ; vres->z = vec->x*mx[0][2] + vec->y*mx[1][2] + vec->z*mx[2][2] + vec->w*mx[3][2] ; vres->w = vec->x*mx[0][3] + vec->y*mx[1][3] + vec->z*mx[2][3] + vec->w*mx[3][3] ; } /* * Multiply two 4x4 matrices. */ lib_matrix_multiply( mxres, mx1, mx2 ) MATRIX mxres ; MATRIX mx1 ; MATRIX mx2 ; { long i ; long j ; for ( i = 0; i < 4; i++ ) { for ( j = 0; j < 4; j++ ) { mxres[i][j] = mx1[i][0]*mx2[0][j] + mx1[i][1]*mx2[1][j] + mx1[i][2]*mx2[2][j] + mx1[i][3]*mx2[3][j] ; } } } /* * Rotate a vector pointing towards the major-axis faces (i.e. the major-axis * component of the vector is defined as the largest value) 90 degrees to * another cube face. Mod_face is a face number. * * If the routine is called six times, with mod_face=0..5, the vector will be * rotated to each face of a cube. Rotations are: * mod_face = 0 mod 3, +Z axis rotate * mod_face = 1 mod 3, +X axis rotate * mod_face = 2 mod 3, -Y axis rotate */ lib_rotate_cube_face( vec, major_axis, mod_face ) COORD4 *vec ; long major_axis ; long mod_face ; { double swap ; mod_face = (mod_face+major_axis) % 3 ; if ( mod_face == 0 ) { swap = vec->x ; vec->x = -vec->y ; vec->y = swap ; } else if ( mod_face == 1 ) { swap = vec->y ; vec->y = -vec->z ; vec->z = swap ; } else { swap = vec->x ; vec->x = -vec->z ; vec->z = swap ; } } /* * Portable gaussian random number generator (from "Numerical Recipes", GASDEV) * Returns a uniform random deviate between 0.0 and 1.0. 'iseed' must be * less than M1 to avoid repetition, and less than (2**31-C1)/A1 [= 300718] * to avoid overflow. */ #define M1 134456 #define IA1 8121 #define IC1 28411 #define RM1 1.0/M1 double lib_gauss_rand(iseed) long iseed ; { double fac ; long ix1, ix2 ; double r ; double v1, v2 ; ix2 = iseed ; do { ix1 = (IC1+ix2*IA1) % M1 ; ix2 = (IC1+ix1*IA1) % M1 ; v1 = ix1 * 2.0 * RM1 - 1.0 ; v2 = ix2 * 2.0 * RM1 - 1.0 ; r = v1*v1 + v2*v2 ; } while ( r >= 1.0 ) ; fac = sqrt( (double)( -2.0 * log( (double)r ) / r ) ) ; return( v1 * fac ) ; } /* OUTPUT ROUTINES * * Files are output as lines of text. For each entity, the first line * defines its type. The rest of the first line and possibly other lines * contain further information about the entity. Entities include: * * "v" - viewing vectors and angles * "l" - positional light location * "b" - background color * "f" - object material properties * "c" - cone or cylinder primitive * "s" - sphere primitive * "p" - polygon primitive * "pp" - polygonal patch primitive */ /* * Output viewpoint location. The parameters are: * From: the eye location. * At: a position to be at the center of the image. A.k.a. "lookat" * Up: a vector defining which direction is up. * * Note that no assumptions are made about normalizing the data (e.g. the * from-at distance does not have to be 1). Also, vectors are not * required to be perpendicular to each other. * * For all databases some viewing parameters are always the same: * * Viewing angle is defined as from the center of top pixel row to bottom * pixel row and left column to right column. * Yon is "at infinity." * Resolution is always 512 x 512. */ lib_output_viewpoint( from, at, up, angle, hither, resx, resy ) COORD4 *from ; COORD4 *at ; COORD4 *up ; double angle ; double hither ; long resx ; long resy ; { printf( "v\n" ) ; printf( "from %g %g %g\n", from->x, from->y, from->z ) ; printf( "at %g %g %g\n", at->x, at->y, at->z ) ; printf( "up %g %g %g\n", up->x, up->y, up->z ) ; printf( "angle %g\n", angle ) ; printf( "hither %g\n", hither ) ; printf( "resolution %d %d\n", resx, resy ) ; } /* * Output light. A light is defined by position. All lights have the same * intensity. * */ lib_output_light( center_pt ) COORD4 *center_pt ; { printf( "l %g %g %g\n", center_pt->x, center_pt->y, center_pt->z ) ; } /* * Output background color. A color is simply RGB (monitor dependent, but * that's life). The format is: * "b" red green blue */ lib_output_background_color( color ) COORD4 *color ; { printf( "b %g %g %g\n", color->x, color->y, color->z ) ; } /* * Output a color and shading parameters for the object in the format: * "f" red green blue Kd Ks Shine T index_of_refraction * * Kd is the diffuse component, Ks the specular, Shine is the Phong cosine * power for highlights, T is transmittance (fraction of light passed per * unit). 0 <= Kd <= 1 and 0 <= Ks <= 1, though it is not required that * Kd + Ks == 1. * * The fill color is used to color the objects following it until a new color * is assigned or the file ends. */ lib_output_color( color, kd, ks, shine, t, i_of_r ) COORD4 *color ; double kd ; double ks ; double shine ; double t ; double i_of_r ; { printf( "f %g %g %g %g %g %g %g %g\n", color->x, color->y, color->z, kd, ks, shine, t, i_of_r ) ; } /* * Output cylinder or cone. A cylinder is defined as having a radius and an * axis defined by two points, which also define the top and bottom edge of the * cylinder. A cone is defined similarly, the difference being that the apex * and base radii are different. The apex radius is defined as being smaller * than the base radius. Note that the surface exists without endcaps. * * If format=OUTPUT_CURVES, output the cylinder/cone in format: * "c" * base.x base.y base.z base_radius * apex.x apex.y apex.z apex_radius * * If the format=OUTPUT_POLYGONS, the surface is polygonalized and output. * (4*OUTPUT_RESOLUTION) polygons are output as rectangles by * lib_output_polypatch. */ lib_output_cylcone( base_pt, apex_pt, format ) COORD4 *base_pt ; COORD4 *apex_pt ; long format ; { double angle ; COORD4 axis ; COORD4 dir ; double divisor ; COORD4 lip_norm[4], lip_pt[4] ; MATRIX mx ; COORD4 norm_axis ; long num_pol ; COORD4 start_norm, start_radius[4] ; if ( format == OUTPUT_CURVES ) { printf( "c\n" ) ; printf( "%g %g %g %g\n", base_pt->x, base_pt->y, base_pt->z, base_pt->w ) ; printf( "%g %g %g %g\n", apex_pt->x, apex_pt->y, apex_pt->z, apex_pt->w ) ; } else { SUB3_COORD( axis, (*apex_pt), (*base_pt) ) ; COPY_COORD( norm_axis, axis ) ; lib_normalize_coord3( &norm_axis ) ; dir.x = 0.0 ; dir.y = 0.0 ; dir.z = 1.0 ; dir.w = 0.0 ; CROSS( start_norm, axis, dir ) ; divisor = lib_normalize_coord3( &start_norm ) ; if ( ABSOLUTE( divisor ) < EPSILON ) { dir.x = 1.0 ; dir.y = 0.0 ; dir.z = 0.0 ; CROSS( start_norm, axis, dir ) ; lib_normalize_coord3( &start_norm ) ; } start_radius[0].x = start_norm.x * base_pt->w ; start_radius[0].y = start_norm.y * base_pt->w ; start_radius[0].z = start_norm.z * base_pt->w ; start_radius[0].w = 0.0 ; ADD3_COORD( lip_pt[0], (*base_pt), start_radius[0] ) ; start_radius[1].x = start_norm.x * apex_pt->w ; start_radius[1].y = start_norm.y * apex_pt->w ; start_radius[1].z = start_norm.z * apex_pt->w ; start_radius[1].w = 0.0 ; ADD3_COORD( lip_pt[1], (*apex_pt), start_radius[1] ) ; COPY_COORD4( lip_norm[0], start_norm ) ; COPY_COORD4( lip_norm[1], start_norm ) ; for ( num_pol = 0 ; num_pol < 4*OUTPUT_RESOLUTION ; ++num_pol ) { COPY_COORD4( lip_pt[3], lip_pt[0] ) ; COPY_COORD4( lip_pt[2], lip_pt[1] ) ; COPY_COORD4( lip_norm[3], lip_norm[0] ) ; COPY_COORD4( lip_norm[2], lip_norm[1] ) ; angle = 2.0 * PI * (double)( num_pol+1 ) / (double)( 4*OUTPUT_RESOLUTION ) ; lib_create_axis_rotate_matrix( mx, &norm_axis, angle ) ; lib_transform_coord( &lip_pt[0], &start_radius[0], mx ) ; ADD2_COORD( lip_pt[0], (*base_pt) ) ; lib_transform_coord( &lip_pt[1], &start_radius[1], mx ) ; ADD2_COORD( lip_pt[1], (*apex_pt) ) ; lib_transform_coord( &lip_norm[0], &start_norm, mx ) ; COPY_COORD4( lip_norm[1], lip_norm[0] ) ; lib_output_polypatch( 4, lip_pt, lip_norm ) ; } } } /* * Output sphere. A sphere is defined by a radius and center position. * * If format=OUTPUT_CURVES, output the sphere in format: * "s" center.x center.y center.z radius * * If the format=OUTPUT_POLYGONS, the sphere is polygonalized and output. * The sphere is polygonalized by splitting it into 6 faces (of a cube * projected onto the sphere) and dividing these faces by equally spaced * great circles. OUTPUT_RESOLUTION affects the number of great circles. * (6*2*OUTPUT_RESOLUTION*OUTPUT_RESOLUTION) polygons are output as triangles * using lib_output_polypatch. */ lib_output_sphere( center_pt, format ) COORD4 *center_pt ; long format ; { double angle ; COORD4 edge_norm[3], edge_pt[3] ; long num_face, num_edge, num_tri, num_vert ; COORD4 x_axis[OUTPUT_RESOLUTION+1], y_axis[OUTPUT_RESOLUTION+1] ; COORD4 pt[OUTPUT_RESOLUTION+1][OUTPUT_RESOLUTION+1] ; COORD4 mid_axis ; MATRIX rot_mx ; long u_pol, v_pol ; if ( format == OUTPUT_CURVES ) { printf( "s %g %g %g %g\n", center_pt->x, center_pt->y, center_pt->z, center_pt->w ) ; } else { /* calculate axes used to find grid points */ for ( num_edge = 0 ; num_edge <= OUTPUT_RESOLUTION ; ++num_edge ) { angle = (PI/4.0) * (2.0*(double)num_edge/OUTPUT_RESOLUTION - 1.0) ; mid_axis.w = 0.0 ; mid_axis.x = 1.0 ; mid_axis.y = 0.0 ; mid_axis.z = 0.0 ; lib_create_rotate_matrix( rot_mx, Y_AXIS, angle ) ; lib_transform_coord( &x_axis[num_edge], &mid_axis, rot_mx ) ; mid_axis.x = 0.0 ; mid_axis.y = 1.0 ; mid_axis.z = 0.0 ; lib_create_rotate_matrix( rot_mx, X_AXIS, angle ) ; lib_transform_coord( &y_axis[num_edge], &mid_axis, rot_mx ) ; } /* set up grid of points on +Z sphere surface */ for ( u_pol = 0 ; u_pol <= OUTPUT_RESOLUTION ; ++u_pol ) { for ( v_pol = 0 ; v_pol <= OUTPUT_RESOLUTION ; ++v_pol ) { CROSS( pt[u_pol][v_pol], x_axis[u_pol], y_axis[v_pol] ) ; lib_normalize_coord3( &pt[u_pol][v_pol] ) ; pt[u_pol][v_pol].w = 1.0 ; } } for ( num_face = 0 ; num_face < 6 ; ++num_face ) { /* transform points to cube face */ for ( u_pol = 0 ; u_pol <= OUTPUT_RESOLUTION ; ++u_pol ) { for ( v_pol = 0 ; v_pol <= OUTPUT_RESOLUTION ; ++v_pol ) { lib_rotate_cube_face( &pt[u_pol][v_pol] , Z_AXIS , num_face ) ; } } /* output grid */ for ( u_pol = 0 ; u_pol < OUTPUT_RESOLUTION ; ++u_pol ) { for ( v_pol = 0 ; v_pol < OUTPUT_RESOLUTION ; ++v_pol ) { for ( num_tri = 0 ; num_tri < 2 ; ++num_tri ) { for ( num_edge = 0 ; num_edge < 3 ; ++num_edge ) { num_vert = (num_tri*2 + num_edge) % 4 ; if ( num_vert == 0 ) { COPY_COORD4( edge_pt[num_edge], pt[u_pol][v_pol] ) ; } else if ( num_vert == 1 ) { COPY_COORD4( edge_pt[num_edge], pt[u_pol][v_pol+1] ) ; } else if ( num_vert == 2 ) { COPY_COORD4( edge_pt[num_edge], pt[u_pol+1][v_pol+1] ) ; } else { COPY_COORD4( edge_pt[num_edge], pt[u_pol+1][v_pol] ) ; } COPY_COORD4( edge_norm[num_edge], edge_pt[num_edge] ) ; edge_pt[num_edge].x = edge_pt[num_edge].x * center_pt->w + center_pt->x ; edge_pt[num_edge].y = edge_pt[num_edge].y * center_pt->w + center_pt->y ; edge_pt[num_edge].z = edge_pt[num_edge].z * center_pt->w + center_pt->z ; } lib_output_polypatch( 3, edge_pt, edge_norm ) ; } } } } } } /* * Output polygon. A polygon is defined by a set of vertices. With these * databases, a polygon is defined to have all points coplanar. A polygon has * only one side, with the order of the vertices being counterclockwise as you * face the polygon (right-handed coordinate system). * * The output format is always: * "p" total_vertices * vert1.x vert1.y vert1.z * [etc. for total_vertices polygons] * */ lib_output_polygon( tot_vert, vert ) long tot_vert ; COORD4 *vert ; { long num_vert ; printf( "p %d\n", tot_vert ) ; for ( num_vert = 0 ; num_vert < tot_vert ; ++num_vert ) { printf( "%g %g %g\n", vert[num_vert].x , vert[num_vert].y , vert[num_vert].z ) ; } } /* * Output polygonal patch. A patch is defined by a set of vertices and their * normals. With these databases, a patch is defined to have all points * coplanar. A patch has only one side, with the order of the vertices being * counterclockwise as you face the patch (right-handed coordinate system). * * The output format is always: * "pp" total_vertices * vert1.x vert1.y vert1.z norm1.x norm1.y norm1.z * [etc. for total_vertices polygonal patches] * */ lib_output_polypatch( tot_vert, vert, norm ) long tot_vert ; COORD4 *vert ; COORD4 *norm ; { long num_vert ; printf( "pp %d\n", tot_vert ) ; for ( num_vert = 0 ; num_vert < tot_vert ; ++num_vert ) { printf( "%g %g %g %g %g %g\n", vert[num_vert].x , vert[num_vert].y , vert[num_vert].z , norm[num_vert].x , norm[num_vert].y , norm[num_vert].z ) ; } } @EOF chmod 644 lib.c echo x - lib.h cat >lib.h <<'@EOF' /* * lib.h - vector library definitions * * Version: 2.2 (11/17/87) * Author: Eric Haines, 3D/Eye, Inc. */ #define X_AXIS 0 #define Y_AXIS 1 #define Z_AXIS 2 /* Output library definitions */ #define OUTPUT_CURVES 0 /* true curve output */ #define OUTPUT_PATCHES 1 /* polygonal patches output */ #define OUTPUT_RESOLUTION 4 /* amount of polygonalization */ double lib_normalize_coord3() ; double lib_gauss_rand() ; @EOF chmod 640 lib.h echo x - lookat.c cat >lookat.c <<'@EOF' /************************************************************************/ /* */ /* program: lookat */ /* */ /* usage: lookat [filename] */ /* */ /* function: examine a file in my neutral file format. */ /* Creates a display list, uses the mouse to move */ /* around (left/right - rotate on screen's y axis, */ /* up/down - rotate on screen's x axis, left */ /* button - move closer, right button - move back. */ /* Buttons also move the screen's axis' z-depth). */ /* */ /* input: filename.nff */ /* Define OUTDEV, OUTDRIVER, INDEV and INDRIVER */ /* (default is SRX and mouse if not defined). */ /* If redefined, make sure the makefile links in */ /* the libraries you need. gescape commands may */ /* also have to be modified or deleted. */ /* */ /* output: a display on the screen */ /* */ /* comments: program components are described within the */ /* corresponding modules */ /* */ /* author: Eric Haines, 12/5/86 */ /* */ /************************************************************************/ #include <stdio.h> #include <math.h> #include <fcntl.h> #include <starbase.c.h> #include <sbdl.c.h> #include "def.h" #include "lib.h" #define NEG_COORD(r) (r).x = -(r).x, (r).y = -(r).y, (r).z = -(r).z extern char *getenv() ; int devopen() ; #define BUFSIZE 255 #define OUT_RESOLUTION 4 #define MAX_EDGES 255 /* maximum edges in a polygon */ #define SEG_DATA 1 /* default devices and drivers */ char default_indev[] = "/dev/hil2" ; char default_indriver[] = "hp-hil" ; char default_outdev[] = "/dev/crt" ; char default_outdriver[] = "hp98721" ; static camera_arg camera ; COORD4 from ; COORD4 at ; COORD4 up ; static int screendes ; static int inputdes ; main(argc,argv) int argc; char *argv[]; { char *device, *driver ; int create_database() ; from.x = from.y = from.z = 0.0 ; at.x = 0.0 ; at.y = 1.0 ; at.z = 0.0 ; up.x = 0.0 ; up.y = 0.0 ; up.z = 1.0 ; screendes = devopen(OUTDEV,INIT|THREE_D|MODEL_XFORM) ; if ( screendes == -1 ) { printf("error opening output device\n" ) ; exit(1) ; } inputdes = devopen(INDEV,INIT) ; if ( inputdes == -1 ) { printf("error opening input device\n" ) ; exit(1) ; } vdc_extent(inputdes,-1.0,-0.8,0.8, 1.0,0.8,0.8 ) ; crt_setup() ; camera_setup() ; if ( !create_database( argc, argv ) ) { exit(1) ; } showtime() ; disable_events( inputdes ); gclose( inputdes ) ; gclose( screendes ) ; } crt_setup() /* this may have to be modified if the various gescapes are * not supported on your device */ { gescape_arg arg1,arg2 ; buffer_mode ( screendes , TRUE ) ; /* buffering is on */ gescape( screendes, SWITCH_SEMAPHORE, &arg1, &arg1 ) ; arg1.f[0] = 1.0 ; gescape( screendes, LS_OVERFLOW_CONTROL, &arg1, &arg2 ) ; shade_mode ( screendes , INIT | CMAP_FULL /* full color map */ , TRUE ) ; /* use light source equations */ double_buffer ( screendes , TRUE | INIT /* Enable double buffer and initialize color map accordingly. */ , 12 ) ; /* 12 planes for each buffer */ clear_control(screendes,CLEAR_DISPLAY_SURFACE|CLEAR_ALL_BANKS) ; clear_view_surface(screendes) ; clear_control(screendes,CLEAR_VIEWPORT) ; } camera_setup() { camera.front = 0.0 ; camera.back = 100.0 ; camera.projection = CAM_PERSPECTIVE ; } showtime() { int curr_buffer ; float dummy ; int frame ; int ok ; int mbutton ; float x_change, y_change ; hidden_surface ( screendes , TRUE /* enable hidden surface removal */ , TRUE ) ; /* cull back-facing polygons */ set_locator(inputdes,1,0.0, 0.0, 0.0 ) ; clear_view_surface(screendes); for ( frame = 0, curr_buffer=0; frame < 10000; ++frame ) { sample_locator( inputdes,1,&ok,&x_change,&y_change,&dummy); sample_choice(inputdes,1,&ok,&mbutton); set_locator(inputdes,1,0.0, 0.0, 0.0 ) ; move_camera(x_change,y_change,mbutton) ; zbuffer_switch(screendes,1) ; /* clear z-buffer */ draw_object() ; /* Switch buffers */ curr_buffer = !curr_buffer ; dbuffer_switch( screendes, curr_buffer ) ; make_picture_current( screendes ) ; } } move_camera( x_change, y_change, mbutton ) float x_change ; float y_change ; int mbutton ; { COORD4 toat, out, toward, axis, new_toat, new_up, moveat ; double angle, dot_prod, toat_distance ; int i, j ; MATRIX mx ; static double mmove = 0.1 ; float viewmx[4][4] ; /* find CROSS product of to-at & up */ SUB3_COORD( toat, at, from ) ; CROSS( out, toat, up ) ; /* perpendicularize and normalize up wrto toat */ toat_distance = lib_normalize_coord3( &toat ) ; lib_normalize_coord3( &out ) ; lib_normalize_coord3( &toat ) ; CROSS( up, out, toat ) ; /* find new toat to move to */ toward.x = x_change * out.x - y_change * up.x + toat.x ; toward.y = x_change * out.y - y_change * up.y + toat.y ; toward.z = x_change * out.z - y_change * up.z + toat.z ; /* find angle between toat and new toat */ lib_normalize_coord3( &toward ) ; dot_prod = DOT_PRODUCT( toat, toward ) ; if ( ABSOLUTE(dot_prod) <= 1.000 ) { angle = acos( dot_prod ) ; CROSS( axis, toat, toward ) ; /* angle to rotate */ lib_normalize_coord3( &axis ) ; lib_create_axis_rotate_matrix( mx, &axis, angle ) ; toat.w = 0.0 ; lib_transform_coord( &new_toat, &toat, mx ) ; from.x = at.x - new_toat.x * toat_distance ; from.y = at.y - new_toat.y * toat_distance ; from.z = at.z - new_toat.z * toat_distance ; up.w = 0.0 ; lib_transform_coord( &new_up, &up, mx ) ; COPY_COORD( up, new_up ) ; } SUB3_COORD( toat, at, from ) ; lib_normalize_coord3( &toat ) ; if ( mbutton != 0 ) { moveat.x = toat.x * mmove ; moveat.y = toat.y * mmove ; moveat.z = toat.z * mmove ; mmove = mmove * 1.7 ; if ( mmove > 1.0 ) { mmove = 1.0 ; } if ( mbutton == 2 ) { NEG_COORD( moveat ) ; } ADD2_COORD( from, moveat ) ; ADD2_COORD( at, moveat ) ; } else { mmove = 0.1 ; } camera.camx = from.x ; camera.camy = from.y ; camera.camz = from.z ; camera.upx = up.x ; camera.upy = up.y ; camera.upz = up.z ; camera.refx = camera.camx + toat.x ; camera.refy = camera.camy + toat.y ; camera.refz = camera.camz + toat.z ; /* view right handed coords */ /* for ( i = 0 ; i < 4 ; ++i ) { for ( j = 0 ; j < 4 ; ++j ) { if ( i == j ) { viewmx[i][j] = 1.0 ; } else { viewmx[i][j] = 0.0 ; } } } viewmx[0][0] = -1.0 ; view_matrix3d( screendes, viewmx, POST_CONCAT_VW ) ; */ view_camera( screendes, &camera ) ; } draw_object() { refresh_segment(screendes,SEG_DATA) ; } int create_database(argc,argv) int argc; char *argv[]; { gescape_arg arg1, arg2 ; COORD4 apex ; COORD4 base ; char buffer[BUFSIZE] ; COORD4 center ; FILE *fd ; double hither ; int int_shine ; double kd, ks, shine, t, i_of_r ; int light_flag ; double light_int ; double light_color[3] ; double light_pt[24] ; int num_arg ; int num_light ; int num_vert ; double poly_color[3] ; int polygon_format ; /* 0 - 3pt, 1 - 6pt w/normal */ int spec_flag ; int tot_light ; int tot_vert ; float vert[MAX_EDGES*6] ; int xresolution ; int yresolution ; polygon_format = -1 ; tot_light = 0 ; open_segment(screendes,SEG_DATA,TRUE,TRUE); num_arg = 1 ; do { if ( num_arg >= argc ) { fd = stdin ; } else { if ( ( fd = fopen( argv[num_arg], "r" ) ) == NULL ) { fprintf( stderr, "cannot open file %s. Bye!\n", argv[num_arg] ) ; return( FALSE ) ; } } while ( fgets( buffer, BUFSIZE, fd ) ) { /* polygonal patch */ if ( sscanf( buffer, "pp %d", &tot_vert ) == 1 ) { for ( num_vert = 0 ; num_vert < tot_vert ; ++num_vert ) { fgets( buffer, BUFSIZE, fd ) ; sscanf( buffer, "%f %f %f %f %f %f", &vert[num_vert*6], &vert[num_vert*6+1], &vert[num_vert*6+2], &vert[num_vert*6+3], &vert[num_vert*6+4], &vert[num_vert*6+5] ) ; } if ( polygon_format != 1 ) { polygon_format = 1 ; vertex_format ( screendes , 3 /* 3 extra coordinates */ , 3 /* coordinates used for normal determination */ , FALSE /* no color coordinates */ , FALSE /* 1st vertex is not polygon normal */ , CLOCKWISE ) ; /* polygon vertices are in clockwise order */ } polygon3d(screendes, vert, tot_vert, FALSE ) ; } /* polygon */ else if ( sscanf( buffer, "p %d", &tot_vert ) == 1 ) { for ( num_vert = 0 ; num_vert < tot_vert ; ++num_vert ) { fgets( buffer, BUFSIZE, fd ) ; sscanf( buffer, "%f %f %f", &vert[num_vert*3], &vert[num_vert*3+1], &vert[num_vert*3+2] ) ; } if ( polygon_format != 0 ) { polygon_format = 0 ; vertex_format ( screendes , 0 /* # no extra coordinates */ , 0 /* # coordinates used for normal determination */ , FALSE /* no extra coordinates */ , FALSE /* 1st vertex is not polygon normal */ , CLOCKWISE ) ; /* polygon vertices are in clockwise order */ } polygon3d(screendes, vert, tot_vert, FALSE ) ; } /* sphere */ else if ( sscanf( buffer, "s %lf %lf %lf %lf", ¢er.x, ¢er.y, ¢er.z, ¢er.w ) == 4 ) { if ( polygon_format != 1 ) { polygon_format = 1 ; vertex_format ( screendes , 3 /* 3 extra coordinates */ , 3 /* coordinates used for normal determination */ , FALSE /* no color coordinates */ , FALSE /* 1st vertex is not polygon normal */ , CLOCKWISE ) ; /* polygon vertices are in clockwise order */ } sphere( screendes, ¢er ) ; } /* cylinder / cone */ else if ( buffer[0] == 'c' ) { fgets( buffer, BUFSIZE, fd ) ; sscanf( buffer, "%lf %lf %lf %lf", &base.x, &base.y, &base.z, &base.w ) ; fgets( buffer, BUFSIZE, fd ) ; sscanf( buffer, "%lf %lf %lf %lf", &apex.x, &apex.y, &apex.z, &apex.w ) ; if ( polygon_format != 1 ) { polygon_format = 1 ; vertex_format ( screendes , 3 /* 3 extra coordinates */ , 3 /* coordinates used for normal determination */ , FALSE /* no color coordinates */ , FALSE /* 1st vertex is not polygon normal */ , CLOCKWISE ) ; /* polygon vertices are in clockwise order */ } cylcone( screendes, &base, &apex ) ; } /* fill color */ else if ( sscanf( buffer, "f %lf %lf %lf %lf %lf %lf %lf" , &poly_color[0] , &poly_color[1] , &poly_color[2] , &kd , &ks , &shine , &t , &i_of_r ) == 7 ) { if ( t > 0.0 ) { arg1.i[0] = 0x5A5A ; kd = 1.0 ; } else { arg1.i[0] = 0xFFFF ; } gescape(screendes, TRANSPARENCY, &arg1, &arg2 ) ; fill_color(screendes, (float)(poly_color[0]*kd) , (float)(poly_color[1]*kd) , (float)(poly_color[2]*kd) ) ; spec_flag = ( ks > 0.0 ) ; int_shine = (int)(shine+0.5) ; surface_model(screendes, spec_flag , int_shine >= 1 ? int_shine : 1 , (float)(poly_color[0]*ks) , (float)(poly_color[1]*ks) , (float)(poly_color[2]*ks) ) ; } /* light */ else if ( sscanf( buffer, "l %lf %lf %lf", &light_pt[tot_light*3+0], &light_pt[tot_light*3+1], &light_pt[tot_light*3+2] ) == 3 ) { if ( polygon_format != 1 ) { polygon_format = 1 ; vertex_format ( screendes , 3 /* 3 extra coordinates */ , 3 /* coordinates used for normal determination */ , FALSE /* no color coordinates */ , FALSE /* 1st vertex is not polygon normal */ , CLOCKWISE ) ; /* polygon vertices are in clockwise order */ } arg1.i[0] = 0x5A5A ; gescape(screendes, TRANSPARENCY, &arg1, &arg2 ) ; light_color[0] = 1.0 ; light_color[1] = 1.0 ; light_color[2] = 1.0 ; fill_color(screendes, (float)light_color[0] , (float)light_color[1] , (float)light_color[2] ) ; surface_model(screendes, 1, 1, 0.0,0.0,0.0 ) ; center.x = light_pt[tot_light*3+0] ; center.y = light_pt[tot_light*3+1] ; center.z = light_pt[tot_light*3+2] ; center.w = 0.1 ; sphere( screendes, ¢er ) ; ++tot_light ; } /* view */ else if ( buffer[0] == 'v' ) { fgets( buffer, BUFSIZE, fd ) ; sscanf( buffer, "from %lf %lf %lf", &from.x, &from.y, &from.z ) ; fgets( buffer, BUFSIZE, fd ) ; sscanf( buffer, "at %lf %lf %lf", &at.x, &at.y, &at.z ) ; fgets( buffer, BUFSIZE, fd ) ; sscanf( buffer, "up %lf %lf %lf", &up.x, &up.y, &up.z ) ; fgets( buffer, BUFSIZE, fd ) ; sscanf( buffer, "angle %f", &camera.field_of_view ) ; fgets( buffer, BUFSIZE, fd ) ; sscanf( buffer, "hither %lf", &hither ) ; camera.front = (float)(hither - 1.0) ; fgets( buffer, BUFSIZE, fd ) ; /* ???? unused for now */ sscanf( buffer, "resolution %d %d\n", &xresolution, &yresolution ) ; } /* background color */ else if ( sscanf( buffer, "b %lf %lf %lf", &poly_color[0], &poly_color[1], &poly_color[2] ) == 3 ) { background_color(screendes, (float)poly_color[0],(float)poly_color[1],(float)poly_color[2]) ; clear_view_surface(screendes) ; } /* error */ else { fprintf( stderr, "Error analyzing %s\n", buffer ) ; } } if ( num_arg < argc ) { fclose( fd ) ; } } while ( ++num_arg < argc ) ; close_segment(screendes) ; /* set up lights */ light_flag = 2 ; if ( tot_light == 0 ) { light_ambient(screendes,1.0,1.0,1.0); } else { light_int = sqrt((double)tot_light) / (double)(tot_light*2) ; light_ambient(screendes,(float)light_int,(float)light_int,(float)light_int ) ; for ( num_light = 0 ; num_light < tot_light ; ++num_light ) { light_flag *= 2 ; light_source(screendes,num_light+1,POSITIONAL, (float)light_int,(float)light_int,(float)light_int, (float)light_pt[num_light*3], (float)light_pt[num_light*3+1], (float)light_pt[num_light*3+2] ) ; light_model(screendes,num_light+1, 0,1,10.0,30.0,1.0,1.0,1.0) ; } } light_switch(screendes,light_flag-1); return( TRUE ) ; } /* * Output cylinder or cone. A cylinder is defined as having a radius and an axis * defined by two points, which also define the top and bottom edge of the * cylinder. A cone is defined similarly, the difference being that the apex * and base radii are different. The apex radius is defined as being smaller * than the base radius. Note that the surface exists without endcaps. */ cylcone( fildes, base_pt, apex_pt ) int fildes ; COORD4 *base_pt ; COORD4 *apex_pt ; { double angle ; COORD4 axis ; COORD4 dir ; double divisor ; int i ; COORD4 lip_coord, lip_cnorm ; float lip_pt[24] ; MATRIX mx ; COORD4 norm_axis ; int num_pol ; COORD4 start_norm, start_radius[4] ; SUB3_COORD( axis, (*apex_pt), (*base_pt) ) ; COPY_COORD( norm_axis, axis ) ; lib_normalize_coord3( &norm_axis ) ; dir.x = 0.0 ; dir.y = 0.0 ; dir.z = 1.0 ; dir.w = 0.0 ; CROSS( start_norm, axis, dir ) ; divisor = lib_normalize_coord3( &start_norm ) ; if ( ABSOLUTE( divisor ) < EPSILON ) { dir.x = 1.0 ; dir.y = 0.0 ; dir.z = 0.0 ; CROSS( start_norm, axis, dir ) ; lib_normalize_coord3( &start_norm ) ; } start_radius[0].x = start_norm.x * base_pt->w ; start_radius[0].y = start_norm.y * base_pt->w ; start_radius[0].z = start_norm.z * base_pt->w ; start_radius[0].w = 0.0 ; lip_pt[0] = base_pt->x + start_radius[0].x ; lip_pt[1] = base_pt->y + start_radius[0].y ; lip_pt[2] = base_pt->z + start_radius[0].z ; start_radius[1].x = start_norm.x * apex_pt->w ; start_radius[1].y = start_norm.y * apex_pt->w ; start_radius[1].z = start_norm.z * apex_pt->w ; start_radius[1].w = 0.0 ; lip_pt[6] = apex_pt->x + start_radius[1].x ; lip_pt[7] = apex_pt->y + start_radius[1].y ; lip_pt[8] = apex_pt->z + start_radius[1].z ; lip_pt[3] = lip_pt[9] = start_norm.x ; lip_pt[4] = lip_pt[10] = start_norm.y ; lip_pt[5] = lip_pt[11] = start_norm.z ; for ( num_pol = 0 ; num_pol < 4*OUT_RESOLUTION ; ++num_pol ) { for ( i = 0 ; i < 6 ; ++i ) { lip_pt[i+18] = lip_pt[i] ; lip_pt[i+12] = lip_pt[i+6] ; } angle = 2.0 * PI * (double)( num_pol+1 ) / (double)( 4*OUT_RESOLUTION ) ; lib_create_axis_rotate_matrix( mx, &norm_axis, angle ) ; lib_transform_coord( &lip_coord, &start_radius[0], mx ) ; ADD2_COORD( lip_coord, (*base_pt) ) ; lip_pt[0] = lip_coord.x ; lip_pt[1] = lip_coord.y ; lip_pt[2] = lip_coord.z ; lib_transform_coord( &lip_coord, &start_radius[1], mx ) ; ADD2_COORD( lip_coord, (*apex_pt) ) ; lip_pt[6] = lip_coord.x ; lip_pt[7] = lip_coord.y ; lip_pt[8] = lip_coord.z ; lib_transform_coord( &lip_cnorm, &start_norm, mx ) ; lip_pt[3] = lip_pt[9] = lip_cnorm.x ; lip_pt[4] = lip_pt[10] = lip_cnorm.y ; lip_pt[5] = lip_pt[11] = lip_cnorm.z ; polygon3d( fildes, lip_pt, 4, FALSE ) ; } } /* * Output sphere. A sphere is defined by a radius and center position. */ sphere( fildes, center_pt ) int fildes ; COORD4 *center_pt ; { double angle ; float edge_pt[18] ; int num_face, num_edge, num_tri, num_vert ; COORD4 x_axis[OUT_RESOLUTION+1], y_axis[OUT_RESOLUTION+1] ; COORD4 pt[OUT_RESOLUTION+1][OUT_RESOLUTION+1] ; COORD4 mid_axis ; MATRIX rot_mx ; int u_pol, v_pol ; int u_vert, v_vert ; /* calculate axes used to find grid points */ for ( num_edge = 0 ; num_edge <= OUT_RESOLUTION ; ++num_edge ) { angle = (PI/4.0) * ( 2.0*(double)num_edge/OUT_RESOLUTION - 1.0 ) ; mid_axis.w = 0.0 ; mid_axis.x = 1.0 ; mid_axis.y = 0.0 ; mid_axis.z = 0.0 ; lib_create_rotate_matrix( rot_mx, Y_AXIS, angle ) ; lib_transform_coord( &x_axis[num_edge], &mid_axis, rot_mx ) ; mid_axis.x = 0.0 ; mid_axis.y = 1.0 ; mid_axis.z = 0.0 ; lib_create_rotate_matrix( rot_mx, X_AXIS, angle ) ; lib_transform_coord( &y_axis[num_edge], &mid_axis, rot_mx ) ; } /* set up grid of points on +Z sphere surface */ for ( u_pol = 0 ; u_pol <= OUT_RESOLUTION ; ++u_pol ) { for ( v_pol = 0 ; v_pol <= OUT_RESOLUTION ; ++v_pol ) { CROSS( pt[u_pol][v_pol], x_axis[u_pol], y_axis[v_pol] ) ; lib_normalize_coord3( &pt[u_pol][v_pol] ) ; pt[u_pol][v_pol].w = 1.0 ; } } for ( num_face = 0 ; num_face < 6 ; ++num_face ) { /* transform points to cube face */ for ( u_pol = 0 ; u_pol <= OUT_RESOLUTION ; ++u_pol ) { for ( v_pol = 0 ; v_pol <= OUT_RESOLUTION ; ++v_pol ) { lib_rotate_cube_face( &pt[u_pol][v_pol] , Z_AXIS , num_face ) ; } } /* output grid */ for ( u_pol = 0 ; u_pol < OUT_RESOLUTION ; ++u_pol ) { for ( v_pol = 0 ; v_pol < OUT_RESOLUTION ; ++v_pol ) { for ( num_tri = 0 ; num_tri < 2 ; ++num_tri ) { for ( num_edge = 0 ; num_edge < 3 ; ++num_edge ) { num_vert = (num_tri*2 + num_edge) % 4 ; if ( num_vert == 0 ) { u_vert = u_pol ; v_vert = v_pol ; } else if ( num_vert == 1 ) { u_vert = u_pol ; v_vert = v_pol + 1 ; } else if ( num_vert == 2 ) { u_vert = u_pol + 1 ; v_vert = v_pol + 1 ; } else { u_vert = u_pol + 1 ; v_vert = v_pol ; } edge_pt[num_edge*6+3] = pt[u_vert][v_vert].x ; edge_pt[num_edge*6+4] = pt[u_vert][v_vert].y ; edge_pt[num_edge*6+5] = pt[u_vert][v_vert].z ; edge_pt[num_edge*6+0] = edge_pt[num_edge*6+3] * center_pt->w + center_pt->x ; edge_pt[num_edge*6+1] = edge_pt[num_edge*6+4] * center_pt->w + center_pt->y ; edge_pt[num_edge*6+2] = edge_pt[num_edge*6+5] * center_pt->w + center_pt->z ; } polygon3d( fildes, edge_pt, 3, FALSE ) ; } } } } } int devopen(dev_kind,init_mode) int dev_kind,init_mode; { char *dev, *driver; int fildes ; if ( dev_kind == OUTDEV ) { dev = getenv("OUTDEV"); if (!dev) dev = default_outdev ; driver = getenv("OUTDRIVER"); if (!driver) driver = default_outdriver ; } else { dev = getenv("INDEV"); if (!dev) dev = default_indev ; driver = getenv("INDRIVER"); if (!driver) driver = default_indriver ; } fildes = gopen(dev,dev_kind,driver,init_mode); return(fildes) ; } @EOF chmod 644 lookat.c echo x - makefile cat >makefile <<'@EOF' # cc = C compiler # -c compile only, do not try to link # -g debug mode # -O optimize # -p monitor timing # -Wc,-Yf use floating point numbers as themselves - don't convert # this option has problems - not sure what to do CC=cc -c -O INC=def.h lib.h BASELIB=-lm -lmalloc all: lookat lib.o: $(INC) lib.c $(CC) lib.c lookat: lib.o lookat.o cc -o lookat lookat.o lib.o -lsbdl \ -ldd98721 -ldd98731 -lddhil -lsb1 -lsb2 $(BASELIB) lookat.o: $(INC) lookat.c $(CC) lookat.c @EOF chmod 644 makefile echo x - pol005.nff cat >pol005.nff <<'@EOF' v from 1.77033 1.52969 0.164572 at -0.258552 -0.643251 -2.17386 up 0 1 0 angle 45 hither 1 resolution 512 512 b 0.078 0.361 0.753 l 10 10 10 l 10 -8 -12 l -8 12 -10 l -12 -10 8 f 1 1 1 1 0 0 0 0 p 5 -0.636237 -0.993877 -2.45654 -0.193076 -0.100015 -2.38857 -0.0252202 -1.08063 -2.4897 -0.739978 -0.387826 -2.39404 0.248668 -0.528189 -2.44769 f 1 0.1 0.1 1 0 0 0 0 p 5 -0.193076 -0.100015 -2.38857 -0.636237 -0.993877 -2.45654 -0.491883 -0.205877 -1.85803 -0.282292 -0.587026 -2.75847 -0.765771 -0.758314 -1.90004 f 0 1 0.1 1 0 0 0 0 p 5 -0.0252202 -1.08063 -2.4897 -0.193076 -0.100015 -2.38857 0.222874 -0.898677 -1.95368 -0.282292 -0.587026 -2.75847 0.119134 -0.292626 -1.89118 f 0 0.1 1 1 0 0 0 0 p 5 -0.739978 -0.387826 -2.39404 -0.0252202 -1.08063 -2.4897 -0.765771 -0.758314 -1.90004 -0.282292 -0.587026 -2.75847 -0.324027 -1.18649 -1.95915 f 0 1 1 1 0 0 0 0 p 5 0.248668 -0.528189 -2.44769 -0.739978 -0.387826 -2.39404 0.119134 -0.292626 -1.89118 -0.282292 -0.587026 -2.75847 -0.491883 -0.205877 -1.85803 f 1 0.1 1 1 0 0 0 0 p 5 -0.636237 -0.993877 -2.45654 0.248668 -0.528189 -2.44769 -0.324027 -1.18649 -1.95915 -0.282292 -0.587026 -2.75847 0.222874 -0.898677 -1.95368 f 1 1 0.1 1 0 0 0 0 p 5 0.119134 -0.292626 -1.89118 -0.765771 -0.758314 -1.90004 0.222874 -0.898677 -1.95368 -0.491883 -0.205877 -1.85803 -0.324027 -1.18649 -1.95915 f 1 1 1 1 0 0 0 0 p 5 -0.765771 -0.758314 -1.90004 0.119134 -0.292626 -1.89118 -0.739978 -0.387826 -2.39404 -0.234811 -0.699477 -1.58925 -0.193076 -0.100015 -2.38857 f 1 0.1 0.1 1 0 0 0 0 p 5 0.222874 -0.898677 -1.95368 -0.765771 -0.758314 -1.90004 -0.0252202 -1.08063 -2.4897 -0.234811 -0.699477 -1.58925 -0.636237 -0.993877 -2.45654 f 0 1 0.1 1 0 0 0 0 p 5 -0.491883 -0.205877 -1.85803 0.222874 -0.898677 -1.95368 -0.193076 -0.100015 -2.38857 -0.234811 -0.699477 -1.58925 0.248668 -0.528189 -2.44769 f 0 0.1 1 1 0 0 0 0 p 5 -0.324027 -1.18649 -1.95915 -0.491883 -0.205877 -1.85803 -0.636237 -0.993877 -2.45654 -0.234811 -0.699477 -1.58925 -0.739978 -0.387826 -2.39404 f 0 1 1 1 0 0 0 0 p 5 0.119134 -0.292626 -1.89118 -0.324027 -1.18649 -1.95915 0.248668 -0.528189 -2.44769 -0.234811 -0.699477 -1.58925 -0.0252202 -1.08063 -2.4897 @EOF chmod 644 pol005.nff echo x - pol006.nff cat >pol006.nff <<'@EOF' v from 5.65079 1.45769 2.28561 at 2.04071 -2.10085 -1.14963 up 0 1 0 angle 45 hither 1 resolution 512 512 b 0.078 0.361 0.753 l 10 10 10 l 10 -8 -12 l -8 12 -10 l -12 -10 8 f 1 1 1 1 0 0 0 0 p 5 1.4296 -1.42108 -1.41224 2.37642 -1.21122 -1.16835 2.94323 -1.99263 -1.42936 2.34671 -2.68543 -1.83457 1.41123 -2.33219 -1.82399 f 1 0.1 0.1 1 0 0 0 0 p 5 2.37642 -1.21122 -1.16835 1.4296 -1.42108 -1.41224 1.13819 -2.20908 -0.869896 1.90491 -2.48623 -0.290821 2.67018 -1.86951 -0.475274 f 0 1 0.1 1 0 0 0 0 p 5 2.94323 -1.99263 -1.42936 2.37642 -1.21122 -1.16835 1.7347 -1.51628 -0.464689 1.90491 -2.48623 -0.290821 2.65181 -2.78063 -0.887023 f 0 0.1 1 1 0 0 0 0 p 5 2.34671 -2.68543 -1.83457 2.94323 -1.99263 -1.42936 2.67018 -1.86951 -0.475274 1.90491 -2.48623 -0.290821 1.70499 -2.99049 -1.13091 f 0 1 1 1 0 0 0 0 p 5 1.41123 -2.33219 -1.82399 2.34671 -2.68543 -1.83457 2.65181 -2.78063 -0.887023 1.90491 -2.48623 -0.290821 1.13819 -2.20908 -0.869896 f 1 0.1 1 1 0 0 0 0 p 5 1.4296 -1.42108 -1.41224 1.41123 -2.33219 -1.82399 1.70499 -2.99049 -1.13091 1.90491 -2.48623 -0.290821 1.7347 -1.51628 -0.464689 f 1 1 0.1 1 0 0 0 0 p 5 2.65181 -2.78063 -0.887023 2.67018 -1.86951 -0.475274 1.7347 -1.51628 -0.464689 1.13819 -2.20908 -0.869896 1.70499 -2.99049 -1.13091 f 1 1 1 1 0 0 0 0 p 5 2.67018 -1.86951 -0.475274 2.65181 -2.78063 -0.887023 2.34671 -2.68543 -1.83457 2.17651 -1.71548 -2.00844 2.37642 -1.21122 -1.16835 f 1 0.1 0.1 1 0 0 0 0 p 5 1.7347 -1.51628 -0.464689 2.67018 -1.86951 -0.475274 2.94323 -1.99263 -1.42936 2.17651 -1.71548 -2.00844 1.4296 -1.42108 -1.41224 f 0 1 0.1 1 0 0 0 0 p 5 1.13819 -2.20908 -0.869896 1.7347 -1.51628 -0.464689 2.37642 -1.21122 -1.16835 2.17651 -1.71548 -2.00844 1.41123 -2.33219 -1.82399 f 0 0.1 1 1 0 0 0 0 p 5 1.70499 -2.99049 -1.13091 1.13819 -2.20908 -0.869896 1.4296 -1.42108 -1.41224 2.17651 -1.71548 -2.00844 2.34671 -2.68543 -1.83457 f 0 1 1 1 0 0 0 0 p 5 2.65181 -2.78063 -0.887023 1.70499 -2.99049 -1.13091 1.41123 -2.33219 -1.82399 2.17651 -1.71548 -2.00844 2.94323 -1.99263 -1.42936 @EOF chmod 644 pol006.nff echo x - tetra.nff cat >tetra.nff <<'@EOF' v from 1.02285 -3.17715 -2.17451 at -0.004103 -0.004103 0.216539 up -0.816497 -0.816497 0.816497 angle 45 hither 1 resolution 512 512 b 0.078 0.361 0.753 l 1.87607 -18.1239 -5.00042 f 1 0.2 0.2 1 0 0 0 0 p 3 -1 -1 1 -1 -0.5 0.5 -0.5 -1 0.5 p 3 -0.5 -0.5 1 -0.5 -1 0.5 -1 -0.5 0.5 p 3 -0.5 -1 0.5 -0.5 -0.5 1 -1 -1 1 p 3 -1 -0.5 0.5 -1 -1 1 -0.5 -0.5 1 p 3 -1 -0.5 0.5 -1 0 0 -0.5 -0.5 0 p 3 -0.5 0 0.5 -0.5 -0.5 0 -1 0 0 p 3 -0.5 -0.5 0 -0.5 0 0.5 -1 -0.5 0.5 p 3 -1 0 0 -1 -0.5 0.5 -0.5 0 0.5 p 3 -0.5 -1 0.5 -0.5 -0.5 0 0 -1 0 p 3 0 -0.5 0.5 0 -1 0 -0.5 -0.5 0 p 3 0 -1 0 0 -0.5 0.5 -0.5 -1 0.5 p 3 -0.5 -0.5 0 -0.5 -1 0.5 0 -0.5 0.5 p 3 -0.5 -0.5 1 -0.5 0 0.5 0 -0.5 0.5 p 3 0 0 1 0 -0.5 0.5 -0.5 0 0.5 p 3 0 -0.5 0.5 0 0 1 -0.5 -0.5 1 p 3 -0.5 0 0.5 -0.5 -0.5 1 0 0 1 p 3 -1 0 0 -1 0.5 -0.5 -0.5 0 -0.5 p 3 -0.5 0.5 0 -0.5 0 -0.5 -1 0.5 -0.5 p 3 -0.5 0 -0.5 -0.5 0.5 0 -1 0 0 p 3 -1 0.5 -0.5 -1 0 0 -0.5 0.5 0 p 3 -1 0.5 -0.5 -1 1 -1 -0.5 0.5 -1 p 3 -0.5 1 -0.5 -0.5 0.5 -1 -1 1 -1 p 3 -0.5 0.5 -1 -0.5 1 -0.5 -1 0.5 -0.5 p 3 -1 1 -1 -1 0.5 -0.5 -0.5 1 -0.5 p 3 -0.5 0 -0.5 -0.5 0.5 -1 0 0 -1 p 3 0 0.5 -0.5 0 0 -1 -0.5 0.5 -1 p 3 0 0 -1 0 0.5 -0.5 -0.5 0 -0.5 p 3 -0.5 0.5 -1 -0.5 0 -0.5 0 0.5 -0.5 p 3 -0.5 0.5 0 -0.5 1 -0.5 0 0.5 -0.5 p 3 0 1 0 0 0.5 -0.5 -0.5 1 -0.5 p 3 0 0.5 -0.5 0 1 0 -0.5 0.5 0 p 3 -0.5 1 -0.5 -0.5 0.5 0 0 1 0 p 3 0 -1 0 0 -0.5 -0.5 0.5 -1 -0.5 p 3 0.5 -0.5 0 0.5 -1 -0.5 0 -0.5 -0.5 p 3 0.5 -1 -0.5 0.5 -0.5 0 0 -1 0 p 3 0 -0.5 -0.5 0 -1 0 0.5 -0.5 0 p 3 0 -0.5 -0.5 0 0 -1 0.5 -0.5 -1 p 3 0.5 0 -0.5 0.5 -0.5 -1 0 0 -1 p 3 0.5 -0.5 -1 0.5 0 -0.5 0 -0.5 -0.5 p 3 0 0 -1 0 -0.5 -0.5 0.5 0 -0.5 p 3 0.5 -1 -0.5 0.5 -0.5 -1 1 -1 -1 p 3 1 -0.5 -0.5 1 -1 -1 0.5 -0.5 -1 p 3 1 -1 -1 1 -0.5 -0.5 0.5 -1 -0.5 p 3 0.5 -0.5 -1 0.5 -1 -0.5 1 -0.5 -0.5 p 3 0.5 -0.5 0 0.5 0 -0.5 1 -0.5 -0.5 p 3 1 0 0 1 -0.5 -0.5 0.5 0 -0.5 p 3 1 -0.5 -0.5 1 0 0 0.5 -0.5 0 p 3 0.5 0 -0.5 0.5 -0.5 0 1 0 0 p 3 0 0 1 0 0.5 0.5 0.5 0 0.5 p 3 0.5 0.5 1 0.5 0 0.5 0 0.5 0.5 p 3 0.5 0 0.5 0.5 0.5 1 0 0 1 p 3 0 0.5 0.5 0 0 1 0.5 0.5 1 p 3 0 0.5 0.5 0 1 0 0.5 0.5 0 p 3 0.5 1 0.5 0.5 0.5 0 0 1 0 p 3 0.5 0.5 0 0.5 1 0.5 0 0.5 0.5 p 3 0 1 0 0 0.5 0.5 0.5 1 0.5 p 3 0.5 0 0.5 0.5 0.5 0 1 0 0 p 3 1 0.5 0.5 1 0 0 0.5 0.5 0 p 3 1 0 0 1 0.5 0.5 0.5 0 0.5 p 3 0.5 0.5 0 0.5 0 0.5 1 0.5 0.5 p 3 0.5 0.5 1 0.5 1 0.5 1 0.5 0.5 p 3 1 1 1 1 0.5 0.5 0.5 1 0.5 p 3 1 0.5 0.5 1 1 1 0.5 0.5 1 p 3 0.5 1 0.5 0.5 0.5 1 1 1 1 @EOF chmod 644 tetra.nff exit 0
spirit@uxe.cso.uiuc.edu (05/19/89)
Hello, Just a note about the above viewer... We tried to compile it on our HP9000/835 and SRX. We have Starbase and GKS. Unfortunately and include file "sbdl.c.h" and a library "-lsbdl" are required. Does anybody have these things? The specific calls used therein are all related to creating, drawing, and closing segments. Good luck, spirit@uxe.cso.uiuc.edu
stroyan@hpfcdc.HP.COM (Mike Stroyan) (05/22/89)
> We tried to compile it on our HP9000/835 and > SRX. We have Starbase and GKS. > > Unfortunately and include file "sbdl.c.h" > and a library "-lsbdl" are required. Does > anybody have these things? The header and library are from the "Starbase Display List". It is a separate product that you would have to purchase in addition to Starbase. Mike Stroyan, stroyan@hpfcla.hp.com
lavar@grlab.UUCP (LaVar Edwards) (05/24/89)
/ grlab:comp.sys.hp / stroyan@hpfcdc.HP.COM (Mike Stroyan) / 1:33 pm May 21, 1989 / >> We tried to compile it on our HP9000/835 and >> SRX. We have Starbase and GKS. >> >> Unfortunately and include file "sbdl.c.h" >> and a library "-lsbdl" are required. Does >> anybody have these things? > >The header and library are from the "Starbase Display List". It is a >separate product that you would have to purchase in addition to Starbase. > >Mike Stroyan, stroyan@hpfcla.hp.com We own the product HP-UX Display List (98674L Rev. 6.5) on our 370. This was purchased with our 370 less than 2 months ago. Unfortunately and include file "sbdl.c.h" and a library "-lsbdl" are NOT on our system, any suggestions? We also own Display List on our 320 and 825 and we do not have these libraries on any of our systems. LaVar Edwards USPS: Graphicus UUCP: ...!hpubvwa!grlab!lavar 150 Lake St., Suite 206 VoicePh: USA (206) 828-4691 Kirkland, WA 98033 FAX: USA (206) 828-4236
cnsy@vax5.CIT.CORNELL.EDU (05/24/89)
In article <47500010@uxe.cso.uiuc.edu> spirit@uxe.cso.uiuc.edu writes: > > >Hello, > >Just a note about the above viewer... >We tried to compile it on our HP9000/835 and >SRX. We have Starbase and GKS. > >Unfortunately and include file "sbdl.c.h" >and a library "-lsbdl" are required. Does >anybody have these things? Sorry about that--I forgot that the Starbase Display List software is not a standard product on every HP machine. One solution would be to rip out all the interactive code in lookat.c (mouse calls, and associated loops to refresh the segment), all SBDL *_segment() code, and to perform the lights setup in draw_object() immediately upon encountering a "f" command in the *.nff files (not fool-proof, but all my NFF generators from the SPD package do not output any "f" (fill color) commands until all lights are output). Alternately, wait a few days and I'll post my lookonce.c code, which does not have any sbdl calls (it's not interactive, though). BTW, if you're doing anything 3D & interactive, you should seriously consider getting the SBDL package, as it'll save you a lot of reinventing the wheel. Eric Haines, 3D/Eye Inc
rodean@hpfcdc.HP.COM (Bruce Rodean) (05/27/89)
In article <240036@grlab.UUCP> lavar@grlab.UUCP (LaVar Edwards) writes: >>> We tried to compile it on our HP9000/835 and >>> SRX. We have Starbase and GKS. >>> >>> Unfortunately and include file "sbdl.c.h" >>> and a library "-lsbdl" are required. Does >>> anybody have these things? >> >>The header and library are from the "Starbase Display List". It is a >>separate product that you would have to purchase in addition to Starbase. >> >>Mike Stroyan, stroyan@hpfcla.hp.com >We own the product HP-UX Display List (98674L Rev. 6.5) on our 370. >This was purchased with our 370 less than 2 months ago. >Unfortunately and include file "sbdl.c.h" and a library "-lsbdl" >are NOT on our system, any suggestions? If the Starbase Display List product has been installed on your system, you should find a file called /etc/filesets/SBDL. That file is a list of the files that the update program placed on your system. You should find both /usr/include/sbdl.c.h and /usr/lib/libsbdl.a listed in that file. If that file is missing, then SBDL is not on your system. The appropriate revision information for Release 6.5 is: # what libsbdl.a libsbdl.a: 250.1.2.1 01/27/89 libsbdl.a # what sbdl.c.h sbdl.c.h: sbdl.c.h 01/27/89 07:56:17 */ Bruce Rodean rodean%hpfcrn@hplabs.HP.COM
stroyan@hpfcdc.HP.COM (Mike Stroyan) (05/27/89)
> We own the product HP-UX Display List (98674L Rev. 6.5) on our 370. > This was purchased with our 370 less than 2 months ago. > > Unfortunately and include file "sbdl.c.h" and a library "-lsbdl" > are NOT on our system, any suggestions? Read the files off the "Starbase Display List" install tape again. Those files are on the tape. Mike Stroyan, stroyan@hpfcla.hp.com