Merge from trunk -r 23000:23968.
[blender-staging.git] / source / blender / render / intern / include / rayobject.h
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2009 Blender Foundation.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): AndrĂ© Pinto.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29 #ifndef RE_RAYOBJECT_H
30 #define RE_RAYOBJECT_H
31
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35
36 #include "RE_raytrace.h"
37 #include "render_types.h"
38 #include <stdio.h>
39 #include <float.h>
40
41
42 /* RayObject
43         
44         A ray object is everything where we can cast rays like:
45                 * a face/triangle
46                 * an octree
47                 * a bvh tree
48                 * an octree of bvh's
49                 * a bvh of bvh's
50         
51                 
52         All types of RayObjects can be created by implementing the
53         callbacks of the RayObject.
54
55         Due to high computing time evolved with casting on faces
56         there is a special type of RayObject (named RayFace)
57         which won't use callbacks like other generic nodes.
58         
59         In order to allow a mixture of RayFace+RayObjects,
60         all RayObjects must be 4byte aligned, allowing us to use the
61         2 least significant bits (with the mask 0x03) to define the
62         type of RayObject.
63         
64         This leads to 4 possible types of RayObject:
65
66          addr&3  - type of object
67                 0               Self (reserved for each structure)
68                 1       RayFace (tri/quad primitive)
69                 2               RayObject (generic with API callbacks)
70                 3               VlakPrimitive
71                                 (vlak primitive - to be used when we have a vlak describing the data
72                                  eg.: on render code)
73
74         0 means it's reserved and has it own meaning inside each ray acceleration structure
75         (this way each structure can use the allign offset to determine if a node represents a
76          RayObject primitive, which can be used to save memory)
77
78         You actually don't need to care about this if you are only using the API
79         described on RE_raytrace.h
80  */
81
82 /* used to align a given ray object */
83 #define RE_rayobject_align(o)                           ((RayObject*)(((intptr_t)o)&(~3)))
84
85 /* used to unalign a given ray object */
86 #define RE_rayobject_unalignRayFace(o)          ((RayObject*)(((intptr_t)o)|1))
87 #define RE_rayobject_unalignRayAPI(o)           ((RayObject*)(((intptr_t)o)|2))
88 #define RE_rayobject_unalignVlakPrimitive(o)    ((RayObject*)(((intptr_t)o)|3))
89
90 /* used to test the type of ray object */
91 #define RE_rayobject_isAligned(o)       ((((intptr_t)o)&3) == 0)
92 #define RE_rayobject_isRayFace(o)       ((((intptr_t)o)&3) == 1)
93 #define RE_rayobject_isRayAPI(o)        ((((intptr_t)o)&3) == 2)
94 #define RE_rayobject_isVlakPrimitive(o) ((((intptr_t)o)&3) == 3)
95
96
97
98 /*
99  * This class is intended as a place holder for control, configuration of the rayobject like:
100  *      - stop building (TODO maybe when porting build to threads this could be implemented with some thread_cancel function)
101  *  - max number of threads and threads callback to use during build
102  *      ...
103  */     
104 typedef int  (*RE_rayobjectcontrol_test_break_callback)(void *data);
105 typedef struct RayObjectControl RayObjectControl;
106 struct RayObjectControl
107 {
108         void *data;
109         RE_rayobjectcontrol_test_break_callback test_break;     
110 };
111
112 /*
113  * This rayobject represents a generic object. With it's own callbacks for raytrace operations.
114  * It's suitable to implement things like LOD.
115  */
116 struct RayObject
117 {
118         struct RayObjectAPI *api;
119
120         struct RayObjectControl control;
121 };
122
123
124
125
126 typedef int  (*RE_rayobject_raycast_callback)(RayObject *, Isect *);
127 typedef void (*RE_rayobject_add_callback)(RayObject *raytree, RayObject *rayobject);
128 typedef void (*RE_rayobject_done_callback)(RayObject *);
129 typedef void (*RE_rayobject_free_callback)(RayObject *);
130 typedef void (*RE_rayobject_merge_bb_callback)(RayObject *, float *min, float *max);
131 typedef float (*RE_rayobject_cost_callback)(RayObject *);
132 typedef void (*RE_rayobject_hint_bb_callback)(RayObject *, RayHint *, float *, float *);
133
134 typedef struct RayObjectAPI
135 {
136         RE_rayobject_raycast_callback   raycast;
137         RE_rayobject_add_callback               add;
138         RE_rayobject_done_callback              done;
139         RE_rayobject_free_callback              free;
140         RE_rayobject_merge_bb_callback  bb;
141         RE_rayobject_cost_callback              cost;
142         RE_rayobject_hint_bb_callback   hint_bb;
143         
144 } RayObjectAPI;
145
146
147 /*
148  * This function differs from RE_rayobject_raycast
149  * RE_rayobject_intersect does NOT perform last-hit optimization
150  * So this is probably a function to call inside raytrace structures
151  */
152 int RE_rayobject_intersect(RayObject *r, Isect *i);
153
154 /*
155  * Returns distance ray must travel to hit the given bounding box
156  * BB should be in format [2][3]
157  */
158 /* float RE_rayobject_bb_intersect(const Isect *i, const float *bb); */
159 int RE_rayobject_bb_intersect_test(const Isect *i, const float *bb); /* same as bb_intersect but doens't calculates distance */
160
161 /*
162  * Returns the expected cost of raycast on this node, primitives have a cost of 1
163  */
164 float RE_rayobject_cost(RayObject *r);
165
166
167 /*
168  * Returns true if for some reason a heavy processing function should stop
169  * (eg.: user asked to stop during a tree a build)
170  */
171 int RE_rayobjectcontrol_test_break(RayObjectControl *c);
172
173
174 #define ISECT_EPSILON ((float)FLT_EPSILON)
175
176
177
178 #if !defined(_WIN32) && !defined(_WIN64)
179
180 #include <sys/time.h>
181 #include <time.h>
182
183 #define BENCH(a,name)   \
184         do {                    \
185                 double _t1, _t2;                                \
186                 struct timeval _tstart, _tend;  \
187                 clock_t _clock_init = clock();  \
188                 gettimeofday ( &_tstart, NULL); \
189                 (a);                                                    \
190                 gettimeofday ( &_tend, NULL);   \
191                 _t1 = ( double ) _tstart.tv_sec + ( double ) _tstart.tv_usec/ ( 1000*1000 );    \
192                 _t2 = ( double )   _tend.tv_sec + ( double )   _tend.tv_usec/ ( 1000*1000 );    \
193                 printf("BENCH:%s: %fs (real) %fs (cpu)\n", #name, _t2-_t1, (float)(clock()-_clock_init)/CLOCKS_PER_SEC);\
194         } while(0)
195 #else
196
197 #define BENCH(a,name)   (a)
198
199 #endif
200
201
202
203 #ifdef __cplusplus
204 }
205 #endif
206
207
208 #endif