RayModel.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 library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library 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 Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                               SOFA :: Modules                               *
00020 *                                                                             *
00021 * Authors: The SOFA Team and external contributors (see Authors.txt)          *
00022 *                                                                             *
00023 * Contact information: contact@sofa-framework.org                             *
00024 ******************************************************************************/
00025 #include <sofa/component/collision/RayModel.h>
00026 #include <sofa/component/collision/CubeModel.h>
00027 #include <sofa/core/ObjectFactory.h>
00028 #include <sofa/helper/gl/template.h>
00029 #include <sofa/helper/system/glut.h>
00030 
00031 
00032 namespace sofa
00033 {
00034 
00035 namespace component
00036 {
00037 
00038 namespace collision
00039 {
00040 
00041 SOFA_DECL_CLASS(Ray)
00042 
00043 int RayModelClass = core::RegisterObject("Collision model representing a ray in space, e.g. a mouse click")
00044 .add< RayModel >()
00045 .addAlias("Ray")
00046 ;
00047 
00048 
00049 using namespace sofa::defaulttype;
00050 
00051 RayModel::RayModel(Real length)
00052 : defaultLength(initData(&defaultLength, length, "", "TODO"))
00053 {
00054     this->contactResponse.setValue("ray"); // use RayContact response class
00055 }
00056 
00057 void RayModel::resize(int size)
00058 {
00059     this->component::MechanicalObject<Vec3Types>::resize(size);
00060     this->core::CollisionModel::resize(size/2);
00061     if ((int)length.size() < size/2)
00062     {
00063         length.reserve(size/2);
00064         while ((int)length.size() < size/2)
00065             length.push_back(defaultLength.getValue());
00066     }
00067     else
00068     {
00069         length.resize(size/2);
00070     }
00071 }
00072 
00073 int RayModel::addRay(const Vector3& origin, const Vector3& direction, Real length)
00074 {
00075     int i = size;
00076     resize(2*(i+1));
00077     Ray r = getRay(i);
00078     r.origin() = origin;
00079     r.direction() = direction;
00080     r.l() = length;
00081     return i;
00082 }
00083 
00084 void RayModel::draw(int index)
00085 {
00086     Ray r(this, index);
00087     const Vector3& p1 = r.origin();
00088     const Vector3 p2 = p1 + r.direction()*r.l();
00089     glBegin(GL_LINES);
00090     helper::gl::glVertexT(p1);
00091     helper::gl::glVertexT(p2);
00092     glEnd();
00093 }
00094 
00095 void RayModel::draw()
00096 {
00097     if (getContext()->getShowCollisionModels())
00098     {
00099         glDisable(GL_LIGHTING);
00100         glColor4fv(getColor4f());
00101         for (int i=0;i<size;i++)
00102         {
00103             draw(i);
00104         }
00105     }
00106     if (getPrevious()!=NULL && getContext()->getShowBoundingCollisionModels())
00107         getPrevious()->draw();
00108 }
00109 
00110 void RayModel::computeBoundingTree(int maxDepth)
00111 {
00112     CubeModel* cubeModel = createPrevious<CubeModel>();
00113     if (!isMoving() && !cubeModel->empty()) return; // No need to recompute BBox if immobile
00114     
00115     Vector3 minElem, maxElem;
00116 
00117     cubeModel->resize(size);
00118     if (!empty())
00119     {
00120         for (int i=0;i<size;i++)
00121         {
00122             Ray r(this, i);
00123             const Vector3& o = r.origin();
00124             const Vector3& d = r.direction();
00125             const Real l = r.l();
00126             for (int c=0;c<3;c++)
00127             {
00128                 if (d[c]<0)
00129                 {
00130                     minElem[c] = o[c] + d[c]*l;
00131                     maxElem[c] = o[c];
00132                 }
00133                 else
00134                 {
00135                     minElem[c] = o[c];
00136                     maxElem[c] = o[c] + d[c]*l;
00137                 }
00138             }
00139             cubeModel->setParentOf(i, minElem, maxElem);
00140         }
00141         cubeModel->computeBoundingTree(maxDepth);
00142     }
00143 }
00144 
00145 void RayModel::applyTranslation(double dx, double dy, double dz)
00146 {
00147     Vector3 d(dx,dy,dz);
00148     for (int i = 0; i < getNbRay(); i++)
00149         getRay(i).origin() += d;
00150 }
00151 
00152 } // namespace collision
00153 
00154 } // namespace component
00155 
00156 } // namespace sofa
00157 

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