Bullet Collision Detection & Physics Library

btTypedConstraint.cpp

Go to the documentation of this file.
00001 /*
00002 Bullet Continuous Collision Detection and Physics Library
00003 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
00004 
00005 This software is provided 'as-is', without any express or implied warranty.
00006 In no event will the authors be held liable for any damages arising from the use of this software.
00007 Permission is granted to anyone to use this software for any purpose, 
00008 including commercial applications, and to alter it and redistribute it freely, 
00009 subject to the following restrictions:
00010 
00011 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
00012 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
00013 3. This notice may not be removed or altered from any source distribution.
00014 */
00015 
00016 
00017 #include "btTypedConstraint.h"
00018 #include "BulletDynamics/Dynamics/btRigidBody.h"
00019 #include "LinearMath/btSerializer.h"
00020 
00021 
00022 #define DEFAULT_DEBUGDRAW_SIZE btScalar(0.3f)
00023 
00024 btTypedConstraint::btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA)
00025 :btTypedObject(type),
00026 m_userConstraintType(-1),
00027 m_userConstraintId(-1),
00028 m_breakingImpulseThreshold(SIMD_INFINITY),
00029 m_isEnabled(true),
00030 m_needsFeedback(false),
00031 m_overrideNumSolverIterations(-1),
00032 m_rbA(rbA),
00033 m_rbB(getFixedBody()),
00034 m_appliedImpulse(btScalar(0.)),
00035 m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE)
00036 {
00037 }
00038 
00039 
00040 btTypedConstraint::btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA,btRigidBody& rbB)
00041 :btTypedObject(type),
00042 m_userConstraintType(-1),
00043 m_userConstraintId(-1),
00044 m_breakingImpulseThreshold(SIMD_INFINITY),
00045 m_isEnabled(true),
00046 m_needsFeedback(false),
00047 m_overrideNumSolverIterations(-1),
00048 m_rbA(rbA),
00049 m_rbB(rbB),
00050 m_appliedImpulse(btScalar(0.)),
00051 m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE)
00052 {
00053 }
00054 
00055 
00056 
00057 
00058 btScalar btTypedConstraint::getMotorFactor(btScalar pos, btScalar lowLim, btScalar uppLim, btScalar vel, btScalar timeFact)
00059 {
00060         if(lowLim > uppLim)
00061         {
00062                 return btScalar(1.0f);
00063         }
00064         else if(lowLim == uppLim)
00065         {
00066                 return btScalar(0.0f);
00067         }
00068         btScalar lim_fact = btScalar(1.0f);
00069         btScalar delta_max = vel / timeFact;
00070         if(delta_max < btScalar(0.0f))
00071         {
00072                 if((pos >= lowLim) && (pos < (lowLim - delta_max)))
00073                 {
00074                         lim_fact = (lowLim - pos) / delta_max;
00075                 }
00076                 else if(pos  < lowLim)
00077                 {
00078                         lim_fact = btScalar(0.0f);
00079                 }
00080                 else
00081                 {
00082                         lim_fact = btScalar(1.0f);
00083                 }
00084         }
00085         else if(delta_max > btScalar(0.0f))
00086         {
00087                 if((pos <= uppLim) && (pos > (uppLim - delta_max)))
00088                 {
00089                         lim_fact = (uppLim - pos) / delta_max;
00090                 }
00091                 else if(pos  > uppLim)
00092                 {
00093                         lim_fact = btScalar(0.0f);
00094                 }
00095                 else
00096                 {
00097                         lim_fact = btScalar(1.0f);
00098                 }
00099         }
00100         else
00101         {
00102                         lim_fact = btScalar(0.0f);
00103         }
00104         return lim_fact;
00105 }
00106 
00108 const char*     btTypedConstraint::serialize(void* dataBuffer, btSerializer* serializer) const
00109 {
00110         btTypedConstraintData* tcd = (btTypedConstraintData*) dataBuffer;
00111 
00112         tcd->m_rbA = (btRigidBodyData*)serializer->getUniquePointer(&m_rbA);
00113         tcd->m_rbB = (btRigidBodyData*)serializer->getUniquePointer(&m_rbB);
00114         char* name = (char*) serializer->findNameForPointer(this);
00115         tcd->m_name = (char*)serializer->getUniquePointer(name);
00116         if (tcd->m_name)
00117         {
00118                 serializer->serializeName(name);
00119         }
00120 
00121         tcd->m_objectType = m_objectType;
00122         tcd->m_needsFeedback = m_needsFeedback;
00123         tcd->m_overrideNumSolverIterations = m_overrideNumSolverIterations;
00124         tcd->m_breakingImpulseThreshold = float(m_breakingImpulseThreshold);
00125         tcd->m_isEnabled = m_isEnabled? 1: 0;
00126         
00127         tcd->m_userConstraintId =m_userConstraintId;
00128         tcd->m_userConstraintType =m_userConstraintType;
00129 
00130         tcd->m_appliedImpulse = float(m_appliedImpulse);
00131         tcd->m_dbgDrawSize = float(m_dbgDrawSize );
00132 
00133         tcd->m_disableCollisionsBetweenLinkedBodies = false;
00134 
00135         int i;
00136         for (i=0;i<m_rbA.getNumConstraintRefs();i++)
00137                 if (m_rbA.getConstraintRef(i) == this)
00138                         tcd->m_disableCollisionsBetweenLinkedBodies = true;
00139         for (i=0;i<m_rbB.getNumConstraintRefs();i++)
00140                 if (m_rbB.getConstraintRef(i) == this)
00141                         tcd->m_disableCollisionsBetweenLinkedBodies = true;
00142 
00143         return "btTypedConstraintData";
00144 }
00145 
00146 btRigidBody& btTypedConstraint::getFixedBody()
00147 {
00148         static btRigidBody s_fixed(0, 0,0);
00149         s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.)));
00150         return s_fixed;
00151 }
00152 
00153 
00154 void btAngularLimit::set(btScalar low, btScalar high, btScalar _softness, btScalar _biasFactor, btScalar _relaxationFactor)
00155 {
00156         m_halfRange = (high - low) / 2.0f;
00157         m_center = btNormalizeAngle(low + m_halfRange);
00158         m_softness =  _softness;
00159         m_biasFactor = _biasFactor;
00160         m_relaxationFactor = _relaxationFactor;
00161 }
00162 
00163 void btAngularLimit::test(const btScalar angle)
00164 {
00165         m_correction = 0.0f;
00166         m_sign = 0.0f;
00167         m_solveLimit = false;
00168 
00169         if (m_halfRange >= 0.0f)
00170         {
00171                 btScalar deviation = btNormalizeAngle(angle - m_center);
00172                 if (deviation < -m_halfRange)
00173                 {
00174                         m_solveLimit = true;
00175                         m_correction = - (deviation + m_halfRange);
00176                         m_sign = +1.0f;
00177                 }
00178                 else if (deviation > m_halfRange)
00179                 {
00180                         m_solveLimit = true;
00181                         m_correction = m_halfRange - deviation;
00182                         m_sign = -1.0f;
00183                 }
00184         }
00185 }
00186 
00187 
00188 btScalar btAngularLimit::getError() const
00189 {
00190         return m_correction * m_sign;
00191 }
00192 
00193 void btAngularLimit::fit(btScalar& angle) const
00194 {
00195         if (m_halfRange > 0.0f)
00196         {
00197                 btScalar relativeAngle = btNormalizeAngle(angle - m_center);
00198                 if (!btEqual(relativeAngle, m_halfRange))
00199                 {
00200                         if (relativeAngle > 0.0f)
00201                         {
00202                                 angle = getHigh();
00203                         }
00204                         else
00205                         {
00206                                 angle = getLow();
00207                         }
00208                 }
00209         }
00210 }
00211 
00212 btScalar btAngularLimit::getLow() const
00213 {
00214         return btNormalizeAngle(m_center - m_halfRange);
00215 }
00216 
00217 btScalar btAngularLimit::getHigh() const
00218 {
00219         return btNormalizeAngle(m_center + m_halfRange);
00220 }