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