Elbeem: fix memory leak and add guarded allocator directives
[blender.git] / intern / elbeem / intern / ntl_ray.h
1 /** \file elbeem/intern/ntl_ray.h
2  *  \ingroup elbeem
3  */
4 /******************************************************************************
5  *
6  * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method
7  * Copyright 2003-2006 Nils Thuerey
8  *
9  * ray class
10  *
11  *****************************************************************************/
12 #ifndef NTL_RAY_H
13 #define NTL_RAY_H
14
15 #include <sstream>
16 #include "ntl_vector3dim.h"
17 #include "ntl_lighting.h"
18 #include "ntl_geometryobject.h"
19 #include "ntl_bsptree.h"
20
21 #ifdef WITH_CXX_GUARDEDALLOC
22 #  include "MEM_guardedalloc.h"
23 #endif
24
25 class ntlTriangle;
26 class ntlRay;
27 class ntlTree;
28 class ntlScene;
29 class ntlRenderGlobals;
30 class ntlGeometryObject;
31
32 //! store data for an intersection of a ray and a triangle
33 // NOT YET USED
34 class ntlIntersection {
35         public:
36
37                 ntlIntersection() :
38                         distance(-1.0), normal(0.0),
39                         ray(NULL), tri(NULL), flags(0) { };
40
41                 gfxReal distance;
42                 ntlVec3Gfx normal;
43                 ntlRay *ray; 
44                 ntlTriangle *tri;
45                 char flags;
46
47 private:
48 #ifdef WITH_CXX_GUARDEDALLOC
49         MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlIntersection")
50 #endif
51 };
52
53 //! the main ray class
54 class ntlRay
55 {
56 public:
57   // CONSTRUCTORS
58   //! Initialize ray memebers, prints error message
59   ntlRay();
60   //! Copy constructor, copy all members
61   ntlRay(const ntlRay &r);
62   //! Explicitly init member variables with global render object
63   ntlRay(const ntlVec3Gfx &o, const ntlVec3Gfx &d, unsigned int i, gfxReal contrib, ntlRenderGlobals *glob);
64   //! Destructor
65   ~ntlRay();
66
67   //! Set the refraction flag for refracted rays
68   inline void setRefracted(unsigned char set) { mIsRefracted = set; }
69   inline void setReflected(unsigned char set) { mIsReflected = set; }
70
71   //! main ray recursion function
72   /*!
73    * First get closest object intersection, return background color if nothing
74    * was hit, else calculate shading and reflection components 
75    * and return mixed color */
76   const ntlColor shade() /*const*/;
77
78         /*! Trace a photon through the scene */
79         void tracePhoton(ntlColor) const;
80
81   //! intersect ray with AABB
82   void intersectFrontAABB(ntlVec3Gfx mStart, ntlVec3Gfx mEnd, gfxReal &t, ntlVec3Gfx &normal, ntlVec3Gfx &retcoord) const;
83   void intersectBackAABB(ntlVec3Gfx mStart, ntlVec3Gfx mEnd, gfxReal &t, ntlVec3Gfx &normal, ntlVec3Gfx &retcoord) const;
84   void intersectCompleteAABB(ntlVec3Gfx mStart, ntlVec3Gfx mEnd, gfxReal &tmin, gfxReal &tmax) const;
85         // intersection routines in bsptree.cpp
86   //! optimized intersect ray with triangle
87   inline void intersectTriangle(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v) const;
88   //! optimized intersect ray with triangle along +X axis dir
89   inline void intersectTriangleX(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v) const;
90   //! intersect only with front side
91   inline void intersectTriangleFront(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v) const;
92   //! intersect ray only with backsides
93   inline void intersectTriangleBack(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v) const;
94
95   // access methods
96   //! Returns the ray origin
97   inline ntlVec3Gfx getOrigin() const { return ntlVec3Gfx(mOrigin); }
98   //! Returns the ray direction
99   inline ntlVec3Gfx getDirection() const { return ntlVec3Gfx(mDirection); }
100   /*! Returns the ray relfection normal */
101   inline ntlVec3Gfx getNormal() const { return ntlVec3Gfx(mvNormal); }
102                 //! Is this ray refracted?
103   inline unsigned char getRefracted() const  { return mIsRefracted; }
104   inline unsigned char getReflected() const  { return mIsReflected; }
105   /*! Get position along ray */
106   inline ntlVec3Gfx getPositionAt(gfxReal t) const { return (mOrigin+(mDirection*t)); }
107         /*! Get render globals pointer of this ray */
108         inline ntlRenderGlobals *getRenderglobals( void ) const { return mpGlob; }
109         /*! get this ray's ID */
110         inline int getID( void ) const { return mID; }
111
112   /*! Set origin of this ray */
113   inline void setOrigin(ntlVec3Gfx set) { mOrigin = set; }
114         /*! Set direction of this ray */
115   inline void setDirection(ntlVec3Gfx set) { mDirection = set; }
116   /*! Set normal of this ray */
117   inline void setNormal(ntlVec3Gfx set) { mvNormal = set; }
118
119 protected:
120   /* Calulates the Lambertian and Specular color for
121    * the given reflection and returns it */
122   const ntlColor getShadedColor(ntlLightObject *light, const ntlRay &reflectedray, 
123                                                                                                                                 const ntlVec3Gfx &normal, ntlMaterial *surf) const;
124   
125 private:
126   /*! Origin of ray */
127   ntlVec3Gfx     mOrigin;
128   /*! Normalized direction vector of ray */
129   ntlVec3Gfx     mDirection;
130   /*! For reflected/refracted rays, the normal is stored here */
131   ntlVec3Gfx     mvNormal;
132   /*! recursion depth */
133   unsigned int mDepth;
134         /*! How much does this ray contribute to the surface color? abort if too small */
135         gfxReal mContribution;
136
137   /*! Global rendering settings */
138   ntlRenderGlobals *mpGlob;
139
140   /*! If this ray is a refracted one, this flag has to be set
141    *  This is necessary to for example also give the background color
142    *  to refracted rays. Otherwise things may look strange... 
143    */
144   unsigned char mIsRefracted;
145   unsigned char mIsReflected;
146
147         /*! ID of this ray (from renderglobals */
148         int mID;
149
150 private:
151 #ifdef WITH_CXX_GUARDEDALLOC
152         MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlRay")
153 #endif
154 };
155
156
157 /******************************************************************************
158  *
159  * a single triangle
160  *
161  *****************************************************************************/
162
163 // triangle intersection code in bsptree.cpp
164 // intersectTriangle(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v);
165
166 /*! Triangle flag defines */
167 #define TRI_GEOMETRY      (1<<0)
168 #define TRI_CASTSHADOWS   (1<<1)
169
170
171 class ntlTriangle
172 {
173 public:
174   /* CONSTRUCTORS */
175   /*! Default constructor */
176   inline ntlTriangle( void );
177   /*! Constructor with parameters */
178   inline ntlTriangle(int *p, bool smooth, int obj, ntlVec3Gfx norm, int setflags);
179   /*! Copy - Constructor */
180   inline ntlTriangle(const ntlTriangle &tri);
181   /*! Destructor */
182   inline ~ntlTriangle() {}
183
184         /* Access methods */
185
186         /*! Acces to points of triangle */
187         inline int *getPoints( void ) { return mPoints; }
188         /*! Acces normal smoothing */
189         inline bool getSmoothNormals( void ) const { return mSmoothNormals; }
190         inline void setSmoothNormals( bool set){ mSmoothNormals = set; }
191         /*! Access object */
192         inline int getObjectId( void ) const { return mObjectId; }
193         inline void setObjectId( int set) { mObjectId = set; }
194         /*! Acces normal index */
195         inline ntlVec3Gfx getNormal( void ) const { return mNormal; }
196         inline void setNormal( ntlVec3Gfx set ) { mNormal = set; }
197         /*! Acces flags */
198         inline int getFlags( void ) const { return mFlags; }
199         inline void setFlags( int set ) { mFlags = set; }
200         /*! Access last intersection ray ID */
201         inline int  getLastRay( void ) const { return mLastRay; }
202         inline void setLastRay( int set ) { mLastRay = set; }
203         /*! Acces bbox id */
204         inline int getBBoxId( void ) const { return mBBoxId; }
205         inline void setBBoxId( int set ) { mBBoxId = set; }
206
207         /*! Get average of the three points for this axis */
208         inline gfxReal getAverage( int axis ) const;
209
210         /*! operator < for sorting, uses global sorting axis */
211         inline friend bool operator<(const ntlTriangle &lhs, const ntlTriangle &rhs);
212         /*! operator > for sorting, uses global sorting axis */
213         inline friend bool operator>(const ntlTriangle &lhs, const ntlTriangle &rhs);
214
215 protected:
216
217 private:
218
219         /*! indices to the three points of the triangle */
220         int mPoints[3];
221
222         /*! bounding box id (for tree generation), -1 if invalid */
223         int mBBoxId;
224
225         /*! Should the normals of this triangle get smoothed? */
226         bool mSmoothNormals;
227
228         /*! Id of parent object */
229         int mObjectId;
230
231         /*! Index to normal (for not smooth triangles) */
232         //int mNormalIndex; ??
233         ntlVec3Gfx mNormal;
234
235         /*! Flags for object attributes cast shadows */
236         int mFlags;
237
238         /*! ID of last ray that an intersection was calculated for */
239         int mLastRay;
240
241 private:
242 #ifdef WITH_CXX_GUARDEDALLOC
243         MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlTriangle")
244 #endif
245 };
246
247
248         
249
250 /******************************************************************************
251  * Default Constructor
252  *****************************************************************************/
253 ntlTriangle::ntlTriangle( void ) :
254         mBBoxId(-1),
255         mLastRay( 0 )
256 {
257         mPoints[0] = mPoints[1] = mPoints[2] = 0;
258         mSmoothNormals = 0;
259         mObjectId = 0;
260         mNormal = ntlVec3Gfx(0.0);
261         mFlags = 0;
262 }
263
264
265 /******************************************************************************
266  * Constructor
267  *****************************************************************************/
268 ntlTriangle::ntlTriangle(int *p, bool smooth, int obj, ntlVec3Gfx norm, int setflags) :
269         mBBoxId(-1),
270         mLastRay( 0 )
271 {
272         mPoints[0] = p[0];
273         mPoints[1] = p[1];
274         mPoints[2] = p[2];
275         mSmoothNormals = smooth;
276         mObjectId = obj;
277         mNormal = norm;
278         mFlags = setflags;
279 }
280
281
282 /******************************************************************************
283  * Copy Constructor
284  *****************************************************************************/
285 ntlTriangle::ntlTriangle(const ntlTriangle &tri) :
286         mBBoxId(-1),
287         mLastRay( 0 )
288 {
289         mPoints[0] = tri.mPoints[0];
290         mPoints[1] = tri.mPoints[1];
291         mPoints[2] = tri.mPoints[2];
292         mSmoothNormals = tri.mSmoothNormals;
293         mObjectId      = tri.mObjectId;
294         mNormal        = tri.mNormal;
295         mFlags         = tri.mFlags;
296 }
297
298
299
300
301 /******************************************************************************
302  * Triangle sorting functions
303  *****************************************************************************/
304
305 /* variables imported from ntl_bsptree.cc, necessary for using the stl sort funtion */
306 /* Static global variable for sorting direction */
307 extern int globalSortingAxis;
308 /* Access to points array for sorting */
309 extern vector<ntlVec3Gfx> *globalSortingPoints;
310         
311
312 gfxReal ntlTriangle::getAverage( int axis ) const
313
314         return ( ( (*globalSortingPoints)[ mPoints[0] ][axis] + 
315                                                  (*globalSortingPoints)[ mPoints[1] ][axis] + 
316                                                  (*globalSortingPoints)[ mPoints[2] ][axis] )/3.0);
317 }
318
319 bool operator<(const ntlTriangle &lhs,const ntlTriangle &rhs)
320 {
321         return ( lhs.getAverage(globalSortingAxis) < 
322                                          rhs.getAverage(globalSortingAxis) );
323 }
324
325 bool operator>(const ntlTriangle &lhs,const ntlTriangle &rhs)
326 {
327         return ( lhs.getAverage(globalSortingAxis) > 
328                                          rhs.getAverage(globalSortingAxis) );
329 }
330
331
332
333 /******************************************************************************
334  *
335  * Scene object, that contains and manages all geometry objects
336  *
337  *****************************************************************************/
338
339
340
341 class ntlScene
342 {
343 public:
344   /* CONSTRUCTORS */
345   /*! Default constructor */
346   ntlScene( ntlRenderGlobals *glob, bool del=true );
347   /*! Default destructor  */
348   ~ntlScene();
349
350         /*! Add an object to the scene */
351         inline void addGeoClass(ntlGeometryClass *geo) { 
352                 mGeos.push_back( geo ); 
353                 geo->setObjectId(mGeos.size());
354         }
355         /*! Add a geo object to the scene, warning - only needed for hand init */
356         inline void addGeoObject(ntlGeometryObject *geo) { mObjects.push_back( geo ); }
357
358         /*! Acces a certain object */
359         inline ntlGeometryObject *getObject(int id) { 
360                 if(!mSceneBuilt) { errFatal("ntlScene::getObject","Scene not inited!", SIMWORLD_INITERROR); }
361                 return mObjects[id]; }
362
363         /*! Acces object array */
364         inline vector<ntlGeometryObject*> *getObjects() { 
365                 if(!mSceneBuilt) { errFatal("ntlScene::getObjects[]","Scene not inited!", SIMWORLD_INITERROR); }
366                 return &mObjects; }
367
368         /*! Acces geo class array */
369         inline vector<ntlGeometryClass*> *getGeoClasses() { 
370                 if(!mSceneBuilt) { errFatal("ntlScene::getGeoClasses[]","Scene not inited!", SIMWORLD_INITERROR); }
371                 return &mGeos; }
372
373         /*! draw scene with opengl */
374         //void draw();
375         
376         /*! Build/first init the scene arrays */
377         void buildScene(double time, bool firstInit);
378         
379         //! Prepare the scene triangles and maps for raytracing
380         void prepareScene(double time);
381         //! Do some memory cleaning, when frame is finished
382         void cleanupScene( void );
383
384         /*! Intersect a ray with the scene triangles */
385         void intersectScene(const ntlRay &r, gfxReal &distance, ntlVec3Gfx &normal, ntlTriangle *&tri, int flags) const;
386
387         /*! return a vertex */
388         ntlVec3Gfx getVertex(int index) { return mVertices[index]; } 
389
390         // for tree generation 
391         /*! return pointer to vertices vector */
392         vector<ntlVec3Gfx> *getVertexPointer( void ) { return &mVertices; }
393         /*! return pointer to vertices vector */
394         vector<ntlVec3Gfx> *getVertexNormalPointer( void ) { return &mVertNormals; }
395         /*! return pointer to vertices vector */
396         vector<ntlTriangle> *getTrianglePointer( void ) { return &mTriangles; }
397
398 private:
399
400         /*! Global settings */
401         ntlRenderGlobals *mpGlob;
402
403         /*! free objects? (only necessary for render scene, which  contains all) */
404         bool mSceneDel;
405
406   /*! List of geometry classes */
407   vector<ntlGeometryClass *> mGeos;
408
409   /*! List of geometry objects */
410   vector<ntlGeometryObject *> mObjects;
411
412   /*! List of triangles */
413   vector<ntlTriangle> mTriangles;
414   /*! List of vertices */
415   vector<ntlVec3Gfx>  mVertices;
416   /*! List of normals */
417   vector<ntlVec3Gfx>  mVertNormals;
418   /*! List of triangle normals */
419   vector<ntlVec3Gfx>  mTriangleNormals;
420
421         /*! Tree to store quickly intersect triangles */
422         ntlTree *mpTree;
423
424         /*! was the scene successfully built? only then getObject(i) requests are valid */
425         bool mSceneBuilt;
426
427         /*! shader/obj initializations are only done on first init */
428         bool mFirstInitDone;
429
430 private:
431 #ifdef WITH_CXX_GUARDEDALLOC
432         MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlScene")
433 #endif
434 };
435
436
437 #endif
438