RayModel.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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");
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;
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 }
00153
00154 }
00155
00156 }
00157