Blender V2.61 - r43446

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 }