TAPs 0.7.7.3
TAPsDeformMesh.hpp
Go to the documentation of this file.
00001 /******************************************************************************
00002 TAPsDeformMesh.hpp
00003 
00004 DeformMesh class is a class for a deformable mesh modeled by a network of 
00005 springs.
00006 
00007 SUKITTI PUNAK   (02/01/2005)
00008 UPDATE          (02/01/2005)
00009 *******************************************************************************
00010 +====================+
00011 | DESCRIPTION / NOTE |
00012 +====================+
00013 The model is a mesh of m-by-n virtual masses, which each mass linked to 
00014 its neighbors by massless springs of natural length greater than zeroes.
00015 The linkage between neighbors comprised of three kinds of linking springs:
00016   -- Structural springs linking masses [m,n] and [m+1,n], and 
00017                                 masses [m,n] and [m,n+1]
00018   -- Shear springs linking masses [m,n] and [m+1,n+1], and 
00019                            masses [m+1,n] and [m,n+1]
00020   -- Flexion springs linking masses [m,n] and [m+2,n], and 
00021                              masses [m,n] and [m,n+2]
00022 
00023   (0,0)---------(0,1)---------(0,2)
00024     |  \       /  |  \       /  |
00025     |    \   /    |    \   /    |
00026     |      +      |      +      |
00027     |    /   \    |    /   \    |
00028     |  /       \  |  /       \  |
00029   (1,0)---------(1,1)---------(1,2)
00030     |  \       /  |  \       /  |
00031     |    \   /    |    \   /    |
00032     |      +      |      +      |
00033     |    /   \    |    /   \    |
00034     |  /       \  |  /       \  |
00035   (2,0)---------(2,1)---------(2,2)
00036 
00037 ******************************************************************************/
00038 #ifndef TAPs_DEFORM_MESH_HPP
00039 #define TAPs_DEFORM_MESH_HPP
00040 
00041 #include "../Physics/TAPsPhysics.hpp"   // for gravitational constant
00042 #include "../Physics/TAPsSpring.hpp"    // SPT_Spring.h all ready include SPT_Particle.h
00043 #include "../OpenGL/TAPsOpenGLSupport.hpp"
00044 
00045 BEGIN_NAMESPACE_TAPs
00046 //=============================================================================
00047 template <typename T>
00048 class DeformMesh : public /*virtual*/ OpenGL::OpenGLSupport {
00049 //=============================================================================
00050     //-------------------------------------------------------------------------
00051     // put it through ostream
00052     friend std::ostream &operator<<( std::ostream &output, const DeformMesh<T> &Obj )
00053     {
00054         output  << "DeformMesh ==> "
00055                 << "\n  number of rows:       " << Obj.m_iNoRows
00056                 << "\n  number of columns:    " << Obj.m_iNoCols
00057                 << "\n";
00058         return output;
00059     }
00060 
00061 //-------------------------------------------------------------------------------------------------
00062 private:
00063     // Data Members     ============================================================================
00064     int m_iNoRows;  // number of rows in y-direction    (y values)
00065     int m_iNoCols;  // number of columns in x-direction (x values)
00066     // Mass Points
00067     Particle<T> ***m_pcParticle;
00068     // object counters
00069     int m, n;   // m = row number; n = col number
00070 //-------------------------------------------------------------------------------------------------
00071 private:
00072     // Helper Functions     ========================================================================
00073     void CreateParticles( Vector3<T> const &topLeftPos, Vector3<T> const &bottomRightPos, T mass );
00074     void DeleteParticles();
00075 //-------------------------------------------------------------------------------------------------
00076 public:
00077     // Member Functions     ========================================================================
00078     // Constructor -------------------------------------------------------------
00079     DeformMesh(    
00080               int rows,         // number of rows (on world-y-axis)
00081               int cols,         // number of columns (on world-x-axis)
00082               const Vector3<T> &topLeftPos,         // start position (should be top left cornor)
00083               const Vector3<T> &bottomRightPos,     // end position (should be bottom right cornor)
00084               T mass,                                   // the whole mass
00085               BitmapImage * = NULL );       // Image Pointer
00086     //-------------------------------------------------------------------------
00087     ~DeformMesh();                          // destructor
00088     //-------------------------------------------------------------------------
00089     // CalParticleNormals( int i ) should runs faster than CalParticleNormals(),
00090     // since it calculates the normals more direct.
00091     void CalParticleNormals();          // calculate particle normals
00092     void CalParticleNormals( int i );   // calculate particle normals, int i is dummy
00093     void AddNormal( Vector3<T> & Dest, 
00094                     Vector3<T> const & A, Vector3<T> const & B, Vector3<T> const & C );
00095 
00096 
00097     // Calculate Forces --------------------------------------------------------
00098     /*
00099     void ClearForce();                      // clear force of particles to zeros
00100     void ForceDueToGravity( T g = SP_Physics::g );  // calculate (weight) force due to (acceleration of) gravity
00101     void ForceDueToViscousDamping();        // calculate (a loss) force due to viscous damping
00102     void ForceDueToViscousFluidMoving();    // calculate (wind)   force due to viscous fluid moving
00103     */
00104     // Calculate All Forces Acting on Particles
00105 //  void CalForces( Vector3<T> vWind = Vector3<T>(0,0,0), T g = Physics_SI::K::g );
00106 
00107     // Display Routine(s) ------------------------------------------------------
00108     void DisplayGL( OpenGL::Enum::DrawMode DM = OpenGL::Enum::POLYGON );        // display cloth
00109     void DisplayGL_ParticleNormals();                       // display particle normals
00110     //-------------------------------------------------------------------------
00111     // Get/Set and Animation / Simulation Fns
00112     Vector3<T> GetPositionOfPointNumber( int row, int col ) const {
00113         assert( 0 <= row && row < m_iNoRows );
00114         assert( 0 <= col && col < m_iNoCols );
00115         return m_pcParticle[row][col]->GetPosition();
00116     }
00117     void SetPositionOfPointNumber( int row, int col, Vector3<T> & newPosition ) {
00118         assert( 0 <= row && row < m_iNoRows );
00119         assert( 0 <= col && col < m_iNoCols );
00120         //-----------------------------
00121         m_pcParticle[row][col]->SetPosition( newPosition );
00122     }
00123     void MovePositionOfPointNumber( int row, int col, Vector3<T> & addPosition ) {
00124         assert( 0 <= row && row < m_iNoRows );
00125         assert( 0 <= col && col < m_iNoCols );
00126         //-----------------------------
00127         m_pcParticle[row][col]->SetPosition( 
00128             m_pcParticle[row][col]->GetPosition() + addPosition );
00129     }
00130     //-------------------------------------------------------------------------
00131 protected:
00132     //-------------------------------------------------------------------------
00133     // Pure Virtual Fns
00134     // Helper Fn
00135     // void DrawGL()
00136     virtual void DrawGL ( GLenum ) {};
00137     //-------------------------------------------------------------------------
00138 public:
00139     // Get/Set Functions
00140     void GetNumberOfRowsAndColumns ( int & rows, int & cols ) const
00141     {   rows = m_iNoRows;   cols = m_iNoCols;   }
00142     bool GetParticleFixStatus( int r, int c ) const     { return m_pcParticle[r][c]->m_bFixed; }
00143     void SetParticleFixStatus( int r, int c, bool b )   { m_pcParticle[r][c]->m_bFixed = b; }
00144 
00145     // TEST
00146     void StepSimulation( T dt ) {
00147         T divider = 10.0;
00148         //CalForces( Vector3<T>( (rand()%1000)/divider, (rand()%10)/divider, (rand()%10)/divider ) );
00149         // Explicit Euler's Method for Integration for ODE Solver
00150         for ( m = 0; m < m_iNoRows; m++ ) {
00151             for ( n = 0; n < m_iNoCols; n++ ) {
00152                 m_pcParticle[m][n]->m_vtAccel  = m_pcParticle[m][n]->m_vtForce / m_pcParticle[m][n]->m_tMass;
00153                 m_pcParticle[m][n]->m_vtVeloc += m_pcParticle[m][n]->m_vtAccel * dt;
00154                 m_pcParticle[m][n]->m_vtPosit += m_pcParticle[m][n]->m_vtVeloc * dt;
00155             }
00156         }
00157     }
00158 
00159     //===============================================================
00160     // DeformUpdate
00161     //          North
00162     //            |
00163     //     West---C---East
00164     //            |
00165     //          South
00166     void DeformUpdate() {
00167         //static T testValue = 1.6; // Good Number
00168         static T testValue = 4;
00169         static T damp  = testValue * testValue;
00170         static T freq1 = testValue * testValue;
00171         static T freq2 = testValue / 5;
00172 
00173         T x, y, z;
00174         T vx, vy, vz;
00175         T ax, ay, az;               // change in velocity -- i.e. acceleration * time unit
00176         Vector3<T> nWest, nEast, nNorth, nSouth;    // locations of neighbors
00177         Vector3<T> nNorthWest, nNorthEast, nSouthWest, nSouthEast;
00178         Vector3<T> neighborsAvg;
00179         //------------------------------------------------------------
00180         // Middle Vertices
00181         for ( m = 1; m < m_iNoRows-1; ++m ) {
00182             for ( n = 1; n < m_iNoCols-1; ++n ) {
00183                 if ( m_pcParticle[m][n]->GetFixStatus() )   continue;
00184                 //-------------------------------
00185                 // Get neighbors' positions
00186                 nWest   = m_pcParticle[m][n-1]->GetPosition();
00187                 nEast   = m_pcParticle[m][n+1]->GetPosition();
00188                 nSouth  = m_pcParticle[m-1][n]->GetPosition();
00189                 nNorth  = m_pcParticle[m+1][n]->GetPosition();
00190                 //-------------------------------
00191                 nNorthWest  = m_pcParticle[m+1][n-1]->GetPosition();
00192                 nNorthEast  = m_pcParticle[m+1][n+1]->GetPosition();
00193                 nSouthWest  = m_pcParticle[m-1][n-1]->GetPosition();
00194                 nSouthEast  = m_pcParticle[m-1][n+1]->GetPosition();
00195                 //-------------------------------
00196                 //neighborsAvg = (nWest + nEast + nSouth + nNorth ) / 4.0;
00197                 neighborsAvg = (nWest + nEast + nSouth + nNorth + nNorthWest + nNorthEast + nSouthWest + nSouthEast) / 8.0;
00198                 m_pcParticle[m][n]->GetPosition().GetXYZ( x, y, z );
00199                 m_pcParticle[m][n]->GetVelocity().GetXYZ( vx, vy, vz );
00200 
00201                 //m_pcParticle[m][n]->SetPosition( m_pcParticle[m][n]->GetPosition() + Vector3<T>(0.01,0.01,0.01) );
00202                 ax = 0.1 * ( 
00203                             freq1 * (neighborsAvg.GetX() - x) / m_pcParticle[m][n]->GetMass()
00204                             + freq2 * (neighborsAvg.GetX()*neighborsAvg.GetX() - x*x) 
00205                           //+ freq2 * (n * 1.0/*size/meshSize = 1.0*/ - x) // Not working for 3D
00206                           - damp * vx
00207                 );
00208                 ay = 0.1 * ( 
00209                             freq1 * (neighborsAvg.GetY() - y) / m_pcParticle[m][n]->GetMass()
00210                             + freq2 * (neighborsAvg.GetY()*neighborsAvg.GetY() - y*y) 
00211                           //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - y) // Not working for 3D
00212                           - damp * vy
00213                 );
00214                 az = 0.1 * ( 
00215                             freq1 * (neighborsAvg.GetZ() - z) / m_pcParticle[m][n]->GetMass()
00216                             + freq2 * (neighborsAvg.GetZ()*neighborsAvg.GetZ() - z*z) 
00217                           //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - z) // Not working for 3D
00218                           - damp * vz
00219                 );
00220                 vx += ax;
00221                 vy += ay;
00222                 vz += az;
00223                 m_pcParticle[m][n]->SetVelocity( vx, vy, vz );
00224                 x += vx;
00225                 y += vy;
00226                 z += vz;
00227                 m_pcParticle[m][n]->SetPosition( x, y, z );
00228             }
00229         }
00232         //{ m = 0;
00233         //  for ( n = 1; n < m_iNoCols-1; ++n ) {
00234         //      if ( m_pcParticle[m][n]->GetFixStatus() )   continue;
00235         //      //-------------------------------
00236         //      // Get neighbors' positions
00237         //      nWest   = m_pcParticle[m][n-1]->GetPosition();
00238         //      nEast   = m_pcParticle[m][n+1]->GetPosition();
00239         //      nNorth  = m_pcParticle[m+1][n]->GetPosition();
00240         //      //-------------------------------
00241         //      nNorthWest  = m_pcParticle[m+1][n-1]->GetPosition();
00242         //      nNorthEast  = m_pcParticle[m+1][n+1]->GetPosition();
00243         //      //-------------------------------
00244         //      //neighborsAvg = (nWest + nEast + nSouth + nNorth ) / 4.0;
00245         //      neighborsAvg = (nWest + nEast + nNorth + nNorthWest + nNorthEast) / 5.0;
00246         //      m_pcParticle[m][n]->GetPosition().GetXYZ( x, y, z );
00247         //      m_pcParticle[m][n]->GetVelocity().GetXYZ( vx, vy, vz );
00248 
00249         //      //m_pcParticle[m][n]->SetPosition( m_pcParticle[m][n]->GetPosition() + Vector3<T>(0.01,0.01,0.01) );
00250         //      ax = 0.1 * ( 
00251         //                  freq1 * (neighborsAvg.GetX() - x) / m_pcParticle[m][n]->GetMass()
00252         //                  + freq2 * (neighborsAvg.GetX()*neighborsAvg.GetX() - x*x) 
00253         //                //+ freq2 * (n * 1.0/*size/meshSize = 1.0*/ - x) // Not working for 3D
00254         //                - damp * vx
00255         //      );
00256         //      ay = 0.1 * ( 
00257         //                  freq1 * (neighborsAvg.GetY() - y) / m_pcParticle[m][n]->GetMass()
00258         //                  + freq2 * (neighborsAvg.GetY()*neighborsAvg.GetY() - y*y) 
00259         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - y) // Not working for 3D
00260         //                - damp * vy
00261         //      );
00262         //      az = 0.1 * ( 
00263         //                  freq1 * (neighborsAvg.GetZ() - z) / m_pcParticle[m][n]->GetMass()
00264         //                  + freq2 * (neighborsAvg.GetZ()*neighborsAvg.GetZ() - z*z) 
00265         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - z) // Not working for 3D
00266         //                - damp * vz
00267         //      );
00268         //      vx += ax;
00269         //      vy += ay;
00270         //      vz += az;
00271         //      m_pcParticle[m][n]->SetVelocity( vx, vy, vz );
00272         //      x += vx;
00273         //      y += vy;
00274         //      z += vz;
00275         //      m_pcParticle[m][n]->SetPosition( x, y, z );
00276         //  }
00277         //}
00280         //{ m = m_iNoRows-1;
00281         //  for ( n = 1; n < m_iNoCols-1; ++n ) {
00282         //      if ( m_pcParticle[m][n]->GetFixStatus() )   continue;
00283         //      //-------------------------------
00284         //      // Get neighbors' positions
00285         //      nWest   = m_pcParticle[m][n-1]->GetPosition();
00286         //      nEast   = m_pcParticle[m][n+1]->GetPosition();
00287         //      nSouth  = m_pcParticle[m-1][n]->GetPosition();
00288         //      //-------------------------------
00289         //      nSouthWest  = m_pcParticle[m-1][n-1]->GetPosition();
00290         //      nSouthEast  = m_pcParticle[m-1][n+1]->GetPosition();
00291         //      //-------------------------------
00292         //      //neighborsAvg = (nWest + nEast + nSouth + nNorth ) / 4.0;
00293         //      neighborsAvg = (nWest + nEast + nSouth + nSouthWest + nSouthEast) / 5.0;
00294         //      m_pcParticle[m][n]->GetPosition().GetXYZ( x, y, z );
00295         //      m_pcParticle[m][n]->GetVelocity().GetXYZ( vx, vy, vz );
00296 
00297         //      //m_pcParticle[m][n]->SetPosition( m_pcParticle[m][n]->GetPosition() + Vector3<T>(0.01,0.01,0.01) );
00298         //      ax = 0.1 * ( 
00299         //                  freq1 * (neighborsAvg.GetX() - x) / m_pcParticle[m][n]->GetMass()
00300         //                  + freq2 * (neighborsAvg.GetX()*neighborsAvg.GetX() - x*x) 
00301         //                //+ freq2 * (n * 1.0/*size/meshSize = 1.0*/ - x) // Not working for 3D
00302         //                - damp * vx
00303         //      );
00304         //      ay = 0.1 * ( 
00305         //                  freq1 * (neighborsAvg.GetY() - y) / m_pcParticle[m][n]->GetMass()
00306         //                  + freq2 * (neighborsAvg.GetY()*neighborsAvg.GetY() - y*y) 
00307         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - y) // Not working for 3D
00308         //                - damp * vy
00309         //      );
00310         //      az = 0.1 * ( 
00311         //                  freq1 * (neighborsAvg.GetZ() - z) / m_pcParticle[m][n]->GetMass()
00312         //                  + freq2 * (neighborsAvg.GetZ()*neighborsAvg.GetZ() - z*z) 
00313         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - z) // Not working for 3D
00314         //                - damp * vz
00315         //      );
00316         //      vx += ax;
00317         //      vy += ay;
00318         //      vz += az;
00319         //      m_pcParticle[m][n]->SetVelocity( vx, vy, vz );
00320         //      x += vx;
00321         //      y += vy;
00322         //      z += vz;
00323         //      m_pcParticle[m][n]->SetPosition( x, y, z );
00324         //  }
00325         //}
00328         //{ n = 0;
00329         //  for ( m = 1; m < m_iNoRows-1; ++m ) {
00330         //      if ( m_pcParticle[m][n]->GetFixStatus() )   continue;
00331         //      //-------------------------------
00332         //      // Get neighbors' positions
00333         //      nEast   = m_pcParticle[m][n+1]->GetPosition();
00334         //      nSouth  = m_pcParticle[m-1][n]->GetPosition();
00335         //      nNorth  = m_pcParticle[m+1][n]->GetPosition();
00336         //      //-------------------------------
00337         //      nNorthEast  = m_pcParticle[m+1][n+1]->GetPosition();
00338         //      nSouthEast  = m_pcParticle[m-1][n+1]->GetPosition();
00339         //      //-------------------------------
00340         //      //neighborsAvg = (nWest + nEast + nSouth + nNorth ) / 4.0;
00341         //      neighborsAvg = (nEast + nSouth + nNorth + nNorthEast + nSouthEast) / 5.0;
00342         //      m_pcParticle[m][n]->GetPosition().GetXYZ( x, y, z );
00343         //      m_pcParticle[m][n]->GetVelocity().GetXYZ( vx, vy, vz );
00344 
00345         //      //m_pcParticle[m][n]->SetPosition( m_pcParticle[m][n]->GetPosition() + Vector3<T>(0.01,0.01,0.01) );
00346         //      ax = 0.1 * ( 
00347         //                  freq1 * (neighborsAvg.GetX() - x) / m_pcParticle[m][n]->GetMass()
00348         //                  + freq2 * (neighborsAvg.GetX()*neighborsAvg.GetX() - x*x) 
00349         //                //+ freq2 * (n * 1.0/*size/meshSize = 1.0*/ - x) // Not working for 3D
00350         //                - damp * vx
00351         //      );
00352         //      ay = 0.1 * ( 
00353         //                  freq1 * (neighborsAvg.GetY() - y) / m_pcParticle[m][n]->GetMass()
00354         //                  + freq2 * (neighborsAvg.GetY()*neighborsAvg.GetY() - y*y) 
00355         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - y) // Not working for 3D
00356         //                - damp * vy
00357         //      );
00358         //      az = 0.1 * ( 
00359         //                  freq1 * (neighborsAvg.GetZ() - z) / m_pcParticle[m][n]->GetMass()
00360         //                  + freq2 * (neighborsAvg.GetZ()*neighborsAvg.GetZ() - z*z) 
00361         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - z) // Not working for 3D
00362         //                - damp * vz
00363         //      );
00364         //      vx += ax;
00365         //      vy += ay;
00366         //      vz += az;
00367         //      m_pcParticle[m][n]->SetVelocity( vx, vy, vz );
00368         //      x += vx;
00369         //      y += vy;
00370         //      z += vz;
00371         //      m_pcParticle[m][n]->SetPosition( x, y, z );
00372         //  }
00373         //}
00376         //{ n = m_iNoCols-1;
00377         //  for ( m = 1; m < m_iNoRows-1; ++m ) {
00378         //      if ( m_pcParticle[m][n]->GetFixStatus() )   continue;
00379         //      //-------------------------------
00380         //      // Get neighbors' positions
00381         //      nWest   = m_pcParticle[m][n-1]->GetPosition();
00382         //      nSouth  = m_pcParticle[m-1][n]->GetPosition();
00383         //      nNorth  = m_pcParticle[m+1][n]->GetPosition();
00384         //      //-------------------------------
00385         //      nNorthWest  = m_pcParticle[m+1][n-1]->GetPosition();
00386         //      nSouthWest  = m_pcParticle[m-1][n-1]->GetPosition();
00387         //      //-------------------------------
00388         //      //neighborsAvg = (nWest + nEast + nSouth + nNorth ) / 4.0;
00389         //      neighborsAvg = (nWest + nSouth + nNorth + nNorthWest + nSouthWest) / 5.0;
00390         //      m_pcParticle[m][n]->GetPosition().GetXYZ( x, y, z );
00391         //      m_pcParticle[m][n]->GetVelocity().GetXYZ( vx, vy, vz );
00392 
00393         //      //m_pcParticle[m][n]->SetPosition( m_pcParticle[m][n]->GetPosition() + Vector3<T>(0.01,0.01,0.01) );
00394         //      ax = 0.1 * ( 
00395         //                  freq1 * (neighborsAvg.GetX() - x) / m_pcParticle[m][n]->GetMass()
00396         //                  + freq2 * (neighborsAvg.GetX()*neighborsAvg.GetX() - x*x) 
00397         //                //+ freq2 * (n * 1.0/*size/meshSize = 1.0*/ - x) // Not working for 3D
00398         //                - damp * vx
00399         //      );
00400         //      ay = 0.1 * ( 
00401         //                  freq1 * (neighborsAvg.GetY() - y) / m_pcParticle[m][n]->GetMass()
00402         //                  + freq2 * (neighborsAvg.GetY()*neighborsAvg.GetY() - y*y) 
00403         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - y) // Not working for 3D
00404         //                - damp * vy
00405         //      );
00406         //      az = 0.1 * ( 
00407         //                  freq1 * (neighborsAvg.GetZ() - z) / m_pcParticle[m][n]->GetMass()
00408         //                  + freq2 * (neighborsAvg.GetZ()*neighborsAvg.GetZ() - z*z) 
00409         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - z) // Not working for 3D
00410         //                - damp * vz
00411         //      );
00412         //      vx += ax;
00413         //      vy += ay;
00414         //      vz += az;
00415         //      m_pcParticle[m][n]->SetVelocity( vx, vy, vz );
00416         //      x += vx;
00417         //      y += vy;
00418         //      z += vz;
00419         //      m_pcParticle[m][n]->SetPosition( x, y, z );
00420         //  }
00421         //}
00424         //{ m = 0;
00425         //  n = 0;
00426         //  if ( !m_pcParticle[m][n]->GetFixStatus() ) {
00427         //      //-------------------------------
00428         //      // Get neighbors' positions
00429         //      nEast   = m_pcParticle[m][n+1]->GetPosition();
00430         //      nNorth  = m_pcParticle[m+1][n]->GetPosition();
00431         //      //-------------------------------
00432         //      nNorthEast  = m_pcParticle[m+1][n+1]->GetPosition();
00433         //      //-------------------------------
00434         //      //neighborsAvg = (nWest + nEast + nSouth + nNorth ) / 4.0;
00435         //      neighborsAvg = (nEast + nNorth + nNorthEast) / 3.0;
00436         //      m_pcParticle[m][n]->GetPosition().GetXYZ( x, y, z );
00437         //      m_pcParticle[m][n]->GetVelocity().GetXYZ( vx, vy, vz );
00438 
00439         //      //m_pcParticle[m][n]->SetPosition( m_pcParticle[m][n]->GetPosition() + Vector3<T>(0.01,0.01,0.01) );
00440         //      ax = 0.1 * ( 
00441         //                  freq1 * (neighborsAvg.GetX() - x) / m_pcParticle[m][n]->GetMass()
00442         //                  + freq2 * (neighborsAvg.GetX()*neighborsAvg.GetX() - x*x) 
00443         //                //+ freq2 * (n * 1.0/*size/meshSize = 1.0*/ - x) // Not working for 3D
00444         //                - damp * vx
00445         //      );
00446         //      ay = 0.1 * ( 
00447         //                  freq1 * (neighborsAvg.GetY() - y) / m_pcParticle[m][n]->GetMass()
00448         //                  + freq2 * (neighborsAvg.GetY()*neighborsAvg.GetY() - y*y) 
00449         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - y) // Not working for 3D
00450         //                - damp * vy
00451         //      );
00452         //      az = 0.1 * ( 
00453         //                  freq1 * (neighborsAvg.GetZ() - z) / m_pcParticle[m][n]->GetMass()
00454         //                  + freq2 * (neighborsAvg.GetZ()*neighborsAvg.GetZ() - z*z) 
00455         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - z) // Not working for 3D
00456         //                - damp * vz
00457         //      );
00458         //      vx += ax;
00459         //      vy += ay;
00460         //      vz += az;
00461         //      m_pcParticle[m][n]->SetVelocity( vx, vy, vz );
00462         //      x += vx;
00463         //      y += vy;
00464         //      z += vz;
00465         //      m_pcParticle[m][n]->SetPosition( x, y, z );
00466         //  }
00467         //}
00470         //{ m = 0;
00471         //  n = m_iNoCols-1;
00472         //  if ( !m_pcParticle[m][n]->GetFixStatus() ) {
00473         //      //-------------------------------
00474         //      // Get neighbors' positions
00475         //      nWest   = m_pcParticle[m][n-1]->GetPosition();
00476         //      nNorth  = m_pcParticle[m+1][n]->GetPosition();
00477         //      //-------------------------------
00478         //      nNorthWest  = m_pcParticle[m+1][n-1]->GetPosition();
00479         //      //-------------------------------
00480         //      //neighborsAvg = (nWest + nEast + nSouth + nNorth ) / 4.0;
00481         //      neighborsAvg = (nWest + nNorth + nNorthWest) / 3.0;
00482         //      m_pcParticle[m][n]->GetPosition().GetXYZ( x, y, z );
00483         //      m_pcParticle[m][n]->GetVelocity().GetXYZ( vx, vy, vz );
00484 
00485         //      //m_pcParticle[m][n]->SetPosition( m_pcParticle[m][n]->GetPosition() + Vector3<T>(0.01,0.01,0.01) );
00486         //      ax = 0.1 * ( 
00487         //                  freq1 * (neighborsAvg.GetX() - x) / m_pcParticle[m][n]->GetMass()
00488         //                  + freq2 * (neighborsAvg.GetX()*neighborsAvg.GetX() - x*x) 
00489         //                //+ freq2 * (n * 1.0/*size/meshSize = 1.0*/ - x) // Not working for 3D
00490         //                - damp * vx
00491         //      );
00492         //      ay = 0.1 * ( 
00493         //                  freq1 * (neighborsAvg.GetY() - y) / m_pcParticle[m][n]->GetMass()
00494         //                  + freq2 * (neighborsAvg.GetY()*neighborsAvg.GetY() - y*y) 
00495         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - y) // Not working for 3D
00496         //                - damp * vy
00497         //      );
00498         //      az = 0.1 * ( 
00499         //                  freq1 * (neighborsAvg.GetZ() - z) / m_pcParticle[m][n]->GetMass()
00500         //                  + freq2 * (neighborsAvg.GetZ()*neighborsAvg.GetZ() - z*z) 
00501         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - z) // Not working for 3D
00502         //                - damp * vz
00503         //      );
00504         //      vx += ax;
00505         //      vy += ay;
00506         //      vz += az;
00507         //      m_pcParticle[m][n]->SetVelocity( vx, vy, vz );
00508         //      x += vx;
00509         //      y += vy;
00510         //      z += vz;
00511         //      m_pcParticle[m][n]->SetPosition( x, y, z );
00512         //  }
00513         //}
00516         //{ m = m_iNoRows-1;
00517         //  n = 0;
00518         //  if ( !m_pcParticle[m][n]->GetFixStatus() ) {
00519         //      //-------------------------------
00520         //      // Get neighbors' positions
00521         //      nEast   = m_pcParticle[m][n+1]->GetPosition();
00522         //      nSouth  = m_pcParticle[m-1][n]->GetPosition();
00523         //      //-------------------------------
00524         //      nSouthEast  = m_pcParticle[m-1][n+1]->GetPosition();
00525         //      //-------------------------------
00526         //      //neighborsAvg = (nWest + nEast + nSouth + nNorth ) / 4.0;
00527         //      neighborsAvg = (nEast + nSouth + nSouthEast) / 3.0;
00528         //      m_pcParticle[m][n]->GetPosition().GetXYZ( x, y, z );
00529         //      m_pcParticle[m][n]->GetVelocity().GetXYZ( vx, vy, vz );
00530 
00531         //      //m_pcParticle[m][n]->SetPosition( m_pcParticle[m][n]->GetPosition() + Vector3<T>(0.01,0.01,0.01) );
00532         //      ax = 0.1 * ( 
00533         //                  freq1 * (neighborsAvg.GetX() - x) / m_pcParticle[m][n]->GetMass()
00534         //                  + freq2 * (neighborsAvg.GetX()*neighborsAvg.GetX() - x*x) 
00535         //                //+ freq2 * (n * 1.0/*size/meshSize = 1.0*/ - x) // Not working for 3D
00536         //                - damp * vx
00537         //      );
00538         //      ay = 0.1 * ( 
00539         //                  freq1 * (neighborsAvg.GetY() - y) / m_pcParticle[m][n]->GetMass()
00540         //                  + freq2 * (neighborsAvg.GetY()*neighborsAvg.GetY() - y*y) 
00541         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - y) // Not working for 3D
00542         //                - damp * vy
00543         //      );
00544         //      az = 0.1 * ( 
00545         //                  freq1 * (neighborsAvg.GetZ() - z) / m_pcParticle[m][n]->GetMass()
00546         //                  + freq2 * (neighborsAvg.GetZ()*neighborsAvg.GetZ() - z*z) 
00547         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - z) // Not working for 3D
00548         //                - damp * vz
00549         //      );
00550         //      vx += ax;
00551         //      vy += ay;
00552         //      vz += az;
00553         //      m_pcParticle[m][n]->SetVelocity( vx, vy, vz );
00554         //      x += vx;
00555         //      y += vy;
00556         //      z += vz;
00557         //      m_pcParticle[m][n]->SetPosition( x, y, z );
00558         //  }
00559         //}
00562         //{ m = m_iNoRows-1;
00563         //  n = m_iNoCols-1;
00564         //  if ( !m_pcParticle[m][n]->GetFixStatus() ) {
00565         //      //-------------------------------
00566         //      // Get neighbors' positions
00567         //      nWest   = m_pcParticle[m][n-1]->GetPosition();
00568         //      nSouth  = m_pcParticle[m-1][n]->GetPosition();
00569         //      //-------------------------------
00570         //      nSouthWest  = m_pcParticle[m-1][n-1]->GetPosition();
00571         //      //-------------------------------
00572         //      //neighborsAvg = (nWest + nEast + nSouth + nNorth ) / 4.0;
00573         //      neighborsAvg = (nWest + nSouth + nSouthWest) / 3.0;
00574         //      m_pcParticle[m][n]->GetPosition().GetXYZ( x, y, z );
00575         //      m_pcParticle[m][n]->GetVelocity().GetXYZ( vx, vy, vz );
00576 
00577         //      //m_pcParticle[m][n]->SetPosition( m_pcParticle[m][n]->GetPosition() + Vector3<T>(0.01,0.01,0.01) );
00578         //      ax = 0.1 * ( 
00579         //                  freq1 * (neighborsAvg.GetX() - x) / m_pcParticle[m][n]->GetMass()
00580         //                  + freq2 * (neighborsAvg.GetX()*neighborsAvg.GetX() - x*x) 
00581         //                //+ freq2 * (n * 1.0/*size/meshSize = 1.0*/ - x) // Not working for 3D
00582         //                - damp * vx
00583         //      );
00584         //      ay = 0.1 * ( 
00585         //                  freq1 * (neighborsAvg.GetY() - y) / m_pcParticle[m][n]->GetMass()
00586         //                  + freq2 * (neighborsAvg.GetY()*neighborsAvg.GetY() - y*y) 
00587         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - y) // Not working for 3D
00588         //                - damp * vy
00589         //      );
00590         //      az = 0.1 * ( 
00591         //                  freq1 * (neighborsAvg.GetZ() - z) / m_pcParticle[m][n]->GetMass()
00592         //                  + freq2 * (neighborsAvg.GetZ()*neighborsAvg.GetZ() - z*z) 
00593         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - z) // Not working for 3D
00594         //                - damp * vz
00595         //      );
00596         //      vx += ax;
00597         //      vy += ay;
00598         //      vz += az;
00599         //      m_pcParticle[m][n]->SetVelocity( vx, vy, vz );
00600         //      x += vx;
00601         //      y += vy;
00602         //      z += vz;
00603         //      m_pcParticle[m][n]->SetPosition( x, y, z );
00604         //  }
00605         //}
00606         //------------------------------------------------------------
00607         CalParticleNormals();
00608     }
00609 };
00610 //CLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLA
00611 
00612 
00613 //HELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHE
00614 //
00615 //      DeformMesh  H E L P E R    F U N C T I O N    M E M B E R    D E F I N I T I O N S
00616 //
00617 //HELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHE
00618 //-------------------------------------------------------------------------------------------------
00619 // Create Particles
00620 template <typename T>
00621 void DeformMesh<T>::CreateParticles( const Vector3<T> &topLeftPos, const Vector3<T> &bottomRightPos, T mass )
00622 {
00623     // Local Variable
00624     Vector3<T> currentPosVector = topLeftPos;
00625     Vector3<T> diagonalVector = bottomRightPos - topLeftPos;
00626     T ptMass = mass / ( m_iNoCols * m_iNoRows );
00627     T colIncStep = diagonalVector[0] / (m_iNoCols-1);
00628     T rowIncStep = diagonalVector[1] / (m_iNoRows-1);
00629     //T zIncStep   = diagonalVector[2] / ((m_iNoCols + m_iNoRows)/2.0);
00630     T zIncStep   = diagonalVector[2] / (m_iNoRows-1);
00631 
00632     // Create Particle Pointers
00633     m_pcParticle = new Particle<T>**[m_iNoRows];
00634     for ( m = 0; m < m_iNoRows; m++ ) {
00635         m_pcParticle[m] = new Particle<T>*[m_iNoCols];
00636     }
00637 
00638     // Create Particles
00639     Vector3<T> zeroVector(0,0,0);
00640     for ( m = 0; m < m_iNoRows; m++ ) { // row loops
00641         for ( n = 0; n < m_iNoCols; n++ ) { // column loops
00642             m_pcParticle[m][n] = new Particle<T>( 
00643                                     ptMass,             // mass 
00644                                     currentPosVector,   // position
00645                                     zeroVector,         // velocity
00646                                     zeroVector,         // acceleration
00647                                     zeroVector );       // force
00648             currentPosVector[0] = currentPosVector[0] + colIncStep; // increment x position
00649         }
00650         currentPosVector[0] = topLeftPos[0];                    // reset x position
00651         currentPosVector[1] = currentPosVector[1] + rowIncStep; // increment y position
00652         currentPosVector[2] = currentPosVector[2] + zIncStep;   // increment z position
00653     }
00654 
00655     /*
00656     // Dump Particle Positions on Screen
00657     std::cout << "Particle Positions:\n";
00658     for ( m = 0; m < m_iNoRows; m++ ) { // row loops
00659         for ( n = 0; n < m_iNoCols; n++ ) { // column loops
00660             std::cout << "[" << m << "," << n << "] " << m_pcParticle[m][n]->m_vtPosit << " ";
00661         }
00662         std::cout << "\n";
00663     }
00664     //*/
00665 }
00666 //-------------------------------------------------------------------------------------------------
00667 // Delete Particles
00668 template <typename T>
00669 void DeformMesh<T>::DeleteParticles()
00670 {
00671     // Delete Particles
00672     for ( m = 0; m < m_iNoRows; m++ ) {
00673         for ( n = 0; n < m_iNoCols; n++ ) {
00674             delete m_pcParticle[m][n];
00675         }
00676         delete [] m_pcParticle[m];
00677     }
00678     delete [] m_pcParticle;
00679 }
00680 //HELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHE
00681 
00682 
00683 //MEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERME
00684 //
00685 //      DeformMesh  F U N C T I O N    M E M B E R    D E F I N I T I O N S
00686 //
00687 //MEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERME
00688 //-------------------------------------------------------------------------------------------------
00689 template <typename T>
00690 DeformMesh<T>::DeformMesh( 
00691               int rows,             // number of rows (on world-y-axis)
00692               int cols,             // number of cols (on world-x-axis)
00693               const Vector3<T> &topLeftPos,         // start position (should be top left cornor)
00694               const Vector3<T> &bottomRightPos,     // end position (should be bottom right cornor)
00695               T mass,                                   // the whole mass
00696               BitmapImage *img )            // Image Pointer
00697     : OpenGLSupport( img ),     // parent class constructor
00698       m_iNoRows( rows ), m_iNoCols( cols )
00699 {
00700     CreateParticles( topLeftPos, bottomRightPos, mass );
00701     CalParticleNormals();
00702 }
00703 //-------------------------------------------------------------------------------------------------
00704 template <typename T>
00705 DeformMesh<T>::~DeformMesh()
00706 {
00707     DeleteParticles();
00708 }
00709 //-------------------------------------------------------------------------------------------------
00710 // Calculate Particle Normals
00711 template <typename T>
00712 void DeformMesh<T>::CalParticleNormals()
00713 {
00714 /*
00715     -----------------
00716     | \  3  |  2  / |
00717     |   \   |   /   |
00718     | 4   \ | /  1  |   Normal of the middle (m,n) particle is the sum of the eight normals.
00719     |<------+------>|   E.g. normal 1 is the unit vector of the cross product of (m,n)-->(m,n+1) 
00720     | 5   / | \  8  |   vector with (m,n)-->(m-1,n+1) vector (rotated counter clockwise).
00721     |   /   |   \   |
00722     | /  6  |  7  \ |
00723     -----------------
00724 */
00725     // These particles have all 8 neighbors ------------------------------------
00726     for ( m = 1; m < m_iNoRows-1; m++ ) {
00727         for ( n = 1; n < m_iNoCols-1; n++ ) {
00728             // (1) (m,n)-->(m,n+1)   and (m,n)-->(m-1,n+1)
00729             m_pcParticle[m][n]->m_vtNormal 
00730                 = ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n+1]->m_vtPosit) 
00731                   ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n+1]->m_vtPosit) ).Normalized();
00732             // (2) (m,n)-->(m-1,n+1) and (m,n)-->(m-1,n)
00733             m_pcParticle[m][n]->m_vtNormal 
00734                 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n+1]->m_vtPosit) 
00735                    ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n  ]->m_vtPosit) ).Normalized();
00736             // (3) (m,n)-->(m-1,n)   and (m,n)-->(m-1,n-1)
00737             m_pcParticle[m][n]->m_vtNormal 
00738                 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n  ]->m_vtPosit) 
00739                    ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n-1]->m_vtPosit) ).Normalized();
00740             // (4) (m,n)-->(m-1,n-1) and (m,n)-->(m,n-1)
00741             m_pcParticle[m][n]->m_vtNormal 
00742                 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n-1]->m_vtPosit) 
00743                    ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n-1]->m_vtPosit) ).Normalized();
00744             // (5) (m,n)-->(m,n-1)   and (m,n)-->(m+1,n-1)
00745             m_pcParticle[m][n]->m_vtNormal 
00746                 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n-1]->m_vtPosit) 
00747                    ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n-1]->m_vtPosit) ).Normalized();
00748             // (6) (m,n)-->(m+1,n-1) and (m,n)-->(m+1,n)
00749             m_pcParticle[m][n]->m_vtNormal 
00750                 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n-1]->m_vtPosit) 
00751                    ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n  ]->m_vtPosit) ).Normalized();
00752             // (7) (m,n)-->(m+1,n)   and (m,n)-->(m+1,n+1)
00753             m_pcParticle[m][n]->m_vtNormal 
00754                 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n  ]->m_vtPosit) 
00755                    ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n+1]->m_vtPosit) ).Normalized();
00756             // (8) (m,n)-->(m+1,n+1) and (m,n)-->(m,n+1)
00757             m_pcParticle[m][n]->m_vtNormal 
00758                 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n+1]->m_vtPosit) 
00759                    ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n+1]->m_vtPosit) ).Normalized();
00760             // normalize the sum result vector
00761             m_pcParticle[m][n]->m_vtNormal.Normalized();
00762         }
00763     }
00764 
00765     //-------------------------------------------------------------------------
00766     // Normals of Particles on the Top Row (Except the Cornor Particle)
00767     m = 0;
00768     for ( n = 1; n < m_iNoCols-1; n++ ) {
00769         // (5) (m,n)-->(m,n-1)   and (m,n)-->(m+1,n-1)
00770         m_pcParticle[m][n]->m_vtNormal 
00771             = ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n-1]->m_vtPosit) 
00772               ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n-1]->m_vtPosit) ).Normalized();
00773         // (6) (m,n)-->(m+1,n-1) and (m,n)-->(m+1,n)
00774         m_pcParticle[m][n]->m_vtNormal 
00775             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n-1]->m_vtPosit) 
00776                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n  ]->m_vtPosit) ).Normalized();
00777         // (7) (m,n)-->(m+1,n)   and (m,n)-->(m+1,n+1)
00778         m_pcParticle[m][n]->m_vtNormal 
00779             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n  ]->m_vtPosit) 
00780                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n+1]->m_vtPosit) ).Normalized();
00781         // (8) (m,n)-->(m+1,n+1) and (m,n)-->(m,n+1)
00782         m_pcParticle[m][n]->m_vtNormal 
00783             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n+1]->m_vtPosit) 
00784                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n+1]->m_vtPosit) ).Normalized();
00785         // normalize the sum result vector
00786         m_pcParticle[m][n]->m_vtNormal.Normalized();
00787     }
00788     //-------------------------------------------------------------------------
00789     // Normals of Particles on the Bottom Row (Except the Cornor Particle)
00790     m = m_iNoRows-1;
00791     for ( n = 1; n < m_iNoCols-1; n++ ) {
00792         // (1) (m,n)-->(m,n+1)   and (m,n)-->(m-1,n+1)
00793         m_pcParticle[m][n]->m_vtNormal 
00794             = ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n+1]->m_vtPosit) 
00795               ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n+1]->m_vtPosit) ).Normalized();
00796         // (2) (m,n)-->(m-1,n+1) and (m,n)-->(m-1,n)
00797         m_pcParticle[m][n]->m_vtNormal 
00798             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n+1]->m_vtPosit) 
00799                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n  ]->m_vtPosit) ).Normalized();
00800         // (3) (m,n)-->(m-1,n)   and (m,n)-->(m-1,n-1)
00801         m_pcParticle[m][n]->m_vtNormal 
00802             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n  ]->m_vtPosit) 
00803                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n-1]->m_vtPosit) ).Normalized();
00804         // (4) (m,n)-->(m-1,n-1) and (m,n)-->(m,n-1)
00805         m_pcParticle[m][n]->m_vtNormal 
00806             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n-1]->m_vtPosit) 
00807                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n-1]->m_vtPosit) ).Normalized();
00808         // normalize the sum result vector
00809         m_pcParticle[m][n]->m_vtNormal.Normalized();
00810     }
00811     //-------------------------------------------------------------------------
00812     // Normals of Particles on the Left Column (Except the Cornor Particle)
00813     n = 0;
00814     for ( m = 1; m < m_iNoRows-1; m++ ) {
00815         // (7) (m,n)-->(m+1,n)   and (m,n)-->(m+1,n+1)
00816         m_pcParticle[m][n]->m_vtNormal 
00817             = ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n  ]->m_vtPosit) 
00818               ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n+1]->m_vtPosit) ).Normalized();
00819         // (8) (m,n)-->(m+1,n+1) and (m,n)-->(m,n+1)
00820         m_pcParticle[m][n]->m_vtNormal 
00821             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n+1]->m_vtPosit) 
00822                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n+1]->m_vtPosit) ).Normalized();
00823         // (1) (m,n)-->(m,n+1)   and (m,n)-->(m-1,n+1)
00824         m_pcParticle[m][n]->m_vtNormal 
00825             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n+1]->m_vtPosit) 
00826                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n+1]->m_vtPosit) ).Normalized();
00827         // (2) (m,n)-->(m-1,n+1) and (m,n)-->(m-1,n)
00828         m_pcParticle[m][n]->m_vtNormal 
00829             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n+1]->m_vtPosit) 
00830                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n  ]->m_vtPosit) ).Normalized();
00831         // normalize the sum result vector
00832         m_pcParticle[m][n]->m_vtNormal.Normalized();
00833     }
00834     //-------------------------------------------------------------------------
00835     // Normals of Particles on the Right Row (Except the Cornor Particle)
00836     n = m_iNoCols-1;
00837     for ( m = 1; m < m_iNoRows-1; m++ ) {
00838         // (3) (m,n)-->(m-1,n)   and (m,n)-->(m-1,n-1)
00839         m_pcParticle[m][n]->m_vtNormal 
00840             = ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n  ]->m_vtPosit) 
00841               ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n-1]->m_vtPosit) ).Normalized();
00842         // (4) (m,n)-->(m-1,n-1) and (m,n)-->(m,n-1)
00843         m_pcParticle[m][n]->m_vtNormal 
00844             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n-1]->m_vtPosit) 
00845                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n-1]->m_vtPosit) ).Normalized();
00846         // (5) (m,n)-->(m,n-1)   and (m,n)-->(m+1,n-1)
00847         m_pcParticle[m][n]->m_vtNormal 
00848             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n-1]->m_vtPosit) 
00849                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n-1]->m_vtPosit) ).Normalized();
00850         // (6) (m,n)-->(m+1,n-1) and (m,n)-->(m+1,n)
00851         m_pcParticle[m][n]->m_vtNormal 
00852             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n-1]->m_vtPosit) 
00853                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n  ]->m_vtPosit) ).Normalized();
00854         // normalize the sum result vector
00855         m_pcParticle[m][n]->m_vtNormal.Normalized();
00856     }
00857     
00858     // Top Left Cornor ---------------------------------------------------------
00859     m = 0; n = 0;
00860         // (7) (m,n)-->(m+1,n)   and (m,n)-->(m+1,n+1)
00861         m_pcParticle[m][n]->m_vtNormal 
00862             = ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n  ]->m_vtPosit) 
00863               ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n+1]->m_vtPosit) ).Normalized();
00864         // (8) (m,n)-->(m+1,n+1) and (m,n)-->(m,n+1)
00865         m_pcParticle[m][n]->m_vtNormal 
00866             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n+1]->m_vtPosit) 
00867                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n+1]->m_vtPosit) ).Normalized();
00868         m_pcParticle[m][n]->m_vtNormal.Normalized();    // normalize the sum result vector
00869     // Bottom Left Cornor ------------------------------------------------------
00870     m = m_iNoRows-1; n = 0;
00871         // (1) (m,n)-->(m,n+1)   and (m,n)-->(m-1,n+1)
00872         m_pcParticle[m][n]->m_vtNormal 
00873             = ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n+1]->m_vtPosit) 
00874               ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n+1]->m_vtPosit) ).Normalized();
00875         // (2) (m,n)-->(m-1,n+1) and (m,n)-->(m-1,n)
00876         m_pcParticle[m][n]->m_vtNormal 
00877             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n+1]->m_vtPosit) 
00878                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n  ]->m_vtPosit) ).Normalized();
00879         m_pcParticle[m][n]->m_vtNormal.Normalized();    // normalize the sum result vector
00880     // Bottom Right Cornor -----------------------------------------------------
00881     m = m_iNoRows-1; n = m_iNoCols-1;
00882         // (3) (m,n)-->(m-1,n)   and (m,n)-->(m-1,n-1)
00883         m_pcParticle[m][n]->m_vtNormal 
00884             = ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n  ]->m_vtPosit) 
00885               ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n-1]->m_vtPosit) ).Normalized();
00886         // (4) (m,n)-->(m-1,n-1) and (m,n)-->(m,n-1)
00887         m_pcParticle[m][n]->m_vtNormal 
00888             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n-1]->m_vtPosit) 
00889                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n-1]->m_vtPosit) ).Normalized();
00890         m_pcParticle[m][n]->m_vtNormal.Normalized();    // normalize the sum result vector
00891     // Top Right Cornor --------------------------------------------------------
00892     m = 0; n = m_iNoCols-1;
00893         // (5) (m,n)-->(m,n-1)   and (m,n)-->(m+1,n-1)
00894         m_pcParticle[m][n]->m_vtNormal 
00895             = ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n-1]->m_vtPosit) 
00896               ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n-1]->m_vtPosit) ).Normalized();
00897         // (6) (m,n)-->(m+1,n-1) and (m,n)-->(m+1,n)
00898         m_pcParticle[m][n]->m_vtNormal 
00899             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n-1]->m_vtPosit) 
00900                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n  ]->m_vtPosit) ).Normalized();
00901         m_pcParticle[m][n]->m_vtNormal.Normalized();    // normalize the sum result vector
00902 }
00903 //-------------------------------------------------------------------------------------------------
00904 // Calculate Particle Normals
00905 template <typename T>
00906 void DeformMesh<T>::CalParticleNormals( int i )
00907 {
00908 /*
00909     -----------------
00910     | \  3  |  2  / |
00911     |   \   |   /   |
00912     | 4   \ | /  1  |   Normal of the middle (m,n) particle is the sum of the eight normals.
00913     |<------+------>|   E.g. normal 1 is the unit vector of the cross product of (m,n)-->(m,n+1) 
00914     | 5   / | \  8  |   vector with (m,n)-->(m-1,n+1) vector (rotated counter clockwise).
00915     |   /   |   \   |
00916     | /  6  |  7  \ |
00917     -----------------
00918 */
00919     // These particles have all 8 neighbors ------------------------------------
00920     for ( m = 1; m < m_iNoRows-1; m++ ) {
00921         for ( n = 1; n < m_iNoCols-1; n++ ) {
00922             // (1) (m,n)-->(m,n+1)   and (m,n)-->(m-1,n+1)
00923             m_pcParticle[m  ][n  ]->m_vtNormal[0] = 0;
00924             m_pcParticle[m  ][n  ]->m_vtNormal[1] = 0;
00925             m_pcParticle[m  ][n  ]->m_vtNormal[2] = 0;
00926             AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
00927                        m_pcParticle[m  ][n  ]->m_vtPosit,
00928                        m_pcParticle[m  ][n+1]->m_vtPosit,
00929                        m_pcParticle[m-1][n+1]->m_vtPosit );
00930             // (2) (m,n)-->(m-1,n+1) and (m,n)-->(m-1,n)
00931             AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
00932                        m_pcParticle[m  ][n  ]->m_vtPosit,
00933                        m_pcParticle[m-1][n+1]->m_vtPosit,
00934                        m_pcParticle[m-1][n  ]->m_vtPosit );
00935             // (3) (m,n)-->(m-1,n)   and (m,n)-->(m-1,n-1)
00936             AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
00937                        m_pcParticle[m  ][n  ]->m_vtPosit,
00938                        m_pcParticle[m-1][n  ]->m_vtPosit,
00939                        m_pcParticle[m-1][n-1]->m_vtPosit );
00940             // (4) (m,n)-->(m-1,n-1) and (m,n)-->(m,n-1)
00941             AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
00942                        m_pcParticle[m  ][n  ]->m_vtPosit,
00943                        m_pcParticle[m-1][n-1]->m_vtPosit,
00944                        m_pcParticle[m  ][n-1]->m_vtPosit );
00945             // (5) (m,n)-->(m,n-1)   and (m,n)-->(m+1,n-1)
00946             AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
00947                        m_pcParticle[m  ][n  ]->m_vtPosit,
00948                        m_pcParticle[m  ][n-1]->m_vtPosit,
00949                        m_pcParticle[m+1][n-1]->m_vtPosit );
00950             // (6) (m,n)-->(m+1,n-1) and (m,n)-->(m+1,n)
00951             AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
00952                        m_pcParticle[m  ][n  ]->m_vtPosit,
00953                        m_pcParticle[m+1][n-1]->m_vtPosit,
00954                        m_pcParticle[m+1][n  ]->m_vtPosit );
00955             // (7) (m,n)-->(m+1,n)   and (m,n)-->(m+1,n+1)
00956             AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
00957                        m_pcParticle[m  ][n  ]->m_vtPosit,
00958                        m_pcParticle[m+1][n  ]->m_vtPosit,
00959                        m_pcParticle[m+1][n+1]->m_vtPosit );
00960             // (8) (m,n)-->(m+1,n+1) and (m,n)-->(m,n+1)
00961             AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
00962                        m_pcParticle[m  ][n  ]->m_vtPosit,
00963                        m_pcParticle[m+1][n+1]->m_vtPosit,
00964                        m_pcParticle[m  ][n+1]->m_vtPosit );
00965             // normalize the sum result vector
00966             m_pcParticle[m][n]->m_vtNormal.Normalized();
00967         }
00968     }
00969 
00970     //-------------------------------------------------------------------------
00971     // Normals of Particles on the Top Row (Except the Cornor Particle)
00972     m = 0;
00973     for ( n = 1; n < m_iNoCols-1; n++ ) {
00974         // (5) (m,n)-->(m,n-1)   and (m,n)-->(m+1,n-1)
00975         m_pcParticle[m][n]->m_vtNormal[0] = 0;
00976         m_pcParticle[m][n]->m_vtNormal[1] = 0;
00977         m_pcParticle[m][n]->m_vtNormal[2] = 0;
00978         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
00979                    m_pcParticle[m  ][n  ]->m_vtPosit,
00980                    m_pcParticle[m  ][n-1]->m_vtPosit,
00981                    m_pcParticle[m+1][n-1]->m_vtPosit );
00982         // (6) (m,n)-->(m+1,n-1) and (m,n)-->(m+1,n)
00983         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
00984                    m_pcParticle[m  ][n  ]->m_vtPosit,
00985                    m_pcParticle[m+1][n-1]->m_vtPosit,
00986                    m_pcParticle[m+1][n  ]->m_vtPosit );
00987         // (7) (m,n)-->(m+1,n)   and (m,n)-->(m+1,n+1)
00988         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
00989                    m_pcParticle[m  ][n  ]->m_vtPosit,
00990                    m_pcParticle[m+1][n  ]->m_vtPosit,
00991                    m_pcParticle[m+1][n+1]->m_vtPosit );
00992         // (8) (m,n)-->(m+1,n+1) and (m,n)-->(m,n+1)
00993         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
00994                    m_pcParticle[m  ][n  ]->m_vtPosit,
00995                    m_pcParticle[m+1][n+1]->m_vtPosit,
00996                    m_pcParticle[m  ][n+1]->m_vtPosit );
00997         // normalize the sum result vector
00998         m_pcParticle[m][n]->m_vtNormal.Normalized();
00999     }
01000     //-------------------------------------------------------------------------
01001     // Normals of Particles on the Bottom Row (Except the Cornor Particle)
01002     m = m_iNoRows-1;
01003     for ( n = 1; n < m_iNoCols-1; n++ ) {
01004         // (1) (m,n)-->(m,n+1)   and (m,n)-->(m-1,n+1)
01005         m_pcParticle[m][n]->m_vtNormal[0] = 0;
01006         m_pcParticle[m][n]->m_vtNormal[1] = 0;
01007         m_pcParticle[m][n]->m_vtNormal[2] = 0;
01008         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01009                    m_pcParticle[m  ][n  ]->m_vtPosit,
01010                    m_pcParticle[m  ][n+1]->m_vtPosit,
01011                    m_pcParticle[m-1][n+1]->m_vtPosit );
01012         // (2) (m,n)-->(m-1,n+1) and (m,n)-->(m-1,n)
01013         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01014                    m_pcParticle[m  ][n  ]->m_vtPosit,
01015                    m_pcParticle[m-1][n+1]->m_vtPosit,
01016                    m_pcParticle[m-1][n  ]->m_vtPosit );
01017         // (3) (m,n)-->(m-1,n)   and (m,n)-->(m-1,n-1)
01018         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01019                    m_pcParticle[m  ][n  ]->m_vtPosit,
01020                    m_pcParticle[m-1][n  ]->m_vtPosit,
01021                    m_pcParticle[m-1][n-1]->m_vtPosit );
01022         // (4) (m,n)-->(m-1,n-1) and (m,n)-->(m,n-1)
01023         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01024                    m_pcParticle[m  ][n  ]->m_vtPosit,
01025                    m_pcParticle[m-1][n-1]->m_vtPosit,
01026                    m_pcParticle[m  ][n-1]->m_vtPosit );
01027         // normalize the sum result vector
01028         m_pcParticle[m][n]->m_vtNormal.Normalized();
01029     }
01030     //-------------------------------------------------------------------------
01031     // Normals of Particles on the Left Column (Except the Cornor Particle)
01032     n = 0;
01033     for ( m = 1; m < m_iNoRows-1; m++ ) {
01034         // (7) (m,n)-->(m+1,n)   and (m,n)-->(m+1,n+1)
01035         m_pcParticle[m][n]->m_vtNormal[0] = 0;
01036         m_pcParticle[m][n]->m_vtNormal[1] = 0;
01037         m_pcParticle[m][n]->m_vtNormal[2] = 0;
01038         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01039                    m_pcParticle[m  ][n  ]->m_vtPosit,
01040                    m_pcParticle[m+1][n  ]->m_vtPosit,
01041                    m_pcParticle[m+1][n+1]->m_vtPosit );
01042         // (8) (m,n)-->(m+1,n+1) and (m,n)-->(m,n+1)
01043         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01044                    m_pcParticle[m  ][n  ]->m_vtPosit,
01045                    m_pcParticle[m+1][n+1]->m_vtPosit,
01046                    m_pcParticle[m  ][n+1]->m_vtPosit );
01047         // (1) (m,n)-->(m,n+1)   and (m,n)-->(m-1,n+1)
01048         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01049                    m_pcParticle[m  ][n  ]->m_vtPosit,
01050                    m_pcParticle[m  ][n+1]->m_vtPosit,
01051                    m_pcParticle[m-1][n+1]->m_vtPosit );
01052         // (2) (m,n)-->(m-1,n+1) and (m,n)-->(m-1,n)
01053         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01054                    m_pcParticle[m  ][n  ]->m_vtPosit,
01055                    m_pcParticle[m-1][n+1]->m_vtPosit,
01056                    m_pcParticle[m-1][n  ]->m_vtPosit );
01057         // normalize the sum result vector
01058         m_pcParticle[m][n]->m_vtNormal.Normalized();
01059     }
01060     //-------------------------------------------------------------------------
01061     // Normals of Particles on the Right Row (Except the Cornor Particle)
01062     n = m_iNoCols-1;
01063     for ( m = 1; m < m_iNoRows-1; m++ ) {
01064         // (3) (m,n)-->(m-1,n)   and (m,n)-->(m-1,n-1)
01065         m_pcParticle[m][n]->m_vtNormal[0] = 0;
01066         m_pcParticle[m][n]->m_vtNormal[1] = 0;
01067         m_pcParticle[m][n]->m_vtNormal[2] = 0;
01068         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01069                    m_pcParticle[m  ][n  ]->m_vtPosit,
01070                    m_pcParticle[m-1][n  ]->m_vtPosit,
01071                    m_pcParticle[m-1][n-1]->m_vtPosit );
01072         // (4) (m,n)-->(m-1,n-1) and (m,n)-->(m,n-1)
01073         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01074                    m_pcParticle[m  ][n  ]->m_vtPosit,
01075                    m_pcParticle[m-1][n-1]->m_vtPosit,
01076                    m_pcParticle[m  ][n-1]->m_vtPosit );
01077         // (5) (m,n)-->(m,n-1)   and (m,n)-->(m+1,n-1)
01078         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01079                    m_pcParticle[m  ][n  ]->m_vtPosit,
01080                    m_pcParticle[m  ][n-1]->m_vtPosit,
01081                    m_pcParticle[m+1][n-1]->m_vtPosit );
01082         // (6) (m,n)-->(m+1,n-1) and (m,n)-->(m+1,n)
01083         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01084                    m_pcParticle[m  ][n  ]->m_vtPosit,
01085                    m_pcParticle[m+1][n-1]->m_vtPosit,
01086                    m_pcParticle[m+1][n  ]->m_vtPosit );
01087         // normalize the sum result vector
01088         m_pcParticle[m][n]->m_vtNormal.Normalized();
01089     }
01090     
01091     // Top Left Cornor ---------------------------------------------------------
01092     m = 0; n = 0;
01093         // (7) (m,n)-->(m+1,n)   and (m,n)-->(m+1,n+1)
01094         m_pcParticle[m][n]->m_vtNormal[0] = 0;
01095         m_pcParticle[m][n]->m_vtNormal[1] = 0;
01096         m_pcParticle[m][n]->m_vtNormal[2] = 0;
01097         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01098                    m_pcParticle[m  ][n  ]->m_vtPosit,
01099                    m_pcParticle[m+1][n  ]->m_vtPosit,
01100                    m_pcParticle[m+1][n+1]->m_vtPosit );
01101         // (8) (m,n)-->(m+1,n+1) and (m,n)-->(m,n+1)
01102         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01103                    m_pcParticle[m  ][n  ]->m_vtPosit,
01104                    m_pcParticle[m+1][n+1]->m_vtPosit,
01105                    m_pcParticle[m  ][n+1]->m_vtPosit );
01106         m_pcParticle[m][n]->m_vtNormal.Normalized();    // normalize the sum result vector
01107     // Bottom Left Cornor ------------------------------------------------------
01108     m = m_iNoRows-1; n = 0;
01109         // (1) (m,n)-->(m,n+1)   and (m,n)-->(m-1,n+1)
01110         m_pcParticle[m][n]->m_vtNormal[0] = 0;
01111         m_pcParticle[m][n]->m_vtNormal[1] = 0;
01112         m_pcParticle[m][n]->m_vtNormal[2] = 0;
01113         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01114                    m_pcParticle[m  ][n  ]->m_vtPosit,
01115                    m_pcParticle[m  ][n+1]->m_vtPosit,
01116                    m_pcParticle[m-1][n+1]->m_vtPosit );
01117         // (2) (m,n)-->(m-1,n+1) and (m,n)-->(m-1,n)
01118         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01119                    m_pcParticle[m  ][n  ]->m_vtPosit,
01120                    m_pcParticle[m-1][n+1]->m_vtPosit,
01121                    m_pcParticle[m-1][n  ]->m_vtPosit );
01122         m_pcParticle[m][n]->m_vtNormal.Normalized();    // normalize the sum result vector
01123     // Bottom Right Cornor -----------------------------------------------------
01124     m = m_iNoRows-1; n = m_iNoCols-1;
01125         // (3) (m,n)-->(m-1,n)   and (m,n)-->(m-1,n-1)
01126         m_pcParticle[m][n]->m_vtNormal[0] = 0;
01127         m_pcParticle[m][n]->m_vtNormal[1] = 0;
01128         m_pcParticle[m][n]->m_vtNormal[2] = 0;
01129         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01130                    m_pcParticle[m  ][n  ]->m_vtPosit,
01131                    m_pcParticle[m-1][n  ]->m_vtPosit,
01132                    m_pcParticle[m-1][n-1]->m_vtPosit );
01133         // (4) (m,n)-->(m-1,n-1) and (m,n)-->(m,n-1)
01134         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01135                    m_pcParticle[m  ][n  ]->m_vtPosit,
01136                    m_pcParticle[m-1][n-1]->m_vtPosit,
01137                    m_pcParticle[m  ][n-1]->m_vtPosit );
01138         m_pcParticle[m][n]->m_vtNormal.Normalized();    // normalize the sum result vector
01139     // Top Right Cornor --------------------------------------------------------
01140     m = 0; n = m_iNoCols-1;
01141         // (5) (m,n)-->(m,n-1)   and (m,n)-->(m+1,n-1)
01142         m_pcParticle[m][n]->m_vtNormal[0] = 0;
01143         m_pcParticle[m][n]->m_vtNormal[1] = 0;
01144         m_pcParticle[m][n]->m_vtNormal[2] = 0;
01145         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01146                    m_pcParticle[m  ][n  ]->m_vtPosit,
01147                    m_pcParticle[m  ][n-1]->m_vtPosit,
01148                    m_pcParticle[m+1][n-1]->m_vtPosit );
01149         // (6) (m,n)-->(m+1,n-1) and (m,n)-->(m+1,n)
01150         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01151                    m_pcParticle[m  ][n  ]->m_vtPosit,
01152                    m_pcParticle[m+1][n-1]->m_vtPosit,
01153                    m_pcParticle[m+1][n  ]->m_vtPosit );
01154         m_pcParticle[m][n]->m_vtNormal.Normalized();    // normalize the sum result vector
01155 }
01156 /*
01157 //-------------------------------------------------------------------------------------------------
01158 // Clear Force of Particles to Zeros
01159 template <typename T>
01160 void DeformMesh<T>::ClearForce()
01161 {
01162     T x = 0, y = 0, z = 0;
01163     for ( m = 0; m < m_iNoRows; m++ ) {
01164         for ( n = 0; n < m_iNoCols; n++ ) {
01165             m_pcParticle[m][n]->m_vtForce( x, y, z );
01166         }
01167     }
01168 }
01169 //-------------------------------------------------------------------------------------------------
01170 // Calculate (Weight) Force due to (Acceleration of) Gravity
01171 template <typename T>
01172 void DeformMesh<T>::ForceDueToGravity( T g )
01173 {
01174     
01175 }
01176 //-------------------------------------------------------------------------------------------------
01177 // Calculate (a Loss) Force due to Viscous Damping
01178 template <typename T>
01179 void DeformMesh<T>::ForceDueToViscousDamping()
01180 {
01181 }
01182 //-------------------------------------------------------------------------------------------------
01183 // Calculate (Wind) Force due to Viscous Fluid Moving
01184 template <typename T>
01185 void DeformMesh<T>::ForceDueToViscousFluidMoving()
01186 {
01187 }
01188 */
01189 //-------------------------------------------------------------------------------------------------
01190 // Display Via OpenGL
01191 template <typename T>
01192 void DeformMesh<T>::DisplayGL( OpenGL::Enum::DrawMode DM )
01193 {
01194     //int ptSize[1];
01195     glColor3f( 1.0f, 1.0f, 1.0f );
01196 
01197     DeformUpdate();
01198     /*
01199     for ( count = 0; count < 8; count++ ) {
01200         StepSimulation( 0.0005 );
01201     }
01202     */
01203 
01204     glPushAttrib( GL_ALL_ATTRIB_BITS );
01205 
01206     //SetMaterial( OpenGL::Enum::METAL_GOLD );
01207     //SetMaterial( OpenGL::Enum::METAL_SILVER );
01208     //SetMaterial( OpenGL::Enum::METAL_BRONZE );
01209     SetMaterial( OpenGL::Enum::RED_01 );
01210     ApplyMaterial( OpenGL::Enum::FRONT );
01211     SetMaterial( OpenGL::Enum::METAL_GOLD );
01212     material.ApplyMaterial( OpenGL::Enum::BACK );
01213     
01214     switch (DM) {
01215         // Draw Points for DeformMesh
01216         case OpenGL::Enum::POINT:
01217             // Set Point Size
01218             //glGetIntegerv( GL_POINT_SIZE, ptSize );
01219             //glPointSize( 2 );
01220             glBegin( GL_POINTS );
01221             for ( m = 0; m < m_iNoRows; m++ ) {
01222                 for ( n = 0; n < m_iNoCols; n++ ) {
01223                     glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 
01224                                 m_pcParticle[m][n]->m_vtPosit[1],
01225                                 m_pcParticle[m][n]->m_vtPosit[2] );
01226                 }
01227             }
01228             glEnd();
01229 
01230             //-------------------------------------------
01231             // Display Starting Points
01232             glDisable( GL_LIGHTING );
01233             glColor3f( 0.0f, 1.0f, 0.0f );
01234             glPointSize( 7 );
01235             m = 0; n = 0;
01236             glBegin( GL_POINTS );
01237                 glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 
01238                             m_pcParticle[m][n]->m_vtPosit[1],
01239                             m_pcParticle[m][n]->m_vtPosit[2] );
01240             glEnd();
01241             glColor3f( 0.0f, 1.0f, 1.0f );
01242             glPointSize( 5 );
01243             m = 0; n = 1;
01244             glBegin( GL_POINTS );
01245                 glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 
01246                             m_pcParticle[m][n]->m_vtPosit[1],
01247                             m_pcParticle[m][n]->m_vtPosit[2] );
01248             glEnd();
01249             glPointSize( 1 );
01250             glEnable( GL_LIGHTING );
01251             //-------------------------------------------
01252 
01253             // Restore Point Size
01254             //glPointSize( ptSize[0] );
01255             break;
01256 
01257         // Draw Wire Frame for DeformMesh
01258         case OpenGL::Enum::WIRE_FRAME:
01259             // Draw Row Lines
01260             for ( m = 0; m < m_iNoRows; m++ ) {
01261                 glBegin( GL_LINE_STRIP );
01262                 for ( n = 0; n < m_iNoCols; n++ ) {
01263                     glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 
01264                                 m_pcParticle[m][n]->m_vtPosit[1],
01265                                 m_pcParticle[m][n]->m_vtPosit[2] );
01266                 }
01267                 glEnd();
01268             }
01269             // Draw Column Lines
01270             for ( n = 0; n < m_iNoCols; n++ ) {
01271                 glBegin( GL_LINE_STRIP );
01272                 for ( m = 0; m < m_iNoRows; m++ ) {
01273                     glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 
01274                                 m_pcParticle[m][n]->m_vtPosit[1],
01275                                 m_pcParticle[m][n]->m_vtPosit[2] );
01276                 }
01277                 glEnd();
01278             }
01279 
01280             /*
01281             //-------------------------------------------
01282             // Display Starting Points
01283             glDisable( GL_LIGHTING );
01284             glColor3f( 0.0f, 1.0f, 0.0f );
01285             glPointSize( 7 );
01286             m = 0; n = 0;
01287             glBegin( GL_POINTS );
01288                 glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 
01289                             m_pcParticle[m][n]->m_vtPosit[1],
01290                             m_pcParticle[m][n]->m_vtPosit[2] );
01291             glEnd();
01292             glColor3f( 0.0f, 1.0f, 1.0f );
01293             glPointSize( 5 );
01294             m = 0; n = 1;
01295             glBegin( GL_POINTS );
01296                 glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 
01297                             m_pcParticle[m][n]->m_vtPosit[1],
01298                             m_pcParticle[m][n]->m_vtPosit[2] );
01299             glEnd();
01300             glPointSize( 1 );
01301             glEnable( GL_LIGHTING );
01302             //-------------------------------------------
01303             //*/
01304 
01305             /*
01306             // Draw Diagonal Lines
01307             glBegin( GL_LINES );
01308             for ( m = 0; m < m_iNoRows-1; m++ ) {
01309                 for ( n = 0; n < m_iNoCols-1; n++ ) {
01310                     // Draw a line from [m][n] --- [m+1][n+1]
01311                     glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 
01312                                 m_pcParticle[m][n]->m_vtPosit[1],
01313                                 m_pcParticle[m][n]->m_vtPosit[2] );
01314                     glVertex3f( m_pcParticle[m+1][n+1]->m_vtPosit[0], 
01315                                 m_pcParticle[m+1][n+1]->m_vtPosit[1],
01316                                 m_pcParticle[m+1][n+1]->m_vtPosit[2] );
01317                     // Draw a line from [m+1][n] to [m][n+1]
01318                     glVertex3f( m_pcParticle[m+1][n]->m_vtPosit[0], 
01319                                 m_pcParticle[m+1][n]->m_vtPosit[1],
01320                                 m_pcParticle[m+1][n]->m_vtPosit[2] );
01321                     glVertex3f( m_pcParticle[m][n+1]->m_vtPosit[0], 
01322                                 m_pcParticle[m][n+1]->m_vtPosit[1],
01323                                 m_pcParticle[m][n+1]->m_vtPosit[2] );
01324                 }
01325             }
01326             glEnd();
01327             //*/
01328             break;
01329 
01330         // Draw Polygons for DeformMesh
01331         case OpenGL::Enum::POLYGON:
01332             // With Texture
01333             if ( m_pcImg != NULL ) {
01334 
01335                 DrawTexture();
01336 
01337                 float tr, tc;
01338                 float trStep = 1.0 / (m_iNoRows-1);
01339                 float tcStep = 1.0 / (m_iNoCols-1);
01340                 for ( m = 0, tr = 1.0; m < m_iNoRows-1; m++, tr -= trStep ) {
01341                     glBegin( GL_QUAD_STRIP );
01342                     for ( n = 0, tc = 0.0; n < m_iNoCols; n++, tc += tcStep ) {
01343                         glNormal3f( m_pcParticle[m][n]->m_vtNormal[0], 
01344                                     m_pcParticle[m][n]->m_vtNormal[1],
01345                                     m_pcParticle[m][n]->m_vtNormal[2] );
01346                         glTexCoord2f(tc, tr);
01347                         glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 
01348                                     m_pcParticle[m][n]->m_vtPosit[1],
01349                                     m_pcParticle[m][n]->m_vtPosit[2] );
01350 
01351                         glNormal3f( m_pcParticle[m+1][n]->m_vtNormal[0], 
01352                                     m_pcParticle[m+1][n]->m_vtNormal[1],
01353                                     m_pcParticle[m+1][n]->m_vtNormal[2] );
01354                         glTexCoord2f(tc, tr-trStep);
01355                         glVertex3f( m_pcParticle[m+1][n]->m_vtPosit[0], 
01356                                     m_pcParticle[m+1][n]->m_vtPosit[1],
01357                                     m_pcParticle[m+1][n]->m_vtPosit[2] );
01358                     }
01359                     glEnd();
01360                 }
01361                 //glBindTexture( GL_TEXTURE_2D, 0 );
01362             }
01363             // Without Texture
01364             else {
01365                 for ( m = 0; m < m_iNoRows-1; m++ ) {
01366                     glBegin( GL_QUAD_STRIP );
01367                     for ( n = 0; n < m_iNoCols; n++ ) {
01368                         glNormal3f( m_pcParticle[m][n]->m_vtNormal[0], 
01369                                     m_pcParticle[m][n]->m_vtNormal[1],
01370                                     m_pcParticle[m][n]->m_vtNormal[2] );
01371                         glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 
01372                                     m_pcParticle[m][n]->m_vtPosit[1],
01373                                     m_pcParticle[m][n]->m_vtPosit[2] );
01374 
01375                         glNormal3f( m_pcParticle[m+1][n]->m_vtNormal[0], 
01376                                     m_pcParticle[m+1][n]->m_vtNormal[1],
01377                                     m_pcParticle[m+1][n]->m_vtNormal[2] );
01378                         glVertex3f( m_pcParticle[m+1][n]->m_vtPosit[0], 
01379                                     m_pcParticle[m+1][n]->m_vtPosit[1],
01380                                     m_pcParticle[m+1][n]->m_vtPosit[2] );
01381                     }
01382                     glEnd();
01383                 }
01384             }
01385             break;
01386     }
01387 
01388     // DEBUG
01389     //DisplayGL_ParticleNormals();
01390 
01391     /*
01392     //-------------------------------------------
01393     // Display Starting Points
01394     glDisable( GL_LIGHTING );
01395     glColor3f( 0.0f, 1.0f, 0.0f );
01396     glPointSize( 7 );
01397     m = 0; n = 0;
01398     glBegin( GL_POINTS );
01399         glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 
01400                     m_pcParticle[m][n]->m_vtPosit[1],
01401                     m_pcParticle[m][n]->m_vtPosit[2] );
01402     glEnd();
01403     glColor3f( 0.0f, 1.0f, 1.0f );
01404     glPointSize( 5 );
01405     m = 0; n = 1;
01406     glBegin( GL_POINTS );
01407         glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 
01408                     m_pcParticle[m][n]->m_vtPosit[1],
01409                     m_pcParticle[m][n]->m_vtPosit[2] );
01410     glEnd();
01411     glPointSize( 1 );
01412     glEnable( GL_LIGHTING );
01413     //-------------------------------------------
01414     //*/
01415 
01416     glPopAttrib();
01417     // END TEST
01418 }
01419 //-------------------------------------------------------------------------------------------------
01420 // Display Particle Normals Via OpenGL
01421 template <typename T>
01422 void DeformMesh<T>::DisplayGL_ParticleNormals()
01423 {
01424     T x, y, z;
01425 
01426     // Draw Normal of each particle
01427     glDisable( GL_LIGHTING );
01428     glColor3f( 1.0f, 0.0f, 0.0f );
01429     glBegin( GL_LINES );
01430     for ( m = 0; m < m_iNoRows; m++ ) {
01431         for ( n = 0; n < m_iNoCols; n++ ) {
01432             m_pcParticle[m][n]->m_vtPosit.GetXYZ( x, y, z );
01433             glVertex3f( x, y, z );
01434             glVertex3f( x + m_pcParticle[m][n]->m_vtNormal[0], 
01435                         y + m_pcParticle[m][n]->m_vtNormal[1],
01436                         z + m_pcParticle[m][n]->m_vtNormal[2] );
01437         }
01438     }
01439     glEnd();
01440     glEnable( GL_LIGHTING );
01441 }
01442 //================================================================================================
01443 // FRIEND FUNCTIONS
01444 //-------------------------------------------------------------------------------------------------
01445 // put it through ostream
01446 /*template <typename T>
01447 ostream &operator<<( ostream &output, const DeformMesh<T> &Obj )
01448 {
01449     output  << "DeformMesh ==> "
01450             << "\n  number of rows:       " << Obj.m_iNoRows
01451             << "\n  number of columns:    " << Obj.m_iNoCols
01452             << "\n  viscous damping:      " << Obj.m_tKvd
01453             << "\n  wind damping:         " << Obj.m_tKvfm
01454             << "\n  stiffness of structural, shear, and flexion springs: " 
01455                     << Obj.m_tKs[0] << ", " << Obj.m_tKs[1] << ", and " << Obj.m_tKs[2]
01456             << "\n  damping constant for structural, shear, and flexion springs: "
01457                     << Obj.m_tKd[0] << ", " << Obj.m_tKd[1] << ", and " << Obj.m_tKd[2]
01458             << "\n  length constrain for structural, shear, and flextion springs: "
01459                     << Obj.m_tLengthConstrain[0] << ", " 
01460                     << Obj.m_tLengthConstrain[1] << ", and " 
01461                     << Obj.m_tLengthConstrain[2]
01462             << "\n";
01463 
01464     return output;
01465 }*/
01466 
01467 template <typename T>
01468 void DeformMesh<T>::AddNormal( Vector3<T> & Dest, 
01469                        Vector3<T> const & A, Vector3<T> const & B, Vector3<T> const & C )
01470 {
01471     T U[3] = { A[0]-B[0], A[1]-B[1], A[2]-B[2] };
01472     T V[3] = { A[0]-C[0], A[1]-C[1], A[2]-C[2] };
01473     T W[3] = { U[1]*V[2] - U[2]*V[1], U[2]*V[0] - U[0]*V[2], U[0]*V[1] - U[1]*V[0] };
01474     T SqrtLength = Math<T>::Sqrt( W[0]*W[0] + W[1]*W[1] + W[2]*W[2] );
01475     Dest[0] += W[0]/SqrtLength;
01476     Dest[1] += W[1]/SqrtLength;
01477     Dest[2] += W[2]/SqrtLength;
01478 }
01479 //MEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBER
01480 
01481 //=============================================================================
01482 END_NAMESPACE_TAPs
01483 //-----------------------------------------------------------------------------
01484 #endif
01485 //345678901234567890123456789012345678901234567890123456789012345678901234567890
01486 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines