|
Bullet Collision Detection & Physics Library
|
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 }