blob: aa1b104026a54f2e002357be09620e7e4cf99359 [file] [log] [blame]
/*************************************************************************/
/* */
/* 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
/************************************************************************
*
* 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. */
extern float visibility() ;
extern void compute_visibility_values() ;
extern void visibility_task() ;
/************************************************************************
*
* 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)
/************************************************************************
*
* Vertex - 3D coordinate
*
*************************************************************************/
typedef struct {
float x, y, z ;
} Vertex ;
extern float vector_length() ;
extern float distance() ;
extern float normalize_vector() ;
extern float inner_product() ;
extern void cross_product() ;
extern float plane_normal() ;
extern void center_point(), four_center_points() ;
extern void print_point() ;
/************************************************************************
*
* Color (R,G,B)
*
*************************************************************************/
typedef struct {
float r, g, b ;
} Rgb ;
extern void print_rgb() ;
/************************************************************************
*
* 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)
extern ElemVertex *get_elemvertex() ;
extern ElemVertex *create_elemvertex() ; /* Constructor */
extern void init_elemvertex() ; /* Initialize free buffer */
/************************************************************************
*
* 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)
extern Edge *get_edge() ;
extern Edge *create_edge() ; /* Constructor */
extern void subdivide_edge() ;
extern void init_edge() ; /* Initialize free buffer */
extern void foreach_leaf_edge() ;
#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 ;
extern float plane_equ() ;
extern float comp_plane_equ() ;
extern int point_intersection() ;
extern int patch_intersection() ;
extern void print_plane_equ() ;
/************************************************************************
*
* 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 */
int seq_no ; /* Patch sequence number */
} Patch ;
extern void foreach_patch_in_bsp(), foreach_depth_sorted_patch() ;
extern void define_patch() ;
extern void refine_newpatch() ;
extern Patch *get_patch() ;
extern void init_patchlist() ;
extern void print_patch() ;
extern void print_bsp_tree() ;
typedef struct {
Patch *patch ;
Shared_Lock *cost_lock ; /* Cost variable lock */
int n_bsp_node ; /* Number of BSP nodes visited */
int n_total_inter ; /* Total number of interactions */
int cost_estimate ; /* Cost estimate */
int 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 */
int n_interactions ; /* Total # of interactions */
struct _interact *vis_undef_inter ; /* Top of visibility undef list */
int 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) */
int 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 ;
extern void foreach_element_in_patch(), foreach_leaf_element_in_patch() ;
extern void ff_refine_elements() ;
extern void subdivide_element() ;
extern int element_completely_invisible() ;
extern void process_rays() ;
extern Element *get_element() ;
extern void init_elemlist() ;
extern void print_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 int 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 ;
extern void foreach_interaction_in_element() ;
extern void compute_interaction(), compute_formfactor() ;
extern void insert_interaction(), delete_interaction() ;
extern void insert_vis_undef_interaction(), delete_vis_undef_interaction() ;
extern void init_interactionlist() ;
extern Interaction *get_interaction() ;
extern void free_interaction() ;
extern void print_interaction() ;
#endif