TAPs 0.7.7.3
TAPsDeformMeshWithCut.hpp
Go to the documentation of this file.
00001 /******************************************************************************
00002 TAPsDeformMeshWithCut.hpp
00003 
00004 DeformMeshWithCut 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_WITH_CUT_HPP
00039 #define TAPs_DEFORM_MESH_WITH_CUT_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 DeformMeshWithCut : public /*virtual*/ OpenGL::OpenGLSupport {
00049 //=============================================================================
00050     //-------------------------------------------------------------------------
00051     // put it through ostream
00052     friend std::ostream &operator<<( std::ostream &output, const DeformMeshWithCut<T> &Obj )
00053     {
00054         output  << "DeformMeshWithCut ==> "
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     DeformMeshWithCut(    
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     ~DeformMeshWithCut();                           // 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         int iHalfNoCols = m_iNoCols / 2;
00182         for ( m = 1; m < m_iNoRows-1; ++m ) {
00183             for ( n = 1; n < m_iNoCols-1; ++n ) {       // Full plane
00184             //for ( n = 1; n < iHalfNoCols-1; ++n ) {       // Half plane
00185                 if ( m_pcParticle[m][n]->GetFixStatus() )   continue;
00186                 //-------------------------------
00187                 // Get neighbors' positions
00188                 nWest   = m_pcParticle[m][n-1]->GetPosition();
00189                 nEast   = m_pcParticle[m][n+1]->GetPosition();
00190                 nSouth  = m_pcParticle[m-1][n]->GetPosition();
00191                 nNorth  = m_pcParticle[m+1][n]->GetPosition();
00192                 //-------------------------------
00193                 nNorthWest  = m_pcParticle[m+1][n-1]->GetPosition();
00194                 nNorthEast  = m_pcParticle[m+1][n+1]->GetPosition();
00195                 nSouthWest  = m_pcParticle[m-1][n-1]->GetPosition();
00196                 nSouthEast  = m_pcParticle[m-1][n+1]->GetPosition();
00197                 //-------------------------------
00198                 //neighborsAvg = (nWest + nEast + nSouth + nNorth ) / 4.0;
00199                 neighborsAvg = (nWest + nEast + nSouth + nNorth + nNorthWest + nNorthEast + nSouthWest + nSouthEast) / 8.0;
00200                 m_pcParticle[m][n]->GetPosition().GetXYZ( x, y, z );
00201                 m_pcParticle[m][n]->GetVelocity().GetXYZ( vx, vy, vz );
00202 
00203                 //m_pcParticle[m][n]->SetPosition( m_pcParticle[m][n]->GetPosition() + Vector3<T>(0.01,0.01,0.01) );
00204                 ax = 0.1 * ( 
00205                             freq1 * (neighborsAvg.GetX() - x) / m_pcParticle[m][n]->GetMass()
00206                             + freq2 * (neighborsAvg.GetX()*neighborsAvg.GetX() - x*x) 
00207                           //+ freq2 * (n * 1.0/*size/meshSize = 1.0*/ - x) // Not working for 3D
00208                           - damp * vx
00209                 );
00210                 ay = 0.1 * ( 
00211                             freq1 * (neighborsAvg.GetY() - y) / m_pcParticle[m][n]->GetMass()
00212                             + freq2 * (neighborsAvg.GetY()*neighborsAvg.GetY() - y*y) 
00213                           //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - y) // Not working for 3D
00214                           - damp * vy
00215                 );
00216                 az = 0.1 * ( 
00217                             freq1 * (neighborsAvg.GetZ() - z) / m_pcParticle[m][n]->GetMass()
00218                             + freq2 * (neighborsAvg.GetZ()*neighborsAvg.GetZ() - z*z) 
00219                           //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - z) // Not working for 3D
00220                           - damp * vz
00221                 );
00222                 vx += ax;
00223                 vy += ay;
00224                 vz += az;
00225                 m_pcParticle[m][n]->SetVelocity( vx, vy, vz );
00226                 x += vx;
00227                 y += vy;
00228                 z += vz;
00229                 m_pcParticle[m][n]->SetPosition( x, y, z );
00230             }
00231             /*
00232             for ( n = iHalfNoCols+2; n < m_iNoRows-1; ++n ) {
00233                 if ( m_pcParticle[m][n]->GetFixStatus() )   continue;
00234                 //-------------------------------
00235                 // Get neighbors' positions
00236                 nWest   = m_pcParticle[m][n-1]->GetPosition();
00237                 nEast   = m_pcParticle[m][n+1]->GetPosition();
00238                 nSouth  = m_pcParticle[m-1][n]->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                 nSouthWest  = m_pcParticle[m-1][n-1]->GetPosition();
00244                 nSouthEast  = m_pcParticle[m-1][n+1]->GetPosition();
00245                 //-------------------------------
00246                 //neighborsAvg = (nWest + nEast + nSouth + nNorth ) / 4.0;
00247                 neighborsAvg = (nWest + nEast + nSouth + nNorth + nNorthWest + nNorthEast + nSouthWest + nSouthEast) / 8.0;
00248                 m_pcParticle[m][n]->GetPosition().GetXYZ( x, y, z );
00249                 m_pcParticle[m][n]->GetVelocity().GetXYZ( vx, vy, vz );
00250 
00251                 //m_pcParticle[m][n]->SetPosition( m_pcParticle[m][n]->GetPosition() + Vector3<T>(0.01,0.01,0.01) );
00252                 ax = 0.1 * ( 
00253                             freq1 * (neighborsAvg.GetX() - x) / m_pcParticle[m][n]->GetMass()
00254                             + freq2 * (neighborsAvg.GetX()*neighborsAvg.GetX() - x*x) 
00255                           - damp * vx
00256                 );
00257                 ay = 0.1 * ( 
00258                             freq1 * (neighborsAvg.GetY() - y) / m_pcParticle[m][n]->GetMass()
00259                             + freq2 * (neighborsAvg.GetY()*neighborsAvg.GetY() - y*y) 
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                           - damp * vz
00266                 );
00267                 vx += ax;
00268                 vy += ay;
00269                 vz += az;
00270                 m_pcParticle[m][n]->SetVelocity( vx, vy, vz );
00271                 x += vx;
00272                 y += vy;
00273                 z += vz;
00274                 m_pcParticle[m][n]->SetPosition( x, y, z );
00275             }
00276             //*/
00277         }
00278 
00279 
00280 
00283         //{ m = 0;
00284         //  for ( n = 1; n < m_iNoCols-1; ++n ) {
00285         //      if ( m_pcParticle[m][n]->GetFixStatus() )   continue;
00286         //      //-------------------------------
00287         //      // Get neighbors' positions
00288         //      nWest   = m_pcParticle[m][n-1]->GetPosition();
00289         //      nEast   = m_pcParticle[m][n+1]->GetPosition();
00290         //      nNorth  = m_pcParticle[m+1][n]->GetPosition();
00291         //      //-------------------------------
00292         //      nNorthWest  = m_pcParticle[m+1][n-1]->GetPosition();
00293         //      nNorthEast  = m_pcParticle[m+1][n+1]->GetPosition();
00294         //      //-------------------------------
00295         //      //neighborsAvg = (nWest + nEast + nSouth + nNorth ) / 4.0;
00296         //      neighborsAvg = (nWest + nEast + nNorth + nNorthWest + nNorthEast) / 5.0;
00297         //      m_pcParticle[m][n]->GetPosition().GetXYZ( x, y, z );
00298         //      m_pcParticle[m][n]->GetVelocity().GetXYZ( vx, vy, vz );
00299 
00300         //      //m_pcParticle[m][n]->SetPosition( m_pcParticle[m][n]->GetPosition() + Vector3<T>(0.01,0.01,0.01) );
00301         //      ax = 0.1 * ( 
00302         //                  freq1 * (neighborsAvg.GetX() - x) / m_pcParticle[m][n]->GetMass()
00303         //                  + freq2 * (neighborsAvg.GetX()*neighborsAvg.GetX() - x*x) 
00304         //                //+ freq2 * (n * 1.0/*size/meshSize = 1.0*/ - x) // Not working for 3D
00305         //                - damp * vx
00306         //      );
00307         //      ay = 0.1 * ( 
00308         //                  freq1 * (neighborsAvg.GetY() - y) / m_pcParticle[m][n]->GetMass()
00309         //                  + freq2 * (neighborsAvg.GetY()*neighborsAvg.GetY() - y*y) 
00310         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - y) // Not working for 3D
00311         //                - damp * vy
00312         //      );
00313         //      az = 0.1 * ( 
00314         //                  freq1 * (neighborsAvg.GetZ() - z) / m_pcParticle[m][n]->GetMass()
00315         //                  + freq2 * (neighborsAvg.GetZ()*neighborsAvg.GetZ() - z*z) 
00316         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - z) // Not working for 3D
00317         //                - damp * vz
00318         //      );
00319         //      vx += ax;
00320         //      vy += ay;
00321         //      vz += az;
00322         //      m_pcParticle[m][n]->SetVelocity( vx, vy, vz );
00323         //      x += vx;
00324         //      y += vy;
00325         //      z += vz;
00326         //      m_pcParticle[m][n]->SetPosition( x, y, z );
00327         //  }
00328         //}
00331         //{ m = m_iNoRows-1;
00332         //  for ( n = 1; n < m_iNoCols-1; ++n ) {
00333         //      if ( m_pcParticle[m][n]->GetFixStatus() )   continue;
00334         //      //-------------------------------
00335         //      // Get neighbors' positions
00336         //      nWest   = m_pcParticle[m][n-1]->GetPosition();
00337         //      nEast   = m_pcParticle[m][n+1]->GetPosition();
00338         //      nSouth  = m_pcParticle[m-1][n]->GetPosition();
00339         //      //-------------------------------
00340         //      nSouthWest  = m_pcParticle[m-1][n-1]->GetPosition();
00341         //      nSouthEast  = m_pcParticle[m-1][n+1]->GetPosition();
00342         //      //-------------------------------
00343         //      //neighborsAvg = (nWest + nEast + nSouth + nNorth ) / 4.0;
00344         //      neighborsAvg = (nWest + nEast + nSouth + nSouthWest + nSouthEast) / 5.0;
00345         //      m_pcParticle[m][n]->GetPosition().GetXYZ( x, y, z );
00346         //      m_pcParticle[m][n]->GetVelocity().GetXYZ( vx, vy, vz );
00347 
00348         //      //m_pcParticle[m][n]->SetPosition( m_pcParticle[m][n]->GetPosition() + Vector3<T>(0.01,0.01,0.01) );
00349         //      ax = 0.1 * ( 
00350         //                  freq1 * (neighborsAvg.GetX() - x) / m_pcParticle[m][n]->GetMass()
00351         //                  + freq2 * (neighborsAvg.GetX()*neighborsAvg.GetX() - x*x) 
00352         //                //+ freq2 * (n * 1.0/*size/meshSize = 1.0*/ - x) // Not working for 3D
00353         //                - damp * vx
00354         //      );
00355         //      ay = 0.1 * ( 
00356         //                  freq1 * (neighborsAvg.GetY() - y) / m_pcParticle[m][n]->GetMass()
00357         //                  + freq2 * (neighborsAvg.GetY()*neighborsAvg.GetY() - y*y) 
00358         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - y) // Not working for 3D
00359         //                - damp * vy
00360         //      );
00361         //      az = 0.1 * ( 
00362         //                  freq1 * (neighborsAvg.GetZ() - z) / m_pcParticle[m][n]->GetMass()
00363         //                  + freq2 * (neighborsAvg.GetZ()*neighborsAvg.GetZ() - z*z) 
00364         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - z) // Not working for 3D
00365         //                - damp * vz
00366         //      );
00367         //      vx += ax;
00368         //      vy += ay;
00369         //      vz += az;
00370         //      m_pcParticle[m][n]->SetVelocity( vx, vy, vz );
00371         //      x += vx;
00372         //      y += vy;
00373         //      z += vz;
00374         //      m_pcParticle[m][n]->SetPosition( x, y, z );
00375         //  }
00376         //}
00379         //{ n = 0;
00380         //  for ( m = 1; m < m_iNoRows-1; ++m ) {
00381         //      if ( m_pcParticle[m][n]->GetFixStatus() )   continue;
00382         //      //-------------------------------
00383         //      // Get neighbors' positions
00384         //      nEast   = m_pcParticle[m][n+1]->GetPosition();
00385         //      nSouth  = m_pcParticle[m-1][n]->GetPosition();
00386         //      nNorth  = m_pcParticle[m+1][n]->GetPosition();
00387         //      //-------------------------------
00388         //      nNorthEast  = m_pcParticle[m+1][n+1]->GetPosition();
00389         //      nSouthEast  = m_pcParticle[m-1][n+1]->GetPosition();
00390         //      //-------------------------------
00391         //      //neighborsAvg = (nWest + nEast + nSouth + nNorth ) / 4.0;
00392         //      neighborsAvg = (nEast + nSouth + nNorth + nNorthEast + nSouthEast) / 5.0;
00393         //      m_pcParticle[m][n]->GetPosition().GetXYZ( x, y, z );
00394         //      m_pcParticle[m][n]->GetVelocity().GetXYZ( vx, vy, vz );
00395 
00396         //      //m_pcParticle[m][n]->SetPosition( m_pcParticle[m][n]->GetPosition() + Vector3<T>(0.01,0.01,0.01) );
00397         //      ax = 0.1 * ( 
00398         //                  freq1 * (neighborsAvg.GetX() - x) / m_pcParticle[m][n]->GetMass()
00399         //                  + freq2 * (neighborsAvg.GetX()*neighborsAvg.GetX() - x*x) 
00400         //                //+ freq2 * (n * 1.0/*size/meshSize = 1.0*/ - x) // Not working for 3D
00401         //                - damp * vx
00402         //      );
00403         //      ay = 0.1 * ( 
00404         //                  freq1 * (neighborsAvg.GetY() - y) / m_pcParticle[m][n]->GetMass()
00405         //                  + freq2 * (neighborsAvg.GetY()*neighborsAvg.GetY() - y*y) 
00406         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - y) // Not working for 3D
00407         //                - damp * vy
00408         //      );
00409         //      az = 0.1 * ( 
00410         //                  freq1 * (neighborsAvg.GetZ() - z) / m_pcParticle[m][n]->GetMass()
00411         //                  + freq2 * (neighborsAvg.GetZ()*neighborsAvg.GetZ() - z*z) 
00412         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - z) // Not working for 3D
00413         //                - damp * vz
00414         //      );
00415         //      vx += ax;
00416         //      vy += ay;
00417         //      vz += az;
00418         //      m_pcParticle[m][n]->SetVelocity( vx, vy, vz );
00419         //      x += vx;
00420         //      y += vy;
00421         //      z += vz;
00422         //      m_pcParticle[m][n]->SetPosition( x, y, z );
00423         //  }
00424         //}
00427         //{ n = m_iNoCols-1;
00428         //  for ( m = 1; m < m_iNoRows-1; ++m ) {
00429         //      if ( m_pcParticle[m][n]->GetFixStatus() )   continue;
00430         //      //-------------------------------
00431         //      // Get neighbors' positions
00432         //      nWest   = m_pcParticle[m][n-1]->GetPosition();
00433         //      nSouth  = m_pcParticle[m-1][n]->GetPosition();
00434         //      nNorth  = m_pcParticle[m+1][n]->GetPosition();
00435         //      //-------------------------------
00436         //      nNorthWest  = m_pcParticle[m+1][n-1]->GetPosition();
00437         //      nSouthWest  = m_pcParticle[m-1][n-1]->GetPosition();
00438         //      //-------------------------------
00439         //      //neighborsAvg = (nWest + nEast + nSouth + nNorth ) / 4.0;
00440         //      neighborsAvg = (nWest + nSouth + nNorth + nNorthWest + nSouthWest) / 5.0;
00441         //      m_pcParticle[m][n]->GetPosition().GetXYZ( x, y, z );
00442         //      m_pcParticle[m][n]->GetVelocity().GetXYZ( vx, vy, vz );
00443 
00444         //      //m_pcParticle[m][n]->SetPosition( m_pcParticle[m][n]->GetPosition() + Vector3<T>(0.01,0.01,0.01) );
00445         //      ax = 0.1 * ( 
00446         //                  freq1 * (neighborsAvg.GetX() - x) / m_pcParticle[m][n]->GetMass()
00447         //                  + freq2 * (neighborsAvg.GetX()*neighborsAvg.GetX() - x*x) 
00448         //                //+ freq2 * (n * 1.0/*size/meshSize = 1.0*/ - x) // Not working for 3D
00449         //                - damp * vx
00450         //      );
00451         //      ay = 0.1 * ( 
00452         //                  freq1 * (neighborsAvg.GetY() - y) / m_pcParticle[m][n]->GetMass()
00453         //                  + freq2 * (neighborsAvg.GetY()*neighborsAvg.GetY() - y*y) 
00454         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - y) // Not working for 3D
00455         //                - damp * vy
00456         //      );
00457         //      az = 0.1 * ( 
00458         //                  freq1 * (neighborsAvg.GetZ() - z) / m_pcParticle[m][n]->GetMass()
00459         //                  + freq2 * (neighborsAvg.GetZ()*neighborsAvg.GetZ() - z*z) 
00460         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - z) // Not working for 3D
00461         //                - damp * vz
00462         //      );
00463         //      vx += ax;
00464         //      vy += ay;
00465         //      vz += az;
00466         //      m_pcParticle[m][n]->SetVelocity( vx, vy, vz );
00467         //      x += vx;
00468         //      y += vy;
00469         //      z += vz;
00470         //      m_pcParticle[m][n]->SetPosition( x, y, z );
00471         //  }
00472         //}
00475         //{ m = 0;
00476         //  n = 0;
00477         //  if ( !m_pcParticle[m][n]->GetFixStatus() ) {
00478         //      //-------------------------------
00479         //      // Get neighbors' positions
00480         //      nEast   = m_pcParticle[m][n+1]->GetPosition();
00481         //      nNorth  = m_pcParticle[m+1][n]->GetPosition();
00482         //      //-------------------------------
00483         //      nNorthEast  = m_pcParticle[m+1][n+1]->GetPosition();
00484         //      //-------------------------------
00485         //      //neighborsAvg = (nWest + nEast + nSouth + nNorth ) / 4.0;
00486         //      neighborsAvg = (nEast + nNorth + nNorthEast) / 3.0;
00487         //      m_pcParticle[m][n]->GetPosition().GetXYZ( x, y, z );
00488         //      m_pcParticle[m][n]->GetVelocity().GetXYZ( vx, vy, vz );
00489 
00490         //      //m_pcParticle[m][n]->SetPosition( m_pcParticle[m][n]->GetPosition() + Vector3<T>(0.01,0.01,0.01) );
00491         //      ax = 0.1 * ( 
00492         //                  freq1 * (neighborsAvg.GetX() - x) / m_pcParticle[m][n]->GetMass()
00493         //                  + freq2 * (neighborsAvg.GetX()*neighborsAvg.GetX() - x*x) 
00494         //                //+ freq2 * (n * 1.0/*size/meshSize = 1.0*/ - x) // Not working for 3D
00495         //                - damp * vx
00496         //      );
00497         //      ay = 0.1 * ( 
00498         //                  freq1 * (neighborsAvg.GetY() - y) / m_pcParticle[m][n]->GetMass()
00499         //                  + freq2 * (neighborsAvg.GetY()*neighborsAvg.GetY() - y*y) 
00500         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - y) // Not working for 3D
00501         //                - damp * vy
00502         //      );
00503         //      az = 0.1 * ( 
00504         //                  freq1 * (neighborsAvg.GetZ() - z) / m_pcParticle[m][n]->GetMass()
00505         //                  + freq2 * (neighborsAvg.GetZ()*neighborsAvg.GetZ() - z*z) 
00506         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - z) // Not working for 3D
00507         //                - damp * vz
00508         //      );
00509         //      vx += ax;
00510         //      vy += ay;
00511         //      vz += az;
00512         //      m_pcParticle[m][n]->SetVelocity( vx, vy, vz );
00513         //      x += vx;
00514         //      y += vy;
00515         //      z += vz;
00516         //      m_pcParticle[m][n]->SetPosition( x, y, z );
00517         //  }
00518         //}
00521         //{ m = 0;
00522         //  n = m_iNoCols-1;
00523         //  if ( !m_pcParticle[m][n]->GetFixStatus() ) {
00524         //      //-------------------------------
00525         //      // Get neighbors' positions
00526         //      nWest   = m_pcParticle[m][n-1]->GetPosition();
00527         //      nNorth  = m_pcParticle[m+1][n]->GetPosition();
00528         //      //-------------------------------
00529         //      nNorthWest  = m_pcParticle[m+1][n-1]->GetPosition();
00530         //      //-------------------------------
00531         //      //neighborsAvg = (nWest + nEast + nSouth + nNorth ) / 4.0;
00532         //      neighborsAvg = (nWest + nNorth + nNorthWest) / 3.0;
00533         //      m_pcParticle[m][n]->GetPosition().GetXYZ( x, y, z );
00534         //      m_pcParticle[m][n]->GetVelocity().GetXYZ( vx, vy, vz );
00535 
00536         //      //m_pcParticle[m][n]->SetPosition( m_pcParticle[m][n]->GetPosition() + Vector3<T>(0.01,0.01,0.01) );
00537         //      ax = 0.1 * ( 
00538         //                  freq1 * (neighborsAvg.GetX() - x) / m_pcParticle[m][n]->GetMass()
00539         //                  + freq2 * (neighborsAvg.GetX()*neighborsAvg.GetX() - x*x) 
00540         //                //+ freq2 * (n * 1.0/*size/meshSize = 1.0*/ - x) // Not working for 3D
00541         //                - damp * vx
00542         //      );
00543         //      ay = 0.1 * ( 
00544         //                  freq1 * (neighborsAvg.GetY() - y) / m_pcParticle[m][n]->GetMass()
00545         //                  + freq2 * (neighborsAvg.GetY()*neighborsAvg.GetY() - y*y) 
00546         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - y) // Not working for 3D
00547         //                - damp * vy
00548         //      );
00549         //      az = 0.1 * ( 
00550         //                  freq1 * (neighborsAvg.GetZ() - z) / m_pcParticle[m][n]->GetMass()
00551         //                  + freq2 * (neighborsAvg.GetZ()*neighborsAvg.GetZ() - z*z) 
00552         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - z) // Not working for 3D
00553         //                - damp * vz
00554         //      );
00555         //      vx += ax;
00556         //      vy += ay;
00557         //      vz += az;
00558         //      m_pcParticle[m][n]->SetVelocity( vx, vy, vz );
00559         //      x += vx;
00560         //      y += vy;
00561         //      z += vz;
00562         //      m_pcParticle[m][n]->SetPosition( x, y, z );
00563         //  }
00564         //}
00567         //{ m = m_iNoRows-1;
00568         //  n = 0;
00569         //  if ( !m_pcParticle[m][n]->GetFixStatus() ) {
00570         //      //-------------------------------
00571         //      // Get neighbors' positions
00572         //      nEast   = m_pcParticle[m][n+1]->GetPosition();
00573         //      nSouth  = m_pcParticle[m-1][n]->GetPosition();
00574         //      //-------------------------------
00575         //      nSouthEast  = m_pcParticle[m-1][n+1]->GetPosition();
00576         //      //-------------------------------
00577         //      //neighborsAvg = (nWest + nEast + nSouth + nNorth ) / 4.0;
00578         //      neighborsAvg = (nEast + nSouth + nSouthEast) / 3.0;
00579         //      m_pcParticle[m][n]->GetPosition().GetXYZ( x, y, z );
00580         //      m_pcParticle[m][n]->GetVelocity().GetXYZ( vx, vy, vz );
00581 
00582         //      //m_pcParticle[m][n]->SetPosition( m_pcParticle[m][n]->GetPosition() + Vector3<T>(0.01,0.01,0.01) );
00583         //      ax = 0.1 * ( 
00584         //                  freq1 * (neighborsAvg.GetX() - x) / m_pcParticle[m][n]->GetMass()
00585         //                  + freq2 * (neighborsAvg.GetX()*neighborsAvg.GetX() - x*x) 
00586         //                //+ freq2 * (n * 1.0/*size/meshSize = 1.0*/ - x) // Not working for 3D
00587         //                - damp * vx
00588         //      );
00589         //      ay = 0.1 * ( 
00590         //                  freq1 * (neighborsAvg.GetY() - y) / m_pcParticle[m][n]->GetMass()
00591         //                  + freq2 * (neighborsAvg.GetY()*neighborsAvg.GetY() - y*y) 
00592         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - y) // Not working for 3D
00593         //                - damp * vy
00594         //      );
00595         //      az = 0.1 * ( 
00596         //                  freq1 * (neighborsAvg.GetZ() - z) / m_pcParticle[m][n]->GetMass()
00597         //                  + freq2 * (neighborsAvg.GetZ()*neighborsAvg.GetZ() - z*z) 
00598         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - z) // Not working for 3D
00599         //                - damp * vz
00600         //      );
00601         //      vx += ax;
00602         //      vy += ay;
00603         //      vz += az;
00604         //      m_pcParticle[m][n]->SetVelocity( vx, vy, vz );
00605         //      x += vx;
00606         //      y += vy;
00607         //      z += vz;
00608         //      m_pcParticle[m][n]->SetPosition( x, y, z );
00609         //  }
00610         //}
00613         //{ m = m_iNoRows-1;
00614         //  n = m_iNoCols-1;
00615         //  if ( !m_pcParticle[m][n]->GetFixStatus() ) {
00616         //      //-------------------------------
00617         //      // Get neighbors' positions
00618         //      nWest   = m_pcParticle[m][n-1]->GetPosition();
00619         //      nSouth  = m_pcParticle[m-1][n]->GetPosition();
00620         //      //-------------------------------
00621         //      nSouthWest  = m_pcParticle[m-1][n-1]->GetPosition();
00622         //      //-------------------------------
00623         //      //neighborsAvg = (nWest + nEast + nSouth + nNorth ) / 4.0;
00624         //      neighborsAvg = (nWest + nSouth + nSouthWest) / 3.0;
00625         //      m_pcParticle[m][n]->GetPosition().GetXYZ( x, y, z );
00626         //      m_pcParticle[m][n]->GetVelocity().GetXYZ( vx, vy, vz );
00627 
00628         //      //m_pcParticle[m][n]->SetPosition( m_pcParticle[m][n]->GetPosition() + Vector3<T>(0.01,0.01,0.01) );
00629         //      ax = 0.1 * ( 
00630         //                  freq1 * (neighborsAvg.GetX() - x) / m_pcParticle[m][n]->GetMass()
00631         //                  + freq2 * (neighborsAvg.GetX()*neighborsAvg.GetX() - x*x) 
00632         //                //+ freq2 * (n * 1.0/*size/meshSize = 1.0*/ - x) // Not working for 3D
00633         //                - damp * vx
00634         //      );
00635         //      ay = 0.1 * ( 
00636         //                  freq1 * (neighborsAvg.GetY() - y) / m_pcParticle[m][n]->GetMass()
00637         //                  + freq2 * (neighborsAvg.GetY()*neighborsAvg.GetY() - y*y) 
00638         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - y) // Not working for 3D
00639         //                - damp * vy
00640         //      );
00641         //      az = 0.1 * ( 
00642         //                  freq1 * (neighborsAvg.GetZ() - z) / m_pcParticle[m][n]->GetMass()
00643         //                  + freq2 * (neighborsAvg.GetZ()*neighborsAvg.GetZ() - z*z) 
00644         //                //+ freq2 * (m * 1.0/*size/meshSize = 1.0*/ - z) // Not working for 3D
00645         //                - damp * vz
00646         //      );
00647         //      vx += ax;
00648         //      vy += ay;
00649         //      vz += az;
00650         //      m_pcParticle[m][n]->SetVelocity( vx, vy, vz );
00651         //      x += vx;
00652         //      y += vy;
00653         //      z += vz;
00654         //      m_pcParticle[m][n]->SetPosition( x, y, z );
00655         //  }
00656         //}
00657         //------------------------------------------------------------
00658         CalParticleNormals();
00659     }
00660 };
00661 //CLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLA
00662 
00663 
00664 //HELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHE
00665 //
00666 //      DeformMeshWithCut   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
00667 //
00668 //HELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHE
00669 //-------------------------------------------------------------------------------------------------
00670 // Create Particles
00671 template <typename T>
00672 void DeformMeshWithCut<T>::CreateParticles( const Vector3<T> &topLeftPos, const Vector3<T> &bottomRightPos, T mass )
00673 {
00674     // Local Variable
00675     Vector3<T> currentPosVector = topLeftPos;
00676     Vector3<T> diagonalVector = bottomRightPos - topLeftPos;
00677     T ptMass = mass / ( m_iNoCols * m_iNoRows );
00678     T colIncStep = diagonalVector[0] / (m_iNoCols-1);
00679     T rowIncStep = diagonalVector[1] / (m_iNoRows-1);
00680     //T zIncStep   = diagonalVector[2] / ((m_iNoCols + m_iNoRows)/2.0);
00681     T zIncStep   = diagonalVector[2] / (m_iNoRows-1);
00682 
00683     // Create Particle Pointers
00684     m_pcParticle = new Particle<T>**[m_iNoRows];
00685     for ( m = 0; m < m_iNoRows; m++ ) {
00686         m_pcParticle[m] = new Particle<T>*[m_iNoCols];
00687     }
00688 
00689     // Create Particles
00690     Vector3<T> zeroVector(0,0,0);
00691     for ( m = 0; m < m_iNoRows; m++ ) { // row loops
00692         for ( n = 0; n < m_iNoCols; n++ ) { // column loops
00693             m_pcParticle[m][n] = new Particle<T>( 
00694                                     ptMass,             // mass 
00695                                     currentPosVector,   // position
00696                                     zeroVector,         // velocity
00697                                     zeroVector,         // acceleration
00698                                     zeroVector );       // force
00699             currentPosVector[0] = currentPosVector[0] + colIncStep; // increment x position
00700         }
00701         currentPosVector[0] = topLeftPos[0];                    // reset x position
00702         currentPosVector[1] = currentPosVector[1] + rowIncStep; // increment y position
00703         currentPosVector[2] = currentPosVector[2] + zIncStep;   // increment z position
00704     }
00705 
00706     
00707     int iHalfNoCols = m_iNoCols / 2;
00708     T deepAdjustment[] = { -0.1, -0.4, -1.2, -0.4, -0.1 };
00709     for ( m = 5; m < m_iNoRows-5; m++ ) {   // row loops
00710         int iCount = 0;
00711         for ( n = iHalfNoCols-2; n <= iHalfNoCols+2; ++n ) {    // column loops
00712             m_pcParticle[m][n]->SetPosition( m_pcParticle[m][n]->GetPosition() + Vector3<T>( 0, deepAdjustment[iCount++], 0 ) );
00713         }
00714     }
00715 
00716     /*
00717     // Dump Particle Positions on Screen
00718     std::cout << "Particle Positions:\n";
00719     for ( m = 0; m < m_iNoRows; m++ ) { // row loops
00720         for ( n = 0; n < m_iNoCols; n++ ) { // column loops
00721             std::cout << "[" << m << "," << n << "] " << m_pcParticle[m][n]->m_vtPosit << " ";
00722         }
00723         std::cout << "\n";
00724     }
00725     //*/
00726 }
00727 //-------------------------------------------------------------------------------------------------
00728 // Delete Particles
00729 template <typename T>
00730 void DeformMeshWithCut<T>::DeleteParticles()
00731 {
00732     // Delete Particles
00733     for ( m = 0; m < m_iNoRows; m++ ) {
00734         for ( n = 0; n < m_iNoCols; n++ ) {
00735             delete m_pcParticle[m][n];
00736         }
00737         delete [] m_pcParticle[m];
00738     }
00739     delete [] m_pcParticle;
00740 }
00741 //HELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHE
00742 
00743 
00744 //MEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERME
00745 //
00746 //      DeformMeshWithCut   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
00747 //
00748 //MEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERME
00749 //-------------------------------------------------------------------------------------------------
00750 template <typename T>
00751 DeformMeshWithCut<T>::DeformMeshWithCut( 
00752               int rows,             // number of rows (on world-y-axis)
00753               int cols,             // number of cols (on world-x-axis)
00754               const Vector3<T> &topLeftPos,         // start position (should be top left cornor)
00755               const Vector3<T> &bottomRightPos,     // end position (should be bottom right cornor)
00756               T mass,                                   // the whole mass
00757               BitmapImage *img )            // Image Pointer
00758     : OpenGLSupport( img ),     // parent class constructor
00759       m_iNoRows( rows ), m_iNoCols( cols )
00760 {
00761     CreateParticles( topLeftPos, bottomRightPos, mass );
00762     CalParticleNormals();
00763 }
00764 //-------------------------------------------------------------------------------------------------
00765 template <typename T>
00766 DeformMeshWithCut<T>::~DeformMeshWithCut()
00767 {
00768     DeleteParticles();
00769 }
00770 //-------------------------------------------------------------------------------------------------
00771 // Calculate Particle Normals
00772 template <typename T>
00773 void DeformMeshWithCut<T>::CalParticleNormals()
00774 {
00775 /*
00776     -----------------
00777     | \  3  |  2  / |
00778     |   \   |   /   |
00779     | 4   \ | /  1  |   Normal of the middle (m,n) particle is the sum of the eight normals.
00780     |<------+------>|   E.g. normal 1 is the unit vector of the cross product of (m,n)-->(m,n+1) 
00781     | 5   / | \  8  |   vector with (m,n)-->(m-1,n+1) vector (rotated counter clockwise).
00782     |   /   |   \   |
00783     | /  6  |  7  \ |
00784     -----------------
00785 */
00786     // These particles have all 8 neighbors ------------------------------------
00787     for ( m = 1; m < m_iNoRows-1; m++ ) {
00788         for ( n = 1; n < m_iNoCols-1; n++ ) {
00789             // (1) (m,n)-->(m,n+1)   and (m,n)-->(m-1,n+1)
00790             m_pcParticle[m][n]->m_vtNormal 
00791                 = ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n+1]->m_vtPosit) 
00792                   ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n+1]->m_vtPosit) ).Normalized();
00793             // (2) (m,n)-->(m-1,n+1) and (m,n)-->(m-1,n)
00794             m_pcParticle[m][n]->m_vtNormal 
00795                 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n+1]->m_vtPosit) 
00796                    ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n  ]->m_vtPosit) ).Normalized();
00797             // (3) (m,n)-->(m-1,n)   and (m,n)-->(m-1,n-1)
00798             m_pcParticle[m][n]->m_vtNormal 
00799                 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n  ]->m_vtPosit) 
00800                    ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n-1]->m_vtPosit) ).Normalized();
00801             // (4) (m,n)-->(m-1,n-1) and (m,n)-->(m,n-1)
00802             m_pcParticle[m][n]->m_vtNormal 
00803                 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n-1]->m_vtPosit) 
00804                    ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n-1]->m_vtPosit) ).Normalized();
00805             // (5) (m,n)-->(m,n-1)   and (m,n)-->(m+1,n-1)
00806             m_pcParticle[m][n]->m_vtNormal 
00807                 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n-1]->m_vtPosit) 
00808                    ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n-1]->m_vtPosit) ).Normalized();
00809             // (6) (m,n)-->(m+1,n-1) and (m,n)-->(m+1,n)
00810             m_pcParticle[m][n]->m_vtNormal 
00811                 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n-1]->m_vtPosit) 
00812                    ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n  ]->m_vtPosit) ).Normalized();
00813             // (7) (m,n)-->(m+1,n)   and (m,n)-->(m+1,n+1)
00814             m_pcParticle[m][n]->m_vtNormal 
00815                 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n  ]->m_vtPosit) 
00816                    ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n+1]->m_vtPosit) ).Normalized();
00817             // (8) (m,n)-->(m+1,n+1) and (m,n)-->(m,n+1)
00818             m_pcParticle[m][n]->m_vtNormal 
00819                 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n+1]->m_vtPosit) 
00820                    ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n+1]->m_vtPosit) ).Normalized();
00821             // normalize the sum result vector
00822             m_pcParticle[m][n]->m_vtNormal.Normalized();
00823         }
00824     }
00825 
00826     //-------------------------------------------------------------------------
00827     // Normals of Particles on the Top Row (Except the Cornor Particle)
00828     m = 0;
00829     for ( n = 1; n < m_iNoCols-1; n++ ) {
00830         // (5) (m,n)-->(m,n-1)   and (m,n)-->(m+1,n-1)
00831         m_pcParticle[m][n]->m_vtNormal 
00832             = ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n-1]->m_vtPosit) 
00833               ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n-1]->m_vtPosit) ).Normalized();
00834         // (6) (m,n)-->(m+1,n-1) and (m,n)-->(m+1,n)
00835         m_pcParticle[m][n]->m_vtNormal 
00836             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n-1]->m_vtPosit) 
00837                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n  ]->m_vtPosit) ).Normalized();
00838         // (7) (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         // (8) (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         // normalize the sum result vector
00847         m_pcParticle[m][n]->m_vtNormal.Normalized();
00848     }
00849     //-------------------------------------------------------------------------
00850     // Normals of Particles on the Bottom Row (Except the Cornor Particle)
00851     m = m_iNoRows-1;
00852     for ( n = 1; n < m_iNoCols-1; n++ ) {
00853         // (1) (m,n)-->(m,n+1)   and (m,n)-->(m-1,n+1)
00854         m_pcParticle[m][n]->m_vtNormal 
00855             = ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n+1]->m_vtPosit) 
00856               ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n+1]->m_vtPosit) ).Normalized();
00857         // (2) (m,n)-->(m-1,n+1) and (m,n)-->(m-1,n)
00858         m_pcParticle[m][n]->m_vtNormal 
00859             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n+1]->m_vtPosit) 
00860                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n  ]->m_vtPosit) ).Normalized();
00861         // (3) (m,n)-->(m-1,n)   and (m,n)-->(m-1,n-1)
00862         m_pcParticle[m][n]->m_vtNormal 
00863             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n  ]->m_vtPosit) 
00864                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n-1]->m_vtPosit) ).Normalized();
00865         // (4) (m,n)-->(m-1,n-1) and (m,n)-->(m,n-1)
00866         m_pcParticle[m][n]->m_vtNormal 
00867             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n-1]->m_vtPosit) 
00868                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n-1]->m_vtPosit) ).Normalized();
00869         // normalize the sum result vector
00870         m_pcParticle[m][n]->m_vtNormal.Normalized();
00871     }
00872     //-------------------------------------------------------------------------
00873     // Normals of Particles on the Left Column (Except the Cornor Particle)
00874     n = 0;
00875     for ( m = 1; m < m_iNoRows-1; m++ ) {
00876         // (7) (m,n)-->(m+1,n)   and (m,n)-->(m+1,n+1)
00877         m_pcParticle[m][n]->m_vtNormal 
00878             = ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n  ]->m_vtPosit) 
00879               ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n+1]->m_vtPosit) ).Normalized();
00880         // (8) (m,n)-->(m+1,n+1) and (m,n)-->(m,n+1)
00881         m_pcParticle[m][n]->m_vtNormal 
00882             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n+1]->m_vtPosit) 
00883                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n+1]->m_vtPosit) ).Normalized();
00884         // (1) (m,n)-->(m,n+1)   and (m,n)-->(m-1,n+1)
00885         m_pcParticle[m][n]->m_vtNormal 
00886             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n+1]->m_vtPosit) 
00887                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n+1]->m_vtPosit) ).Normalized();
00888         // (2) (m,n)-->(m-1,n+1) and (m,n)-->(m-1,n)
00889         m_pcParticle[m][n]->m_vtNormal 
00890             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n+1]->m_vtPosit) 
00891                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n  ]->m_vtPosit) ).Normalized();
00892         // normalize the sum result vector
00893         m_pcParticle[m][n]->m_vtNormal.Normalized();
00894     }
00895     //-------------------------------------------------------------------------
00896     // Normals of Particles on the Right Row (Except the Cornor Particle)
00897     n = m_iNoCols-1;
00898     for ( m = 1; m < m_iNoRows-1; m++ ) {
00899         // (3) (m,n)-->(m-1,n)   and (m,n)-->(m-1,n-1)
00900         m_pcParticle[m][n]->m_vtNormal 
00901             = ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n  ]->m_vtPosit) 
00902               ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n-1]->m_vtPosit) ).Normalized();
00903         // (4) (m,n)-->(m-1,n-1) and (m,n)-->(m,n-1)
00904         m_pcParticle[m][n]->m_vtNormal 
00905             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n-1]->m_vtPosit) 
00906                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n-1]->m_vtPosit) ).Normalized();
00907         // (5) (m,n)-->(m,n-1)   and (m,n)-->(m+1,n-1)
00908         m_pcParticle[m][n]->m_vtNormal 
00909             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n-1]->m_vtPosit) 
00910                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n-1]->m_vtPosit) ).Normalized();
00911         // (6) (m,n)-->(m+1,n-1) and (m,n)-->(m+1,n)
00912         m_pcParticle[m][n]->m_vtNormal 
00913             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n-1]->m_vtPosit) 
00914                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n  ]->m_vtPosit) ).Normalized();
00915         // normalize the sum result vector
00916         m_pcParticle[m][n]->m_vtNormal.Normalized();
00917     }
00918     
00919     // Top Left Cornor ---------------------------------------------------------
00920     m = 0; n = 0;
00921         // (7) (m,n)-->(m+1,n)   and (m,n)-->(m+1,n+1)
00922         m_pcParticle[m][n]->m_vtNormal 
00923             = ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n  ]->m_vtPosit) 
00924               ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n+1]->m_vtPosit) ).Normalized();
00925         // (8) (m,n)-->(m+1,n+1) and (m,n)-->(m,n+1)
00926         m_pcParticle[m][n]->m_vtNormal 
00927             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n+1]->m_vtPosit) 
00928                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n+1]->m_vtPosit) ).Normalized();
00929         m_pcParticle[m][n]->m_vtNormal.Normalized();    // normalize the sum result vector
00930     // Bottom Left Cornor ------------------------------------------------------
00931     m = m_iNoRows-1; n = 0;
00932         // (1) (m,n)-->(m,n+1)   and (m,n)-->(m-1,n+1)
00933         m_pcParticle[m][n]->m_vtNormal 
00934             = ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n+1]->m_vtPosit) 
00935               ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n+1]->m_vtPosit) ).Normalized();
00936         // (2) (m,n)-->(m-1,n+1) and (m,n)-->(m-1,n)
00937         m_pcParticle[m][n]->m_vtNormal 
00938             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n+1]->m_vtPosit) 
00939                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n  ]->m_vtPosit) ).Normalized();
00940         m_pcParticle[m][n]->m_vtNormal.Normalized();    // normalize the sum result vector
00941     // Bottom Right Cornor -----------------------------------------------------
00942     m = m_iNoRows-1; n = m_iNoCols-1;
00943         // (3) (m,n)-->(m-1,n)   and (m,n)-->(m-1,n-1)
00944         m_pcParticle[m][n]->m_vtNormal 
00945             = ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n  ]->m_vtPosit) 
00946               ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n-1]->m_vtPosit) ).Normalized();
00947         // (4) (m,n)-->(m-1,n-1) and (m,n)-->(m,n-1)
00948         m_pcParticle[m][n]->m_vtNormal 
00949             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n-1]->m_vtPosit) 
00950                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n-1]->m_vtPosit) ).Normalized();
00951         m_pcParticle[m][n]->m_vtNormal.Normalized();    // normalize the sum result vector
00952     // Top Right Cornor --------------------------------------------------------
00953     m = 0; n = m_iNoCols-1;
00954         // (5) (m,n)-->(m,n-1)   and (m,n)-->(m+1,n-1)
00955         m_pcParticle[m][n]->m_vtNormal 
00956             = ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m  ][n-1]->m_vtPosit) 
00957               ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n-1]->m_vtPosit) ).Normalized();
00958         // (6) (m,n)-->(m+1,n-1) and (m,n)-->(m+1,n)
00959         m_pcParticle[m][n]->m_vtNormal 
00960             += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n-1]->m_vtPosit) 
00961                ^ (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n  ]->m_vtPosit) ).Normalized();
00962         m_pcParticle[m][n]->m_vtNormal.Normalized();    // normalize the sum result vector
00963 }
00964 //-------------------------------------------------------------------------------------------------
00965 // Calculate Particle Normals
00966 template <typename T>
00967 void DeformMeshWithCut<T>::CalParticleNormals( int i )
00968 {
00969 /*
00970     -----------------
00971     | \  3  |  2  / |
00972     |   \   |   /   |
00973     | 4   \ | /  1  |   Normal of the middle (m,n) particle is the sum of the eight normals.
00974     |<------+------>|   E.g. normal 1 is the unit vector of the cross product of (m,n)-->(m,n+1) 
00975     | 5   / | \  8  |   vector with (m,n)-->(m-1,n+1) vector (rotated counter clockwise).
00976     |   /   |   \   |
00977     | /  6  |  7  \ |
00978     -----------------
00979 */
00980     // These particles have all 8 neighbors ------------------------------------
00981     for ( m = 1; m < m_iNoRows-1; m++ ) {
00982         for ( n = 1; n < m_iNoCols-1; n++ ) {
00983             // (1) (m,n)-->(m,n+1)   and (m,n)-->(m-1,n+1)
00984             m_pcParticle[m  ][n  ]->m_vtNormal[0] = 0;
00985             m_pcParticle[m  ][n  ]->m_vtNormal[1] = 0;
00986             m_pcParticle[m  ][n  ]->m_vtNormal[2] = 0;
00987             AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
00988                        m_pcParticle[m  ][n  ]->m_vtPosit,
00989                        m_pcParticle[m  ][n+1]->m_vtPosit,
00990                        m_pcParticle[m-1][n+1]->m_vtPosit );
00991             // (2) (m,n)-->(m-1,n+1) and (m,n)-->(m-1,n)
00992             AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
00993                        m_pcParticle[m  ][n  ]->m_vtPosit,
00994                        m_pcParticle[m-1][n+1]->m_vtPosit,
00995                        m_pcParticle[m-1][n  ]->m_vtPosit );
00996             // (3) (m,n)-->(m-1,n)   and (m,n)-->(m-1,n-1)
00997             AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
00998                        m_pcParticle[m  ][n  ]->m_vtPosit,
00999                        m_pcParticle[m-1][n  ]->m_vtPosit,
01000                        m_pcParticle[m-1][n-1]->m_vtPosit );
01001             // (4) (m,n)-->(m-1,n-1) and (m,n)-->(m,n-1)
01002             AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01003                        m_pcParticle[m  ][n  ]->m_vtPosit,
01004                        m_pcParticle[m-1][n-1]->m_vtPosit,
01005                        m_pcParticle[m  ][n-1]->m_vtPosit );
01006             // (5) (m,n)-->(m,n-1)   and (m,n)-->(m+1,n-1)
01007             AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01008                        m_pcParticle[m  ][n  ]->m_vtPosit,
01009                        m_pcParticle[m  ][n-1]->m_vtPosit,
01010                        m_pcParticle[m+1][n-1]->m_vtPosit );
01011             // (6) (m,n)-->(m+1,n-1) and (m,n)-->(m+1,n)
01012             AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01013                        m_pcParticle[m  ][n  ]->m_vtPosit,
01014                        m_pcParticle[m+1][n-1]->m_vtPosit,
01015                        m_pcParticle[m+1][n  ]->m_vtPosit );
01016             // (7) (m,n)-->(m+1,n)   and (m,n)-->(m+1,n+1)
01017             AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01018                        m_pcParticle[m  ][n  ]->m_vtPosit,
01019                        m_pcParticle[m+1][n  ]->m_vtPosit,
01020                        m_pcParticle[m+1][n+1]->m_vtPosit );
01021             // (8) (m,n)-->(m+1,n+1) and (m,n)-->(m,n+1)
01022             AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01023                        m_pcParticle[m  ][n  ]->m_vtPosit,
01024                        m_pcParticle[m+1][n+1]->m_vtPosit,
01025                        m_pcParticle[m  ][n+1]->m_vtPosit );
01026             // normalize the sum result vector
01027             m_pcParticle[m][n]->m_vtNormal.Normalized();
01028         }
01029     }
01030 
01031     //-------------------------------------------------------------------------
01032     // Normals of Particles on the Top Row (Except the Cornor Particle)
01033     m = 0;
01034     for ( n = 1; n < m_iNoCols-1; n++ ) {
01035         // (5) (m,n)-->(m,n-1)   and (m,n)-->(m+1,n-1)
01036         m_pcParticle[m][n]->m_vtNormal[0] = 0;
01037         m_pcParticle[m][n]->m_vtNormal[1] = 0;
01038         m_pcParticle[m][n]->m_vtNormal[2] = 0;
01039         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01040                    m_pcParticle[m  ][n  ]->m_vtPosit,
01041                    m_pcParticle[m  ][n-1]->m_vtPosit,
01042                    m_pcParticle[m+1][n-1]->m_vtPosit );
01043         // (6) (m,n)-->(m+1,n-1) and (m,n)-->(m+1,n)
01044         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01045                    m_pcParticle[m  ][n  ]->m_vtPosit,
01046                    m_pcParticle[m+1][n-1]->m_vtPosit,
01047                    m_pcParticle[m+1][n  ]->m_vtPosit );
01048         // (7) (m,n)-->(m+1,n)   and (m,n)-->(m+1,n+1)
01049         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01050                    m_pcParticle[m  ][n  ]->m_vtPosit,
01051                    m_pcParticle[m+1][n  ]->m_vtPosit,
01052                    m_pcParticle[m+1][n+1]->m_vtPosit );
01053         // (8) (m,n)-->(m+1,n+1) and (m,n)-->(m,n+1)
01054         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01055                    m_pcParticle[m  ][n  ]->m_vtPosit,
01056                    m_pcParticle[m+1][n+1]->m_vtPosit,
01057                    m_pcParticle[m  ][n+1]->m_vtPosit );
01058         // normalize the sum result vector
01059         m_pcParticle[m][n]->m_vtNormal.Normalized();
01060     }
01061     //-------------------------------------------------------------------------
01062     // Normals of Particles on the Bottom Row (Except the Cornor Particle)
01063     m = m_iNoRows-1;
01064     for ( n = 1; n < m_iNoCols-1; n++ ) {
01065         // (1) (m,n)-->(m,n+1)   and (m,n)-->(m-1,n+1)
01066         m_pcParticle[m][n]->m_vtNormal[0] = 0;
01067         m_pcParticle[m][n]->m_vtNormal[1] = 0;
01068         m_pcParticle[m][n]->m_vtNormal[2] = 0;
01069         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01070                    m_pcParticle[m  ][n  ]->m_vtPosit,
01071                    m_pcParticle[m  ][n+1]->m_vtPosit,
01072                    m_pcParticle[m-1][n+1]->m_vtPosit );
01073         // (2) (m,n)-->(m-1,n+1) and (m,n)-->(m-1,n)
01074         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01075                    m_pcParticle[m  ][n  ]->m_vtPosit,
01076                    m_pcParticle[m-1][n+1]->m_vtPosit,
01077                    m_pcParticle[m-1][n  ]->m_vtPosit );
01078         // (3) (m,n)-->(m-1,n)   and (m,n)-->(m-1,n-1)
01079         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01080                    m_pcParticle[m  ][n  ]->m_vtPosit,
01081                    m_pcParticle[m-1][n  ]->m_vtPosit,
01082                    m_pcParticle[m-1][n-1]->m_vtPosit );
01083         // (4) (m,n)-->(m-1,n-1) and (m,n)-->(m,n-1)
01084         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01085                    m_pcParticle[m  ][n  ]->m_vtPosit,
01086                    m_pcParticle[m-1][n-1]->m_vtPosit,
01087                    m_pcParticle[m  ][n-1]->m_vtPosit );
01088         // normalize the sum result vector
01089         m_pcParticle[m][n]->m_vtNormal.Normalized();
01090     }
01091     //-------------------------------------------------------------------------
01092     // Normals of Particles on the Left Column (Except the Cornor Particle)
01093     n = 0;
01094     for ( m = 1; m < m_iNoRows-1; m++ ) {
01095         // (7) (m,n)-->(m+1,n)   and (m,n)-->(m+1,n+1)
01096         m_pcParticle[m][n]->m_vtNormal[0] = 0;
01097         m_pcParticle[m][n]->m_vtNormal[1] = 0;
01098         m_pcParticle[m][n]->m_vtNormal[2] = 0;
01099         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01100                    m_pcParticle[m  ][n  ]->m_vtPosit,
01101                    m_pcParticle[m+1][n  ]->m_vtPosit,
01102                    m_pcParticle[m+1][n+1]->m_vtPosit );
01103         // (8) (m,n)-->(m+1,n+1) and (m,n)-->(m,n+1)
01104         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01105                    m_pcParticle[m  ][n  ]->m_vtPosit,
01106                    m_pcParticle[m+1][n+1]->m_vtPosit,
01107                    m_pcParticle[m  ][n+1]->m_vtPosit );
01108         // (1) (m,n)-->(m,n+1)   and (m,n)-->(m-1,n+1)
01109         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01110                    m_pcParticle[m  ][n  ]->m_vtPosit,
01111                    m_pcParticle[m  ][n+1]->m_vtPosit,
01112                    m_pcParticle[m-1][n+1]->m_vtPosit );
01113         // (2) (m,n)-->(m-1,n+1) and (m,n)-->(m-1,n)
01114         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01115                    m_pcParticle[m  ][n  ]->m_vtPosit,
01116                    m_pcParticle[m-1][n+1]->m_vtPosit,
01117                    m_pcParticle[m-1][n  ]->m_vtPosit );
01118         // normalize the sum result vector
01119         m_pcParticle[m][n]->m_vtNormal.Normalized();
01120     }
01121     //-------------------------------------------------------------------------
01122     // Normals of Particles on the Right Row (Except the Cornor Particle)
01123     n = m_iNoCols-1;
01124     for ( m = 1; m < m_iNoRows-1; m++ ) {
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         // (5) (m,n)-->(m,n-1)   and (m,n)-->(m+1,n-1)
01139         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01140                    m_pcParticle[m  ][n  ]->m_vtPosit,
01141                    m_pcParticle[m  ][n-1]->m_vtPosit,
01142                    m_pcParticle[m+1][n-1]->m_vtPosit );
01143         // (6) (m,n)-->(m+1,n-1) and (m,n)-->(m+1,n)
01144         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01145                    m_pcParticle[m  ][n  ]->m_vtPosit,
01146                    m_pcParticle[m+1][n-1]->m_vtPosit,
01147                    m_pcParticle[m+1][n  ]->m_vtPosit );
01148         // normalize the sum result vector
01149         m_pcParticle[m][n]->m_vtNormal.Normalized();
01150     }
01151     
01152     // Top Left Cornor ---------------------------------------------------------
01153     m = 0; n = 0;
01154         // (7) (m,n)-->(m+1,n)   and (m,n)-->(m+1,n+1)
01155         m_pcParticle[m][n]->m_vtNormal[0] = 0;
01156         m_pcParticle[m][n]->m_vtNormal[1] = 0;
01157         m_pcParticle[m][n]->m_vtNormal[2] = 0;
01158         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01159                    m_pcParticle[m  ][n  ]->m_vtPosit,
01160                    m_pcParticle[m+1][n  ]->m_vtPosit,
01161                    m_pcParticle[m+1][n+1]->m_vtPosit );
01162         // (8) (m,n)-->(m+1,n+1) and (m,n)-->(m,n+1)
01163         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01164                    m_pcParticle[m  ][n  ]->m_vtPosit,
01165                    m_pcParticle[m+1][n+1]->m_vtPosit,
01166                    m_pcParticle[m  ][n+1]->m_vtPosit );
01167         m_pcParticle[m][n]->m_vtNormal.Normalized();    // normalize the sum result vector
01168     // Bottom Left Cornor ------------------------------------------------------
01169     m = m_iNoRows-1; n = 0;
01170         // (1) (m,n)-->(m,n+1)   and (m,n)-->(m-1,n+1)
01171         m_pcParticle[m][n]->m_vtNormal[0] = 0;
01172         m_pcParticle[m][n]->m_vtNormal[1] = 0;
01173         m_pcParticle[m][n]->m_vtNormal[2] = 0;
01174         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01175                    m_pcParticle[m  ][n  ]->m_vtPosit,
01176                    m_pcParticle[m  ][n+1]->m_vtPosit,
01177                    m_pcParticle[m-1][n+1]->m_vtPosit );
01178         // (2) (m,n)-->(m-1,n+1) and (m,n)-->(m-1,n)
01179         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01180                    m_pcParticle[m  ][n  ]->m_vtPosit,
01181                    m_pcParticle[m-1][n+1]->m_vtPosit,
01182                    m_pcParticle[m-1][n  ]->m_vtPosit );
01183         m_pcParticle[m][n]->m_vtNormal.Normalized();    // normalize the sum result vector
01184     // Bottom Right Cornor -----------------------------------------------------
01185     m = m_iNoRows-1; n = m_iNoCols-1;
01186         // (3) (m,n)-->(m-1,n)   and (m,n)-->(m-1,n-1)
01187         m_pcParticle[m][n]->m_vtNormal[0] = 0;
01188         m_pcParticle[m][n]->m_vtNormal[1] = 0;
01189         m_pcParticle[m][n]->m_vtNormal[2] = 0;
01190         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01191                    m_pcParticle[m  ][n  ]->m_vtPosit,
01192                    m_pcParticle[m-1][n  ]->m_vtPosit,
01193                    m_pcParticle[m-1][n-1]->m_vtPosit );
01194         // (4) (m,n)-->(m-1,n-1) and (m,n)-->(m,n-1)
01195         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01196                    m_pcParticle[m  ][n  ]->m_vtPosit,
01197                    m_pcParticle[m-1][n-1]->m_vtPosit,
01198                    m_pcParticle[m  ][n-1]->m_vtPosit );
01199         m_pcParticle[m][n]->m_vtNormal.Normalized();    // normalize the sum result vector
01200     // Top Right Cornor --------------------------------------------------------
01201     m = 0; n = m_iNoCols-1;
01202         // (5) (m,n)-->(m,n-1)   and (m,n)-->(m+1,n-1)
01203         m_pcParticle[m][n]->m_vtNormal[0] = 0;
01204         m_pcParticle[m][n]->m_vtNormal[1] = 0;
01205         m_pcParticle[m][n]->m_vtNormal[2] = 0;
01206         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01207                    m_pcParticle[m  ][n  ]->m_vtPosit,
01208                    m_pcParticle[m  ][n-1]->m_vtPosit,
01209                    m_pcParticle[m+1][n-1]->m_vtPosit );
01210         // (6) (m,n)-->(m+1,n-1) and (m,n)-->(m+1,n)
01211         AddNormal( m_pcParticle[m  ][n  ]->m_vtNormal,
01212                    m_pcParticle[m  ][n  ]->m_vtPosit,
01213                    m_pcParticle[m+1][n-1]->m_vtPosit,
01214                    m_pcParticle[m+1][n  ]->m_vtPosit );
01215         m_pcParticle[m][n]->m_vtNormal.Normalized();    // normalize the sum result vector
01216 }
01217 /*
01218 //-------------------------------------------------------------------------------------------------
01219 // Clear Force of Particles to Zeros
01220 template <typename T>
01221 void DeformMeshWithCut<T>::ClearForce()
01222 {
01223     T x = 0, y = 0, z = 0;
01224     for ( m = 0; m < m_iNoRows; m++ ) {
01225         for ( n = 0; n < m_iNoCols; n++ ) {
01226             m_pcParticle[m][n]->m_vtForce( x, y, z );
01227         }
01228     }
01229 }
01230 //-------------------------------------------------------------------------------------------------
01231 // Calculate (Weight) Force due to (Acceleration of) Gravity
01232 template <typename T>
01233 void DeformMeshWithCut<T>::ForceDueToGravity( T g )
01234 {
01235     
01236 }
01237 //-------------------------------------------------------------------------------------------------
01238 // Calculate (a Loss) Force due to Viscous Damping
01239 template <typename T>
01240 void DeformMeshWithCut<T>::ForceDueToViscousDamping()
01241 {
01242 }
01243 //-------------------------------------------------------------------------------------------------
01244 // Calculate (Wind) Force due to Viscous Fluid Moving
01245 template <typename T>
01246 void DeformMeshWithCut<T>::ForceDueToViscousFluidMoving()
01247 {
01248 }
01249 */
01250 //-------------------------------------------------------------------------------------------------
01251 // Display Via OpenGL
01252 template <typename T>
01253 void DeformMeshWithCut<T>::DisplayGL( OpenGL::Enum::DrawMode DM )
01254 {
01255     //int ptSize[1];
01256     glColor3f( 1.0f, 1.0f, 1.0f );
01257 
01258     DeformUpdate();
01259     /*
01260     for ( count = 0; count < 8; count++ ) {
01261         StepSimulation( 0.0005 );
01262     }
01263     */
01264 
01265     glPushAttrib( GL_ALL_ATTRIB_BITS );
01266 
01267     //SetMaterial( OpenGL::Enum::METAL_GOLD );
01268     //SetMaterial( OpenGL::Enum::METAL_SILVER );
01269     //SetMaterial( OpenGL::Enum::METAL_BRONZE );
01270     //SetMaterial( OpenGL::Enum::RED_01 );
01271     SetMaterial( OpenGL::Enum::WHITE_01 );
01272     ApplyMaterial( OpenGL::Enum::FRONT );
01273     SetMaterial( OpenGL::Enum::METAL_GOLD );
01274     material.ApplyMaterial( OpenGL::Enum::BACK );
01275     
01276     switch (DM) {
01277         // Draw Points for DeformMeshWithCut
01278         case OpenGL::Enum::POINT:
01279             // Set Point Size
01280             //glGetIntegerv( GL_POINT_SIZE, ptSize );
01281             //glPointSize( 2 );
01282             glBegin( GL_POINTS );
01283             for ( m = 0; m < m_iNoRows; m++ ) {
01284                 for ( n = 0; n < m_iNoCols; n++ ) {
01285                     glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 
01286                                 m_pcParticle[m][n]->m_vtPosit[1],
01287                                 m_pcParticle[m][n]->m_vtPosit[2] );
01288                 }
01289             }
01290             glEnd();
01291 
01292             //-------------------------------------------
01293             // Display Starting Points
01294             glDisable( GL_LIGHTING );
01295             glColor3f( 0.0f, 1.0f, 0.0f );
01296             glPointSize( 7 );
01297             m = 0; n = 0;
01298             glBegin( GL_POINTS );
01299                 glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 
01300                             m_pcParticle[m][n]->m_vtPosit[1],
01301                             m_pcParticle[m][n]->m_vtPosit[2] );
01302             glEnd();
01303             glColor3f( 0.0f, 1.0f, 1.0f );
01304             glPointSize( 5 );
01305             m = 0; n = 1;
01306             glBegin( GL_POINTS );
01307                 glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 
01308                             m_pcParticle[m][n]->m_vtPosit[1],
01309                             m_pcParticle[m][n]->m_vtPosit[2] );
01310             glEnd();
01311             glPointSize( 1 );
01312             glEnable( GL_LIGHTING );
01313             //-------------------------------------------
01314 
01315             // Restore Point Size
01316             //glPointSize( ptSize[0] );
01317             break;
01318 
01319         // Draw Wire Frame for DeformMeshWithCut
01320         case OpenGL::Enum::WIRE_FRAME:
01321             // Draw Row Lines
01322             for ( m = 0; m < m_iNoRows; m++ ) {
01323                 glBegin( GL_LINE_STRIP );
01324                 for ( n = 0; n < m_iNoCols; n++ ) {
01325                     glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 
01326                                 m_pcParticle[m][n]->m_vtPosit[1],
01327                                 m_pcParticle[m][n]->m_vtPosit[2] );
01328                 }
01329                 glEnd();
01330             }
01331             // Draw Column Lines
01332             for ( n = 0; n < m_iNoCols; n++ ) {
01333                 glBegin( GL_LINE_STRIP );
01334                 for ( m = 0; m < m_iNoRows; m++ ) {
01335                     glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 
01336                                 m_pcParticle[m][n]->m_vtPosit[1],
01337                                 m_pcParticle[m][n]->m_vtPosit[2] );
01338                 }
01339                 glEnd();
01340             }
01341 
01342             /*
01343             //-------------------------------------------
01344             // Display Starting Points
01345             glDisable( GL_LIGHTING );
01346             glColor3f( 0.0f, 1.0f, 0.0f );
01347             glPointSize( 7 );
01348             m = 0; n = 0;
01349             glBegin( GL_POINTS );
01350                 glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 
01351                             m_pcParticle[m][n]->m_vtPosit[1],
01352                             m_pcParticle[m][n]->m_vtPosit[2] );
01353             glEnd();
01354             glColor3f( 0.0f, 1.0f, 1.0f );
01355             glPointSize( 5 );
01356             m = 0; n = 1;
01357             glBegin( GL_POINTS );
01358                 glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 
01359                             m_pcParticle[m][n]->m_vtPosit[1],
01360                             m_pcParticle[m][n]->m_vtPosit[2] );
01361             glEnd();
01362             glPointSize( 1 );
01363             glEnable( GL_LIGHTING );
01364             //-------------------------------------------
01365             //*/
01366 
01367             /*
01368             // Draw Diagonal Lines
01369             glBegin( GL_LINES );
01370             for ( m = 0; m < m_iNoRows-1; m++ ) {
01371                 for ( n = 0; n < m_iNoCols-1; n++ ) {
01372                     // Draw a line from [m][n] --- [m+1][n+1]
01373                     glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 
01374                                 m_pcParticle[m][n]->m_vtPosit[1],
01375                                 m_pcParticle[m][n]->m_vtPosit[2] );
01376                     glVertex3f( m_pcParticle[m+1][n+1]->m_vtPosit[0], 
01377                                 m_pcParticle[m+1][n+1]->m_vtPosit[1],
01378                                 m_pcParticle[m+1][n+1]->m_vtPosit[2] );
01379                     // Draw a line from [m+1][n] to [m][n+1]
01380                     glVertex3f( m_pcParticle[m+1][n]->m_vtPosit[0], 
01381                                 m_pcParticle[m+1][n]->m_vtPosit[1],
01382                                 m_pcParticle[m+1][n]->m_vtPosit[2] );
01383                     glVertex3f( m_pcParticle[m][n+1]->m_vtPosit[0], 
01384                                 m_pcParticle[m][n+1]->m_vtPosit[1],
01385                                 m_pcParticle[m][n+1]->m_vtPosit[2] );
01386                 }
01387             }
01388             glEnd();
01389             //*/
01390             break;
01391 
01392         // Draw Polygons for DeformMeshWithCut
01393         case OpenGL::Enum::POLYGON:
01394             // With Texture
01395             if ( m_pcImg != NULL ) {
01396 
01397                 //glPushAttrib( GL_ENABLE_BIT );
01398                 //glEnable( GL_TEXTURE_2D );
01399                 DrawTexture();
01400 
01401                 float tr, tc;
01402                 float trStep = 1.0 / (m_iNoRows-1);
01403                 float tcStep = 1.0 / (m_iNoCols-1);
01404                 for ( m = 0, tr = 1.0; m < m_iNoRows-1; m++, tr -= trStep ) {
01405                     glBegin( GL_QUAD_STRIP );
01406                     for ( n = 0, tc = 0.0; n < m_iNoCols; n++, tc += tcStep ) {
01407                         glNormal3f( m_pcParticle[m][n]->m_vtNormal[0], 
01408                                     m_pcParticle[m][n]->m_vtNormal[1],
01409                                     m_pcParticle[m][n]->m_vtNormal[2] );
01410                         glTexCoord2f(tc, tr);
01411                         glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 
01412                                     m_pcParticle[m][n]->m_vtPosit[1],
01413                                     m_pcParticle[m][n]->m_vtPosit[2] );
01414 
01415                         glNormal3f( m_pcParticle[m+1][n]->m_vtNormal[0], 
01416                                     m_pcParticle[m+1][n]->m_vtNormal[1],
01417                                     m_pcParticle[m+1][n]->m_vtNormal[2] );
01418                         glTexCoord2f(tc, tr-trStep);
01419                         glVertex3f( m_pcParticle[m+1][n]->m_vtPosit[0], 
01420                                     m_pcParticle[m+1][n]->m_vtPosit[1],
01421                                     m_pcParticle[m+1][n]->m_vtPosit[2] );
01422                     }
01423                     glEnd();
01424                 }
01425                 //glBindTexture( GL_TEXTURE_2D, 0 );
01426                 //glPopAttrib();
01427                 //glDisable( GL_TEXTURE_2D );
01428             }
01429             // Without Texture
01430             else {
01431                 for ( m = 0; m < m_iNoRows-1; m++ ) {
01432                     glBegin( GL_QUAD_STRIP );
01433                     for ( n = 0; n < m_iNoCols; n++ ) {
01434                         glNormal3f( m_pcParticle[m][n]->m_vtNormal[0], 
01435                                     m_pcParticle[m][n]->m_vtNormal[1],
01436                                     m_pcParticle[m][n]->m_vtNormal[2] );
01437                         glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 
01438                                     m_pcParticle[m][n]->m_vtPosit[1],
01439                                     m_pcParticle[m][n]->m_vtPosit[2] );
01440 
01441                         glNormal3f( m_pcParticle[m+1][n]->m_vtNormal[0], 
01442                                     m_pcParticle[m+1][n]->m_vtNormal[1],
01443                                     m_pcParticle[m+1][n]->m_vtNormal[2] );
01444                         glVertex3f( m_pcParticle[m+1][n]->m_vtPosit[0], 
01445                                     m_pcParticle[m+1][n]->m_vtPosit[1],
01446                                     m_pcParticle[m+1][n]->m_vtPosit[2] );
01447                     }
01448                     glEnd();
01449                 }
01450             }
01451             break;
01452     }
01453 
01454     // DEBUG
01455     //DisplayGL_ParticleNormals();
01456 
01457     /*
01458     //-------------------------------------------
01459     // Display Starting Points
01460     glDisable( GL_LIGHTING );
01461     glColor3f( 0.0f, 1.0f, 0.0f );
01462     glPointSize( 7 );
01463     m = 0; n = 0;
01464     glBegin( GL_POINTS );
01465         glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 
01466                     m_pcParticle[m][n]->m_vtPosit[1],
01467                     m_pcParticle[m][n]->m_vtPosit[2] );
01468     glEnd();
01469     glColor3f( 0.0f, 1.0f, 1.0f );
01470     glPointSize( 5 );
01471     m = 0; n = 1;
01472     glBegin( GL_POINTS );
01473         glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 
01474                     m_pcParticle[m][n]->m_vtPosit[1],
01475                     m_pcParticle[m][n]->m_vtPosit[2] );
01476     glEnd();
01477     glPointSize( 1 );
01478     glEnable( GL_LIGHTING );
01479     //-------------------------------------------
01480     //*/
01481 
01482     glPopAttrib();
01483     // END TEST
01484 }
01485 //-------------------------------------------------------------------------------------------------
01486 // Display Particle Normals Via OpenGL
01487 template <typename T>
01488 void DeformMeshWithCut<T>::DisplayGL_ParticleNormals()
01489 {
01490     T x, y, z;
01491 
01492     // Draw Normal of each particle
01493     glPushAttrib( GL_ENABLE_BIT | GL_CURRENT_BIT );
01494     glEnable( GL_TEXTURE_2D );
01495     //glDisable( GL_LIGHTING );
01496     glColor3f( 1.0f, 0.0f, 0.0f );
01497     glBegin( GL_LINES );
01498     for ( m = 0; m < m_iNoRows; m++ ) {
01499         for ( n = 0; n < m_iNoCols; n++ ) {
01500             m_pcParticle[m][n]->m_vtPosit.GetXYZ( x, y, z );
01501             glVertex3f( x, y, z );
01502             glVertex3f( x + m_pcParticle[m][n]->m_vtNormal[0], 
01503                         y + m_pcParticle[m][n]->m_vtNormal[1],
01504                         z + m_pcParticle[m][n]->m_vtNormal[2] );
01505         }
01506     }
01507     glEnd();
01508     glPopAttrib();
01509 }
01510 //================================================================================================
01511 // FRIEND FUNCTIONS
01512 //-------------------------------------------------------------------------------------------------
01513 // put it through ostream
01514 /*template <typename T>
01515 ostream &operator<<( ostream &output, const DeformMeshWithCut<T> &Obj )
01516 {
01517     output  << "DeformMeshWithCut ==> "
01518             << "\n  number of rows:       " << Obj.m_iNoRows
01519             << "\n  number of columns:    " << Obj.m_iNoCols
01520             << "\n  viscous damping:      " << Obj.m_tKvd
01521             << "\n  wind damping:         " << Obj.m_tKvfm
01522             << "\n  stiffness of structural, shear, and flexion springs: " 
01523                     << Obj.m_tKs[0] << ", " << Obj.m_tKs[1] << ", and " << Obj.m_tKs[2]
01524             << "\n  damping constant for structural, shear, and flexion springs: "
01525                     << Obj.m_tKd[0] << ", " << Obj.m_tKd[1] << ", and " << Obj.m_tKd[2]
01526             << "\n  length constrain for structural, shear, and flextion springs: "
01527                     << Obj.m_tLengthConstrain[0] << ", " 
01528                     << Obj.m_tLengthConstrain[1] << ", and " 
01529                     << Obj.m_tLengthConstrain[2]
01530             << "\n";
01531 
01532     return output;
01533 }*/
01534 
01535 template <typename T>
01536 void DeformMeshWithCut<T>::AddNormal( Vector3<T> & Dest, 
01537                        Vector3<T> const & A, Vector3<T> const & B, Vector3<T> const & C )
01538 {
01539     T U[3] = { A[0]-B[0], A[1]-B[1], A[2]-B[2] };
01540     T V[3] = { A[0]-C[0], A[1]-C[1], A[2]-C[2] };
01541     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] };
01542     T SqrtLength = Math<T>::Sqrt( W[0]*W[0] + W[1]*W[1] + W[2]*W[2] );
01543     Dest[0] += W[0]/SqrtLength;
01544     Dest[1] += W[1]/SqrtLength;
01545     Dest[2] += W[2]/SqrtLength;
01546 }
01547 //MEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBER
01548 
01549 //=============================================================================
01550 END_NAMESPACE_TAPs
01551 //-----------------------------------------------------------------------------
01552 #endif
01553 //345678901234567890123456789012345678901234567890123456789012345678901234567890
01554 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines