5d328907e713a52c4bab09e0f891811ad5c66604
[blender.git] / intern / elbeem / intern / particletracer.h
1 /** \file elbeem/intern/particletracer.h
2  *  \ingroup elbeem
3  */
4 /******************************************************************************
5  *
6  * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method
7  * Copyright 2003-2006 Nils Thuerey
8  *
9  * Particle Viewer/Tracer
10  *
11  *****************************************************************************/
12 #ifndef NTL_PARTICLETRACER_H
13
14 #include "ntl_geometryobject.h"
15 template<class Scalar> class ntlMatrix4x4;
16
17 // particle types
18 #define PART_BUBBLE (1<< 1)
19 #define PART_DROP   (1<< 2)
20 #define PART_INTER  (1<< 3)
21 #define PART_FLOAT  (1<< 4)
22 #define PART_TRACER (1<< 5)
23
24 // particle state
25 #define PART_IN     (1<< 8)
26 #define PART_OUT    (1<< 9)
27 #define PART_INACTIVE (1<<10)
28 #define PART_OUTFLUID  (1<<11)
29
30 // defines for particle movement
31 #define MOVE_FLOATS 1
32 #define FLOAT_JITTER 0.03
33 //#define FLOAT_JITTER 0.0
34
35 extern int ParticleObjectIdCnt;
36
37 //! A single particle
38 class ParticleObject
39 {
40         public:
41         //! Standard constructor
42         inline ParticleObject(ntlVec3Gfx mp) :
43                         mPos(mp),mVel(0.0), mSize(1.0), mStatus(0),mLifeTime(0),mpNext(NULL) 
44                                 { mId = ParticleObjectIdCnt++; };
45         //! Copy constructor
46         inline ParticleObject(const ParticleObject &a) :
47                         mPos(a.mPos), mVel(a.mVel), mSize(a.mSize), 
48                         mStatus(a.mStatus),
49                         mLifeTime(a.mLifeTime), mpNext(NULL) 
50                                 { mId = ParticleObjectIdCnt++; };
51         //! Destructor
52         inline ~ParticleObject() { /* empty */ };
53
54                 //! add vector to position
55                 inline void advance(float vx, float vy, float vz) {
56                         mPos[0] += vx; mPos[1] += vy; mPos[2] += vz; }
57                 inline void advanceVec(ntlVec3Gfx v) {
58                         mPos[0] += v[0]; mPos[1] += v[1]; mPos[2] += v[2]; }
59                 //! advance with own velocity
60                 inline void advanceVel() { mPos += mVel; }
61                 //! add acceleration to velocity
62                 inline void addToVel(ntlVec3Gfx acc) { mVel += acc; }
63
64                 //! get/set vector to position
65                 inline ntlVec3Gfx getPos() { return mPos; }
66                 inline void setPos(ntlVec3Gfx set) { mPos=set; }
67                 //! set velocity
68                 inline void setVel(ntlVec3Gfx set) { mVel = set; }
69                 //! set velocity
70                 inline void setVel(gfxReal x, gfxReal y, gfxReal z) { mVel = ntlVec3Gfx(x,y,z); }
71                 //! get velocity
72                 inline ntlVec3Gfx getVel() { return mVel; }
73
74                 //! get/set size value
75                 inline gfxReal getSize() { return mSize; }
76                 inline void setSize(gfxReal set) { mSize=set; }
77
78                 //! get/set next pointer
79                 inline ParticleObject* getNext() { return mpNext; }
80                 inline void setNext(ParticleObject* set) { mpNext=set; }
81
82                 //! get whole flags
83                 inline int getFlags() const { return mStatus; }
84                 //! get status (higher byte)
85                 inline int getStatus() const { return (mStatus&0xFF00); }
86                 //! set status  (higher byte)
87                 inline void setStatus(int set) { mStatus = set|(mStatus&0x00FF); }
88                 //! get type (lower byte)
89                 inline int getType() const { return (mStatus&0x00FF); }
90                 //! set type (lower byte)
91                 inline void setType(int set) { mStatus = set|(mStatus&0xFF00); }
92                 //! get active flag
93                 inline bool getActive() const { return ((mStatus&PART_INACTIVE)==0); }
94                 //! set active flag
95                 inline void setActive(bool set) { 
96                         if(set) mStatus &= (~PART_INACTIVE);    
97                         else mStatus |= PART_INACTIVE;
98                 }
99                 //! get influid flag
100                 inline bool getInFluid() const { return ((mStatus&PART_OUTFLUID)==0); }
101                 //! set influid flag
102                 inline void setInFluid(bool set) { 
103                         if(set) mStatus &= (~PART_OUTFLUID);    
104                         else mStatus |= PART_OUTFLUID;
105                 }
106                 //! get/set lifetime
107                 inline float getLifeTime() const { return mLifeTime; }
108                 //! set type (lower byte)
109                 inline void setLifeTime(float set) { mLifeTime = set; }
110                 
111                 inline int getId() const { return mId; }
112
113                 static inline float getMass(float size) { 
114                         return 4.0/3.0 * M_PI* (size)*(size)*(size); // mass: 4/3 pi r^3 rho
115                 }
116
117         protected:
118
119                 /*! only for debugging */
120                 int mId;
121                 /*! the particle position */
122                 ntlVec3Gfx mPos;
123                 /*! the particle velocity */
124                 ntlVec3Gfx mVel;
125                 /*! size / mass of particle */
126                 gfxReal mSize;
127                 /*! particle status */
128                 int mStatus;
129                 /*! count survived time steps */
130                 float mLifeTime;
131
132                 /* for list constructions */
133                 ParticleObject *mpNext;
134 };
135
136
137 //! A whole particle array
138 class ParticleTracer :
139         public ntlGeometryObject
140 {
141         public:
142         //! Standard constructor
143         ParticleTracer();
144         //! Destructor
145         ~ParticleTracer();
146
147                 //! add a particle at this position
148                 void addParticle(float x, float y, float z);
149                 //! add/copy a particle from inited struct 
150                 void addFullParticle(ParticleObject &np);
151
152                 //! draw the particle array
153                 void draw();
154                 
155                 //! parse settings from attributes (dont use own list!)
156                 void parseAttrList( AttributeList *att );
157
158                 //! adapt time step by rescaling velocities
159                 void adaptPartTimestep(float factor);
160
161                 // access funcs
162                 
163                 //! get the number of particles
164                 inline int  getNumParticles()                           { return mParts.size(); }
165                 //! set/get the number of particles
166                 inline void setNumInitialParticles(int set) { mNumInitialParts=set; }
167                 inline int  getNumInitialParticles()          { return mNumInitialParts; }
168
169                 //! iterate over all newest particles (for advancing positions)
170                 inline vector<ParticleObject>::iterator getParticlesBegin() { return mParts.begin(); }
171                 //! end iterator for newest particles
172                 inline vector<ParticleObject>::iterator getParticlesEnd() { return mParts.end(); }
173                 //! end iterator for newest particles
174                 inline ParticleObject* getLast() { return &(mParts[ mParts.size()-1 ]); }
175                 
176                 /*! set geometry start (for renderer) */
177                 inline void setStart(ntlVec3Gfx set) { mStart = set; initTrafoMatrix(); }
178                 /*! set geometry end (for renderer) */
179                 inline void setEnd(ntlVec3Gfx set) { mEnd = set; initTrafoMatrix(); }
180                 /*! get values */
181                 inline ntlVec3Gfx getStart() { return mStart; }
182                 /*! set geometry end (for renderer) */
183                 inline ntlVec3Gfx getEnd() { return mEnd; }
184                 
185                 /*! set simulation domain start */
186                 inline void setSimStart(ntlVec3Gfx set) { mSimStart = set; initTrafoMatrix(); }
187                 /*! set simulation domain end */
188                 inline void setSimEnd(ntlVec3Gfx set) { mSimEnd = set; initTrafoMatrix(); }
189                 
190                 /*! set/get dump flag */
191                 inline void setDumpParts(bool set) { mDumpParts = set; }
192                 inline bool getDumpParts()         { return mDumpParts; }
193                 /*! set/get dump text file */
194                 inline void setDumpTextFile(string set) { mDumpTextFile = set; }
195                 inline string getDumpTextFile()         { return mDumpTextFile; }
196                 /*! set/get dump text interval */
197                 inline void setDumpTextInterval(float set) { mDumpTextInterval = set; }
198                 inline float getDumpTextInterval()         { return mDumpTextInterval; }
199                 /*! set/get init times */
200                 inline void setInitStart(float set) { mInitStart = set; }
201                 inline float getInitStart()         { return mInitStart; }
202                 inline void setInitEnd(float set)   { mInitEnd = set; }
203                 inline float getInitEnd()           { return mInitEnd; }
204                 
205                 //! set the particle scaling factor
206                 inline void setPartScale(float set) { mPartScale = set; }
207
208                 //! called after each frame to check if positions should be dumped
209                 void checkDumpTextPositions(double simtime);
210
211                 // NTL geometry implementation
212                 /*! Get the triangles from this object */
213                 virtual void getTriangles(double t, vector<ntlTriangle> *triangles, 
214                                 vector<ntlVec3Gfx> *vertices, 
215                                 vector<ntlVec3Gfx> *normals, int objectId );
216
217                 virtual void notifyOfDump(int dumptype, int frameNr,char *frameNrStr,string outfilename,double simtime);
218
219                 // notify of next step for trails
220                 void checkTrails(double time);
221                 // free deleted particles
222                 void cleanup();
223
224         protected:
225
226                 /*! the particle array (for multiple timesteps) */
227                 vector<ParticleObject> mParts;
228
229                 /*! size of the particles to display */
230                 float mPartSize;
231
232                 /*! start and end vectors for the triangulation region to create particles in */
233                 ntlVec3Gfx mStart, mEnd;
234
235                 /*! start and end vectors of the simulation domain */
236                 ntlVec3Gfx mSimStart, mSimEnd;
237
238                 /*! scaling param for particles */
239                 float mPartScale;
240                 /*! head and tail distance for particle shapes */
241                 float mPartHeadDist, mPartTailDist;
242                 /*! no of segments for particle cone */
243                 int mPartSegments;
244                 /*! use length/absval of values to scale particles? */
245                 int mValueScale;
246                 /*! value length maximal cutoff value, for mValueScale==2 */
247                 float mValueCutoffTop;
248                 /*! value length minimal cutoff value, for mValueScale==2 */
249                 float mValueCutoffBottom;
250
251                 /*! dump particles (or certain types of) to disk? */
252                 int mDumpParts;
253                 /*! text dump output file */
254                 string mDumpTextFile;
255                 /*! text dump interval, start at t=0, dumping active if >0 */
256                 float mDumpTextInterval;
257                 float mDumpTextLastTime;
258                 int mDumpTextCount;
259                 /*! show only a certain type (debugging) */
260                 int mShowOnly;
261                 /*! no. of particles to init */
262                 int mNumInitialParts;
263
264                 //! transform matrix
265                 ntlMatrix4x4<gfxReal> *mpTrafo;
266                 /*! init sim/pos transformation */
267                 void initTrafoMatrix();
268
269                 //! init time distribution start/end
270                 float mInitStart, mInitEnd;
271
272                 /*! the particle array (for multiple timesteps) */
273                 vector< vector<ParticleObject> > mPrevs;
274                 /* prev pos save interval */
275                 float mTrailTimeLast, mTrailInterval;
276                 int mTrailLength;
277 };
278
279 #define NTL_PARTICLETRACER_H
280 #endif
281