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;
24 //! store data for an intersection of a ray and a triangle
26 class ntlIntersection {
30 distance(-1.0), normal(0.0),
31 ray(NULL), tri(NULL), flags(0) { };
40 //! the main ray class
45 //! Initialize ray memebers, prints error message
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);
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; }
58 //! main ray recursion function
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*/;
65 /*! Trace a photon through the scene */
66 void tracePhoton(ntlColor) const;
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;
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; }
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; }
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;
115 /*! Normalized direction vector of ray */
116 ntlVec3Gfx mDirection;
117 /*! For reflected/refracted rays, the normal is stored here */
119 /*! recursion depth */
121 /*! How much does this ray contribute to the surface color? abort if too small */
122 gfxReal mContribution;
124 /*! Global rendering settings */
125 ntlRenderGlobals *mpGlob;
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...
131 unsigned char mIsRefracted;
132 unsigned char mIsReflected;
134 /*! ID of this ray (from renderglobals */
140 /******************************************************************************
144 *****************************************************************************/
146 // triangle intersection code in bsptree.cpp
147 // intersectTriangle(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v);
149 /*! Triangle flag defines */
150 #define TRI_GEOMETRY (1<<0)
151 #define TRI_CASTSHADOWS (1<<1)
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);
165 inline ~ntlTriangle() {}
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; }
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; }
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; }
187 inline int getBBoxId( void ) const { return mBBoxId; }
188 inline void setBBoxId( int set ) { mBBoxId = set; }
190 /*! Get average of the three points for this axis */
191 inline gfxReal getAverage( int axis ) const;
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);
202 /*! indices to the three points of the triangle */
205 /*! bounding box id (for tree generation), -1 if invalid */
208 /*! Should the normals of this triangle get smoothed? */
211 /*! Id of parent object */
214 /*! Index to normal (for not smooth triangles) */
215 //int mNormalIndex; ??
218 /*! Flags for object attributes cast shadows */
221 /*! ID of last ray that an intersection was calculated for */
229 /******************************************************************************
230 * Default Constructor
231 *****************************************************************************/
232 ntlTriangle::ntlTriangle( void ) :
236 mPoints[0] = mPoints[1] = mPoints[2] = 0;
239 mNormal = ntlVec3Gfx(0.0);
244 /******************************************************************************
246 *****************************************************************************/
247 ntlTriangle::ntlTriangle(int *p, bool smooth, int obj, ntlVec3Gfx norm, int setflags) :
254 mSmoothNormals = smooth;
261 /******************************************************************************
263 *****************************************************************************/
264 ntlTriangle::ntlTriangle(const ntlTriangle &tri) :
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;
280 /******************************************************************************
281 * Triangle sorting functions
282 *****************************************************************************/
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;
291 gfxReal ntlTriangle::getAverage( int axis ) const
293 return ( ( (*globalSortingPoints)[ mPoints[0] ][axis] +
294 (*globalSortingPoints)[ mPoints[1] ][axis] +
295 (*globalSortingPoints)[ mPoints[2] ][axis] )/3.0);
298 bool operator<(const ntlTriangle &lhs,const ntlTriangle &rhs)
300 return ( lhs.getAverage(globalSortingAxis) <
301 rhs.getAverage(globalSortingAxis) );
304 bool operator>(const ntlTriangle &lhs,const ntlTriangle &rhs)
306 return ( lhs.getAverage(globalSortingAxis) >
307 rhs.getAverage(globalSortingAxis) );
312 /******************************************************************************
314 * Scene object, that contains and manages all geometry objects
316 *****************************************************************************/
324 /*! Default constructor */
325 ntlScene( ntlRenderGlobals *glob, bool del=true );
326 /*! Default destructor */
329 /*! Add an object to the scene */
330 inline void addGeoClass(ntlGeometryClass *geo) {
331 mGeos.push_back( geo );
332 geo->setObjectId(mGeos.size());
334 /*! Add a geo object to the scene, warning - only needed for hand init */
335 inline void addGeoObject(ntlGeometryObject *geo) { mObjects.push_back( geo ); }
337 /*! Acces a certain object */
338 inline ntlGeometryObject *getObject(int id) {
339 if(!mSceneBuilt) { errFatal("ntlScene::getObject","Scene not inited!", SIMWORLD_INITERROR); }
340 return mObjects[id]; }
342 /*! Acces object array */
343 inline vector<ntlGeometryObject*> *getObjects() {
344 if(!mSceneBuilt) { errFatal("ntlScene::getObjects[]","Scene not inited!", SIMWORLD_INITERROR); }
347 /*! Acces geo class array */
348 inline vector<ntlGeometryClass*> *getGeoClasses() {
349 if(!mSceneBuilt) { errFatal("ntlScene::getGeoClasses[]","Scene not inited!", SIMWORLD_INITERROR); }
352 /*! draw scene with opengl */
355 /*! Build/first init the scene arrays */
356 void buildScene(double time, bool firstInit);
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 );
363 /*! Intersect a ray with the scene triangles */
364 void intersectScene(const ntlRay &r, gfxReal &distance, ntlVec3Gfx &normal, ntlTriangle *&tri, int flags) const;
366 /*! return a vertex */
367 ntlVec3Gfx getVertex(int index) { return mVertices[index]; }
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; }
379 /*! Global settings */
380 ntlRenderGlobals *mpGlob;
382 /*! free objects? (only necessary for render scene, which contains all) */
385 /*! List of geometry classes */
386 vector<ntlGeometryClass *> mGeos;
388 /*! List of geometry objects */
389 vector<ntlGeometryObject *> mObjects;
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;
400 /*! Tree to store quickly intersect triangles */
403 /*! id of dislpay list for raytracer stuff */
406 /*! was the scene successfully built? only then getObject(i) requests are valid */
409 /*! shader/obj initializations are only done on first init */