/* FILE pazstore.c declarations of functions to play with paz storage types Phil Atkin (c) Division Ltd. 1991 */ #include #include #include #include #include "pazpl5.h" #include "macros.h" #include "matrix.h" /*{{{ static float vertex_max ( VERTEX *p, int axis)*/ static float vertex_max ( VERTEX *p, int axis) { float t=p->position[axis]; for (p=p->next; p!=NULL; p=p->next ) t=max_of(p->position[axis], t); return(t); } /*}}} */ /*{{{ static float vertex_min ( VERTEX *p, int axis)*/ static float vertex_min ( VERTEX *p, int axis) { float t=p->position[axis]; for (p=p->next; p!=NULL; p=p->next ) t=min_of(p->position[axis], t); return(t); } /*}}} */ /*{{{ void build_bound ( POINT *bound, POINT mini, POINT maxi )*/ void build_bound ( POINT *bound, POINT mini, POINT maxi ) { /* this leaves mini in 0, maxi in 7 */ int i, j, k; for (i=0; i<2; i++ ) { for (j=0; j<2; j++ ) { for (k=0; k<2; k++ ) { float *b=(float *) bound; if (k&1) b[X]=maxi[X]; else b[X]=mini[X]; if (j&1) b[Y]=maxi[Y]; else b[Y]=mini[Y]; if (i&1) b[Z]=maxi[Z]; else b[Z]=mini[Z]; b[W]=1.0f; bound++; } } } } /*}}} */ /*{{{ void bound_patch ( PATCH *p )*/ void bound_patch ( PATCH *p ) { int axis; POINT mini, maxi; VSTRIP *v=p->head; if (p==NULL) { printf ("Attempt to bound NULL patch\n" ); return; } else if (p->head == NULL) { printf ("Attempt to bound empty patch\n" ); return; } for (axis=X; axishead, axis ); maxi[axis]=vertex_max(v->head, axis ); } if (p->patch_type == patch_type_patch) { for (v=v->next; v!=NULL; v=v->next ) { for (axis=X; axishead, axis )); maxi[axis]=max_of(maxi[axis], vertex_max(v->head, axis )); } } } build_bound ( p->bound, mini, maxi ); } /*}}} */ /*{{{ static float sphere_max ( VERTEX *p, int axis)*/ static float sphere_max ( VERTEX *p, int axis) { float t=p->position[axis]+p->position[W]; for (p=p->next; p!=NULL; p=p->next ) { float tt=p->position[axis]+p->position[W]; t=max_of(tt, t ); } return(t); } /*}}} */ /*{{{ static float sphere_min ( VERTEX *p, int axis)*/ static float sphere_min ( VERTEX *p, int axis) { float t=p->position[axis]-p->position[W]; for (p=p->next; p!=NULL; p=p->next ) { float tt=p->position[axis]-p->position[W]; t=min_of(tt, t); } return(t); } /*}}} */ /*{{{ void bound_spatch ( PATCH *p )*/ void bound_spatch ( PATCH *p ) { int axis; POINT mini, maxi; VSTRIP *v=p->head; if (p==NULL) { printf ("Attempt to bound NULL patch\n" ); return; } else if (p->head == NULL) { printf ("Attempt to bound empty patch\n" ); return; } for (axis=X; axishead, axis ); maxi[axis]=sphere_max(v->head, axis ); } for (v=v->next; v!=NULL; v=v->next ) { for (axis=X; axishead, axis )); maxi[axis]=max_of(maxi[axis], sphere_max(v->head, axis )); } } build_bound ( p->bound, mini, maxi ); } /*}}} */ /*{{{ void reboundLOD ( LOD *o )*/ void reboundLOD ( LOD *o ) { int axis; POINT mini, maxi; PATCH *p=o->head; memcpy(mini, p->bound, sizeof(POINT)); memcpy(maxi, p->bound[7], sizeof(POINT)); for (p=p->next; p!=NULL; p=p->next ) { POINT *vmin=p->bound; POINT *vmax=vmin+7; for (axis=X; axisbound[8][axis]=(mini[axis]+maxi[axis]) * 0.5f; build_bound ( o->bound, mini, maxi ); } /*}}} */ /*{{{ void _BoundLOD ( LOD *o )*/ void _BoundLOD ( LOD *o ) { int axis; POINT mini, maxi; PATCH *p=o->head; bound_patch ( p ); memcpy(mini, p->bound, sizeof(POINT)); memcpy(maxi, p->bound[7], sizeof(POINT)); for (p=p->next; p!=NULL; p=p->next ) { POINT *vmin=p->bound; POINT *vmax=vmin+7; bound_patch ( p ); for (axis=X; axisbound[8][axis]=(mini[axis]+maxi[axis]) * 0.5f; build_bound ( o->bound, mini, maxi ); } /*}}} */ /* PAZ library calls */ /*{{{ void reboundObject ( OBJECT *o )*/ void reboundObject ( OBJECT *o ) { int axis; POINT mini, maxi; LOD *l=o->head; memcpy(mini, l->bound, sizeof(POINT)); memcpy(maxi, l->bound[7], sizeof(POINT)); for (l=l->next; l!=NULL; l=l->next ) { POINT *vmin=l->bound; POINT *vmax=vmin+7; for (axis=X; axisbound, mini, maxi ); } /*}}} */ /*{{{ void _BoundObject ( OBJECT *o )*/ void _BoundObject ( OBJECT *o ) { int axis; POINT mini, maxi; LOD *l=o->head; _BoundLOD ( l ); memcpy(mini, l->bound, sizeof(POINT)); memcpy(maxi, l->bound[7], sizeof(POINT)); for (l=l->next; l!=NULL; l=l->next ) { POINT *vmin=l->bound; POINT *vmax=vmin+7; _BoundLOD ( l ); for (axis=X; axisbound, mini, maxi ); } /*}}} */ /*{{{ void _InitVertex ( VERTEX *v )*/ void _InitVertex ( VERTEX *v ) { checkNull ( v, " initVertex" ); v->next=NULL; } /*}}} */ /*{{{ void _InitVstrip ( VSTRIP *v )*/ void _InitVstrip ( VSTRIP *v ) { checkNull ( v, " initVstrip" ); v->next=NULL; v->head=NULL; v->tail=NULL; v->vertex_count=0; } /*}}} */ /*{{{ void _InitPatch ( PATCH *p )*/ void _InitPatch ( PATCH *p ) { checkNull ( p, " initPatch" ); p->fmaterial=NULL; p->bmaterial=NULL; p->next=NULL; p->head=NULL; p->tail=NULL; } /*}}} */ /*{{{ void _InitObject ( OBJECT *p )*/ void _InitObject ( OBJECT *p ) { checkNull ( p, " initObject" ); p->next=NULL; p->head=NULL; p->tail=NULL; } /*}}} */ /*{{{ void _InitLOD ( LOD *l )*/ void _InitLOD ( LOD *l ) { checkNull ( l, " initLOD" ); l->next=NULL; l->head=NULL; l->tail=NULL; } /*}}} */ /*{{{ void _InitLight ( LIGHTSOURCE *l )*/ void _InitLight ( LIGHTSOURCE *l ) { checkNull ( l, " initLight" ); l->next=NULL; } /*}}} */ /*{{{ void _InitView ( VIEW *v )*/ void _InitView ( VIEW *v ) { int *t; char *s=" initView"; checkNull ( v, s ); t=(int *) malloc(32); /* URGH link_poly_list ? */ checkNull ( t, s ); v->buffer_A=t; v->buffer_B=v->buffer_A; /* this is IMPORTANT */ _idmatrix( v->f ); _idmatrix( v->b ); v->next=NULL; } /*}}} */ /*{{{ void _InitInstance ( INSTANCE *p )*/ void _InitInstance ( INSTANCE *p ) { int i; checkNull ( p, " initInstance" ); p->next=NULL; p->nest=NULL; p->link=NULL; p->daddy=NULL; /* uplink to parent */ p->obj=NULL; p->lastLODscale=0.0f; p->lastLODindex=0; p->enable=3; p->billboard=0; p->f_material=NULL; p->b_material=NULL; p->f_texture=NULL; p->b_texture=NULL; _idmatrix( p->f ); _idmatrix( p->b ); } /*}}} */ /*{{{ void _InitScene ( SCENE *p )*/ void _InitScene ( SCENE *p ) { checkNull ( p, " initScene" ); p->next=NULL; p->instances.head=NULL; p->lights.head=NULL; p->eyes.head=NULL; } /*}}} */ /*{{{ void _LinkVertices ( VERTEX *start, int vertices )*/ void _LinkVertices ( VERTEX *start, int vertices ) { VERTEX *v=start; int i; for (i=1; inext=v+1; v=v->next; } v->next=NULL; } /*}}} */ /*{{{ PAZlist manipulation*/ /* PAZlists are generic lists, with next, prev and data pointers. The data pointer is cast to a void*, so we can link together anything */ /*{{{ PAZlist *findPAZitem ( void *item, PAZlist **head, PAZlist **tail )*/ PAZlist *findPAZitem ( void *item, PAZlist **head, PAZlist **tail ) { PAZlist *p=*head; while (p) { if (p->data == item) return p; p=p->next; } return NULL; } /*}}} */ /*{{{ void addPAZitem ( void *item, PAZlist **head, PAZlist **tail )*/ void addPAZitem ( void *item, PAZlist **head, PAZlist **tail ) { PAZlist *p=(PAZlist *) malloc ( sizeof(PAZlist)); if (*head == NULL) { *head=p; *tail=p; p->next=NULL; p->prev=NULL; p->data=item; } else { p->prev=NULL; p->next=*head; p->next->prev=p; *head=p; p->data=item; } } /*}}} */ /*{{{ void *removePAZitem ( PAZlist *p, PAZlist **head, PAZlist **tail )*/ void *removePAZitem ( PAZlist *p, PAZlist **head, PAZlist **tail ) { PAZlist *prevItem, *nextItem; void *contents; /* printf ("removePAZitem\n" ); */ if (p==NULL) { /* printf ( "NULL parameter, returning\n" ); */ return NULL; } else { contents=p->data; } prevItem=p->prev; nextItem=p->next; if (prevItem==NULL) { /* printf ( "prev==NULL, I am HEAD\n" ); */ *head=nextItem; } else { /* printf ( "prev NOT NULL, patching prev->next to old next\n" ); */ prevItem->next=nextItem; } if (nextItem==NULL) { /* printf ( "next==NULL, I am TAIL\n" ); */ *tail=prevItem; } else { /* printf ( "next NOT NULL, patching next->prev to old prev\n" ); */ nextItem->prev=prevItem; } free(p); return contents; } /*}}} */ /*}}} */ /*{{{ declare globals*/ VIEW *left=NULL, *right=NULL; VERTEX *render_strip=NULL; int output_device=0; int link_A=0, link_B=0; int raster=0, flip=0; OBJLIST sceneGeometry; /*}}} */