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  * Test: \f$ \w \f$
00089  *
00090  * References:
00091  * - [BarWit98] D. Baraff and A. Witkin. Large Steps in Cloth Simulation.
00092  *    SIGGRAPH Conference Proceedings, 1998, 43-54.
00093  *    http://www-2.cs.cmu.edu/~baraff/papers/sig98.pdf
00094  * - [Pri02] D. Pritchard. "Implementing Baraff & Witkin's Cloth Simulation".
00095  *    Unpublished, 2002.
00096  *    http://freecloth.enigmati.ca/docs/report-chaps/
00097  * - [Mac00] D. Macri. Real-Time Cloth. Game Developers Conference, 2000.
00098  *    http://www.gdconf.com/archives/2000/macri.doc
00099  */
00100 
00101 // FIXME: the mesh should be allowed to have cylindrical or spherical
00102 // topology, not just disc topology.
00103 //
00104 // FIXME: should really implement this as a Bridge pattern, to hide the
00105 // implementation from clients better.
00106 class SimSimulator : public RCBase
00107 {
00108 public:
00109     // ----- classes -----
00110     ////////////////////////////////////////////////////////////////////////////
00111     /*!
00112      * \class Params freecloth/simulator/simSimulator.h
00113      * \brief Parameters for cloth simulator, as described in [BarWit98].
00114      *
00115      * The stretch, shear, and bend parameters control the strength of the
00116      * associated internal forces. For example, a higher _k_stretch value
00117      * makes the internal stretch forces stronger, and hence makes the cloth
00118      * harder to stretch. The bend force can be controlled independently in
00119      * u and v. Generally, stretch forces should be very, very strong,
00120      * and bend forces should be very weak.
00121      *
00122      * The damp parameter controls the strength of damping forces. A higher
00123      * damping value will make the cloth come to rest quicker, while a lower
00124      * value will allow it to oscillate back and forth before coming to rest.
00125      *
00126      * The b_u and b_v values allow the client to force stretch/compression
00127      * of the cloth. They're not very useful at present; they should really be
00128      * spatially varying to be useful.
00129      *
00130      * The g parameter is the constant for acceleration due to gravity,
00131      * by default 9.81 m/s^2.
00132      */
00133     class Params
00134     {
00135     public:
00136         // ----- member functions -----
00137 
00138         // MSVC bug requires this to be inline
00139         // Maya values: .5, .35, .01 (unknown scaling...)
00140         inline Params()
00141           : _k_stretch( 5000.f ),
00142             _k_shear( 500.f ),
00143             _k_bend_u( .00001f ),
00144             _k_bend_v( .00001f ),
00145             _k_damp( .2f ),
00146             _k_drag( .1f ),
00147             _b_u( 1.f ),
00148             _b_v( 1.f ),
00149             _g( 9.81f )
00150         {
00151         }
00152 
00153         // ----- data members -----
00154         // TODO: Maya has separate u/v control for this
00155         Float           _k_stretch;
00156         Float           _k_shear;
00157         Float           _k_bend_u, _k_bend_v;
00158         Float           _k_damp;
00159         //! Drag constant.
00160         //! Technically, this is 0.5 * C_D * rho, where rho is density of
00161         //! the medium and C_D is the drag coefficient. We combine this into
00162         //! a single constant for simplicity.
00163         Float           _k_drag;
00164         //! Stretch constant
00165         // FIXME: should be spatially varying, via texture.
00166         Float           _b_u,_b_v;
00167         //! Gravitational acceleration
00168         Float           _g;
00169     };
00170 
00171     // ----- types and enumerations -----
00172 
00173     //! The individual classes of forces.
00174     enum ForceType {
00175         F_STRETCH,
00176         F_SHEAR,
00177         F_BEND,
00178         F_GRAVITY,
00179         F_DRAG,
00180 
00181         NB_FORCES
00182     };
00183 
00184     // ----- member functions -----
00185 
00186     explicit SimSimulator( const GeMesh& initialMesh );
00187 
00188     const GeMesh& getMesh() const;
00189     const RCShdPtr<GeMesh>& getMeshPtr() const;
00190 
00191     //! Rewind simulation time to zero, and return the mesh to its initial
00192     //! state.
00193     void rewind();
00194 
00195     //! Advance the simulation by one timestep.
00196     //! step() is equivalent to calling
00197     //! - preSubSteps()
00198     //! - repeated subStep() calls
00199     //! - postSubSteps()
00200     void step();
00201 
00202     //@{
00203     //! Finer grained simulation control - allows the client more control over
00204     //! the computation. See step() for details.
00205     bool subStepsDone() const;
00206     void preSubSteps();
00207     void subStep();
00208     void postSubSteps();
00209     //@}
00210 
00211     //! Retrieve the current simulation time.
00212     BaTime::Instant getTime() const;
00213 
00214     //@{
00215     //! Mutator
00216     void setTimestep( Float );
00217     void setParams( const Params& );
00218     void setDensity( Float rho );
00219     void setPCGTolerance( Float );
00220     //@}
00221 
00222     //@{
00223     //! Accessor
00224     Float getTimestep() const;
00225     const Params& getParams() const;
00226     Float getDensity() const;
00227     Float getPCGTolerance() const;
00228     //@}
00229 
00230     //! Remove all constraints on all vertices.
00231     void removeAllConstraints();
00232     //! Constrain movement of the vertex to the plane defined by the given
00233     //! normal.
00234     void setPosConstraintPlane( GeMesh::VertexId, const GeVector& );
00235     //! Constrain movement of the vertex to the given line.
00236     void setPosConstraintLine( GeMesh::VertexId, const GeVector& );
00237     //! Completely constrain the vertex, allowing no movement.
00238     void setPosConstraintFull( GeMesh::VertexId );
00239 
00240     //! Force the vertex to move with the specified velocity. This overrides
00241     //! any position constraints.
00242     void setVelConstraint( GeMesh::VertexId, const GeVector& );
00243 
00244     //@{
00245     //! Only exposed for debugging purposes.
00246     GeVector getVelocity( GeMesh::VertexId vid ) const;
00247     GeVector getForce( GeMesh::VertexId vid ) const;
00248     Float getEnergy( ForceType ) const;
00249     Float getTriEnergy( ForceType, GeMesh::FaceId ) const;
00250     // The final two will only work in debug builds.
00251     GeVector getForce( ForceType type, GeMesh::VertexId vid ) const;
00252     GeVector getDampingForce( ForceType type, GeMesh::VertexId vid ) const;
00253 
00254     void setMesh( const GeMesh& );
00255     //@}
00256 
00257 private:
00258 
00259     // ----- types and enumerations -----
00260 
00261     // FIXME: implement custom matrix classes for these some time, if it
00262     // helps the performance much.
00263     typedef SimMatrix Matrix;
00264     typedef SimMatrix SymMatrix;
00265     typedef SimMatrix TridiagMatrix;
00266 
00267     // ----- classes -----
00268 
00269     class CommonVars;
00270     class StretchVars;
00271     class ShearVars;
00272     class BendVars;
00273     
00274     ////////////////////////////////////////////////////////////////////////////
00275     /*!
00276      * \class ModPCGSolver freecloth/simulator/simSimulator.h
00277      *
00278      * Preconditioned modified conjugate gradient solver. Solves a linear
00279      * system Ax=b subject to constraints defined by S and z, as defined by
00280      * [BarWit98] in section 5.3.
00281      */
00282     class ModPCGSolver
00283     {
00284     public:
00285         // ----- member functions -----
00286 
00287         ModPCGSolver();
00288         void preStep();
00289         void step();
00290         bool done() const;
00291         const SimVector& result() const;
00292 
00293         //! Specify the tolerance.
00294         void setTolerance( Float );
00295         //! Access the tolerance
00296         Float getTolerance() const;
00297 
00298         // ----- data members -----
00299         
00300         std::vector<GeMatrix3> _S;
00301         SimVector       _z;
00302 
00303         // Final Ax=b system
00304         SymMatrix       _A;
00305         SimVector       _b;
00306 
00307     private:
00308         // ----- member functions -----
00309 
00310         void setupPreconditioner();
00311         void setupCG();
00312         SimVector filter( const SimVector& ) const;
00313         void filterInPlace( SimVector& ) const;
00314 
00315         // ----- data members -----
00316         
00317         SimMatrix       _P, _Pinv;
00318         bool            _done;
00319         UInt32          _nbSteps;
00320         Float           _tolerance;
00321 
00322         SimVector       _x, _r, _c;
00323         Float           _delta0, _deltaNew;
00324         
00325         // Temporaries within step()
00326         SimVector       _q, _s;
00327     };
00328 
00329 
00330     // ----- member functions -----
00331 
00332     //! Fill the mass matrix (_M) using the initial mesh's triangles areas
00333     //! and the density parameter, as per [BarWit98] section 2.2.
00334     void setupMass();
00335 
00336     //! Calculate values common to the stretch and shear conditions.
00337     void calcStretchShear(
00338         const GeMesh::FaceWrapper& face
00339     );
00340     //! Calculate the stretch condition and its derivatives.
00341     void calcStretch(
00342         const GeMesh::FaceWrapper& face,
00343         const CommonVars &cv,
00344         const GePoint x[3],
00345         const GePoint tp[3],
00346         const GeVector v0[ 3 ]
00347     );
00348     //! Calculate the shear condition and its derivatives.
00349     void calcShear(
00350         const GeMesh::FaceWrapper& face,
00351         const CommonVars &cv,
00352         const GePoint x[3],
00353         const GePoint tp[3],
00354         const GeVector v0[ 3 ]
00355     );
00356     //! Calculate the bend condition and its derivatives.
00357     void calcBend(
00358         const GeMeshWingedEdge::HalfEdgeWrapper& edge
00359     );
00360     
00361     // ----- data members -----
00362     
00363     // FIXME: initial mesh should be RCShdPtr<const GeMesh>
00364     RCShdPtr<GeMesh> _initialMesh;
00365     RCShdPtr<GeMeshWingedEdge> _initialMeshWingedEdge;
00366     RCShdPtr<GeMesh> _mesh;
00367     
00368     Params          _params;
00369     //! Density of cloth ( kg / m^2 )
00370     Float           _rho;
00371     //! Timestep
00372     Float           _h;
00373     //! Current time
00374     Float           _time;
00375 
00376 
00377     //! Variables from the [BarWit98], as defined in equations (6) and (14)
00378     TridiagMatrix   _M;
00379     //! Sum of diagonals of _M
00380     Float           _totalMass;
00381     SimVector       _f0;
00382     SymMatrix       _df_dx;
00383     SymMatrix       _df_dv;
00384     SimVector       _v0;
00385     SimVector       _z0;
00386 
00387     //@{
00388     //! For debugging
00389     SimVector       _f0i[ NB_FORCES ];
00390     SimVector       _d0i[ NB_FORCES ];
00391     SymMatrix       _df_dxi[ NB_FORCES ];
00392     // df_dv is always zero...
00393     // Damping forces from the [BarWit98], as defined in section 4.5
00394     SymMatrix       _dd_dvi[ NB_FORCES ];
00395     SymMatrix       _dd_dxi[ NB_FORCES ];
00396     //@}
00397     
00398     //@{
00399     //! Total energy of cloth
00400     Float           _fenergy[ NB_FORCES ];
00401     Float           _venergy;
00402     Float           _energy;
00403     std::vector<Float> _trienergy[ NB_FORCES ];
00404     //@}
00405 
00406     ModPCGSolver    _modPCG;
00407 };
00408 
00409 FREECLOTH_NAMESPACE_END
00410 
00411 #endif

Generated on Fri May 2 16:51:14 2003 for Freecloth by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002