/*************************************************************************/ /* */ /* Copyright (c) 1994 Stanford University */ /* */ /* All rights reserved. */ /* */ /* Permission is given to use, copy, and modify this software for any */ /* non-commercial purpose as long as this copyright notice is not */ /* removed. All other uses, including redistribution in whole or in */ /* part, are forbidden without prior written permission. */ /* */ /* This software is provided with absolutely no warranty and no */ /* support. */ /* */ /*************************************************************************/ #ifndef _PATCH_H #define _PATCH_H #include "structs.H" /************************************************************************ * * Constants * *************************************************************************/ #define F_COPLANAR (5.0e-2) /* H(P) < F_COPLANAR then P is on the plane */ #define N_VISIBILITY_TEST_RAYS (10) /* number of "random", "magic" rays fired between patches to test visibility */ #define FF_GEOMETRY_ERROR (1.0) /* FF relative error due to Fdf approx and cosine approx of angle */ #define FF_GEOMETRY_VARIANCE (1.0) /* FF relative varance with in elem */ #define FF_VISIBILITY_ERROR (1.0 / N_VISIBILITY_TEST_RAYS) /************************************************************************ * * Intersection code * *************************************************************************/ #define POINT_POSITIVE_SIDE (1) #define POINT_NEGATIVE_SIDE (2) #define POINT_ON_PLANE (0) #define P1_POSITIVE (1) #define P1_NEGATIVE (2) #define P2_POSITIVE (4) #define P2_NEGATIVE (8) #define P3_POSITIVE (16) #define P3_NEGATIVE (32) #define ANY_POSITIVE (P1_POSITIVE | P2_POSITIVE | P3_POSITIVE) #define ANY_NEGATIVE (P1_NEGATIVE | P2_NEGATIVE | P3_NEGATIVE) #define POSITIVE_SIDE(code) (((code) & ANY_NEGATIVE) == 0) #define NEGATIVE_SIDE(code) (((code) & ANY_POSITIVE) == 0) #define INTERSECTING(code) ( ((code) & ANY_NEGATIVE) \ && ((code) & ANY_POSITIVE) ) #define P1_CODE(code) (code & 3) #define P2_CODE(code) ((code >> 2) & 3) #define P3_CODE(code) ((code >> 4) & 3) /************************************************************************ * * Visibility Testing * *************************************************************************/ #define VISIBILITY_UNDEF ((float)-1.0) #define PATCH_CACHE_SIZE (2) /* The first two cache entries covers about 95% of the total cache hits, so using more doesn't help too much. */ /************************************************************************ * * Refinement Advice * *************************************************************************/ #define _NO_INTERACTION (1) #define _NO_REFINEMENT_NECESSARY (2) #define _REFINE_PATCH_1 (4) #define _REFINE_PATCH_2 (8) #define _NO_VISIBILITY_NECESSARY (16) #define NO_INTERACTION(c) ((c) & _NO_INTERACTION) #define NO_REFINEMENT_NECESSARY(c) ((c) & _NO_REFINEMENT_NECESSARY) #define REFINE_PATCH_1(c) ((c) & _REFINE_PATCH_1) #define REFINE_PATCH_2(c) ((c) & _REFINE_PATCH_2) #define NO_VISIBILITY_NECESSARY(c) ((c) & _NO_VISIBILITY_NECESSARY) /************************************************************************ * * Element Vertex * * ElementVertex represents a vertex of an element. A vertex structure * is shared by those elements which contain the vertex as part of their * vertex list. * *************************************************************************/ typedef struct _elemvertex { Vertex p ; /* Coordinate of the vertex */ Rgb col ; /* Color of the vertex */ float weight ; /* weight */ Shared_Lock *ev_lock ; } ElemVertex ; #define N_ELEMVERTEX_ALLOCATE (16) /************************************************************************ * * Edge * * Edge represents each edge of the element. Two adjacent elements * share the same edge. As an element is subdivided, the edge is also * subdivided. The edges form a binary tree, which can be viewed as a * projection of the element subdivision along an edge of the element. * In other words, the edge structure binds elements at the same height. * Note that the vertices may appear in reverse order in the edge structure * with respect to the order in the patch/element definition. * *************************************************************************/ typedef struct _edge { ElemVertex *pa, *pb ; struct _edge *ea, *eb ; /* Edge (A-center) and (center-B) */ Shared_Lock *edge_lock ; /* Use segment0 */ } Edge ; #define N_EDGE_ALLOCATE (16) #define _LEAF_EDGE(e) ((e)->ea == 0) #define EDGE_REVERSE(e,a,b) ((e)->pa == (b)) /************************************************************************ * * Planar equation * * Plane equation (in implicit form) of the triangle patch. * A point P on the plane satisfies * (N.P) + C = 0 * where N is the normal vector of the patch, C is a constant which * is the distance of the plane from the origin scaled by -|N|. * *************************************************************************/ typedef struct { Vertex n ; /* Normal vector (normalized) */ float c ; /* Constant */ /* Nx*x + Ny*y + Nz*z + C = 0 */ } PlaneEqu ; /************************************************************************ * * Patch (also a node of the BSP tree) * * The Patch represents a triangular patch (input polygon) of the given * geometric model (i.e., room scene). The Patch contains 'per-patch' * information such as the plane equation, area, and color. The Patch also * serves as a node of the BSP tree which is used to test patch-patch * visibility. The Patch points to the root level of the element quad-tree. * Geometrically speaking, the Patch and the root represent the same * triangle. * Although coordinates of the vertices are given by the Edge structure, * copies are stored in the Patch to allow fast access to the coordinates * during the visibility test. * For cost based task distribution another structure, Patch_Cost, is * also used. This structure is made separate from the Patch structure * since gathering cost statistics is a frequently read/write operation. * If it were in the Patch structure, updating a cost would result in * invalidation of the Patch structure and cause cache misses during * BSP traversal. * *************************************************************************/ struct _element ; typedef struct _patch { ElemVertex *ev1, *ev2, *ev3 ; /* ElemVertecies of the patch */ Edge *e12, *e23, *e31 ; /* Edges of the patch */ Vertex p1, p2, p3 ; /* Vertices of the patch */ PlaneEqu plane_equ ; /* Plane equation H(x,y,z) */ float area ; /* Area of the patch */ Rgb color ; /* Diffuse color of the patch */ /* (reflectance) */ Rgb emittance ; /* Radiant emmitence */ struct _patch *bsp_positive ; /* BSP tree H(x,y,z) >= 0 */ struct _patch *bsp_negative ; /* H(x,y,z) < 0 */ struct _patch *bsp_parent ; /* BSP backpointer to the parent*/ struct _element *el_root ; /* Root of the element tree */ long seq_no ; /* Patch sequence number */ } Patch ; typedef struct { Patch *patch ; Shared_Lock *cost_lock ; /* Cost variable lock */ long n_bsp_node ; /* Number of BSP nodes visited */ long n_total_inter ; /* Total number of interactions */ long cost_estimate ; /* Cost estimate */ long cost_history[11] ; /* Cost history */ } Patch_Cost ; /* Patch cost: Visiting a node in BSP tree: 150 cyc (overall) Gathering ray per interaction: 50 cyc (overall avg) */ #define PATCH_COST(p) ((p)->n_bsp_node * 3 + (p)->n_total_inter) #define PATCH_COST_ESTIMATE(p) ((p)->cost_history[0] \ + ((p)->cost_history[1] >> 1)\ + ((p)->cost_history[2] >> 2) ) /************************************************************************ * * Element * * The Element represents each node of the quad-tree generated by the * hierarchical subdivision. The Element structure consists of: * - pointers to maintain the tree structure * - a linear list of interacting elements * - radiosity value of the element * - pointer to the vertex and edge data structures * * To allow smooth radiosity interpolation across elements, an element * shares edges and vertices with adjacent elements. * *************************************************************************/ struct _interact ; typedef struct _element { Shared_Lock *elem_lock ; /* Element lock variable (seg 1) */ Patch *patch ; /* Original patch of the element */ struct _element *parent ; /* Quad tree (parent) */ struct _element *center ; /* (center triangle) */ struct _element *top ; /* (top) */ struct _element *left ; /* (left) */ struct _element *right ; /* (right) */ struct _interact *interactions ; /* Top of light interaction list */ long n_interactions ; /* Total # of interactions */ struct _interact *vis_undef_inter ; /* Top of visibility undef list */ long n_vis_undef_inter ; /* # of interactions whose visibility is not yet calculated */ Rgb rad ; /* Radiosity of this element (new guess of B) */ Rgb rad_in ; /* Sum of anscestor's radiosity */ Rgb rad_subtree ; /* Area weighted sum of subtree's radiosity (includes this elem) */ long join_counter ; /* # of unfinished subprocesses */ ElemVertex *ev1, *ev2, *ev3 ; /* Vertices of the element */ Edge *e12, *e23, *e31 ; /* Edges of the element */ float area ; /* Area of the element */ } Element ; #define _LEAF_ELEMENT(e) ((e)->center == 0) #if MEM_CONSISTENCY_PROCESSOR #define LEAF_ELEMENT(e) _LEAF_ELEMENT((e)) #endif #if (MEM_CONSISTENCY_RELEASE || MEM_CONSISTENCY_WEAK) extern long leaf_element() ; #define LEAF_ELEMENT(e) (leaf_element((e))) #endif /************************************************************************ * * Interaction * *************************************************************************/ typedef struct _interact { struct _interact *next ; /* Next entry of the list */ Element *destination ; /* Partner of the interaction */ float formfactor_out ; /* Form factor from this patch */ float formfactor_err ; /* Error of FF */ float area_ratio ; /* Area(this) / Area(dest) */ float visibility ; /* Visibility (0 - 1.0) */ } Interaction ; void foreach_patch_in_bsp(void (*func)(), long arg1, long process_id); void foreach_depth_sorted_patch(Vertex *sort_vec, void (*func)(), long arg1, long process_id); void define_patch(Patch *patch, Patch *root, long process_id); void split_patch(Patch *patch, Patch *node, long xing_code, long process_id); void attach_element(Patch *patch, long process_id); void refine_newpatch(Patch *patch, long newpatch, long process_id); Patch *get_patch(long process_id); void init_patchlist(long process_id); void print_patch(Patch *patch, long process_id); void print_bsp_tree(long process_id); void _pr_patch(Patch *patch, long dummy, long process_id); float plane_equ(PlaneEqu *plane, Vertex *point, long process_id); float comp_plane_equ(PlaneEqu *pln, Vertex *p1, Vertex *p2, Vertex *p3, long process_id); long point_intersection(PlaneEqu *plane, Vertex *point, long process_id); long patch_intersection(PlaneEqu *plane, Vertex *p1, Vertex *p2, Vertex *p3, long process_id); void print_plane_equ(PlaneEqu *peq, long process_id); #endif