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