Welcome to mirror list, hosted at ThFree Co, Russian Federation.

ntl_ray.h « intern « elbeem « intern - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 5f6d34e302060c608900a52ccb3e495af8aa300a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
/** \file elbeem/intern/ntl_ray.h
 *  \ingroup elbeem
 */
/******************************************************************************
 *
 * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method
 * Copyright 2003-2006 Nils Thuerey
 *
 * ray class
 *
 *****************************************************************************/
#ifndef NTL_RAY_H
#define NTL_RAY_H

#include <sstream>
#include "ntl_vector3dim.h"
#include "ntl_lighting.h"
#include "ntl_geometryobject.h"
#include "ntl_bsptree.h"

class ntlTriangle;
class ntlRay;
class ntlTree;
class ntlScene;
class ntlRenderGlobals;
class ntlGeometryObject;

//! store data for an intersection of a ray and a triangle
// NOT YET USED
class ntlIntersection {
	public:

		ntlIntersection() :
			distance(-1.0), normal(0.0),
			ray(NULL), tri(NULL), flags(0) { };

		gfxReal distance;
		ntlVec3Gfx normal;
		ntlRay *ray; 
		ntlTriangle *tri;
		char flags;
};

//! the main ray class
class ntlRay
{
public:
  // CONSTRUCTORS
  //! Initialize ray memebers, prints error message
  ntlRay();
  //! Copy constructor, copy all members
  ntlRay(const ntlRay &r);
  //! Explicitly init member variables with global render object
  ntlRay(const ntlVec3Gfx &o, const ntlVec3Gfx &d, unsigned int i, gfxReal contrib, ntlRenderGlobals *glob);
  //! Destructor
  ~ntlRay();

  //! Set the refraction flag for refracted rays
  inline void setRefracted(unsigned char set) { mIsRefracted = set; }
  inline void setReflected(unsigned char set) { mIsReflected = set; }

  //! main ray recursion function
  /*!
   * First get closest object intersection, return background color if nothing
   * was hit, else calculate shading and reflection components 
   * and return mixed color */
  const ntlColor shade() /*const*/;

	/*! Trace a photon through the scene */
	void tracePhoton(ntlColor) const;

  //! intersect ray with AABB
  void intersectFrontAABB(ntlVec3Gfx mStart, ntlVec3Gfx mEnd, gfxReal &t, ntlVec3Gfx &normal, ntlVec3Gfx &retcoord) const;
  void intersectBackAABB(ntlVec3Gfx mStart, ntlVec3Gfx mEnd, gfxReal &t, ntlVec3Gfx &normal, ntlVec3Gfx &retcoord) const;
  void intersectCompleteAABB(ntlVec3Gfx mStart, ntlVec3Gfx mEnd, gfxReal &tmin, gfxReal &tmax) const;
	// intersection routines in bsptree.cpp
  //! optimized intersect ray with triangle
  inline void intersectTriangle(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v) const;
  //! optimized intersect ray with triangle along +X axis dir
  inline void intersectTriangleX(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v) const;
  //! intersect only with front side
  inline void intersectTriangleFront(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v) const;
  //! intersect ray only with backsides
  inline void intersectTriangleBack(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v) const;

  // access methods
  //! Returns the ray origin
  inline ntlVec3Gfx getOrigin() const { return ntlVec3Gfx(mOrigin); }
  //! Returns the ray direction
  inline ntlVec3Gfx getDirection() const { return ntlVec3Gfx(mDirection); }
  /*! Returns the ray relfection normal */
  inline ntlVec3Gfx getNormal() const { return ntlVec3Gfx(mvNormal); }
		//! Is this ray refracted?
  inline unsigned char getRefracted() const  { return mIsRefracted; }
  inline unsigned char getReflected() const  { return mIsReflected; }
  /*! Get position along ray */
  inline ntlVec3Gfx getPositionAt(gfxReal t) const { return (mOrigin+(mDirection*t)); }
	/*! Get render globals pointer of this ray */
	inline ntlRenderGlobals *getRenderglobals( void ) const { return mpGlob; }
	/*! get this ray's ID */
	inline int getID( void ) const { return mID; }

  /*! Set origin of this ray */
  inline void setOrigin(ntlVec3Gfx set) { mOrigin = set; }
	/*! Set direction of this ray */
  inline void setDirection(ntlVec3Gfx set) { mDirection = set; }
  /*! Set normal of this ray */
  inline void setNormal(ntlVec3Gfx set) { mvNormal = set; }

protected:
  /* Calulates the Lambertian and Specular color for
   * the given reflection and returns it */
  const ntlColor getShadedColor(ntlLightObject *light, const ntlRay &reflectedray, 
																const ntlVec3Gfx &normal, ntlMaterial *surf) const;
  
private:
  /*! Origin of ray */
  ntlVec3Gfx     mOrigin;
  /*! Normalized direction vector of ray */
  ntlVec3Gfx     mDirection;
  /*! For reflected/refracted rays, the normal is stored here */
  ntlVec3Gfx     mvNormal;
  /*! recursion depth */
  unsigned int mDepth;
	/*! How much does this ray contribute to the surface color? abort if too small */
	gfxReal mContribution;

