Home | History | Annotate | Download | only in ConstraintSolver
      1 /*
      2 Bullet Continuous Collision Detection and Physics Library
      3 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
      4 
      5 This software is provided 'as-is', without any express or implied warranty.
      6 In no event will the authors be held liable for any damages arising from the use of this software.
      7 Permission is granted to anyone to use this software for any purpose,
      8 including commercial applications, and to alter it and redistribute it freely,
      9 subject to the following restrictions:
     10 
     11 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.
     12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
     13 3. This notice may not be removed or altered from any source distribution.
     14 */
     15 
     16 
     17 #include "btTypedConstraint.h"
     18 #include "BulletDynamics/Dynamics/btRigidBody.h"
     19 #include "LinearMath/btSerializer.h"
     20 
     21 
     22 #define DEFAULT_DEBUGDRAW_SIZE btScalar(0.3f)
     23 
     24 btTypedConstraint::btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA)
     25 :btTypedObject(type),
     26 m_userConstraintType(-1),
     27 m_userConstraintPtr((void*)-1),
     28 m_breakingImpulseThreshold(SIMD_INFINITY),
     29 m_isEnabled(true),
     30 m_needsFeedback(false),
     31 m_overrideNumSolverIterations(-1),
     32 m_rbA(rbA),
     33 m_rbB(getFixedBody()),
     34 m_appliedImpulse(btScalar(0.)),
     35 m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE),
     36 m_jointFeedback(0)
     37 {
     38 }
     39 
     40 
     41 btTypedConstraint::btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA,btRigidBody& rbB)
     42 :btTypedObject(type),
     43 m_userConstraintType(-1),
     44 m_userConstraintPtr((void*)-1),
     45 m_breakingImpulseThreshold(SIMD_INFINITY),
     46 m_isEnabled(true),
     47 m_needsFeedback(false),
     48 m_overrideNumSolverIterations(-1),
     49 m_rbA(rbA),
     50 m_rbB(rbB),
     51 m_appliedImpulse(btScalar(0.)),
     52 m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE),
     53 m_jointFeedback(0)
     54 {
     55 }
     56 
     57 
     58 
     59 
     60 btScalar btTypedConstraint::getMotorFactor(btScalar pos, btScalar lowLim, btScalar uppLim, btScalar vel, btScalar timeFact)
     61 {
     62 	if(lowLim > uppLim)
     63 	{
     64 		return btScalar(1.0f);
     65 	}
     66 	else if(lowLim == uppLim)
     67 	{
     68 		return btScalar(0.0f);
     69 	}
     70 	btScalar lim_fact = btScalar(1.0f);
     71 	btScalar delta_max = vel / timeFact;
     72 	if(delta_max < btScalar(0.0f))
     73 	{
     74 		if((pos >= lowLim) && (pos < (lowLim - delta_max)))
     75 		{
     76 			lim_fact = (lowLim - pos) / delta_max;
     77 		}
     78 		else if(pos  < lowLim)
     79 		{
     80 			lim_fact = btScalar(0.0f);
     81 		}
     82 		else
     83 		{
     84 			lim_fact = btScalar(1.0f);
     85 		}
     86 	}
     87 	else if(delta_max > btScalar(0.0f))
     88 	{
     89 		if((pos <= uppLim) && (pos > (uppLim - delta_max)))
     90 		{
     91 			lim_fact = (uppLim - pos) / delta_max;
     92 		}
     93 		else if(pos  > uppLim)
     94 		{
     95 			lim_fact = btScalar(0.0f);
     96 		}
     97 		else
     98 		{
     99 			lim_fact = btScalar(1.0f);
    100 		}
    101 	}
    102 	else
    103 	{
    104 			lim_fact = btScalar(0.0f);
    105 	}
    106 	return lim_fact;
    107 }
    108 
    109 ///fills the dataBuffer and returns the struct name (and 0 on failure)
    110 const char*	btTypedConstraint::serialize(void* dataBuffer, btSerializer* serializer) const
    111 {
    112 	btTypedConstraintData2* tcd = (btTypedConstraintData2*) dataBuffer;
    113 
    114 	tcd->m_rbA = (btRigidBodyData*)serializer->getUniquePointer(&m_rbA);
    115 	tcd->m_rbB = (btRigidBodyData*)serializer->getUniquePointer(&m_rbB);
    116 	char* name = (char*) serializer->findNameForPointer(this);
    117 	tcd->m_name = (char*)serializer->getUniquePointer(name);
    118 	if (tcd->m_name)
    119 	{
    120 		serializer->serializeName(name);
    121 	}
    122 
    123 	tcd->m_objectType = m_objectType;
    124 	tcd->m_needsFeedback = m_needsFeedback;
    125 	tcd->m_overrideNumSolverIterations = m_overrideNumSolverIterations;
    126 	tcd->m_breakingImpulseThreshold = m_breakingImpulseThreshold;
    127 	tcd->m_isEnabled = m_isEnabled? 1: 0;
    128 
    129 	tcd->m_userConstraintId =m_userConstraintId;
    130 	tcd->m_userConstraintType =m_userConstraintType;
    131 
    132 	tcd->m_appliedImpulse = m_appliedImpulse;
    133 	tcd->m_dbgDrawSize = m_dbgDrawSize;
    134 
    135 	tcd->m_disableCollisionsBetweenLinkedBodies = false;
    136 
    137 	int i;
    138 	for (i=0;i<m_rbA.getNumConstraintRefs();i++)
    139 		if (m_rbA.getConstraintRef(i) == this)
    140 			tcd->m_disableCollisionsBetweenLinkedBodies = true;
    141 	for (i=0;i<m_rbB.getNumConstraintRefs();i++)
    142 		if (m_rbB.getConstraintRef(i) == this)
    143 			tcd->m_disableCollisionsBetweenLinkedBodies = true;
    144 
    145 	return btTypedConstraintDataName;
    146 }
    147 
    148 btRigidBody& btTypedConstraint::getFixedBody()
    149 {
    150 	static btRigidBody s_fixed(0, 0,0);
    151 	s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.)));
    152 	return s_fixed;
    153 }
    154 
    155 
    156 void btAngularLimit::set(btScalar low, btScalar high, btScalar _softness, btScalar _biasFactor, btScalar _relaxationFactor)
    157 {
    158 	m_halfRange = (high - low) / 2.0f;
    159 	m_center = btNormalizeAngle(low + m_halfRange);
    160 	m_softness =  _softness;
    161 	m_biasFactor = _biasFactor;
    162 	m_relaxationFactor = _relaxationFactor;
    163 }
    164 
    165 void btAngularLimit::test(const btScalar angle)
    166 {
    167 	m_correction = 0.0f;
    168 	m_sign = 0.0f;
    169 	m_solveLimit = false;
    170 
    171 	if (m_halfRange >= 0.0f)
    172 	{
    173 		btScalar deviation = btNormalizeAngle(angle - m_center);
    174 		if (deviation < -m_halfRange)
    175 		{
    176 			m_solveLimit = true;
    177 			m_correction = - (deviation + m_halfRange);
    178 			m_sign = +1.0f;
    179 		}
    180 		else if (deviation > m_halfRange)
    181 		{
    182 			m_solveLimit = true;
    183 			m_correction = m_halfRange - deviation;
    184 			m_sign = -1.0f;
    185 		}
    186 	}
    187 }
    188 
    189 
    190 btScalar btAngularLimit::getError() const
    191 {
    192 	return m_correction * m_sign;
    193 }
    194 
    195 void btAngularLimit::fit(btScalar& angle) const
    196 {
    197 	if (m_halfRange > 0.0f)
    198 	{
    199 		btScalar relativeAngle = btNormalizeAngle(angle - m_center);
    200 		if (!btEqual(relativeAngle, m_halfRange))
    201 		{
    202 			if (relativeAngle > 0.0f)
    203 			{
    204 				angle = getHigh();
    205 			}
    206 			else
    207 			{
    208 				angle = getLow();
    209 			}
    210 		}
    211 	}
    212 }
    213 
    214 btScalar btAngularLimit::getLow() const
    215 {
    216 	return btNormalizeAngle(m_center - m_halfRange);
    217 }
    218 
    219 btScalar btAngularLimit::getHigh() const
    220 {
    221 	return btNormalizeAngle(m_center + m_halfRange);
    222 }
    223