GenerateRigid.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This program is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU General Public License as published by the Free  *
00007 * Software Foundation; either version 2 of the License, or (at your option)   *
00008 * any later version.                                                          *
00009 *                                                                             *
00010 * This program is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    *
00013 * more details.                                                               *
00014 *                                                                             *
00015 * You should have received a copy of the GNU General Public License along     *
00016 * with this program; if not, write to the Free Software Foundation, Inc., 51  *
00017 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.                   *
00018 *******************************************************************************
00019 *                            SOFA :: Applications                             *
00020 *                                                                             *
00021 * Authors: M. Adam, J. Allard, B. Andre, P-J. Bensoussan, S. Cotin, C. Duriez,*
00022 * H. Delingette, F. Falipou, F. Faure, S. Fonteneau, L. Heigeas, C. Mendoza,  *
00023 * M. Nesme, P. Neumann, J-P. de la Plata Alcade, F. Poyer and F. Roy          *
00024 *                                                                             *
00025 * Contact information: contact@sofa-framework.org                             *
00026 ******************************************************************************/
00027 #include "GenerateRigid.h"
00028 
00029 #include <stdlib.h>
00030 #include <math.h>
00031 #include <sofa/helper/vector.h>
00032 
00033 namespace projects
00034 {
00035 
00036 bool GenerateRigid(sofa::defaulttype::Rigid3Mass& mass, sofa::defaulttype::Vec3d& center, sofa::helper::io::Mesh* mesh)
00037 {
00038     using namespace sofa::defaulttype;
00039     using namespace sofa::helper;
00040     // Geometric Tools, Inc.
00041     // http://www.geometrictools.com
00042     // Copyright (c) 1998-2006. All Rights Reserved
00043     //
00044     // The Wild Magic Library (WM3) source code is supplied under the terms of
00045     // the license agreement
00046     //     http://www.geometrictools.com/License/WildMagic3License.pdf
00047     // and may not be copied or disclosed except in accordance with the terms
00048     // of that agreement.
00049     
00050     // order:   1, x, y, z, x^2, y^2, z^2, xy, yz, zx
00051     double afIntegral[10] = { (double)0.0, (double)0.0, (double)0.0, (double)0.0,
00052         (double)0.0, (double)0.0, (double)0.0, (double)0.0, (double)0.0, (double)0.0 };
00053 
00054     const vector<Vector3>& points = mesh->getVertices();
00055     const vector< vector< vector<int> > >& facets = mesh->getFacets();
00056     for (unsigned int i = 0; i < facets.size(); i++)
00057     {
00058         const vector<int>& v = facets[i][0];
00059         for (unsigned int j = 2; j < v.size(); j++)
00060         {
00061             // get vertices of current triangle
00062             const Vector3 kV0 = points[v[0  ]];
00063             const Vector3 kV1 = points[v[j-1]];
00064             const Vector3 kV2 = points[v[j  ]];
00065 
00066             // get cross product of edges
00067             Vector3 kV1mV0 = kV1 - kV0;
00068             Vector3 kV2mV0 = kV2 - kV0;
00069             Vector3 kN = cross(kV1mV0,kV2mV0);
00070 
00071             // compute integral terms
00072             double fTmp0, fTmp1, fTmp2;
00073             double fF1x, fF2x, fF3x, fG0x, fG1x, fG2x;
00074             fTmp0 = kV0[0] + kV1[0];
00075             fF1x = fTmp0 + kV2[0];
00076             fTmp1 = kV0[0]*kV0[0];
00077             fTmp2 = fTmp1 + kV1[0]*fTmp0;
00078             fF2x = fTmp2 + kV2[0]*fF1x;
00079             fF3x = kV0[0]*fTmp1 + kV1[0]*fTmp2 + kV2[0]*fF2x;
00080             fG0x = fF2x + kV0[0]*(fF1x + kV0[0]);
00081             fG1x = fF2x + kV1[0]*(fF1x + kV1[0]);
00082             fG2x = fF2x + kV2[0]*(fF1x + kV2[0]);
00083             
00084             double fF1y, fF2y, fF3y, fG0y, fG1y, fG2y;
00085             fTmp0 = kV0[1] + kV1[1];
00086             fF1y = fTmp0 + kV2[1];
00087             fTmp1 = kV0[1]*kV0[1];
00088             fTmp2 = fTmp1 + kV1[1]*fTmp0;
00089             fF2y = fTmp2 + kV2[1]*fF1y;
00090             fF3y = kV0[1]*fTmp1 + kV1[1]*fTmp2 + kV2[1]*fF2y;
00091             fG0y = fF2y + kV0[1]*(fF1y + kV0[1]);
00092             fG1y = fF2y + kV1[1]*(fF1y + kV1[1]);
00093             fG2y = fF2y + kV2[1]*(fF1y + kV2[1]);
00094             
00095             double fF1z, fF2z, fF3z, fG0z, fG1z, fG2z;
00096             fTmp0 = kV0[2] + kV1[2];
00097             fF1z = fTmp0 + kV2[2];
00098             fTmp1 = kV0[2]*kV0[2];
00099             fTmp2 = fTmp1 + kV1[2]*fTmp0;
00100             fF2z = fTmp2 + kV2[2]*fF1z;
00101             fF3z = kV0[2]*fTmp1 + kV1[2]*fTmp2 + kV2[2]*fF2z;
00102             fG0z = fF2z + kV0[2]*(fF1z + kV0[2]);
00103             fG1z = fF2z + kV1[2]*(fF1z + kV1[2]);
00104             fG2z = fF2z + kV2[2]*(fF1z + kV2[2]);
00105             
00106             // update integrals
00107             afIntegral[0] += kN[0]*fF1x;
00108             afIntegral[1] += kN[0]*fF2x;
00109             afIntegral[2] += kN[1]*fF2y;
00110             afIntegral[3] += kN[2]*fF2z;
00111             afIntegral[4] += kN[0]*fF3x;
00112             afIntegral[5] += kN[1]*fF3y;
00113             afIntegral[6] += kN[2]*fF3z;
00114             afIntegral[7] += kN[0]*(kV0[1]*fG0x + kV1[1]*fG1x + kV2[1]*fG2x);
00115             afIntegral[8] += kN[1]*(kV0[2]*fG0y + kV1[2]*fG1y + kV2[2]*fG2y);
00116             afIntegral[9] += kN[2]*(kV0[0]*fG0z + kV1[0]*fG1z + kV2[0]*fG2z);
00117         }
00118     }
00119     
00120     afIntegral[0] /= 6.0;
00121     afIntegral[1] /= 24.0;
00122     afIntegral[2] /= 24.0;
00123     afIntegral[3] /= 24.0;
00124     afIntegral[4] /= 60.0;
00125     afIntegral[5] /= 60.0;
00126     afIntegral[6] /= 60.0;
00127     afIntegral[7] /= 120.0;
00128     afIntegral[8] /= 120.0;
00129     afIntegral[9] /= 120.0;
00130 
00131     // mass
00132     mass.mass = mass.volume = afIntegral[0];
00133 
00134     // center of mass
00135     center = Vector3(afIntegral[1]/afIntegral[0],afIntegral[2]/afIntegral[0],afIntegral[3]/afIntegral[0]);
00136 
00137     // inertia relative to world origin
00138     mass.inertiaMatrix[0][0] = afIntegral[5] + afIntegral[6];
00139     mass.inertiaMatrix[0][1] = -afIntegral[7];
00140     mass.inertiaMatrix[0][2] = -afIntegral[9];
00141     mass.inertiaMatrix[1][0] = mass.inertiaMatrix[0][1];
00142     mass.inertiaMatrix[1][1] = afIntegral[4] + afIntegral[6];
00143     mass.inertiaMatrix[1][2] = -afIntegral[8];
00144     mass.inertiaMatrix[2][0] = mass.inertiaMatrix[0][2];
00145     mass.inertiaMatrix[2][1] = mass.inertiaMatrix[1][2];
00146     mass.inertiaMatrix[2][2] = afIntegral[4] + afIntegral[5];
00147 
00148     // inertia relative to center of mass
00149     mass.inertiaMatrix[0][0] -= mass.mass*(center[1]*center[1] + center[2]*center[2]);
00150     mass.inertiaMatrix[0][1] += mass.mass*center[0]*center[1];
00151     mass.inertiaMatrix[0][2] += mass.mass*center[2]*center[0];
00152     mass.inertiaMatrix[1][0] = mass.inertiaMatrix[0][1];
00153     mass.inertiaMatrix[1][1] -= mass.mass*(center[2]*center[2] + center[0]*center[0]);
00154     mass.inertiaMatrix[1][2] += mass.mass*center[1]*center[2];
00155     mass.inertiaMatrix[2][0] = mass.inertiaMatrix[0][2];
00156     mass.inertiaMatrix[2][1] = mass.inertiaMatrix[1][2];
00157     mass.inertiaMatrix[2][2] -= mass.mass*(center[0]*center[0] + center[1]*center[1]);
00158 
00159     mass.inertiaMatrix /= mass.mass;
00160 
00161     mass.recalc();
00162     return true;
00163 }
00164 
00165 }

Generated on Sun Nov 23 02:28:34 2008 for Sofa by  doxygen 1.5.7.1