*reserved RayObject align offset 0 for private usage inside each structure
[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 #include "RE_raytrace.h"
33 #include <float.h>
34
35 /* RayObject
36         
37         A ray object is everything where we can cast rays like:
38                 * a face/triangle
39                 * an octree
40                 * a bvh tree
41                 * an octree of bvh's
42                 * a bvh of bvh's
43         
44                 
45         All types of RayObjects can be created by implementing the
46         callbacks of the RayObject.
47
48         Due to high computing time evolved with casting on faces
49         there is a special type of RayObject (named RayFace)
50         which won't use callbacks like other generic nodes.
51         
52         In order to allow a mixture of RayFace+RayObjects,
53         all RayObjects must be 4byte aligned, allowing us to use the
54         2 least significant bits (with the mask 0x02) to define the
55         type of RayObject.
56         
57         This leads to 4 possible types of RayObject, but at the moment
58         only 2 are used:
59
60          addr&2  - type of object
61                 0               Self (reserved for each structure)
62                 1       RayFace
63                 2               RayObject (generic with API callbacks)
64                 3               unused
65
66         0 means it's reserved and has it own meaning inside each ray acceleration structure
67         (this way each structure can use the allign offset to determine if a node represents a
68          RayObject primitive, which can be used to save memory)
69
70         You actually don't need to care about this if you are only using the API
71         described on RE_raytrace.h
72  */
73  
74 typedef struct RayFace
75 {
76         float *v1, *v2, *v3, *v4;
77         
78         void *ob;
79         void *face;
80         
81 } RayFace;
82
83 struct RayObject
84 {
85         struct RayObjectAPI *api;
86         
87 };
88
89 typedef int  (*RE_rayobject_raycast_callback)(RayObject *, Isect *);
90 typedef void (*RE_rayobject_add_callback)(RayObject *, RayObject *);
91 typedef void (*RE_rayobject_done_callback)(RayObject *);
92 typedef void (*RE_rayobject_free_callback)(RayObject *);
93 typedef void (*RE_rayobject_merge_bb_callback)(RayObject *, float *min, float *max);
94
95 typedef struct RayObjectAPI
96 {
97         RE_rayobject_raycast_callback   raycast;
98         RE_rayobject_add_callback               add;
99         RE_rayobject_done_callback              done;
100         RE_rayobject_free_callback              free;
101         RE_rayobject_merge_bb_callback  bb;
102         
103 } RayObjectAPI;
104
105 //TODO use intptr_t
106 #define RayObject_align(o)                              ((RayObject*)(((int)o)&(~3)))
107 #define RayObject_unalignRayFace(o)             ((RayObject*)(((int)o)|1))
108 #define RayObject_unalignRayAPI(o)              ((RayObject*)(((int)o)|2))
109
110 #define RayObject_isAligned(o)  ((((int)o)&3) == 0)
111 #define RayObject_isRayFace(o)  ((((int)o)&3) == 1)
112 #define RayObject_isRayAPI(o)   ((((int)o)&3) == 2)
113
114 /*
115  * Extend min/max coords so that the rayobject is inside them
116  */
117 void RE_rayobject_merge_bb(RayObject *ob, float *min, float *max);
118
119 /*
120  * This function differs from RE_rayobject_raycast
121  * RE_rayobject_intersect does NOT perform last-hit optimization
122  * So this is probably a function to call inside raytrace structures
123  */
124 int RE_rayobject_intersect(RayObject *r, Isect *i);
125
126 #define ISECT_EPSILON ((float)FLT_EPSILON)
127
128
129
130 #if !defined(_WIN32)
131
132 #include <sys/time.h>
133 #include <time.h>
134 #include <stdio.h>
135
136 #define BENCH(a,name)   \
137         do {                    \
138                 double _t1, _t2;                                \
139                 struct timeval _tstart, _tend;  \
140                 clock_t _clock_init = clock();  \
141                 gettimeofday ( &_tstart, NULL); \
142                 (a);                                                    \
143                 gettimeofday ( &_tend, NULL);   \
144                 _t1 = ( double ) _tstart.tv_sec + ( double ) _tstart.tv_usec/ ( 1000*1000 );    \
145                 _t2 = ( double )   _tend.tv_sec + ( double )   _tend.tv_usec/ ( 1000*1000 );    \
146                 printf("BENCH:%s: %fs (real) %fs (cpu)\n", #name, _t2-_t1, (float)(clock()-_clock_init)/CLOCKS_PER_SEC);\
147         } while(0)
148 #else
149
150 #define BENCH(a)        (a)
151
152 #endif
153
154
155 #endif