*Ray counters (number of BB/primitive tests/hits and other raytrace counters) can...
[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 <float.h>
39
40
41 /* RayObject
42         
43         A ray object is everything where we can cast rays like:
44                 * a face/triangle
45                 * an octree
46                 * a bvh tree
47                 * an octree of bvh's
48                 * a bvh of bvh's
49         
50                 
51         All types of RayObjects can be created by implementing the
52         callbacks of the RayObject.
53
54         Due to high computing time evolved with casting on faces
55         there is a special type of RayObject (named RayFace)
56         which won't use callbacks like other generic nodes.
57         
58         In order to allow a mixture of RayFace+RayObjects,
59         all RayObjects must be 4byte aligned, allowing us to use the
60         2 least significant bits (with the mask 0x02) to define the
61         type of RayObject.
62         
63         This leads to 4 possible types of RayObject, but at the moment
64         only 2 are used:
65
66          addr&2  - type of object
67                 0               Self (reserved for each structure)
68                 1       RayFace
69                 2               RayObject (generic with API callbacks)
70                 3               RayObject_Vlak
71
72         0 means it's reserved and has it own meaning inside each ray acceleration structure
73         (this way each structure can use the allign offset to determine if a node represents a
74          RayObject primitive, which can be used to save memory)
75
76         You actually don't need to care about this if you are only using the API
77         described on RE_raytrace.h
78  */
79
80 /* used to align a given ray object */
81 #define RE_rayobject_align(o)                           ((RayObject*)(((intptr_t)o)&(~3)))
82
83 /* used to unalign a given ray object */
84 #define RE_rayobject_unalignRayFace(o)          ((RayObject*)(((intptr_t)o)|1))
85 #define RE_rayobject_unalignRayAPI(o)           ((RayObject*)(((intptr_t)o)|2))
86 #define RE_rayobject_unalignRayVlak(o)          ((RayObject*)(((intptr_t)o)|3))
87
88 /* used to test the type of ray object */
89 #define RE_rayobject_isAligned(o)       ((((intptr_t)o)&3) == 0)
90 #define RE_rayobject_isRayFace(o)       ((((intptr_t)o)&3) == 1)
91 #define RE_rayobject_isRayAPI(o)        ((((intptr_t)o)&3) == 2)
92 #define RE_rayobject_isRayVlak(o)       ((((intptr_t)o)&3) == 3)
93
94
95 /*
96  * This ray object represents faces directly from a given VlakRen structure.
97  * Thus allowing to save memory, but making code dependant on render structures
98 typedef struct RayVlak
99 {
100         struct ObjectInstanceRen *ob;
101         struct VlakRen *face;
102 } RayVlak;
103  */
104
105 /*
106  * This ray object represents a triangle or a quad face.
107  * All data needed to realize intersection is "localy" available.
108  */
109 typedef struct RayFace
110 {
111         float v1[4], v2[4], v3[4], v4[3];
112         int quad;
113         void *ob;
114         void *face;
115         
116 } RayFace;
117
118 #define RE_rayface_isQuad(a) ((a)->quad)
119 /* Loads a VlakRen on a RayFace */
120 void RE_rayface_from_vlak(RayFace *face, ObjectInstanceRen *obi, VlakRen *vlr);
121
122
123
124 /*
125  * This rayobject represents a generic object. With it's own callbacks for raytrace operations.
126  * It's suitable to implement things like LOD.
127  */
128 struct RayObject
129 {
130         struct RayObjectAPI *api;
131 };
132
133
134 typedef int  (*RE_rayobject_raycast_callback)(RayObject *, Isect *);
135 typedef void (*RE_rayobject_add_callback)(RayObject *raytree, RayObject *rayobject);
136 typedef void (*RE_rayobject_done_callback)(RayObject *);
137 typedef void (*RE_rayobject_free_callback)(RayObject *);
138 typedef void (*RE_rayobject_merge_bb_callback)(RayObject *, float *min, float *max);
139 typedef float (*RE_rayobject_cost_callback)(RayObject *);
140 typedef void (*RE_rayobject_hint_bb_callback)(RayObject *, RayHint *, float *, float *);
141
142 typedef struct RayObjectAPI
143 {
144         RE_rayobject_raycast_callback   raycast;
145         RE_rayobject_add_callback               add;
146         RE_rayobject_done_callback              done;
147         RE_rayobject_free_callback              free;
148         RE_rayobject_merge_bb_callback  bb;
149         RE_rayobject_cost_callback              cost;
150         RE_rayobject_hint_bb_callback   hint_bb;
151         
152 } RayObjectAPI;
153
154
155
156
157 /*
158  * Extend min/max coords so that the rayobject is inside them
159  */
160 void RE_rayobject_merge_bb(RayObject *ob, float *min, float *max);
161
162 /*
163  * This function differs from RE_rayobject_raycast
164  * RE_rayobject_intersect does NOT perform last-hit optimization
165  * So this is probably a function to call inside raytrace structures
166  */
167 int RE_rayobject_intersect(RayObject *r, Isect *i);
168
169 /*
170  * Returns distance ray must travel to hit the given bounding box
171  * BB should be in format [2][3]
172  */
173 /* float RE_rayobject_bb_intersect(const Isect *i, const float *bb); */
174 int RE_rayobject_bb_intersect_test(const Isect *i, const float *bb); /* same as bb_intersect but doens't calculates distance */
175
176 /*
177  * Returns the expected cost of raycast on this node, primitives have a cost of 1
178  */
179 float RE_rayobject_cost(RayObject *r);
180
181
182
183
184 #define ISECT_EPSILON ((float)FLT_EPSILON)
185
186
187
188 #if !defined(_WIN32)
189
190 #include <sys/time.h>
191 #include <time.h>
192 #include <stdio.h>
193
194 #define BENCH(a,name)   \
195         do {                    \
196                 double _t1, _t2;                                \
197                 struct timeval _tstart, _tend;  \
198                 clock_t _clock_init = clock();  \
199                 gettimeofday ( &_tstart, NULL); \
200                 (a);                                                    \
201                 gettimeofday ( &_tend, NULL);   \
202                 _t1 = ( double ) _tstart.tv_sec + ( double ) _tstart.tv_usec/ ( 1000*1000 );    \
203                 _t2 = ( double )   _tend.tv_sec + ( double )   _tend.tv_usec/ ( 1000*1000 );    \
204                 printf("BENCH:%s: %fs (real) %fs (cpu)\n", #name, _t2-_t1, (float)(clock()-_clock_init)/CLOCKS_PER_SEC);\
205         } while(0)
206 #else
207
208 #define BENCH(a)        (a)
209
210 #endif
211
212
213
214 #ifdef __cplusplus
215 }
216 #endif
217
218
219 #endif