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