00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef __GU_Turbulence_h__
00023 #define __GU_Turbulence_h__
00024
00025 #include "GU_API.h"
00026 #include <UT/UT_Vector3.h>
00027 #include <UT/UT_BitArray.h>
00028 #include <GEO/GEO_Detail.h>
00029 #include "GU_Attractor.h"
00030
00031 class GU_Detail;
00032 class GEO_PrimParticle;
00033 class GEO_ParticleVertex;
00034 class UT_Vector3;
00035 class GU_RayIntersect;
00036
00037 typedef enum {
00038 GU_EULER,
00039 GU_RUNGEKUTTA_2,
00040 GU_RUNGEKUTTA_4
00041 } GU_INTEGRATION_TYPE;
00042
00043 enum {
00044 GU_LOOPPOINTREUSE = 0,
00045 GU_UNUSEDPOINTREUSE,
00046 GU_NOPOINTREUSE
00047 };
00048
00049 class GU_API GU_TurbulenceFlags {
00050 public:
00051 GU_TurbulenceFlags() {
00052 euler = GU_EULER;
00053 destroyMode = 0;
00054 accurateMove = 0;
00055 jitterBirth = 0;
00056 addId = 0;
00057 splitting = 0;
00058 contact = 0;
00059 birthAll = 0;
00060 pointReuse = 0;
00061 revertFixed = 1;
00062 };
00063
00064 unsigned singleAttractor:1,
00065 modifySource:1,
00066 birthAll:1,
00067
00068 destroyMode:1,
00069 accurateMove:1,
00070 jitterBirth:1,
00071 addId:1,
00072 splitting:2,
00073
00074
00075 contact:2,
00076
00077
00078 pointReuse:2,
00079
00080
00081 revertFixed:1;
00082 GU_INTEGRATION_TYPE euler;
00083 };
00084
00085
00086 class GU_API GU_Turbulence
00087 {
00088 public:
00089 GU_Turbulence();
00090 virtual ~GU_Turbulence();
00091
00092
00093
00094 void cook(float now, float time_step = 1./30.);
00095
00096
00097
00098 void reset();
00099
00100 void setGdp(GU_Detail *g) { myGdp = g; }
00101 void setSource(GU_Detail *gdp) { source = gdp;
00102 initSource(source);
00103 }
00104 void setCollision(GU_Detail *gdp) { collision = gdp;
00105 buildCollisionCache();
00106 initCollision(collision);
00107 }
00108 void setStartTime(float t) { startTime = t; }
00109 void setPreroll(float t) { preroll = t; }
00110 void setLimits(const UT_Vector3 &neg, const UT_Vector3 &pos);
00111 void setGain(float n, float t) { gainNml = n; gainTan = t; }
00112
00113 void setModifySource(int onOff) { flags.modifySource = onOff; }
00114 int getModifySource() const { return flags.modifySource; }
00115 void setPointReuse(int val) { flags.pointReuse = val; }
00116 int getPointReuse() const { return flags.pointReuse; }
00117 void setBirthAll(int onOff) { flags.birthAll = onOff; }
00118 int getBirthAll() const { return flags.birthAll; }
00119 void setRevertFixed(int onOff) { flags.revertFixed = onOff; }
00120 int getRevertFixed() const { return flags.revertFixed; }
00121
00122
00123
00124
00125 void setEuler(int onOff)
00126 {
00127 flags.euler = (onOff) ? GU_EULER : GU_RUNGEKUTTA_4;
00128 }
00129 void setIntegration(GU_INTEGRATION_TYPE t)
00130 {
00131 flags.euler = t;
00132 }
00133 int getEuler(void) const { return flags.euler==GU_EULER;}
00134 GU_INTEGRATION_TYPE getIntegration() const { return flags.euler; }
00135
00136
00137
00138
00139
00140
00141
00142 void setDestroyMode(int onOff) { flags.destroyMode = onOff; }
00143 int getDestroyMode() const { return flags.destroyMode; }
00144
00145
00146
00147
00148
00149
00150
00151
00152 void setAccurateMove(int onOff) { flags.accurateMove = onOff; }
00153 int getAccurateMove() const { return flags.accurateMove; }
00154
00155
00156
00157
00158 void setJitterBirth(int onOff) { flags.jitterBirth = onOff; }
00159 int getJitterBirth() const { return flags.jitterBirth; }
00160
00161
00162
00163
00164 void setSingleAttractor(int onOff)
00165 { flags.singleAttractor = onOff; }
00166 int getSingleAttractor() const
00167 { return flags.singleAttractor; }
00168
00169 void setAddId(int onOff) { flags.addId = onOff; }
00170 int getAddId() const { return flags.addId; }
00171
00172 void setSplitOff() { flags.splitting = 0; }
00173 void setSplitContact() { flags.splitting = 1; }
00174 void setSplitDeath() { flags.splitting = 2; }
00175 int getSplitting() const { return flags.splitting; }
00176
00177 void setDieOnContact() { flags.contact = 0; }
00178 void setBounceOnContact() { flags.contact = 1; }
00179 void setStickOnContact() { flags.contact = 2; }
00180 int getContact() { return flags.contact; }
00181
00182 void setFixedPoints(const GB_PointGroup *group);
00183 void setInputGroup(const GB_PointGroup *group);
00184
00185 void setAttractor (GU_Detail* gdp)
00186 { attractor.setAttractor(gdp); initAttractor(gdp); }
00187
00188
00189
00190 void initAttractor()
00191 { attractor.initPointAttractorForce(); }
00192
00193 void cleanupAttractor()
00194 { attractor.cleanPointAttractorForce(); }
00195
00196
00197
00198
00199 void getAttractorForce (const GEO_Point *ppt, UT_Vector3 &force)
00200 { attractor.getAttractorForce(ppt, force,
00201 getSingleAttractor(), ppt->getNum()); }
00202
00203
00204
00205 virtual void initAttractor (GU_Detail* ) {};
00206
00207
00208
00209 void zeroSystem() { system = 0; }
00210 GEO_PrimParticle *getParticles() { return system; }
00211
00212 const GB_PointGroup *getFixedPoints() { return fixedPoints; }
00213
00214 protected:
00215
00216
00217
00218
00219
00220
00221
00222
00223 virtual int changeTime(float t);
00224
00225
00226 virtual float getBirthRate(float t);
00227
00228
00229
00230 virtual float getLifetime(float t, int split);
00231
00232
00233 virtual int getNumSplit(float t);
00234
00235
00236
00237
00238
00239
00240
00241
00242 virtual void setBirthAttributes(GEO_Point *ppt,
00243 const GEO_Point *srcPoint,
00244 int split) = 0;
00245
00246
00247
00248 virtual float getMass(float t, const GEO_Point *ppt) = 0;
00249
00250 virtual void getForce(float t, const GEO_Point *ppt,
00251 UT_Vector3 &force) = 0;
00252
00253
00254
00255 virtual void updateSource(float t);
00256 virtual void updateCollision(float t);
00257 virtual void updateAttractor(float t);
00258
00259
00260
00261
00262 virtual void initDetail(GU_Detail *gdp);
00263
00264
00265
00266 virtual void initSource(GU_Detail *src);
00267
00268
00269
00270 virtual void resetSource(GU_Detail *src);
00271
00272
00273
00274 virtual void initCollision(GU_Detail *coll);
00275
00276
00277 GEO_PrimParticle *getSystem();
00278
00279
00280 GU_Detail *getMySource() { return source; }
00281 GU_Detail *getMyGdp() { return myGdp; }
00282
00283 protected:
00284
00285
00286 int velocityOffset;
00287 int lifeOffset;
00288 int idOffset;
00289 int pstateOffset;
00290
00291
00292 UT_Vector3 negLimit;
00293 UT_Vector3 posLimit;
00294 float gainNml, gainTan;
00295
00296 UT_BitArray deadPoints;
00297 UT_BitArray stuckPoints;
00298 const GB_PointGroup *fixedPoints;
00299
00300 private:
00301 void cookTime(float t, float tinc);
00302 void updateBitFields();
00303 void changeVelocity(float t, float tinc, GEO_Point *,
00304 UT_Vector3 &vel);
00305 void splitParticle(float t, GEO_ParticleVertex *pvtx,
00306 GEO_PrimParticle *part);
00307 void killParticle(float t, GEO_ParticleVertex *pvtx,
00308 GEO_PrimParticle *part);
00309 void birthParticle(GEO_PrimParticle *, float t, float tinc,
00310 GEO_Point *split = 0);
00311 void killPoint(GEO_Point *ppt);
00312 int birthPoint(float t, float tinc);
00313 int movePoint(UT_Vector4 &p0, UT_Vector3 &vel, float tinc);
00314
00315
00316 void buildCollisionCache();
00317
00318
00319 GU_Detail *myGdp;
00320 GU_Detail *source;
00321 GU_Detail *collision;
00322 GU_RayIntersect *rayIntersector;
00323 GU_Attractor attractor;
00324
00325 GEO_PrimParticle *system;
00326
00327 const GB_PointGroup *inputGroup;
00328
00329 GU_TurbulenceFlags flags;
00330
00331 float lastCookTime;
00332 float startTime;
00333 float preroll;
00334
00335 int idCount;
00336 int sourcePoint;
00337 float nborn;
00338 unsigned mySeed;
00339 };
00340
00341 #endif