  /*! Global rendering settings */
  ntlRenderGlobals *mpGlob;

  /*! If this ray is a refracted one, this flag has to be set
   *  This is necessary to for example also give the background color
   *  to refracted rays. Otherwise things may look strange... 
   */
  unsigned char mIsRefracted;
  unsigned char mIsReflected;

	/*! ID of this ray (from renderglobals */
	int mID;

};


/******************************************************************************
 *
 * a single triangle
 *
 *****************************************************************************/

// triangle intersection code in bsptree.cpp
// intersectTriangle(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v);

/*! Triangle flag defines */
#define TRI_GEOMETRY      (1<<0)
#define TRI_CASTSHADOWS   (1<<1)


class ntlTriangle
{
public:
  /* CONSTRUCTORS */
  /*! Default constructor */
  inline ntlTriangle( void );
  /*! Constructor with parameters */
  inline ntlTriangle(int *p, bool smooth, int obj, ntlVec3Gfx norm, int setflags);
  /*! Copy - Constructor */
  inline ntlTriangle(const ntlTriangle &tri);
  /*! Destructor */
  inline ~ntlTriangle() {}

	/* Access methods */

	/*! Acces to points of triangle */
	inline int *getPoints( void ) { return mPoints; }
	/*! Acces normal smoothing */
	inline bool getSmoothNormals( void ) const { return mSmoothNormals; }
	inline void setSmoothNormals( bool set){ mSmoothNormals = set; }
	/*! Access object */
	inline int getObjectId( void ) const { return mObjectId; }
	inline void setObjectId( int set) { mObjectId = set; }
	/*! Acces normal index */
	inline ntlVec3Gfx getNormal( void ) const { return mNormal; }
	inline void setNormal( ntlVec3Gfx set ) { mNormal = set; }
	/*! Acces flags */
	inline int getFlags( void ) const { return mFlags; }
	inline void setFlags( int set ) { mFlags = set; }
	/*! Access last intersection ray ID */
	inline int  getLastRay( void ) const { return mLastRay; }
	inline void setLastRay( int set ) { mLastRay = set; }
	/*! Acces bbox id */
	inline int getBBoxId( void ) const { return mBBoxId; }
	inline void setBBoxId( int set ) { mBBoxId = set; }

	/*! Get average of the three points for this axis */
	inline gfxReal getAverage( int axis ) const;

	/*! operator < for sorting, uses global sorting axis */
	inline friend bool operator<(const ntlTriangle &lhs, const ntlTriangle &rhs);
	/*! operator > for sorting, uses global sorting axis */
	inline friend bool operator>(const ntlTriangle &lhs, const ntlTriangle &rhs);

protected:

private:

	/*! indices to the three points of the triangle */
	int mPoints[3];

	/*! bounding box id (for tree generation), -1 if invalid */
	int mBBoxId;

	/*! Should the normals of this triangle get smoothed? */
	bool mSmoothNormals;

	/*! Id of parent object */
	int mObjectId;

	/*! Index to normal (for not smooth triangles) */
	//int mNormalIndex; ??
	ntlVec3Gfx mNormal;

	/*! Flags for object attributes cast shadows */
	int mFlags;

	/*! ID of last ray that an intersection was calculated for */
	int mLastRay;

};


	

/******************************************************************************
 * Default Constructor
 *****************************************************************************/
ntlTriangle::ntlTriangle( void ) :
	mBBoxId(-1),
	mLastRay( 0 )
{
	mPoints[0] = mPoints[1] = mPoints[2] = 0;
	mSmoothNormals = 0;
	mObjectId = 0;
	mNormal = ntlVec3Gfx(0.0);
	mFlags = 0;
}


/******************************************************************************
 * Constructor
 *****************************************************************************/
ntlTriangle::ntlTriangle(int *p, bool smooth, int obj, ntlVec3Gfx norm, int setflags) :
	mBBoxId(-1),
	mLastRay( 0 )
{
	mPoints[0] = p[0];
	mPoints[1] = p[1];
	mPoints[2] = p[2];
	mSmoothNormals = smooth;
	mObjectId = obj;
	mNormal = norm;
	mFlags = setflags;
}


/******************************************************************************
 * Copy Constructor
 *****************************************************************************/
ntlTriangle::ntlTriangle(const ntlTriangle &tri) :
	mBBoxId(-1),
	mLastRay( 0 )
{
	mPoints[0] = tri.mPoints[0];
	mPoints[1] = tri.mPoints[1];
	mPoints[2] = tri.mPoints[2];
	mSmoothNormals = tri.mSmoothNormals;
	mObjectId      = tri.mObjectId;
	mNormal        = tri.mNormal;
	mFlags         = tri.mFlags;
}




