springsys.h

Go to the documentation of this file.
00001 //**************************************************************************/
00002 // Copyright (c) 1998-2006 Autodesk, Inc.
00003 // All rights reserved.
00004 // 
00005 // These coded instructions, statements, and computer programs contain
00006 // unpublished proprietary information written by Autodesk, Inc., and are
00007 // protected by Federal copyright law. They may not be disclosed to third
00008 // parties or copied or duplicated in any form, in whole or in part, without
00009 // the prior written consent of Autodesk, Inc.
00010 //**************************************************************************/
00011 // FILE: SpringSys.h
00012 // DESCRIPTION: Public header files for the Spring System created by Adam Felt.
00013 //                  To use this interface you will need to link to "SpringSys.lib"
00014 //
00015 //                  This spring system is a multi-point spring-based dynamic system.
00016 //                  In order to your the sytem you must derive from SpringSysClient and implement
00017 //                  Tab<Matrix3> SpringSysClient::GetForceMatrices(TimeValue t)
00018 //                  You are responsible for gathering the spring constraint forces at any given time.
00019 //                  You initialize the 
00020 //
00021 // AUTHOR:      Adam Felt
00022 // HISTORY: 
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 //A Controlled Particle Class
00041 //Used to constrain a point to an object
00055 class SSConstraintPoint: public MaxHeapOperators  
00056 {                       
00057     public:
00058         int index;      //this bone index is used to identify the bone.  
00059                         //Usually refers to a reference index, or paramblock index...
00060         Point3 pos;     //The control nodes stored position
00061         Point3 vel;     //The control nodes stored velocity
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 //Class used to store a particles state
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 //A Spring Class
00149 //Stores the parameters for binding an object to any force with a controllable spring
00166 class SSSpring : public BaseInterfaceServer
00167 {
00168     private:
00169         float tension;     
00170         float dampening;
00171         Point3 length;      //rest length
00172         SSConstraintPoint bone;       
00173         //AFParticle *p2;   //for use later to apply the reactive force
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;     //the particle's mass
00312         float drag;     //the particle's drag coefficient
00313         Point3 pos;     //particle position
00314         Point3 vel;     //particle velocity
00315         Point3 force;   //Force accumulator
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             //springs = NULL;
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;      //particles
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         //force functions
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         //Solver functions
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