Blender  V2.59
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_needsFeedback(false),
00029 m_rbA(rbA),
00030 m_rbB(getFixedBody()),
00031 m_appliedImpulse(btScalar(0.)),
00032 m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE)
00033 {
00034 }
00035 
00036 
00037 btTypedConstraint::btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA,btRigidBody& rbB)
00038 :btTypedObject(type),
00039 m_userConstraintType(-1),
00040 m_userConstraintId(-1),
00041 m_needsFeedback(false),
00042 m_rbA(rbA),
00043 m_rbB(rbB),
00044 m_appliedImpulse(btScalar(0.)),
00045 m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE)
00046 {
00047 }
00048 
00049 
00050 
00051 
00052 btScalar btTypedConstraint::getMotorFactor(btScalar pos, btScalar lowLim, btScalar uppLim, btScalar vel, btScalar timeFact)
00053 {
00054         if(lowLim > uppLim)
00055         {
00056                 return btScalar(1.0f);
00057         }
00058         else if(lowLim == uppLim)
00059         {
00060                 return btScalar(0.0f);
00061         }
00062         btScalar lim_fact = btScalar(1.0f);
00063         btScalar delta_max = vel / timeFact;
00064         if(delta_max < btScalar(0.0f))
00065         {
00066                 if((pos >= lowLim) && (pos < (lowLim - delta_max)))
00067                 {
00068                         lim_fact = (lowLim - pos) / delta_max;
00069                 }
00070                 else if(pos  < lowLim)
00071                 {
00072                         lim_fact = btScalar(0.0f);
00073                 }
00074                 else
00075                 {
00076                         lim_fact = btScalar(1.0f);
00077                 }
00078         }
00079         else if(delta_max > btScalar(0.0f))
00080         {
00081                 if((pos <= uppLim) && (pos > (uppLim - delta_max)))
00082                 {
00083                         lim_fact = (uppLim - pos) / delta_max;
00084                 }
00085                 else if(pos  > uppLim)
00086                 {
00087                         lim_fact = btScalar(0.0f);
00088                 }
00089                 else
00090                 {
00091                         lim_fact = btScalar(1.0f);
00092                 }
00093         }
00094         else
00095         {
00096                         lim_fact = btScalar(0.0f);
00097         }
00098         return lim_fact;
00099 }
00100 
00102 const char*     btTypedConstraint::serialize(void* dataBuffer, btSerializer* serializer) const
00103 {
00104         btTypedConstraintData* tcd = (btTypedConstraintData*) dataBuffer;
00105 
00106         tcd->m_rbA = (btRigidBodyData*)serializer->getUniquePointer(&m_rbA);
00107         tcd->m_rbB = (btRigidBodyData*)serializer->getUniquePointer(&m_rbB);
00108         char* name = (char*) serializer->findNameForPointer(this);
00109         tcd->m_name = (char*)serializer->getUniquePointer(name);
00110         if (tcd->m_name)
00111         {
00112                 serializer->serializeName(name);
00113         }
00114 
00115         tcd->m_objectType = m_objectType;
00116         tcd->m_needsFeedback = m_needsFeedback;
00117         tcd->m_userConstraintId =m_userConstraintId;
00118         tcd->m_userConstraintType =m_userConstraintType;
00119 
00120         tcd->m_appliedImpulse = float(m_appliedImpulse);
00121         tcd->m_dbgDrawSize = float(m_dbgDrawSize );
00122 
00123         tcd->m_disableCollisionsBetweenLinkedBodies = false;
00124 
00125         int i;
00126         for (i=0;i<m_rbA.getNumConstraintRefs();i++)
00127                 if (m_rbA.getConstraintRef(i) == this)
00128                         tcd->m_disableCollisionsBetweenLinkedBodies = true;
00129         for (i=0;i<m_rbB.getNumConstraintRefs();i++)
00130                 if (m_rbB.getConstraintRef(i) == this)
00131                         tcd->m_disableCollisionsBetweenLinkedBodies = true;
00132 
00133         return "btTypedConstraintData";
00134 }
00135 
00136 btRigidBody& btTypedConstraint::getFixedBody()
00137 {
00138         static btRigidBody s_fixed(0, 0,0);
00139         s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.)));
00140         return s_fixed;
00141 }
00142 
00143 
00144 void btAngularLimit::set(btScalar low, btScalar high, btScalar _softness, btScalar _biasFactor, btScalar _relaxationFactor)
00145 {
00146         m_halfRange = (high - low) / 2.0f;
00147         m_center = btNormalizeAngle(low + m_halfRange);
00148         m_softness =  _softness;
00149         m_biasFactor = _biasFactor;
00150         m_relaxationFactor = _relaxationFactor;
00151 }
00152 
00153 void btAngularLimit::test(const btScalar angle)
00154 {
00155         m_correction = 0.0f;
00156         m_sign = 0.0f;
00157         m_solveLimit = false;
00158 
00159         if (m_halfRange >= 0.0f)
00160         {
00161                 btScalar deviation = btNormalizeAngle(angle - m_center);
00162                 if (deviation < -m_halfRange)
00163                 {
00164                         m_solveLimit = true;
00165                         m_correction = - (deviation + m_halfRange);
00166                         m_sign = +1.0f;
00167                 }
00168                 else if (deviation > m_halfRange)
00169                 {
00170                         m_solveLimit = true;
00171                         m_correction = m_halfRange - deviation;
00172                         m_sign = -1.0f;
00173                 }
00174         }
00175 }
00176 
00177 
00178 btScalar btAngularLimit::getError() const
00179 {
00180         return m_correction * m_sign;
00181 }
00182 
00183 void btAngularLimit::fit(btScalar& angle) const
00184 {
00185         if (m_halfRange > 0.0f)
00186         {
00187                 btScalar relativeAngle = btNormalizeAngle(angle - m_center);
00188                 if (!btEqual(relativeAngle, m_halfRange))
00189                 {
00190                         if (relativeAngle > 0.0f)
00191                         {
00192                                 angle = getHigh();
00193                         }
00194                         else
00195                         {
00196                                 angle = getLow();
00197                         }
00198                 }
00199         }
00200 }
00201 
00202 btScalar btAngularLimit::getLow() const
00203 {
00204         return btNormalizeAngle(m_center - m_halfRange);
00205 }
00206 
00207 btScalar btAngularLimit::getHigh() const
00208 {
00209         return btNormalizeAngle(m_center + m_halfRange);
00210 }