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