copy of docs from 2.4x for python modules that have been kept
[blender-staging.git] / source / blender / render / intern / include / rayobject.h
index a1b35ac04655ddaa0af66851bc762d879e86ed64..309048d8efbb928e396743d826c1131d0bb91174 100644 (file)
 #ifndef RE_RAYOBJECT_H
 #define RE_RAYOBJECT_H
 
 #ifndef RE_RAYOBJECT_H
 #define RE_RAYOBJECT_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include "RE_raytrace.h"
 #include "RE_raytrace.h"
+#include "render_types.h"
+#include <stdio.h>
 #include <float.h>
 
 #include <float.h>
 
+
 /* RayObject
        
        A ray object is everything where we can cast rays like:
 /* RayObject
        
        A ray object is everything where we can cast rays like:
        
        In order to allow a mixture of RayFace+RayObjects,
        all RayObjects must be 4byte aligned, allowing us to use the
        
        In order to allow a mixture of RayFace+RayObjects,
        all RayObjects must be 4byte aligned, allowing us to use the
-       2 least significant bits (with the mask 0x02) to define the
+       2 least significant bits (with the mask 0x03) to define the
        type of RayObject.
        
        type of RayObject.
        
-       This leads to 4 possible types of RayObject, but at the moment
-       only 2 are used:
+       This leads to 4 possible types of RayObject:
 
 
-        addr&2  - type of object
-               0       RayFace
-               1               RayObject (generic with API callbacks)
-               2               unused
-               3               unused
+        addr&3  - type of object
+               0               Self (reserved for each structure)
+               1       RayFace (tri/quad primitive)
+               2               RayObject (generic with API callbacks)
+               3               VlakPrimitive
+                               (vlak primitive - to be used when we have a vlak describing the data
+                                eg.: on render code)
+
+       0 means it's reserved and has it own meaning inside each ray acceleration structure
+       (this way each structure can use the allign offset to determine if a node represents a
+        RayObject primitive, which can be used to save memory)
 
 
-       0 was choosed to RayFace because thats the one where speed will be needed.
-       
        You actually don't need to care about this if you are only using the API
        described on RE_raytrace.h
  */
        You actually don't need to care about this if you are only using the API
        described on RE_raytrace.h
  */
-typedef struct RayFace
+
+/* used to align a given ray object */
+#define RE_rayobject_align(o)                          ((RayObject*)(((intptr_t)o)&(~3)))
+
+/* used to unalign a given ray object */
+#define RE_rayobject_unalignRayFace(o)         ((RayObject*)(((intptr_t)o)|1))
+#define RE_rayobject_unalignRayAPI(o)          ((RayObject*)(((intptr_t)o)|2))
+#define RE_rayobject_unalignVlakPrimitive(o)   ((RayObject*)(((intptr_t)o)|3))
+
+/* used to test the type of ray object */
+#define RE_rayobject_isAligned(o)      ((((intptr_t)o)&3) == 0)
+#define RE_rayobject_isRayFace(o)      ((((intptr_t)o)&3) == 1)
+#define RE_rayobject_isRayAPI(o)       ((((intptr_t)o)&3) == 2)
+#define RE_rayobject_isVlakPrimitive(o)        ((((intptr_t)o)&3) == 3)
+
+
+
+/*
+ * This class is intended as a place holder for control, configuration of the rayobject like:
+ *     - stop building (TODO maybe when porting build to threads this could be implemented with some thread_cancel function)
+ *  - max number of threads and threads callback to use during build
+ *     ...
+ */    
+typedef int  (*RE_rayobjectcontrol_test_break_callback)(void *data);
+typedef struct RayObjectControl RayObjectControl;
+struct RayObjectControl
 {
 {
-       float *v1, *v2, *v3, *v4;
-       
-       void *ob;
-       void *face;
-       
-} RayFace;
+       void *data;
+       RE_rayobjectcontrol_test_break_callback test_break;     
+};
 
 
+/*
+ * This rayobject represents a generic object. With it's own callbacks for raytrace operations.
+ * It's suitable to implement things like LOD.
+ */
 struct RayObject
 {
        struct RayObjectAPI *api;
 struct RayObject
 {
        struct RayObjectAPI *api;
-       
+
+       struct RayObjectControl control;
 };
 
 };
 
