/* File lighting.c Contains the functions involved with lighting the scene currently compile with -opt 4 Phil Atkin (c) Division Ltd. 1991, 1992 Modifications 16th Dec 1992 new Phong shader, requires &H vector in bulb->xformpos[3] */ #include #include #include #include "dpltypes.h" #include "macros.h" #include "speclght.h" /*{{{ #define dot(d,a,b)*/ #define dot(d,a,b) \ ax=*a++; bx=*b++; ay=*a++; by=*b++; az=*a++; bz=*b++; \ d=((ax*bx)+(ay*by)+(az*bz)) /*}}} */ /*{{{ #define sdot(d,a,b)*/ #define sdot(d,a,b,cook) \ ax=*a++; bx=*b++; ay=*a++; by=*b++; az=*a++; bz=*b++; \ d=cook*((ax*bx)+(ay*by)+(az*bz)) /*}}} */ /*{{{ void traceLights ( dpl_LMODEL *head )*/ void traceLights ( dpl_LMODEL *head ) { dpl_list *list=head->light_list; printf ("Trace_lights\n" ); while (list) { dpl_LIGHT *l=(dpl_LIGHT *) list->item; printf ("Bulb 0x%x type 0x%x pos %f,%f,%f\n", (int) head, head->positional, head->position[0], head->position[1], head->position[2] ); list=list->next; } } /*}}} */ /*{{{ void reorderLights ( LIGHTSOURCE *head )*/ void reorderLights ( LIGHTSOURCE **head ) { /* this function places all ambient lights at the head of the list, and returns a pointer to the last non-ambient source */ LIGHTSOURCE *ambient_head=NULL, *direct_head=NULL, *prev=NULL, *bulb=*head, *ambient_tail=NULL; /*{{{ traverse list, put bad or disabled lights into ambient list (hack!)*/ while (bulb) { LIGHTSOURCE *next=bulb->next; float hyp, one=1.0f, px, py, pz; int bogus=0; px=one*bulb->position[0]; py=one*bulb->position[1]; pz=one*bulb->position[2]; hyp=(px*px) + (py*py) + (pz*pz); if (hyp < 0.01f) bogus=1; if (bulb->positional == light_null) bogus=1; /* note that prev is the last bulb we left in the lights list */ if (bogus || (bulb->positional == light_ambient)) { /*{{{ chain out, in*/ LIGHTSOURCE *next=bulb->next; /* chain this bulb into ambient list */ if (ambient_head==NULL) { ambient_tail=bulb; } bulb->next=ambient_head; ambient_head=bulb; /* chain this bulb out of lights list */ if (prev == NULL) *head=next; else prev->next=next; /*}}} */ } else prev=bulb; bulb=next; } /*}}} */ direct_head=*head; /*{{{ merge lists, with ambient at head*/ if (ambient_tail != NULL) { ambient_tail->next=*head; *head=ambient_head; } /*}}} */ return direct_head; } /*}}} */ /*{{{ int keep_this_bulb ( LIGHTSOURCE *bulb, MATRIX m, POINT p )*/ int keep_this_bulb ( LIGHTSOURCE *bulb, POINT centroid, POINT p ) { if (bulb->positional == light_directional) { p[0]=bulb->position[0]; p[1]=bulb->position[1]; p[2]=bulb->position[2]; p[3]=1.0f; return 1; } else if (bulb->positional == light_positional) { float r, ir; float dx, dy, dz; dx=centroid[0]-bulb->position[0]; dy=centroid[1]-bulb->position[1]; dz=centroid[2]-bulb->position[2]; r = sqrt((dx*dx) + (dy*dy) + (dz*dz)); ir = 1.0f/r; if (r > bulb->max_rad) return 0; else { if (r < bulb->min_rad) p[3]=1.0f; else p[3]=1.0f - ((r - bulb->min_rad) / (bulb->max_rad - bulb->min_rad)); p[0]=-dx*ir; p[1]=-dy*ir; /* i think this is due to the -1 in the matrix */ p[2]=-dz*ir; return 1; } } else return 0; } /*}}} */