*Instance support is only enabled if target mesh uses more than 4 faces
[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               unused
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 /* defines where coordinates of rayface primitives are stored */
81 #define RE_RAYFACE_COORDS_LOCAL
82
83 //(ATM this won't work good with all types of instances)
84 //#define RE_RAYFACE_COORDS_POINTER
85 //#define RE_RAYFACE_COORDS_VLAKREN
86  
87 typedef struct RayFace
88 {
89 #ifdef RE_RAYFACE_COORDS_LOCAL
90         float v1[4], v2[4], v3[4], v4[3];
91         int quad;
92         void *ob;
93         void *face;
94 #elif defined(RE_RAYFACE_COORDS_POINTER)
95         float *v1, *v2, *v3, *v4;
96         void *ob;
97         void *face;
98 #elif defined(RE_RAYFACE_COORDS_VLAKREN)
99         void *ob;
100         void *face;
101 #endif
102         
103 } RayFace;
104
105 #ifdef RE_RAYFACE_COORDS_LOCAL
106 #       define RE_rayface_isQuad(a) ((a)->quad)
107 #elif defined(RE_RAYFACE_COORDS_POINTER)
108 #       define RE_rayface_isQuad(a) ((a)->v4)
109 #elif defined(RE_RAYFACE_COORDS_VLAKREN)
110 #       define RE_rayface_isQuad(a) ((((VlakRen*)((a)->face))->v4) != NULL)
111 #endif
112
113
114 struct RayObject
115 {
116         struct RayObjectAPI *api;
117 };
118
119
120 typedef int  (*RE_rayobject_raycast_callback)(RayObject *, Isect *);
121 typedef void (*RE_rayobject_add_callback)(RayObject *raytree, RayObject *rayobject);
122 typedef void (*RE_rayobject_done_callback)(RayObject *);
123 typedef void (*RE_rayobject_free_callback)(RayObject *);
124 typedef void (*RE_rayobject_merge_bb_callback)(RayObject *, float *min, float *max);
125 typedef float (*RE_rayobject_cost_callback)(RayObject *);
126 typedef void (*RE_rayobject_hint_bb_callback)(RayObject *, RayHint *, float *, float *);
127
128 typedef struct RayObjectAPI
129 {
130         RE_rayobject_raycast_callback   raycast;
131         RE_rayobject_add_callback               add;
132         RE_rayobject_done_callback              done;
133         RE_rayobject_free_callback              free;
134         RE_rayobject_merge_bb_callback  bb;
135         RE_rayobject_cost_callback              cost;
136         RE_rayobject_hint_bb_callback   hint_bb;
137         
138 } RayObjectAPI;
139
140 #define RayObject_align(o)                              ((RayObject*)(((intptr_t)o)&(~3)))
141 #define RayObject_unalignRayFace(o)             ((RayObject*)(((intptr_t)o)|1))
142 #define RayObject_unalignRayAPI(o)              ((RayObject*)(((intptr_t)o)|2))
143
144 #define RayObject_isAligned(o)  ((((intptr_t)o)&3) == 0)
145 #define RayObject_isRayFace(o)  ((((intptr_t)o)&3) == 1)
146 #define RayObject_isRayAPI(o)   ((((intptr_t)o)&3) == 2)
147
148 /*
149  * Loads a VlakRen on a RayFace
150  */
151 void RE_rayface_from_vlak(RayFace *face, ObjectInstanceRen *obi, VlakRen *vlr);
152
153 /*
154  * Extend min/max coords so that the rayobject is inside them
155  */
156 void RE_rayobject_merge_bb(RayObject *ob, float *min, float *max);
157
158 /*
159  * This function differs from RE_rayobject_raycast
160  * RE_rayobject_intersect does NOT perform last-hit optimization
161  * So this is probably a function to call inside raytrace structures
162  */
163 int RE_rayobject_intersect(RayObject *r, Isect *i);
164
165 /*
166  * Returns distance ray must travel to hit the given bounding box
167  * BB should be in format [2][3]
168  */
169 /* float RE_rayobject_bb_intersect(const Isect *i, const float *bb); */
170 int RE_rayobject_bb_intersect_test(const Isect *i, const float *bb); /* same as bb_intersect but doens't calculates distance */
171
172 /*
173  * Returns the expected cost of raycast on this node, primitives have a cost of 1
174  */
175 float RE_rayobject_cost(RayObject *r);
176
177
178 #define ISECT_EPSILON ((float)FLT_EPSILON)
179
180
181
182 #if !defined(_WIN32)
183
184 #include <sys/time.h>
185 #include <time.h>
186 #include <stdio.h>
187
188 #define BENCH(a,name)   \
189         do {                    \
190                 double _t1, _t2;                                \
191                 struct timeval _tstart, _tend;  \
192                 clock_t _clock_init = clock();  \
193                 gettimeofday ( &_tstart, NULL); \
194                 (a);                                                    \
195                 gettimeofday ( &_tend, NULL);   \
196                 _t1 = ( double ) _tstart.tv_sec + ( double ) _tstart.tv_usec/ ( 1000*1000 );    \
197                 _t2 = ( double )   _tend.tv_sec + ( double )   _tend.tv_usec/ ( 1000*1000 );    \
198                 printf("BENCH:%s: %fs (real) %fs (cpu)\n", #name, _t2-_t1, (float)(clock()-_clock_init)/CLOCKS_PER_SEC);\
199         } while(0)
200 #else
201
202 #define BENCH(a)        (a)
203
204 #endif
205
206
207
208 #ifdef __cplusplus
209 }
210 #endif
211
212
213 #endif