/******************************************************************************
 * Triangle sorting functions
 *****************************************************************************/

/* variables imported from ntl_bsptree.cc, necessary for using the stl sort funtion */
/* Static global variable for sorting direction */
extern int globalSortingAxis;
/* Access to points array for sorting */
extern vector<ntlVec3Gfx> *globalSortingPoints;
	

gfxReal ntlTriangle::getAverage( int axis ) const
{ 
	return ( ( (*globalSortingPoints)[ mPoints[0] ][axis] + 
						 (*globalSortingPoints)[ mPoints[1] ][axis] + 
						 (*globalSortingPoints)[ mPoints[2] ][axis] )/3.0);
}

bool operator<(const ntlTriangle &lhs,const ntlTriangle &rhs)
{
	return ( lhs.getAverage(globalSortingAxis) < 
					 rhs.getAverage(globalSortingAxis) );
}

bool operator>(const ntlTriangle &lhs,const ntlTriangle &rhs)
{
	return ( lhs.getAverage(globalSortingAxis) > 
					 rhs.getAverage(globalSortingAxis) );
}



/******************************************************************************
 *
 * Scene object, that contains and manages all geometry objects
 *
 *****************************************************************************/



class ntlScene
{
public:
  /* CONSTRUCTORS */
  /*! Default constructor */
  ntlScene( ntlRenderGlobals *glob, bool del=true );
  /*! Default destructor  */
  ~ntlScene();

	/*! Add an object to the scene */
	inline void addGeoClass(ntlGeometryClass *geo) { 
		mGeos.push_back( geo ); 
		geo->setObjectId(mGeos.size());
	}
	/*! Add a geo object to the scene, warning - only needed for hand init */
	inline void addGeoObject(ntlGeometryObject *geo) { mObjects.push_back( geo ); }

	/*! Acces a certain object */
	inline ntlGeometryObject *getObject(int id) { 
		if(!mSceneBuilt) { errFatal("ntlScene::getObject","Scene not inited!", SIMWORLD_INITERROR); }
		return mObjects[id]; }

	/*! Acces object array */
	inline vector<ntlGeometryObject*> *getObjects() { 
		if(!mSceneBuilt) { errFatal("ntlScene::getObjects[]","Scene not inited!", SIMWORLD_INITERROR); }
		return &mObjects; }

	/*! Acces geo class array */
	inline vector<ntlGeometryClass*> *getGeoClasses() { 
		if(!mSceneBuilt) { errFatal("ntlScene::getGeoClasses[]","Scene not inited!", SIMWORLD_INITERROR); }
		return &mGeos; }

	/*! draw scene with opengl */
	//void draw();
	
	/*! Build/first init the scene arrays */
	void buildScene(double time, bool firstInit);
	
	//! Prepare the scene triangles and maps for raytracing
	void prepareScene(double time);
	//! Do some memory cleaning, when frame is finished
	void cleanupScene( void );

	/*! Intersect a ray with the scene triangles */
	void intersectScene(const ntlRay &r, gfxReal &distance, ntlVec3Gfx &normal, ntlTriangle *&tri, int flags) const;

	/*! return a vertex */
	ntlVec3Gfx getVertex(int index) { return mVertices[index]; } 

	// for tree generation 
	/*! return pointer to vertices vector */
	vector<ntlVec3Gfx> *getVertexPointer( void ) { return &mVertices; }
	/*! return pointer to vertices vector */
	vector<ntlVec3Gfx> *getVertexNormalPointer( void ) { return &mVertNormals; }
	/*! return pointer to vertices vector */
	vector<ntlTriangle> *getTrianglePointer( void ) { return &mTriangles; }

private:

	/*! Global settings */
	ntlRenderGlobals *mpGlob;

	/*! free objects? (only necessary for render scene, which  contains all) */
	bool mSceneDel;

  /*! List of geometry classes */
  vector<ntlGeometryClass *> mGeos;

  /*! List of geometry objects */
  vector<ntlGeometryObject *> mObjects;

  /*! List of triangles */
  vector<ntlTriangle> mTriangles;
  /*! List of vertices */
  vector<ntlVec3Gfx>  mVertices;
  /*! List of normals */
  vector<ntlVec3Gfx>  mVertNormals;
  /*! List of triangle normals */
  vector<ntlVec3Gfx>  mTriangleNormals;

	/*! Tree to store quickly intersect triangles */
	ntlTree *mpTree;

	/*! was the scene successfully built? only then getObject(i) requests are valid */
	bool mSceneBuilt;

	/*! shader/obj initializations are only done on first init */
	bool mFirstInitDone;

};


#endif