00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #pragma once
00025
00026 #include "maxheap.h"
00027 #include "baseinterface.h"
00028 #include "tab.h"
00029 #include "point3.h"
00030 #include "matrix3.h"
00031
00032 #ifndef SpringSysExport
00033 # ifdef BLD_SPRING_SYS
00034 # define SpringSysExport __declspec( dllexport )
00035 # else
00036 # define SpringSysExport __declspec( dllimport )
00037 # endif
00038 #endif
00039
00040
00041
00055 class SSConstraintPoint: public MaxHeapOperators
00056 {
00057 public:
00058 int index;
00059
00060 Point3 pos;
00061 Point3 vel;
00062
00067 SSConstraintPoint() {index = -1; pos = Point3(0.0f, 0.0f, 0.0f); vel = Point3(0.0f, 0.0f, 0.0f);}
00074 SSConstraintPoint(int id) {index = id; pos = Point3(0.0f, 0.0f, 0.0f); vel = Point3(0,0,0);}
00078 ~SSConstraintPoint() {}
00080 SSConstraintPoint& operator=(const SSConstraintPoint& from)
00081 {
00082 index = from.index;
00083 pos = from.pos;
00084 vel = from.vel;
00085
00086 return *this;
00087 }
00088
00094 SSConstraintPoint Copy(const SSConstraintPoint from)
00095 {
00096 index = from.index;
00097 pos = from.pos;
00098 vel = from.vel;
00099
00100 return *this;
00101 }
00102
00104 int GetIndex() { return index; }
00106 void SetIndex(int id) { index = id; }
00108 Point3 GetPos() { return pos; }
00113 void SetPos(Point3 p) { pos = p; }
00115 Point3 GetVel() { return vel; }
00120 void SetVel(Point3 v) { vel = v; }
00121 };
00122
00123
00135 class SSParticleCache: public MaxHeapOperators
00136 {
00137 public:
00138 Point3 pos;
00139 Point3 vel;
00140 Tab<SSConstraintPoint> bone;
00141
00145 SSParticleCache() {pos = Point3(0,0,0); vel = Point3(0,0,0); bone.Init(); }
00146 };
00147
00148
00149
00166 class SSSpring : public BaseInterfaceServer
00167 {
00168 private:
00169 float tension;
00170 float dampening;
00171 Point3 length;
00172 SSConstraintPoint bone;
00173
00174
00175 public:
00176
00185 SSSpring()
00186 {
00187 bone = NULL;
00188 length = Point3(0.0f, 0.0f, 0.0f);
00189 tension = 1.0f;
00190 dampening = 0.5f;
00191 }
00192
00211 SSSpring(SSConstraintPoint *b, Point3 l, float t=2.0f, float d=1.0f)
00212 {
00213 bone = *b;
00214 length = l;
00215 tension = t;
00216 dampening = d;
00217 }
00218
00220 SSSpring& operator=(const SSSpring& from)
00221 {
00222 tension = from.tension;
00223 dampening = from.dampening;
00224 length = from.length;
00225 bone = from.bone;
00226
00227 return *this;
00228 }
00229
00235 SSSpring Copy(const SSSpring from)
00236 {
00237 tension = from.tension;
00238 dampening = from.dampening;
00239 length = from.length;
00240 bone = from.bone;
00241
00242 return *this;
00243 }
00244
00246 float GetTension() {return tension;}
00251 void SetTension(float t) {tension = t;}
00253 float GetDampening() {return dampening;}
00258 void SetDampening(float d) {dampening = d;}
00260 Point3 GetLength() {return length;}
00265 void SetLength(Point3 len) {length = len;}
00266
00268 SSConstraintPoint* GetPointConstraint() { return &bone;}
00273 void SetPointConstraint(SSConstraintPoint b) { bone = b; }
00282 void SetPointConstraint(int id, Point3 pos, Point3 vel)
00283 {
00284 bone.SetIndex(id);
00285 bone.SetPos(pos);
00286 bone.SetVel(vel);
00287 }
00288
00289 };
00290
00306 class SSParticle: public MaxHeapOperators
00307 {
00308 friend class SpringSys;
00309
00310 private:
00311 float mass;
00312 float drag;
00313 Point3 pos;
00314 Point3 vel;
00315 Point3 force;
00316 Tab<SSSpring> springs;
00317
00318 public:
00327 SSParticle()
00328 {
00329 mass = 300.0f;
00330 drag = 1.0f;
00331 pos = vel = force = Point3(0.0f,0.0f,0.0f);
00332 springs.ZeroCount();
00333 }
00337 ~SSParticle(){}
00338
00340 SSParticle& operator=(const SSParticle& from)
00341 {
00342 mass = from.mass;
00343 drag = from.drag;
00344 pos = from.pos;
00345 vel = from.vel;
00346 force = from.force;
00347 springs.ZeroCount();
00348 springs.Shrink();
00349 for (int i=0;i<from.springs.Count();i++)
00350 {
00351 SSSpring spring = from.springs[i];
00352 springs.Append(1, &spring);
00353 }
00354 return *this;
00355 }
00356
00362 SSParticle Copy(const SSParticle from)
00363 {
00364 SSSpring spring;
00365 mass = from.mass;
00366 drag = from.drag;
00367 pos = from.pos;
00368 vel = from.vel;
00369 force = from.force;
00370 springs.ZeroCount();
00371 for (int i=0;i<from.springs.Count();i++)
00372 {
00373 spring.Copy(from.springs[i]);
00374 springs.Append(1, &spring);
00375 }
00376 return *this;
00377 }
00378
00380 float GetMass() {return mass;}
00385 void SetMass(float m) {mass = m;}
00387 float GetDrag() {return drag;}
00392 void SetDrag(float d) {drag = d;}
00394 Point3 GetPos() {return pos;}
00400 void SetPos(Point3 p) {pos = p;}
00402 Point3 GetVel() {return vel;}
00408 void SetVel(Point3 v) {vel = v;}
00410 Point3 GetForce() {return force;}
00415 void SetForce(Point3 f) {force = f;}
00417 Tab<SSSpring>* GetSprings() { return &springs;}
00423 SSSpring* GetSpring(int i) {if (i>=0 && i<springs.Count()) return &(springs[i]);
00424 else return NULL; }
00432 void SetSpring(int i, SSSpring spring) {if (i>=0 && i<springs.Count())
00433 springs[i] = spring; }
00438 void SetSprings(Tab<SSSpring> sTab)
00439 {
00440
00441 springs.ZeroCount();
00442 for (int i = 0;i<sTab.Count();i++)
00443 {
00444 springs.Append(1, &(sTab[i]));
00445 }
00446 }
00447
00461 SpringSysExport BOOL AddSpring(SSConstraintPoint *bone, Point3 length, float tension=2.0f, float dampening = 1.0f);
00462
00467 void DeleteSpring(int index)
00468 {
00469 if ( index == 0 ) return;
00470 for (int i=0;i<springs.Count();i++)
00471 {
00472 if ( (springs[i].GetPointConstraint()->GetIndex()) == index)
00473 springs.Delete(i--, 1);
00474 else if (springs[i].GetPointConstraint()->GetIndex() > index)
00475 springs[i].GetPointConstraint()->SetIndex(springs[i].GetPointConstraint()->GetIndex()-1);
00476 }
00477 }
00478
00479 };
00480
00486 class SpringSysClient: public MaxHeapOperators
00487 {
00488 public:
00494 virtual Tab<Matrix3> GetForceMatrices(TimeValue t)=0;
00506 virtual Point3 GetDynamicsForces(TimeValue t, Point3 pos, Point3 vel)
00507 {
00508 UNUSED_PARAM(t);
00509 UNUSED_PARAM(pos);
00510 UNUSED_PARAM(vel);
00511 return Point3(0,0,0);
00512 }
00513 };
00514
00515
00553 class SpringSys : public BaseInterfaceServer
00554 {
00555 private:
00556 float referenceTime;
00557 float lastTime;
00558 bool isValid;
00559
00560 SSParticleCache frameCache;
00561 Tab<Point3> pos_cache;
00562 Tab<Point3> vel_cache;
00563
00564 Tab<Point3> initPosTab;
00565 Tab<SSParticle> parts;
00566
00567 SpringSysClient* client;
00568
00569 public:
00570
00572 SpringSys()
00573 {
00574 client = NULL;
00575 referenceTime = lastTime = 0.0f;
00576 SetParticleCount(1);
00577 isValid = false;
00578 }
00579
00587 SpringSys(SpringSysClient* c, int count)
00588 {
00589 client = c;
00590 referenceTime = lastTime = 0.0f;
00591 SetParticleCount(count);
00592 isValid = false;
00593 }
00594
00596 ~SpringSys() {}
00598 SpringSysExport SpringSys& operator=(const SpringSys& from);
00599
00605 SpringSysExport SpringSys Copy(const SpringSys* from);
00606
00611 void SetReferenceTime (float t) { referenceTime = t; }
00613 float GetReferenceTime () { return referenceTime; }
00616 Tab<SSParticle>* GetParticles() { return &parts;}
00622 SSParticle* GetParticle(int i) { if (i >=0 && i< parts.Count()) return &(parts[i]);
00623 else return NULL; }
00629 SpringSysExport void SetParticleCount(int count);
00638 SpringSysExport void SetInitialPosition (Point3 p, int partIndex);
00647 SpringSysExport void SetInitialVelocity (Point3 p, int partIndex);
00653 SpringSysExport void SetInitialBoneStates(Tab<Matrix3> boneTMs);
00656 SpringSysExport void Invalidate ();
00664 SpringSysExport void Solve (int time, float TimeDelta);
00673 SpringSysExport void GetPosition (Point3& p, int index);
00674
00675 SpringSysExport IOResult Load(ILoad *iload);
00676 SpringSysExport IOResult Save(ISave *isave);
00677
00678 protected:
00683 float GetTime() { return lastTime; }
00691 void SetTime(float t) { lastTime = t; }
00692
00693
00699 SpringSysExport void Clear_Forces(int index);
00707 SpringSysExport void Compute_Forces(TimeValue t, int index);
00713 SpringSysExport void ApplyDrag(int index);
00721 SpringSysExport void ApplyUnaryForces(TimeValue t, int index);
00731 SpringSysExport void ComputeControlledParticleForce(Matrix3 tm, int vertIndex, int springIndex);
00739 SpringSysExport void ApplySpring(TimeValue t, int index);
00740
00741
00752 SpringSysExport void UpdateParticleState(TimeValue t, Tab<Matrix3> tmArray, int pIndex, TimeValue Delta);
00762 SpringSysExport void ComputeDerivative(int index, Point3 &pos, Point3 &vel);
00772 SpringSysExport void GetParticleState(int index, Point3 &pos, Point3 &vel);
00782 SpringSysExport void SetParticleState(int index, Point3 pos, Point3 vel);
00792 SpringSysExport void ScaleVectors(Point3 &pos, Point3 &vel, float delta);
00800 SpringSysExport void AddVectors(Point3 pos1, Point3 vel1, Point3 &pos, Point3 &vel);
00801 };
00802