Main Page   Class Hierarchy   Compound List   File List   Compound Members  

simSimulator.h

00001 //////////////////////////////////////////////////////////////////////
00002 // Copyright (c) 2002-2003 David Pritchard <drpritch@alumni.uwaterloo.ca>
00003 // 
00004 // This program is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public License
00006 // as published by the Free Software Foundation; either
00007 // version 2 of the License, or (at your option) any later
00008 // version.
00009 // 
00010 // This program is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU Lesser General Public License for more details.
00014 // 
00015 // You should have received a copy of the GNU Lesser General Public License
00016 // along with this program; if not, write to the Free Software
00017 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018 
00019 #ifndef freecloth_sim_simSimulator_h
00020 #define freecloth_sim_simSimulator_h
00021 
00022 #ifndef freecloth_sim_package_h
00023 #include <freecloth/simulator/package.h>
00024 #endif
00025 
00026 #ifndef freecloth_sim_simMatrix_h
00027 #include <freecloth/simulator/simMatrix.h>
00028 #endif
00029 
00030 #ifndef freecloth_sim_simVector_h
00031 #include <freecloth/simulator/simVector.h>
00032 #endif
00033 
00034 #ifndef freecloth_base_algorithm
00035 #include <freecloth/base/algorithm>
00036 #endif
00037 
00038 #ifndef freecloth_base_list
00039 #include <freecloth/base/list>
00040 #endif
00041 
00042 #ifndef freecloth_base_baTime_h
00043 #include <freecloth/base/baTime.h>
00044 #endif
00045 
00046 #ifndef freecloth_resmgt_rcShdPtr_h
00047 #include <freecloth/resmgt/rcShdPtr.h>
00048 #endif
00049 
00050 #ifndef freecloth_resmgt_rcBase_h
00051 #include <freecloth/resmgt/rcBase.h>
00052 #endif
00053 
00054 #ifndef freecloth_geom_geMesh_h
00055 #include <freecloth/geom/geMesh.h>
00056 #endif
00057 
00058 #ifndef freecloth_geom_geMeshWingedEdge_h
00059 #include <freecloth/geom/geMeshWingedEdge.h>
00060 #endif
00061 
00062 FREECLOTH_NAMESPACE_START
00063 
00064 ////////////////////////////////////////////////////////////////////////////////
00065 // FORWARD DECLARATIONS
00066 
00067 class GeMatrix3;
00068 
00069 ////////////////////////////////////////////////////////////////////////////////
00070 /*!
00071  * \class SimSimulator freecloth/simulator/simSimulator.h
00072  * \brief An implementation of Baraff & Witkin's cloth simulation algorithm.
00073  * 
00074  * Using the simulation is fairly straightforward. The client supplies an
00075  * initial mesh, which must have disc topology. The client also specifies the
00076  * density of the cloth, which indirectly defines the mass of each triangle of
00077  * the mesh. The client can also specify constraints on the cloth motion,
00078  * constraining both the position and the velocity of individual nodes of the
00079  * mesh.
00080  *
00081  * Time starts at zero, and is advanced by a fixed timestep by calls to step().
00082  * The client can retrieve the mesh after each timestep. The simulation can
00083  * be rewound to the beginning by calling rewind().
00084  *
00085  * There are many parameters for the simulation algorithm. See [BarWit98] or
00086  * the description in SimSimulator::Params for details.
00087  *
00088  * References:
00089  * - [BarWit98] D. Baraff and A. Witkin. Large Steps in Cloth Simulation.
00090  *    SIGGRAPH Conference Proceedings, 1998, 43-54.
00091  *    http://www-2.cs.cmu.edu/~baraff/papers/sig98.pdf
00092  * - [Pri02] D. Pritchard. "Implementing Baraff & Witkin's Cloth Simulation".
00093  *    Unpublished, 2002.
00094  *    http://freecloth.enigmati.ca/docs/report-chaps/
00095  * - [Mac00] D. Macri. Real-Time Cloth. Game Developers Conference, 2000.
00096  *    http://www.gdconf.com/archives/2000/macri.doc
00097  */
00098 
00099 // FIXME: the mesh should be allowed to have cylindrical or spherical
00100 // topology, not just disc topology.
00101 //
00102 // FIXME: should really implement this as a Bridge pattern, to hide the
00103 // implementation from clients better.
00104 class SimSimulator : public RCBase
00105 {
00106 public:
00107     // ----- classes -----
00108     ////////////////////////////////////////////////////////////////////////////
00109     /*!
00110      * \class Params freecloth/simulator/simSimulator.h
00111      * \brief Parameters for cloth simulator, as described in [BarWit98].
00112      *
00113      * The stretch, shear, and bend parameters control the strength of the
00114      * associated internal forces. For example, a higher _k_stretch value
00115      * makes the internal stretch forces stronger, and hence makes the cloth
00116      * harder to stretch. The bend force can be controlled independently in
00117      * u and v. Generally, stretch forces should be very, very strong,
00118      * and bend forces should be very weak.
00119      *
00120      * The damp parameter controls the strength of damping forces. A higher
00121      * damping value will make the cloth come to rest quicker, while a lower
00122      * value will allow it to oscillate back and forth before coming to rest.
00123      *
00124      * The b_u and b_v values allow the client to force stretch/compression
00125      * of the cloth. They're not very useful at present; they should really be
00126      * spatially varying to be useful.
00127      *
00128      * The g parameter is the constant for acceleration due to gravity,
00129      * by default 9.81 m/s^2.
00130      */
00131     class Params
00132     {
00133     public:
00134         // ----- member functions -----
00135 
00136         // MSVC bug requires this to be inline
00137         // Maya values: .5, .35, .01 (unknown scaling...)
00138         inline Params()
00139           : _k_stretch( 5000.f ),
00140             _k_shear( 500.f ),
00141             _k_bend_u( .00001f ),
00142             _k_bend_v( .00001f ),
00143             _k_damp( .2f ),
00144             _k_drag( .1f ),
00145             _b_u( 1.f ),
00146             _b_v( 1.f ),
00147             _g( 9.81f )
00148         {
00149         }
00150 
00151         // ----- data members -----
00152         // TODO: Maya has separate u/v control for this
00153         Float           _k_stretch;
00154         Float           _k_shear;
00155         Float           _k_bend_u, _k_bend_v;
00156         Float           _k_damp;
00157         //! Drag constant.
00158         //! Technically, this is 0.5 * C_D * rho, where rho is density of
00159         //! the medium and C_D is the drag coefficient. We combine this into
00160         //! a single constant for simplicity.
00161         Float           _k_drag;
00162         //! Stretch constant
00163         // FIXME: should be spatially varying, via texture.
00164         Float           _b_u,_b_v;
00165         //! Gravitational acceleration
00166         Float           _g;
00167     };
00168 
00169     // ----- types and enumerations -----
00170 
00171     //! The individual classes of forces.
00172     enum ForceType {
00173         F_STRETCH,
00174         F_SHEAR,
00175         F_BEND,
00176         F_GRAVITY,
00177         F_DRAG,
00178 
00179         NB_FORCES
00180     };
00181 
00182     // ----- member functions -----
00183 
00184     explicit SimSimulator( const GeMesh& initialMesh );
00185 
00186     const GeMesh& getMesh() const;
00187     const RCShdPtr<GeMesh>& getMeshPtr() const;
00188 
00189     //! Rewind simulation time to zero, and return the mesh to its initial
00190     //! state.
00191     void rewind();
00192 
00193     //! Advance the simulation by one timestep.
00194     //! step() is equivalent to calling
00195     //! - preSubSteps()
00196     //! - repeated subStep() calls
00197     //! - postSubSteps()
00198     void step();
00199 
00200     //@{
00201     //! Finer grained simulation control - allows the client more control over
00202     //! the computation. See step() for details.
00203     bool subStepsDone() const;
00204     void preSubSteps();
00205     void subStep();
00206     void postSubSteps();
00207     //@}
00208 
00209     //! Retrieve the current simulation time.
00210     BaTime::Instant getTime() const;
00211 
00212     //@{
00213     //! Mutator
00214     void setTimestep( Float );
00215     void setParams( const Params& );
00216     void setDensity( Float rho );
00217     void setPCGTolerance( Float );
00218     //@}
00219 
00220     //@{
00221     //! Accessor
00222     Float getTimestep() const;
00223     const Params& getParams() const;
00224     Float getDensity() const;
00225     Float getPCGTolerance() const;
00226     //@}
00227 
00228     //! Remove all constraints on all vertices.
00229     void removeAllConstraints();
00230     //! Constrain movement of the vertex to the plane defined by the given
00231     //! normal.
00232     void setPosConstraintPlane( GeMesh::VertexId, const GeVector& );
00233     //! Constrain movement of the vertex to the given line.
00234     void setPosConstraintLine( GeMesh::VertexId, const GeVector& );
00235     //! Completely constrain the vertex, allowing no movement.
00236     void setPosConstraintFull( GeMesh::VertexId );
00237 
00238     //! Force the vertex to move with the specified velocity. This overrides
00239     //! any position constraints.
00240     void setVelConstraint( GeMesh::VertexId, const GeVector& );
00241 
00242     //@{
00243     //! Only exposed for debugging purposes.
00244     GeVector getVelocity( GeMesh::VertexId vid ) const;
00245     GeVector getForce( GeMesh::VertexId vid ) const;
00246     Float getEnergy( ForceType ) const;
00247     Float getTriEnergy( ForceType, GeMesh::FaceId ) const;
00248     // The final two will only work in debug builds.
00249     GeVector getForce( ForceType type, GeMesh::VertexId vid ) const;
00250     GeVector getDampingForce( ForceType type, GeMesh::VertexId vid ) const;
00251 
00252     void setMesh( const GeMesh& );
00253     //@}
00254 
00255 private:
00256 
00257     // ----- types and enumerations -----
00258 
00259     // FIXME: implement custom matrix classes for these some time, if it
00260     // helps the performance much.
00261     typedef SimMatrix Matrix;
00262     typedef SimMatrix SymMatrix;
00263     typedef SimMatrix TridiagMatrix;
00264 
00265     // ----- classes -----
00266 
00267     class CommonVars;
00268     class StretchVars;
00269     class ShearVars;
00270     class BendVars;
00271     
00272     ////////////////////////////////////////////////////////////////////////////
00273     /*!
00274      * \class ModPCGSolver freecloth/simulator/simSimulator.h
00275      *
00276      * Preconditioned modified conjugate gradient solver. Solves a linear
00277      * system Ax=b subject to constraints defined by S and z, as defined by
00278      * [BarWit98] in section 5.3.
00279      */
00280     class ModPCGSolver
00281     {
00282     public:
00283         // ----- member functions -----
00284 
00285         ModPCGSolver();
00286         void preStep();
00287         void step();
00288         bool done() const;
00289         const SimVector& result() const;
00290 
00291         //! Specify the tolerance.
00292         void setTolerance( Float );
00293         //! Access the tolerance
00294         Float getTolerance() const;
00295 
00296         // ----- data members -----
00297         
00298         std::vector<GeMatrix3> _S;
00299         SimVector       _z;
00300 
00301         // Final Ax=b system
00302         SymMatrix       _A;
00303         SimVector       _b;
00304 
00305     private:
00306         // ----- member functions -----
00307 
00308         void setupPreconditioner();
00309         void setupCG();
00310         SimVector filter( const SimVector& ) const;
00311         void filterInPlace( SimVector& ) const;
00312 
00313         // ----- data members -----
00314         
00315         SimMatrix       _P, _Pinv;
00316         bool            _done;
00317         UInt32          _nbSteps;
00318         Float           _tolerance;
00319 
00320         SimVector       _x, _r, _c;
00321         Float           _delta0, _deltaNew;
00322         
00323         // Temporaries within step()
00324         SimVector       _q, _s;
00325     };
00326 
00327 
00328     // ----- member functions -----
00329 
00330     //! Fill the mass matrix (_M) using the initial mesh's triangles areas
00331     //! and the density parameter, as per [BarWit98] section 2.2.
00332     void setupMass();
00333 
00334     //! Calculate values common to the stretch and shear conditions.
00335     void calcStretchShear(
00336         const GeMesh::FaceWrapper& face
00337     );
00338     //! Calculate the stretch condition and its derivatives.
00339     void calcStretch(
00340         const GeMesh::FaceWrapper& face,
00341         const CommonVars &cv,
00342         const GePoint x[3],
00343         const GePoint tp[3],
00344         const GeVector v0[ 3 ]
00345     );
00346     //! Calculate the shear condition and its derivatives.
00347     void calcShear(
00348         const GeMesh::FaceWrapper& face,
00349         const CommonVars &cv,
00350         const GePoint x[3],
00351         const GePoint tp[3],
00352         const GeVector v0[ 3 ]
00353     );
00354     //! Calculate the bend condition and its derivatives.
00355     void calcBend(
00356         const GeMeshWingedEdge::HalfEdgeWrapper& edge
00357     );
00358     
00359     // ----- data members -----
00360     
00361     // FIXME: initial mesh should be RCShdPtr<const GeMesh>
00362     RCShdPtr<GeMesh> _initialMesh;
00363     RCShdPtr<GeMeshWingedEdge> _initialMeshWingedEdge;
00364     RCShdPtr<GeMesh> _mesh;
00365     
00366     Params          _params;
00367     //! Density of cloth ( kg / m^2 )
00368     Float           _rho;
00369     //! Timestep
00370     Float           _h;
00371     //! Current time
00372     Float           _time;
00373 
00374 
00375     //! Variables from the [BarWit98], as defined in equations (6) and (14)
00376     TridiagMatrix   _M;
00377     //! Sum of diagonals of _M
00378     Float           _totalMass;
00379     SimVector       _f0;
00380     SymMatrix       _df_dx;
00381     SymMatrix       _df_dv;
00382     SimVector       _v0;
00383     SimVector       _z0;
00384 
00385     //@{
00386     //! For debugging
00387     SimVector       _f0i[ NB_FORCES ];
00388     SimVector       _d0i[ NB_FORCES ];
00389     SymMatrix       _df_dxi[ NB_FORCES ];
00390     // df_dv is always zero...
00391     // Damping forces from the [BarWit98], as defined in section 4.5
00392     SymMatrix       _dd_dvi[ NB_FORCES ];
00393     SymMatrix       _dd_dxi[ NB_FORCES ];
00394     //@}
00395     
00396     //@{
00397     //! Total energy of cloth
00398     Float           _fenergy[ NB_FORCES ];
00399     Float           _venergy;
00400     Float           _energy;
00401     std::vector<Float> _trienergy[ NB_FORCES ];
00402     //@}
00403 
00404     ModPCGSolver    _modPCG;
00405 };
00406 
00407 FREECLOTH_NAMESPACE_END
00408 
00409 #endif

Generated on Wed Apr 23 15:58:52 2003 for Freecloth by doxygen1.3-rc3