1 /******************************************************************************
3 * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method
4 * Copyright 2003-2006 Nils Thuerey
8 *****************************************************************************/
13 #include "ntl_vector3dim.h"
14 #include "ntl_lighting.h"
15 #include "ntl_geometryobject.h"
16 #include "ntl_bsptree.h"
22 class ntlRenderGlobals;
23 class ntlGeometryObject;
25 //! store data for an intersection of a ray and a triangle
27 class ntlIntersection {
31 distance(-1.0), normal(0.0),
32 ray(NULL), tri(NULL), flags(0) { };
41 //! the main ray class
46 //! Initialize ray memebers, prints error message
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);
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; }
59 //! main ray recursion function
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*/;
66 /*! Trace a photon through the scene */
67 void tracePhoton(ntlColor) const;
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;
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; }
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; }
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;
116 /*! Normalized direction vector of ray */
117 ntlVec3Gfx mDirection;
118 /*! For reflected/refracted rays, the normal is stored here */
120 /*! recursion depth */
122 /*! How much does this ray contribute to the surface color? abort if too small */
123 gfxReal mContribution;
125 /*! Global rendering settings */
126 ntlRenderGlobals *mpGlob;
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...
132 unsigned char mIsRefracted;
133 unsigned char mIsReflected;
135 /*! ID of this ray (from renderglobals */
141 /******************************************************************************
145 *****************************************************************************/
147 // triangle intersection code in bsptree.cpp
148 // intersectTriangle(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v);
150 /*! Triangle flag defines */
151 #define TRI_GEOMETRY (1<<0)
152 #define TRI_CASTSHADOWS (1<<1)
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);
166 inline ~ntlTriangle() {}
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; }
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; }
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; }
188 inline int getBBoxId( void ) const { return mBBoxId; }
189 inline void setBBoxId( int set ) { mBBoxId = set; }
191 /*! Get average of the three points for this axis */
192 inline gfxReal getAverage( int axis ) const;
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);
203 /*! indices to the three points of the triangle */
206 /*! bounding box id (for tree generation), -1 if invalid */
209 /*! Should the normals of this triangle get smoothed? */
212 /*! Id of parent object */
215 /*! Index to normal (for not smooth triangles) */
216 //int mNormalIndex; ??
219 /*! Flags for object attributes cast shadows */
222 /*! ID of last ray that an intersection was calculated for */
230 /******************************************************************************
231 * Default Constructor
232 *****************************************************************************/
233 ntlTriangle::ntlTriangle( void ) :
237 mPoints[0] = mPoints[1] = mPoints[2] = 0;
240 mNormal = ntlVec3Gfx(0.0);
245 /******************************************************************************
247 *****************************************************************************/
248 ntlTriangle::ntlTriangle(int *p, bool smooth, int obj, ntlVec3Gfx norm, int setflags) :
255 mSmoothNormals = smooth;
262 /******************************************************************************
264 *****************************************************************************/
265 ntlTriangle::ntlTriangle(const ntlTriangle &tri) :
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;
281 /******************************************************************************
282 * Triangle sorting functions
283 *****************************************************************************/
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;
292 gfxReal ntlTriangle::getAverage( int axis ) const
294 return ( ( (*globalSortingPoints)[ mPoints[0] ][axis] +
295 (*globalSortingPoints)[ mPoints[1] ][axis] +
296 (*globalSortingPoints)[ mPoints[2] ][axis] )/3.0);
299 bool operator<(const ntlTriangle &lhs,const ntlTriangle &rhs)
301 return ( lhs.getAverage(globalSortingAxis) <
302 rhs.getAverage(globalSortingAxis) );
305 bool operator>(const ntlTriangle &lhs,const ntlTriangle &rhs)
307 return ( lhs.getAverage(globalSortingAxis) >
308 rhs.getAverage(globalSortingAxis) );
313 /******************************************************************************
315 * Scene object, that contains and manages all geometry objects
317 *****************************************************************************/
325 /*! Default constructor */
326 ntlScene( ntlRenderGlobals *glob, bool del=true );
327 /*! Default destructor */
330 /*! Add an object to the scene */
331 inline void addGeoClass(ntlGeometryClass *geo) {
332 mGeos.push_back( geo );
333 geo->setObjectId(mGeos.size());
335 /*! Add a geo object to the scene, warning - only needed for hand init */
336 inline void addGeoObject(ntlGeometryObject *geo) { mObjects.push_back( geo ); }
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]; }
343 /*! Acces object array */
344 inline vector<ntlGeometryObject*> *getObjects() {
345 if(!mSceneBuilt) { errFatal("ntlScene::getObjects[]","Scene not inited!", SIMWORLD_INITERROR); }
348 /*! Acces geo class array */
349 inline vector<ntlGeometryClass*> *getGeoClasses() {
350 if(!mSceneBuilt) { errFatal("ntlScene::getGeoClasses[]","Scene not inited!", SIMWORLD_INITERROR); }
353 /*! draw scene with opengl */
356 /*! Build/first init the scene arrays */
357 void buildScene(double time, bool firstInit);
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 );
364 /*! Intersect a ray with the scene triangles */
365 void intersectScene(const ntlRay &r, gfxReal &distance, ntlVec3Gfx &normal, ntlTriangle *&tri, int flags) const;
367 /*! return a vertex */
368 ntlVec3Gfx getVertex(int index) { return mVertices[index]; }
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; }
380 /*! Global settings */
381 ntlRenderGlobals *mpGlob;
383 /*! free objects? (only necessary for render scene, which contains all) */
386 /*! List of geometry classes */
387 vector<ntlGeometryClass *> mGeos;
389 /*! List of geometry objects */
390 vector<ntlGeometryObject *> mObjects;
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;
401 /*! Tree to store quickly intersect triangles */
404 /*! id of dislpay list for raytracer stuff */
407 /*! was the scene successfully built? only then getObject(i) requests are valid */
410 /*! shader/obj initializations are only done on first init */