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 #ifndef SOFA_COMPONENT_CONSTRAINT_PARABOLICCONSTRAINT_INL
00026 #define SOFA_COMPONENT_CONSTRAINT_PARABOLICCONSTRAINT_INL
00027
00028 #include <sofa/component/constraint/ParabolicConstraint.h>
00029 #include <sofa/helper/gl/template.h>
00030
00031 namespace sofa
00032 {
00033
00034 namespace component
00035 {
00036
00037 namespace constraint
00038 {
00039
00040 using namespace sofa::defaulttype;
00041 using namespace sofa::helper;
00042
00043 template <class DataTypes>
00044 ParabolicConstraint<DataTypes>::ParabolicConstraint()
00045 :core::componentmodel::behavior::Constraint<DataTypes>(NULL)
00046 , m_indices( initData(&m_indices,"indices","Indices of the constrained points") )
00047 , m_P1(initData(&m_P1,"P1","first point of the parabol") )
00048 , m_P2(initData(&m_P2,"P2","second point of the parabol") )
00049 , m_P3(initData(&m_P3,"P3","third point of the parabol") )
00050 , m_tBegin(initData(&m_tBegin,"BeginTime","Begin Time of the motion") )
00051 , m_tEnd(initData(&m_tEnd,"EndTime","End Time of the motion") )
00052 {
00053 }
00054
00055
00056 template <class DataTypes>
00057 ParabolicConstraint<DataTypes>::ParabolicConstraint(core::componentmodel::behavior::MechanicalState<DataTypes>* mstate)
00058 : core::componentmodel::behavior::Constraint<DataTypes>(mstate)
00059 , m_indices( initData(&m_indices,"indices","Indices of the constrained points") )
00060 , m_P1(initData(&m_P1,"P1","first point of the parabol") )
00061 , m_P2(initData(&m_P2,"P2","second point of the parabol") )
00062 , m_P3(initData(&m_P3,"P3","third point of the parabol") )
00063 , m_tBegin(initData(&m_tBegin,"BeginTime","Begin Time of the motion") )
00064 , m_tEnd(initData(&m_tEnd,"EndTime","End Time of the motion") )
00065 {
00066 }
00067
00068 template <class DataTypes>
00069 ParabolicConstraint<DataTypes>::~ParabolicConstraint()
00070 {
00071 }
00072
00073 template <class DataTypes>
00074 void ParabolicConstraint<DataTypes>::addConstraint(unsigned index)
00075 {
00076 m_indices.beginEdit()->push_back(index);
00077 m_indices.endEdit();
00078 }
00079
00080
00081 template <class DataTypes>
00082 void ParabolicConstraint<DataTypes>::init()
00083 {
00084 this->core::componentmodel::behavior::Constraint<DataTypes>::init();
00085
00086 Vec3R P1 = m_P1.getValue();
00087 Vec3R P2 = m_P2.getValue();
00088 Vec3R P3 = m_P3.getValue();
00089
00090
00091
00092
00093 if(P1 != P2 && P1 != P3 && P2 != P3){
00094
00095 Vec3R P1P2 = P2 - P1;
00096 Vec3R P1P3 = P3 - P1;
00097
00098 Vec3R ax = P1P3;
00099 Vec3R az = cross(P1P3, P1P2);
00100 Vec3R ay = cross(az, ax);
00101 ax.normalize();
00102 ay.normalize();
00103 az.normalize();
00104
00105 Mat<3,3,Real> Mrot(ax, ay, az);
00106 Mat<3,3,Real> Mrot2;
00107 Mrot2.transpose(Mrot);
00108 m_projection.fromMatrix(Mrot2);
00109 m_projection.normalize();
00110
00111 m_locP1 = Vec3R();
00112 m_locP2 = m_projection.inverseRotate(P1P2);
00113 m_locP3 = m_projection.inverseRotate(P1P3);
00114 }
00115 }
00116
00117 template <class DataTypes>
00118 void ParabolicConstraint<DataTypes>::reinit()
00119 {
00120 init();
00121 }
00122
00123
00124 template <class DataTypes>
00125 void ParabolicConstraint<DataTypes>::projectResponse(VecDeriv& dx)
00126 {
00127 Real t = (Real) getContext()->getTime();
00128 if ( t >= m_tBegin.getValue() && t <= m_tEnd.getValue())
00129 {
00130 const SetIndexArray & indices = m_indices.getValue().getArray();
00131 for(SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it)
00132 dx[*it] = Deriv();
00133 }
00134 }
00135
00136 template <class DataTypes>
00137 void ParabolicConstraint<DataTypes>::projectVelocity(VecDeriv& dx)
00138 {
00139 Real t = (Real) getContext()->getTime();
00140 Real dt = (Real) getContext()->getDt();
00141
00142 if ( t >= m_tBegin.getValue() && t <= m_tEnd.getValue() )
00143 {
00144 Real relativeTime = (t - m_tBegin.getValue() ) / (m_tEnd.getValue() - m_tBegin.getValue());
00145 const SetIndexArray & indices = m_indices.getValue().getArray();
00146
00147 for(SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it)
00148 {
00149
00150 Real pxP = m_locP3.x()*relativeTime;
00151 Real pyP = (- m_locP2.y() / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * (pxP *pxP) + ( (m_locP3.x()*m_locP2.y()) / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * pxP;
00152 relativeTime = (t+dt - m_tBegin.getValue() ) / (m_tEnd.getValue() - m_tBegin.getValue());
00153 Real pxN = m_locP3.x()*relativeTime;
00154 Real pyN = (- m_locP2.y() / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * (pxN *pxN) + ( (m_locP3.x()*m_locP2.y()) / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * pxN;
00155
00156 Vec3R locVel = Vec3R( (pxN-pxP)/dt, (pyN-pyP)/dt, 0.0);
00157
00158 Vec3R worldVel = m_projection.rotate(locVel);
00159
00160 dx[*it] = worldVel;
00161 }
00162 }
00163 }
00164
00165 template <class DataTypes>
00166 void ParabolicConstraint<DataTypes>::projectPosition(VecCoord& x)
00167 {
00168 Real t = (Real) getContext()->getTime();
00169
00170 if ( t >= m_tBegin.getValue() && t <= m_tEnd.getValue() )
00171 {
00172 Real relativeTime = (t - m_tBegin.getValue() ) / (m_tEnd.getValue() - m_tBegin.getValue());
00173 const SetIndexArray & indices = m_indices.getValue().getArray();
00174
00175 for(SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it)
00176 {
00177
00178
00179 Real px = m_locP3.x()*relativeTime;
00180 Real py = (- m_locP2.y() / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * (px *px) + ( (m_locP3.x()*m_locP2.y()) / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * px;
00181 Vec3R locPos( px , py, 0.0);
00182
00183
00184 Vec3R worldPos = m_P1.getValue() + m_projection.rotate(locPos);
00185
00186 x[*it] = worldPos;
00187 }
00188 }
00189 }
00190
00191
00192 template <class DataTypes>
00193 void ParabolicConstraint<DataTypes>::draw()
00194 {
00195 if (!getContext()->getShowBehaviorModels()) return;
00196
00197 Real dt = (Real) getContext()->getDt();
00198 Real t = m_tEnd.getValue() - m_tBegin.getValue();
00199 Real nbStep = t/dt;
00200
00201 glDisable (GL_LIGHTING);
00202 glPointSize(5);
00203 glColor4f (1,0.5,0.5,1);
00204
00205 glBegin (GL_LINES);
00206 for (unsigned int i=0 ; i< nbStep ; i++){
00207
00208
00209 Real relativeTime = i/nbStep;
00210 Real px = m_locP3.x()*relativeTime;
00211 Real py = (- m_locP2.y() / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * (px *px) + ( (m_locP3.x()*m_locP2.y()) / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * px;
00212 Vec3R locPos( px , py, 0.0);
00213 Vec3R worldPos = m_P1.getValue() + m_projection.rotate(locPos);
00214
00215 gl::glVertexT(worldPos);
00216
00217 relativeTime = (i+1)/nbStep;
00218 px = m_locP3.x()*relativeTime;
00219 py = (- m_locP2.y() / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * (px *px) + ( (m_locP3.x()*m_locP2.y()) / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * px;
00220 locPos = Vec3R( px , py, 0.0);
00221 worldPos = m_P1.getValue() + m_projection.rotate(locPos);
00222 gl::glVertexT(worldPos);
00223 }
00224 glEnd();
00225
00226
00227 glBegin(GL_POINTS);
00228 gl::glVertexT(m_P1.getValue());
00229 gl::glVertexT(m_P2.getValue());
00230 gl::glVertexT(m_P3.getValue());
00231 glEnd();
00232 }
00233
00234
00235 }
00236
00237 }
00238
00239 }
00240
00241 #endif