2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans https://bulletphysics.org
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:
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.
16 #include "btTypedConstraint.h"
17 #include "BulletDynamics/Dynamics/btRigidBody.h"
18 #include "LinearMath/btSerializer.h"
20 #define DEFAULT_DEBUGDRAW_SIZE btScalar(0.05f)
22 btTypedConstraint::btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA)
23 : btTypedObject(type),
24 m_userConstraintType(-1),
25 m_userConstraintPtr((void*)-1),
26 m_breakingImpulseThreshold(SIMD_INFINITY),
28 m_needsFeedback(false),
29 m_overrideNumSolverIterations(-1),
31 m_rbB(getFixedBody()),
32 m_appliedImpulse(btScalar(0.)),
33 m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE),
38 btTypedConstraint::btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA, btRigidBody& rbB)
39 : btTypedObject(type),
40 m_userConstraintType(-1),
41 m_userConstraintPtr((void*)-1),
42 m_breakingImpulseThreshold(SIMD_INFINITY),
44 m_needsFeedback(false),
45 m_overrideNumSolverIterations(-1),
48 m_appliedImpulse(btScalar(0.)),
49 m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE),
54 btScalar btTypedConstraint::getMotorFactor(btScalar pos, btScalar lowLim, btScalar uppLim, btScalar vel, btScalar timeFact)
58 return btScalar(1.0f);
60 else if (lowLim == uppLim)
62 return btScalar(0.0f);
64 btScalar lim_fact = btScalar(1.0f);
65 btScalar delta_max = vel / timeFact;
66 if (delta_max < btScalar(0.0f))
68 if ((pos >= lowLim) && (pos < (lowLim - delta_max)))
70 lim_fact = (lowLim - pos) / delta_max;
72 else if (pos < lowLim)
74 lim_fact = btScalar(0.0f);
78 lim_fact = btScalar(1.0f);
81 else if (delta_max > btScalar(0.0f))
83 if ((pos <= uppLim) && (pos > (uppLim - delta_max)))
85 lim_fact = (uppLim - pos) / delta_max;
87 else if (pos > uppLim)
89 lim_fact = btScalar(0.0f);
93 lim_fact = btScalar(1.0f);
98 lim_fact = btScalar(0.0f);
103 ///fills the dataBuffer and returns the struct name (and 0 on failure)
104 const char* btTypedConstraint::serialize(void* dataBuffer, btSerializer* serializer) const
106 btTypedConstraintData2* tcd = (btTypedConstraintData2*)dataBuffer;
108 tcd->m_rbA = (btRigidBodyData*)serializer->getUniquePointer(&m_rbA);
109 tcd->m_rbB = (btRigidBodyData*)serializer->getUniquePointer(&m_rbB);
110 char* name = (char*)serializer->findNameForPointer(this);
111 tcd->m_name = (char*)serializer->getUniquePointer(name);
114 serializer->serializeName(name);
117 tcd->m_objectType = m_objectType;
118 tcd->m_needsFeedback = m_needsFeedback;
119 tcd->m_overrideNumSolverIterations = m_overrideNumSolverIterations;
120 tcd->m_breakingImpulseThreshold = m_breakingImpulseThreshold;
121 tcd->m_isEnabled = m_isEnabled ? 1 : 0;
123 tcd->m_userConstraintId = m_userConstraintId;
124 tcd->m_userConstraintType = m_userConstraintType;
126 tcd->m_appliedImpulse = m_appliedImpulse;
127 tcd->m_dbgDrawSize = m_dbgDrawSize;
129 tcd->m_disableCollisionsBetweenLinkedBodies = false;
132 for (i = 0; i < m_rbA.getNumConstraintRefs(); i++)
133 if (m_rbA.getConstraintRef(i) == this)
134 tcd->m_disableCollisionsBetweenLinkedBodies = true;
135 for (i = 0; i < m_rbB.getNumConstraintRefs(); i++)
136 if (m_rbB.getConstraintRef(i) == this)
137 tcd->m_disableCollisionsBetweenLinkedBodies = true;
139 return btTypedConstraintDataName;
142 btRigidBody& btTypedConstraint::getFixedBody()
144 static btRigidBody s_fixed(0, 0, 0);
145 s_fixed.setMassProps(btScalar(0.), btVector3(btScalar(0.), btScalar(0.), btScalar(0.)));
149 void btAngularLimit::set(btScalar low, btScalar high, btScalar _softness, btScalar _biasFactor, btScalar _relaxationFactor)
151 m_halfRange = (high - low) / 2.0f;
152 m_center = btNormalizeAngle(low + m_halfRange);
153 m_softness = _softness;
154 m_biasFactor = _biasFactor;
155 m_relaxationFactor = _relaxationFactor;
158 void btAngularLimit::test(const btScalar angle)
162 m_solveLimit = false;
164 if (m_halfRange >= 0.0f)
166 btScalar deviation = btNormalizeAngle(angle - m_center);
167 if (deviation < -m_halfRange)
170 m_correction = -(deviation + m_halfRange);
173 else if (deviation > m_halfRange)
176 m_correction = m_halfRange - deviation;
182 btScalar btAngularLimit::getError() const
184 return m_correction * m_sign;
187 void btAngularLimit::fit(btScalar& angle) const
189 if (m_halfRange > 0.0f)
191 btScalar relativeAngle = btNormalizeAngle(angle - m_center);
192 if (!btEqual(relativeAngle, m_halfRange))
194 if (relativeAngle > 0.0f)
206 btScalar btAngularLimit::getLow() const
208 return btNormalizeAngle(m_center - m_halfRange);
211 btScalar btAngularLimit::getHigh() const
213 return btNormalizeAngle(m_center + m_halfRange);