-typedef int  (*RayObject_raycast_callback)(RayObject *, Isect *);
-typedef void (*RayObject_add_callback)(RayObject *, RayObject *);
-typedef void (*RayObject_done_callback)(RayObject *);
-typedef void (*RayObject_free_callback)(RayObject *);
-typedef void (*RayObject_bb_callback)(RayObject *, float *min, float *max);
+
+
+
+typedef int  (*RE_rayobject_raycast_callback)(RayObject *, Isect *);
+typedef void (*RE_rayobject_add_callback)(RayObject *raytree, RayObject *rayobject);
+typedef void (*RE_rayobject_done_callback)(RayObject *);
+typedef void (*RE_rayobject_free_callback)(RayObject *);
+typedef void (*RE_rayobject_merge_bb_callback)(RayObject *, float *min, float *max);
+typedef float (*RE_rayobject_cost_callback)(RayObject *);
+typedef void (*RE_rayobject_hint_bb_callback)(RayObject *, RayHint *, float *, float *);
 
 typedef struct RayObjectAPI
 {
 
 typedef struct RayObjectAPI
 {
-       RayObject_raycast_callback      raycast;
-       RayObject_add_callback          add;
-       RayObject_done_callback         done;
-       RayObject_free_callback         free;
-       RayObject_bb_callback           bb;
+       RE_rayobject_raycast_callback   raycast;
+       RE_rayobject_add_callback               add;
+       RE_rayobject_done_callback              done;
+       RE_rayobject_free_callback              free;
+       RE_rayobject_merge_bb_callback  bb;
+       RE_rayobject_cost_callback              cost;
+       RE_rayobject_hint_bb_callback   hint_bb;
        
 } RayObjectAPI;
 
        
 } RayObjectAPI;
 
-//TODO use intptr_t
-#define RayObject_align(o)             ((RayObject*)(((int)o)&(~3)))
-#define RayObject_unalign(o)   ((RayObject*)(((int)o)|1))
-#define RayObject_isFace(o)            ((((int)o)&3) == 0)
 
 /*
 
 /*
- * Extend min/max coords so that the rayobject is inside them
+ * This function differs from RE_rayobject_raycast
+ * RE_rayobject_intersect does NOT perform last-hit optimization
+ * So this is probably a function to call inside raytrace structures
  */
  */
-void RayObject_merge_bb(RayObject *ob, float *min, float *max);
+int RE_rayobject_intersect(RayObject *r, Isect *i);
 
 /*
 
 /*
- * This function differs from RayObject_raycast
- * RayObject_intersect does NOT perform last-hit optimization
- * So this is probably a function to call inside raytrace structures
+ * Returns distance ray must travel to hit the given bounding box
+ * BB should be in format [2][3]
+ */
+/* float RE_rayobject_bb_intersect(const Isect *i, const float *bb); */
+int RE_rayobject_bb_intersect_test(const Isect *i, const float *bb); /* same as bb_intersect but doens't calculates distance */
+
+/*
+ * Returns the expected cost of raycast on this node, primitives have a cost of 1
  */
  */
-int RayObject_intersect(RayObject *r, Isect *i);
+float RE_rayobject_cost(RayObject *r);
+
+
+/*
+ * Returns true if for some reason a heavy processing function should stop
+ * (eg.: user asked to stop during a tree a build)
+ */
+int RE_rayobjectcontrol_test_break(RayObjectControl *c);
+
 
 #define ISECT_EPSILON ((float)FLT_EPSILON)
 
 
 #define ISECT_EPSILON ((float)FLT_EPSILON)
 
+
+
+#if !defined(_WIN32) && !defined(_WIN64)
+
+#include <sys/time.h>
+#include <time.h>
+
+#define BENCH(a,name)  \
+       {                       \
+               double _t1, _t2;                                \
+               struct timeval _tstart, _tend;  \
+               clock_t _clock_init = clock();  \
+               gettimeofday ( &_tstart, NULL); \
+               (a);                                                    \
+               gettimeofday ( &_tend, NULL);   \
+               _t1 = ( double ) _tstart.tv_sec + ( double ) _tstart.tv_usec/ ( 1000*1000 );    \
+               _t2 = ( double )   _tend.tv_sec + ( double )   _tend.tv_usec/ ( 1000*1000 );    \
+               printf("BENCH:%s: %fs (real) %fs (cpu)\n", #name, _t2-_t1, (float)(clock()-_clock_init)/CLOCKS_PER_SEC);\
+       }
+#else
+
+#define BENCH(a,name)  (a)
+
+#endif
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
 #endif
 #endif