47 top_out = rotation_matrix * top_in;
48 bottom_out = -displacement.
cross(top_out) + rotation_matrix * bottom_in;
56 void InverseSpatialTransform(
const btMatrix3x3 &rotation_matrix,
63 top_out = rotation_matrix.
transpose() * top_in;
64 bottom_out = rotation_matrix.
transpose() * (bottom_in + displacement.
cross(top_in));
72 return a_bottom.
dot(b_top) + a_top.
dot(b_bottom);
75 void SpatialCrossProduct(
const btVector3 &a_top,
82 top_out = a_top.
cross(b_top);
83 bottom_out = a_bottom.
cross(b_top) + a_top.
cross(b_bottom);
102 m_baseQuat(0, 0, 0, 1),
103 m_basePos_interpolate(0, 0, 0),
104 m_baseQuat_interpolate(0, 0, 0, 1),
106 m_baseInertia(inertia),
108 m_fixedBase(fixedBase),
110 m_canSleep(canSleep),
113 m_sleepEpsilon(INITIAL_SLEEP_EPSILON),
114 m_sleepTimeout(INITIAL_SLEEP_TIMEOUT),
116 m_userObjectPointer(0),
120 m_linearDamping(0.04f),
121 m_angularDamping(0.04f),
123 m_maxAppliedImpulse(1000.f),
124 m_maxCoordinateVelocity(100.f),
125 m_hasSelfCollision(true),
130 m_useGlobalVelocities(false),
131 m_internalNeedsJointFeedback(false),
132 m_kinematic_calculate_velocity(false)
159 const btVector3 &parentComToThisPivotOffset,
160 const btVector3 &thisPivotToThisComOffset,
bool )
163 m_links[i].m_inertiaLocal = inertia;
165 m_links[i].setAxisTop(0, 0., 0., 0.);
167 m_links[i].m_zeroRotParentToThis = rotParentToThis;
168 m_links[i].m_dVector = thisPivotToThisComOffset;
169 m_links[i].m_eVector = parentComToThisPivotOffset;
177 m_links[i].updateCacheMultiDof();
188 const btVector3 &parentComToThisPivotOffset,
189 const btVector3 &thisPivotToThisComOffset,
190 bool disableParentCollision)
196 m_links[i].m_inertiaLocal = inertia;
198 m_links[i].m_zeroRotParentToThis = rotParentToThis;
199 m_links[i].setAxisTop(0, 0., 0., 0.);
200 m_links[i].setAxisBottom(0, jointAxis);
201 m_links[i].m_eVector = parentComToThisPivotOffset;
202 m_links[i].m_dVector = thisPivotToThisComOffset;
203 m_links[i].m_cachedRotParentToThis = rotParentToThis;
208 m_links[i].m_jointPos[0] = 0.f;
209 m_links[i].m_jointTorque[0] = 0.f;
211 if (disableParentCollision)
215 m_links[i].updateCacheMultiDof();
226 const btVector3 &parentComToThisPivotOffset,
227 const btVector3 &thisPivotToThisComOffset,
228 bool disableParentCollision)
234 m_links[i].m_inertiaLocal = inertia;
236 m_links[i].m_zeroRotParentToThis = rotParentToThis;
237 m_links[i].setAxisTop(0, jointAxis);
238 m_links[i].setAxisBottom(0, jointAxis.
cross(thisPivotToThisComOffset));
239 m_links[i].m_dVector = thisPivotToThisComOffset;
240 m_links[i].m_eVector = parentComToThisPivotOffset;
245 m_links[i].m_jointPos[0] = 0.f;
246 m_links[i].m_jointTorque[0] = 0.f;
248 if (disableParentCollision)
251 m_links[i].updateCacheMultiDof();
261 const btVector3 &parentComToThisPivotOffset,
262 const btVector3 &thisPivotToThisComOffset,
263 bool disableParentCollision)
269 m_links[i].m_inertiaLocal = inertia;
271 m_links[i].m_zeroRotParentToThis = rotParentToThis;
272 m_links[i].m_dVector = thisPivotToThisComOffset;
273 m_links[i].m_eVector = parentComToThisPivotOffset;
278 m_links[i].setAxisTop(0, 1.f, 0.f, 0.f);
279 m_links[i].setAxisTop(1, 0.f, 1.f, 0.f);
280 m_links[i].setAxisTop(2, 0.f, 0.f, 1.f);
281 m_links[i].setAxisBottom(0,
m_links[i].getAxisTop(0).cross(thisPivotToThisComOffset));
282 m_links[i].setAxisBottom(1,
m_links[i].getAxisTop(1).cross(thisPivotToThisComOffset));
283 m_links[i].setAxisBottom(2,
m_links[i].getAxisTop(2).cross(thisPivotToThisComOffset));
285 m_links[i].m_jointPos[3] = 1.f;
288 if (disableParentCollision)
291 m_links[i].updateCacheMultiDof();
302 const btVector3 &parentComToThisComOffset,
303 bool disableParentCollision)
309 m_links[i].m_inertiaLocal = inertia;
311 m_links[i].m_zeroRotParentToThis = rotParentToThis;
312 m_links[i].m_dVector.setZero();
313 m_links[i].m_eVector = parentComToThisComOffset;
316 btVector3 vecNonParallelToRotAxis(1, 0, 0);
317 if (rotationAxis.
normalized().
dot(vecNonParallelToRotAxis) > 0.999)
318 vecNonParallelToRotAxis.
setValue(0, 1, 0);
325 m_links[i].setAxisTop(0, n[0], n[1], n[2]);
326 m_links[i].setAxisTop(1, 0, 0, 0);
327 m_links[i].setAxisTop(2, 0, 0, 0);
328 m_links[i].setAxisBottom(0, 0, 0, 0);
330 m_links[i].setAxisBottom(1, cr[0], cr[1], cr[2]);
332 m_links[i].setAxisBottom(2, cr[0], cr[1], cr[2]);
336 if (disableParentCollision)
339 m_links[i].updateCacheMultiDof();
343 m_links[i].setAxisBottom(1,
m_links[i].getAxisBottom(1).normalized());
344 m_links[i].setAxisBottom(2,
m_links[i].getAxisBottom(2).normalized());
365 return m_links[link_num].m_parent;
375 return m_links[i].m_inertiaLocal;
380 return m_links[i].m_jointPos[0];
390 return &
m_links[i].m_jointPos[0];
400 return &
m_links[i].m_jointPos[0];
411 m_links[i].updateCacheMultiDof();
417 for (
int pos = 0; pos <
m_links[i].m_posVarCount; ++pos)
420 m_links[i].updateCacheMultiDof();
425 for (
int pos = 0; pos <
m_links[i].m_posVarCount; ++pos)
428 m_links[i].updateCacheMultiDof();
440 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
446 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
452 return m_links[i].m_cachedRVector;
457 return m_links[i].m_cachedRotParentToThis;
462 return m_links[i].m_cachedRVector_interpolate;
467 return m_links[i].m_cachedRotParentToThis_interpolate;
560 result.
setValue(frameInWorld0[0], frameInWorld1[0], frameInWorld2[0], frameInWorld0[1], frameInWorld1[1], frameInWorld2[1], frameInWorld0[2], frameInWorld1[2], frameInWorld2[2]);
572 for (
int i = 0; i < num_links; ++i)
579 omega[parent + 1], vel[parent + 1],
580 omega[i + 1], vel[i + 1]);
584 for (
int dof = 0; dof < link.
m_dofCount; ++dof)
586 omega[i + 1] += jointVel[dof] * link.
getAxisTop(dof);
600 m_links[i].m_appliedConstraintForce.setValue(0, 0, 0);
601 m_links[i].m_appliedConstraintTorque.setValue(0, 0, 0);
611 m_links[i].m_appliedForce.setValue(0, 0, 0);
612 m_links[i].m_appliedTorque.setValue(0, 0, 0);
626 m_links[i].m_appliedForce += f;
631 m_links[i].m_appliedTorque += t;
636 m_links[i].m_appliedConstraintForce += f;
641 m_links[i].m_appliedConstraintTorque += t;
646 m_links[i].m_jointTorque[0] += Q;
651 m_links[i].m_jointTorque[dof] += Q;
656 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
657 m_links[i].m_jointTorque[dof] = Q[dof];
662 return m_links[i].m_appliedForce;
667 return m_links[i].m_appliedTorque;
672 return m_links[i].m_jointTorque[0];
677 return &
m_links[i].m_jointTorque[0];
720 row1[0], row1[1], row1[2],
721 row2[0], row2[1], row2[2]);
725#define vecMulVecTranspose(v0, v1Transposed) outerProduct(v0, v1Transposed)
732 bool isConstraintPass,
733 bool jointFeedbackInWorldSpace,
734 bool jointFeedbackInJointFrame)
767 scratch_v.
resize(8 * num_links + 6);
768 scratch_m.
resize(4 * num_links + 4);
776 v_ptr += num_links * 2 + 2;
780 v_ptr += num_links * 2 + 2;
784 v_ptr += num_links * 2;
797 v_ptr += num_links * 2 + 2;
827 spatVel[0].
setVector(rot_from_parent[0] * base_omega, rot_from_parent[0] * base_vel);
838 zeroAccSpatFrc[0].
setVector(-(rot_from_parent[0] * baseTorque), -(rot_from_parent[0] * baseForce));
841 const btScalar linDampMult = 1., angDampMult = 1.;
842 zeroAccSpatFrc[0].
addVector(angDampMult *
m_baseInertia * spatVel[0].getAngular() * (DAMPING_K1_ANGULAR + DAMPING_K2_ANGULAR * spatVel[0].getAngular().safeNorm()),
843 linDampMult *
m_baseMass * spatVel[0].getLinear() * (DAMPING_K1_LINEAR + DAMPING_K2_LINEAR * spatVel[0].getLinear().safeNorm()));
850 zeroAccSpatFrc[0].
addLinear(
m_baseMass * spatVel[0].getAngular().cross(spatVel[0].getLinear()));
864 rot_from_world[0] = rot_from_parent[0];
867 for (
int i = 0; i < num_links; ++i)
869 const int parent =
m_links[i].m_parent;
871 rot_from_world[i + 1] = rot_from_parent[i + 1] * rot_from_world[parent + 1];
873 fromParent.
m_rotMat = rot_from_parent[i + 1];
875 fromWorld.
m_rotMat = rot_from_world[i + 1];
876 fromParent.
transform(spatVel[parent + 1], spatVel[i + 1]);
884 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
888 spatVel[i + 1] += spatJointVel;
901 spatVel[i + 1].
cross(spatJointVel, spatCoriolisAcc[i]);
911 btVector3 linkAppliedForce = isConstraintPass ?
m_links[i].m_appliedConstraintForce :
m_links[i].m_appliedForce;
912 btVector3 linkAppliedTorque = isConstraintPass ?
m_links[i].m_appliedConstraintTorque :
m_links[i].m_appliedTorque;
914 zeroAccSpatFrc[i + 1].
setVector(-(rot_from_world[i + 1] * linkAppliedTorque), -(rot_from_world[i + 1] * linkAppliedForce));
919 b3Printf(
"stepVelocitiesMultiDof zeroAccSpatFrc[%d] linear:%f,%f,%f, angular:%f,%f,%f",
921 zeroAccSpatFrc[i+1].m_topVec[0],
922 zeroAccSpatFrc[i+1].m_topVec[1],
923 zeroAccSpatFrc[i+1].m_topVec[2],
925 zeroAccSpatFrc[i+1].m_bottomVec[0],
926 zeroAccSpatFrc[i+1].m_bottomVec[1],
927 zeroAccSpatFrc[i+1].m_bottomVec[2]);
932 btScalar linDampMult = 1., angDampMult = 1.;
933 zeroAccSpatFrc[i + 1].
addVector(angDampMult *
m_links[i].m_inertiaLocal * spatVel[i + 1].getAngular() * (DAMPING_K1_ANGULAR + DAMPING_K2_ANGULAR * spatVel[i + 1].getAngular().safeNorm()),
934 linDampMult *
m_links[i].m_mass * spatVel[i + 1].getLinear() * (DAMPING_K1_LINEAR + DAMPING_K2_LINEAR * spatVel[i + 1].getLinear().safeNorm()));
937 zeroAccSpatFrc[i + 1].
addAngular(spatVel[i + 1].getAngular().cross(
m_links[i].m_inertiaLocal * spatVel[i + 1].getAngular()));
939 zeroAccSpatFrc[i + 1].
addLinear(
m_links[i].m_mass * spatVel[i + 1].getAngular().cross(spatVel[i + 1].getLinear()));
962 0,
m_links[i].m_inertiaLocal[1], 0,
963 0, 0,
m_links[i].m_inertiaLocal[2]));
972 for (
int i = num_links - 1; i >= 0; --i)
976 const int parent =
m_links[i].m_parent;
977 fromParent.
m_rotMat = rot_from_parent[i + 1];
980 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
984 hDof = spatInertia[i + 1] *
m_links[i].m_axes[dof];
986 Y[
m_links[i].m_dofOffset + dof] =
m_links[i].m_jointTorque[dof] -
m_links[i].m_axes[dof].dot(zeroAccSpatFrc[i + 1]) - spatCoriolisAcc[i].
dot(hDof);
988 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
991 for (
int dof2 = 0; dof2 <
m_links[i].m_dofCount; ++dof2)
994 D_row[dof2] =
m_links[i].m_axes[dof].dot(hDof2);
999 switch (
m_links[i].m_jointType)
1006 invDi[0] = 1.0f / D[0];
1017 const btMatrix3x3 D3x3(D[0], D[1], D[2], D[3], D[4], D[5], D[6], D[7], D[8]);
1021 for (
int row = 0; row < 3; ++row)
1023 for (
int col = 0; col < 3; ++col)
1025 invDi[row * 3 + col] = invD3x3[row][col];
1037 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
1039 spatForceVecTemps[dof].
setZero();
1041 for (
int dof2 = 0; dof2 <
m_links[i].m_dofCount; ++dof2)
1045 spatForceVecTemps[dof] += hDof2 * invDi[dof2 *
m_links[i].m_dofCount + dof];
1049 dyadTemp = spatInertia[i + 1];
1052 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
1061 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
1063 invD_times_Y[dof] = 0.f;
1065 for (
int dof2 = 0; dof2 <
m_links[i].m_dofCount; ++dof2)
1067 invD_times_Y[dof] += invDi[dof *
m_links[i].m_dofCount + dof2] * Y[
m_links[i].m_dofOffset + dof2];
1071 spatForceVecTemps[0] = zeroAccSpatFrc[i + 1] + spatInertia[i + 1] * spatCoriolisAcc[i];
1073 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
1077 spatForceVecTemps[0] += hDof * invD_times_Y[dof];
1082 zeroAccSpatFrc[parent + 1] += spatForceVecTemps[1];
1104 spatAcc[0] = -result;
1108 for (
int i = 0; i < num_links; ++i)
1116 const int parent =
m_links[i].m_parent;
1117 fromParent.
m_rotMat = rot_from_parent[i + 1];
1120 fromParent.
transform(spatAcc[parent + 1], spatAcc[i + 1]);
1124 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
1128 Y_minus_hT_a[dof] = Y[
m_links[i].m_dofOffset + dof] - spatAcc[i + 1].
dot(hDof);
1134 spatAcc[i + 1] += spatCoriolisAcc[i];
1136 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
1137 spatAcc[i + 1] +=
m_links[i].m_axes[dof] * joint_accel[
m_links[i].m_dofOffset + dof];
1140 if (
m_links[i].m_jointFeedback)
1144 btVector3 angularBotVec = (spatInertia[i + 1] * spatAcc[i + 1] + zeroAccSpatFrc[i + 1]).m_bottomVec;
1145 btVector3 linearTopVec = (spatInertia[i + 1] * spatAcc[i + 1] + zeroAccSpatFrc[i + 1]).m_topVec;
1147 if (jointFeedbackInJointFrame)
1152 angularBotVec = angularBotVec - linearTopVec.
cross(
m_links[i].m_dVector);
1155 if (jointFeedbackInWorldSpace)
1157 if (isConstraintPass)
1159 m_links[i].m_jointFeedback->m_reactionForces.m_bottomVec +=
m_links[i].m_cachedWorldTransform.getBasis() * angularBotVec;
1160 m_links[i].m_jointFeedback->m_reactionForces.m_topVec +=
m_links[i].m_cachedWorldTransform.getBasis() * linearTopVec;
1164 m_links[i].m_jointFeedback->m_reactionForces.m_bottomVec =
m_links[i].m_cachedWorldTransform.getBasis() * angularBotVec;
1165 m_links[i].m_jointFeedback->m_reactionForces.m_topVec =
m_links[i].m_cachedWorldTransform.getBasis() * linearTopVec;
1170 if (isConstraintPass)
1172 m_links[i].m_jointFeedback->m_reactionForces.m_bottomVec += angularBotVec;
1173 m_links[i].m_jointFeedback->m_reactionForces.m_topVec += linearTopVec;
1177 m_links[i].m_jointFeedback->m_reactionForces.m_bottomVec = angularBotVec;
1178 m_links[i].m_jointFeedback->m_reactionForces.m_topVec = linearTopVec;
1186 output[0] = omegadot_out[0];
1187 output[1] = omegadot_out[1];
1188 output[2] = omegadot_out[2];
1215 if (!isConstraintPass)
1250 for (
int i = 0; i < num_links; ++i)
1252 const int parent =
m_links[i].m_parent;
1256 fromParent.
m_rotMat = rot_from_parent[i + 1];
1258 fromWorld.
m_rotMat = rot_from_world[i + 1];
1261 fromParent.
transform(spatVel[parent + 1], spatVel[i + 1]);
1269 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
1273 spatVel[i + 1] += spatJointVel;
1318 for (
int i = 0; i < 6; i++)
1331 btMatrix3x3 invI_lower_right = (invI_upper_left).transpose();
1340 btVector3 vtop = invI_upper_left * rhs_top;
1342 tmp = invIupper_right * rhs_bot;
1344 btVector3 vbot = invI_lower_left * rhs_top;
1345 tmp = invI_lower_right * rhs_bot;
1347 result[0] = vtop[0];
1348 result[1] = vtop[1];
1349 result[2] = vtop[2];
1350 result[3] = vbot[0];
1351 result[4] = vbot[1];
1352 result[5] = vbot[2];
1396 btMatrix3x3 invI_lower_right = (invI_upper_left).transpose();
1419 for (
int row = 0; row < rowsA; row++)
1421 for (
int col = 0; col < colsB; col++)
1423 pC[row * colsB + col] = 0.f;
1424 for (
int inner = 0; inner < rowsB; inner++)
1426 pC[row * colsB + col] += pA[row * colsA + inner] * pB[col + inner * colsB];
1440 scratch_v.
resize(4 * num_links + 4);
1447 v_ptr += num_links * 2 + 2;
1456 v_ptr += num_links * 2 + 2;
1482 fromParent.
m_rotMat = rot_from_parent[0];
1485 for (
int i = 0; i < num_links; ++i)
1487 zeroAccSpatFrc[i + 1].
setZero();
1492 for (
int i = num_links - 1; i >= 0; --i)
1496 const int parent =
m_links[i].m_parent;
1497 fromParent.
m_rotMat = rot_from_parent[i + 1];
1500 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
1502 Y[
m_links[i].m_dofOffset + dof] = force[6 +
m_links[i].m_dofOffset + dof] -
m_links[i].m_axes[dof].dot(zeroAccSpatFrc[i + 1]);
1505 btVector3 in_top, in_bottom, out_top, out_bottom;
1508 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
1510 invD_times_Y[dof] = 0.f;
1512 for (
int dof2 = 0; dof2 <
m_links[i].m_dofCount; ++dof2)
1514 invD_times_Y[dof] += invDi[dof *
m_links[i].m_dofCount + dof2] * Y[
m_links[i].m_dofOffset + dof2];
1519 spatForceVecTemps[0] = zeroAccSpatFrc[i + 1];
1521 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
1525 spatForceVecTemps[0] += hDof * invD_times_Y[dof];
1530 zeroAccSpatFrc[parent + 1] += spatForceVecTemps[1];
1546 spatAcc[0] = -result;
1550 for (
int i = 0; i < num_links; ++i)
1554 const int parent =
m_links[i].m_parent;
1555 fromParent.
m_rotMat = rot_from_parent[i + 1];
1558 fromParent.
transform(spatAcc[parent + 1], spatAcc[i + 1]);
1560 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
1564 Y_minus_hT_a[dof] = Y[
m_links[i].m_dofOffset + dof] - spatAcc[i + 1].
dot(hDof);
1570 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
1571 spatAcc[i + 1] +=
m_links[i].m_axes[dof] * joint_accel[
m_links[i].m_dofOffset + dof];
1577 output[0] = omegadot_out[0];
1578 output[1] = omegadot_out[1];
1579 output[2] = omegadot_out[2];
1607 for (
int i = 0; i < 3; ++i)
1613 pBasePos[0] += dt * pBaseVel[0];
1614 pBasePos[1] += dt * pBaseVel[1];
1615 pBasePos[2] += dt * pBaseVel[2];
1646 axis = angvel * (
btScalar(0.5) * dt - (dt * dt * dt) * (
btScalar(0.020833333333)) * fAngle * fAngle);
1651 axis = angvel * (
btSin(
btScalar(0.5) * fAngle * dt) / fAngle);
1672 for (
int i = 0; i < 4; ++i)
1681 baseQuat.
setValue(pBaseQuat[0], pBaseQuat[1], pBaseQuat[2], pBaseQuat[3]);
1683 baseOmega.
setValue(pBaseOmega[0], pBaseOmega[1], pBaseOmega[2]);
1684 pQuatUpdateFun(baseOmega, baseQuat,
true, dt);
1685 pBaseQuat[0] = baseQuat.
x();
1686 pBaseQuat[1] = baseQuat.
y();
1687 pBaseQuat[2] = baseQuat.
z();
1688 pBaseQuat[3] = baseQuat.
w();
1692 for (
int i = 0; i < num_links; ++i)
1695 pJointPos = &
m_links[i].m_jointPos_interpolate[0];
1697 if (
m_links[i].m_collider &&
m_links[i].m_collider->isStaticOrKinematic())
1699 switch (
m_links[i].m_jointType)
1704 pJointPos[0] =
m_links[i].m_jointPos[0];
1709 for (
int j = 0; j < 4; ++j)
1711 pJointPos[j] =
m_links[i].m_jointPos[j];
1717 for (
int j = 0; j < 3; ++j)
1719 pJointPos[j] =
m_links[i].m_jointPos[j];
1731 switch (
m_links[i].m_jointType)
1737 pJointPos[0] =
m_links[i].m_jointPos[0];
1739 pJointPos[0] += dt * jointVel;
1746 for (
int j = 0; j < 4; ++j)
1748 pJointPos[j] =
m_links[i].m_jointPos[j];
1752 jointVel.
setValue(pJointVel[0], pJointVel[1], pJointVel[2]);
1754 jointOri.
setValue(pJointPos[0], pJointPos[1], pJointPos[2], pJointPos[3]);
1755 pQuatUpdateFun(jointVel, jointOri,
false, dt);
1756 pJointPos[0] = jointOri.
x();
1757 pJointPos[1] = jointOri.
y();
1758 pJointPos[2] = jointOri.
z();
1759 pJointPos[3] = jointOri.
w();
1764 for (
int j = 0; j < 3; ++j)
1766 pJointPos[j] =
m_links[i].m_jointPos[j];
1772 pJointPos[1] +=
m_links[i].getAxisBottom(1).dot(no_q0_coors_qd1qd2) * dt;
1773 pJointPos[2] +=
m_links[i].getAxisBottom(2).dot(no_q0_coors_qd1qd2) * dt;
1782 m_links[i].updateInterpolationCacheMultiDof();
1798 pBasePos[0] += dt * pBaseVel[0];
1799 pBasePos[1] += dt * pBaseVel[1];
1800 pBasePos[2] += dt * pBaseVel[2];
1831 axis = angvel * (
btScalar(0.5) * dt - (dt * dt * dt) * (
btScalar(0.020833333333)) * fAngle * fAngle);
1836 axis = angvel * (
btSin(
btScalar(0.5) * fAngle * dt) / fAngle);
1858 baseQuat.
setValue(pBaseQuat[0], pBaseQuat[1], pBaseQuat[2], pBaseQuat[3]);
1860 baseOmega.
setValue(pBaseOmega[0], pBaseOmega[1], pBaseOmega[2]);
1861 pQuatUpdateFun(baseOmega, baseQuat,
true, dt);
1862 pBaseQuat[0] = baseQuat.
x();
1863 pBaseQuat[1] = baseQuat.
y();
1864 pBaseQuat[2] = baseQuat.
z();
1865 pBaseQuat[3] = baseQuat.
w();
1878 for (
int i = 0; i < num_links; ++i)
1880 if (!(
m_links[i].m_collider &&
m_links[i].m_collider->isStaticOrKinematic()))
1883 pJointPos= (pq ? pq : &
m_links[i].m_jointPos[0]);
1887 switch (
m_links[i].m_jointType)
1894 pJointPos[0] += dt * jointVel;
1901 jointVel.
setValue(pJointVel[0], pJointVel[1], pJointVel[2]);
1903 jointOri.
setValue(pJointPos[0], pJointPos[1], pJointPos[2], pJointPos[3]);
1904 pQuatUpdateFun(jointVel, jointOri,
false, dt);
1905 pJointPos[0] = jointOri.
x();
1906 pJointPos[1] = jointOri.
y();
1907 pJointPos[2] = jointOri.
z();
1908 pJointPos[3] = jointOri.
w();
1917 pJointPos[1] +=
m_links[i].getAxisBottom(1).dot(no_q0_coors_qd1qd2) * dt;
1918 pJointPos[2] +=
m_links[i].getAxisBottom(2).dot(no_q0_coors_qd1qd2) * dt;
1928 m_links[i].updateCacheMultiDof(pq);
1931 pq +=
m_links[i].m_posVarCount;
1949 scratch_v.
resize(3 * num_links + 3);
1950 scratch_m.
resize(num_links + 1);
1954 v_ptr += num_links + 1;
1956 v_ptr += num_links + 1;
1958 v_ptr += num_links + 1;
1967 int numLinksChildToRoot=0;
1971 links[numLinksChildToRoot++]=l;
1978 const btVector3 &normal_lin_world = normal_lin;
1979 const btVector3 &normal_ang_world = normal_ang;
1985 omega_coeffs_world = p_minus_com_world.
cross(normal_lin_world);
1986 jac[0] = omega_coeffs_world[0] + normal_ang_world[0];
1987 jac[1] = omega_coeffs_world[1] + normal_ang_world[1];
1988 jac[2] = omega_coeffs_world[2] + normal_ang_world[2];
1990 jac[3] = normal_lin_world[0];
1991 jac[4] = normal_lin_world[1];
1992 jac[5] = normal_lin_world[2];
1995 p_minus_com_local[0] = rot_from_world[0] * p_minus_com_world;
1996 n_local_lin[0] = rot_from_world[0] * normal_lin_world;
1997 n_local_ang[0] = rot_from_world[0] * normal_ang_world;
2006 if (num_links > 0 && link > -1)
2012 for (
int a = 0; a < numLinksChildToRoot; a++)
2014 int i = links[numLinksChildToRoot-1-a];
2016 const int parent =
m_links[i].m_parent;
2018 rot_from_world[i + 1] = mtx * rot_from_world[parent + 1];
2020 n_local_lin[i + 1] = mtx * n_local_lin[parent + 1];
2021 n_local_ang[i + 1] = mtx * n_local_ang[parent + 1];
2022 p_minus_com_local[i + 1] = mtx * p_minus_com_local[parent + 1] -
m_links[i].m_cachedRVector;
2025 switch (
m_links[i].m_jointType)
2029 results[
m_links[i].m_dofOffset] = n_local_lin[i + 1].dot(
m_links[i].getAxisTop(0).cross(p_minus_com_local[i + 1]) +
m_links[i].getAxisBottom(0));
2030 results[
m_links[i].m_dofOffset] += n_local_ang[i + 1].dot(
m_links[i].getAxisTop(0));
2035 results[
m_links[i].m_dofOffset] = n_local_lin[i + 1].dot(
m_links[i].getAxisBottom(0));
2040 results[
m_links[i].m_dofOffset + 0] = n_local_lin[i + 1].dot(
m_links[i].getAxisTop(0).cross(p_minus_com_local[i + 1]) +
m_links[i].getAxisBottom(0));
2041 results[
m_links[i].m_dofOffset + 1] = n_local_lin[i + 1].dot(
m_links[i].getAxisTop(1).cross(p_minus_com_local[i + 1]) +
m_links[i].getAxisBottom(1));
2042 results[
m_links[i].m_dofOffset + 2] = n_local_lin[i + 1].dot(
m_links[i].getAxisTop(2).cross(p_minus_com_local[i + 1]) +
m_links[i].getAxisBottom(2));
2044 results[
m_links[i].m_dofOffset + 0] += n_local_ang[i + 1].dot(
m_links[i].getAxisTop(0));
2045 results[
m_links[i].m_dofOffset + 1] += n_local_ang[i + 1].dot(
m_links[i].getAxisTop(1));
2046 results[
m_links[i].m_dofOffset + 2] += n_local_ang[i + 1].dot(
m_links[i].getAxisTop(2));
2052 results[
m_links[i].m_dofOffset + 0] = n_local_lin[i + 1].dot(
m_links[i].getAxisTop(0).cross(p_minus_com_local[i + 1]));
2053 results[
m_links[i].m_dofOffset + 1] = n_local_lin[i + 1].dot(
m_links[i].getAxisBottom(1));
2054 results[
m_links[i].m_dofOffset + 2] = n_local_lin[i + 1].dot(
m_links[i].getAxisBottom(2));
2068 for (
int dof = 0; dof <
m_links[link].m_dofCount; ++dof)
2070 jac[6 +
m_links[link].m_dofOffset + dof] = results[
m_links[link].m_dofOffset + dof];
2074 link =
m_links[link].m_parent;
2138 for (
int i = 0; i < num_links; ++i)
2145 world_to_local.
resize(nLinks + 1);
2146 local_origin.
resize(nLinks + 1);
2160 int index = link + 1;
2163 btScalar quat[4] = {-world_to_local[index].x(), -world_to_local[index].y(), -world_to_local[index].z(), world_to_local[index].w()};
2184 btScalar quat[4] = {-world_to_local[0].x(), -world_to_local[0].y(), -world_to_local[0].z(), world_to_local[0].w()};
2209 int index = link + 1;
2213 btScalar quat[4] = {-world_to_local[index].x(), -world_to_local[index].y(), -world_to_local[index].z(), world_to_local[index].w()};
2244 btScalar quat[4] = {-world_to_local[0].x(), -world_to_local[0].y(), -world_to_local[0].z(), world_to_local[0].w()};
2268 int index = link + 1;
2272 btScalar quat[4] = {-world_to_local[index].x(), -world_to_local[index].y(), -world_to_local[index].z(), world_to_local[index].w()};
2303 if (mbd->m_baseName)
2309 if (mbd->m_numLinks)
2312 int numElem = mbd->m_numLinks;
2315 for (
int i = 0; i < numElem; i++, memPtr++)
2350 for (
int posvar = 0; posvar < numPosVar; posvar++)
2358 if (memPtr->m_linkName)
2366 if (memPtr->m_jointName)
2378#ifdef BT_USE_DOUBLE_PRECISION
2379 memset(mbd->m_padding, 0,
sizeof(mbd->m_padding));
2390 btVector3 linearVelocity, angularVelocity;
2408 m_links[i].m_collider->setDynamicType(type);
2422 return m_links[i].m_collider->isStaticOrKinematic();
2436 return m_links[i].m_collider->isKinematic();
2444 while (link != -1) {
2447 link =
m_links[link].m_parent;
2455 while (link != -1) {
2458 link =
m_links[link].m_parent;
#define btCollisionObjectData
@ BT_MULTIBODYLINKFLAGS_DISABLE_PARENT_COLLISION
btMatrix3x3 outerProduct(const btVector3 &v0, const btVector3 &v1)
#define btMultiBodyDataName
#define btMultiBodyData
serialization data, don't change them if you are not familiar with the details of the serialization m...
#define btMultiBodyLinkData
#define btMultiBodyLinkDataName
btQuaternion inverse(const btQuaternion &q)
Return the inverse of a quaternion.
btVector3 quatRotate(const btQuaternion &rotation, const btVector3 &v)
bool gDisableDeactivation
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
btScalar btSin(btScalar x)
btScalar btCos(btScalar x)
void symmetricSpatialOuterProduct(const SpatialVectorType &a, const SpatialVectorType &b, btSymmetricSpatialDyad &out)
int size() const
return the number of elements in the array
void resize(int newsize, const T &fillData=T())
bool isStaticOrKinematicObject() const
void setCollisionFlags(int flags)
bool isStaticObject() const
void setWorldTransform(const btTransform &worldTrans)
bool isKinematicObject() const
int getCollisionFlags() const
void setInterpolationWorldTransform(const btTransform &trans)
The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with...
btMatrix3x3 inverse() const
Return the inverse of the matrix.
btMatrix3x3 transpose() const
Return the transpose of the matrix.
btVector3 getColumn(int i) const
Get a column of the matrix as a vector.
void setValue(const btScalar &xx, const btScalar &xy, const btScalar &xz, const btScalar &yx, const btScalar &yy, const btScalar &yz, const btScalar &zx, const btScalar &zy, const btScalar &zz)
Set the values of the matrix explicitly (row major)
btTransform getInterpolateBaseWorldTransform() const
void setupPrismatic(int i, btScalar mass, const btVector3 &inertia, int parent, const btQuaternion &rotParentToThis, const btVector3 &jointAxis, const btVector3 &parentComToThisPivotOffset, const btVector3 &thisPivotToThisComOffset, bool disableParentCollision)
const btVector3 & getInterpolateBasePos() const
void setJointVelMultiDof(int i, const double *qdot)
const btVector3 & getLinkTorque(int i) const
void updateCollisionObjectInterpolationWorldTransforms(btAlignedObjectArray< btQuaternion > &world_to_local, btAlignedObjectArray< btVector3 > &local_origin)
btAlignedObjectArray< btMultibodyLink > m_links
btAlignedObjectArray< btMatrix3x3 > m_matrixBuf
btMatrix3x3 localFrameToWorld(int i, const btMatrix3x3 &local_frame) const
const btVector3 & getBasePos() const
virtual const char * serialize(void *dataBuffer, class btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
bool isLinkAndAllAncestorsKinematic(const int i) const
btVector3 m_basePos_interpolate
btAlignedObjectArray< btVector3 > m_vectorBuf
const btQuaternion & getInterpolateParentToLocalRot(int i) const
btVector3 worldDirToLocal(int i, const btVector3 &world_dir) const
btScalar getJointPos(int i) const
const btVector3 & getLinkInertia(int i) const
void setBaseDynamicType(int dynamicType)
btScalar * getJointPosMultiDof(int i)
btScalar m_angularDamping
void predictPositionsMultiDof(btScalar dt)
void setBaseVel(const btVector3 &vel)
btMatrix3x3 m_cachedInertiaLowerRight
void setBaseOmega(const btVector3 &omega)
void computeAccelerationsArticulatedBodyAlgorithmMultiDof(btScalar dt, btAlignedObjectArray< btScalar > &scratch_r, btAlignedObjectArray< btVector3 > &scratch_v, btAlignedObjectArray< btMatrix3x3 > &scratch_m, bool isConstraintPass, bool jointFeedbackInWorldSpace, bool jointFeedbackInJointFrame)
void addLinkConstraintForce(int i, const btVector3 &f)
btAlignedObjectArray< btScalar > m_realBuf
btVector3 m_baseConstraintTorque
void stepPositionsMultiDof(btScalar dt, btScalar *pq=0, btScalar *pqd=0)
const btMultibodyLink & getLink(int index) const
const btVector3 & getRVector(int i) const
btVector3 getBaseOmega() const
void calcAccelerationDeltasMultiDof(const btScalar *force, btScalar *output, btAlignedObjectArray< btScalar > &scratch_r, btAlignedObjectArray< btVector3 > &scratch_v) const
stepVelocitiesMultiDof is deprecated, use computeAccelerationsArticulatedBodyAlgorithmMultiDof instea...
btVector3 worldPosToLocal(int i, const btVector3 &world_pos) const
void addLinkTorque(int i, const btVector3 &t)
void checkMotionAndSleepIfRequired(btScalar timestep)
btScalar * getJointTorqueMultiDof(int i)
btQuaternion m_baseQuat_interpolate
void solveImatrix(const btVector3 &rhs_top, const btVector3 &rhs_bot, btScalar result[6]) const
const btVector3 & getInterpolateRVector(int i) const
bool isBaseKinematic() const
btScalar getLinkMass(int i) const
bool m_useGlobalVelocities
void addLinkForce(int i, const btVector3 &f)
void addJointTorque(int i, btScalar Q)
btMatrix3x3 m_cachedInertiaLowerLeft
void mulMatrix(const btScalar *pA, const btScalar *pB, int rowsA, int colsA, int rowsB, int colsB, btScalar *pC) const
void setInterpolateBaseWorldTransform(const btTransform &tr)
const btVector3 & getLinkForce(int i) const
int getParent(int link_num) const
void setJointPosMultiDof(int i, const double *q)
void updateCollisionObjectWorldTransforms(btAlignedObjectArray< btQuaternion > &world_to_local, btAlignedObjectArray< btVector3 > &local_origin)
void setJointVel(int i, btScalar qdot)
btScalar getJointTorque(int i) const
bool hasFixedBase() const
const btQuaternion & getInterpolateWorldToBaseRot() const
bool isLinkAndAllAncestorsStaticOrKinematic(const int i) const
void clearConstraintForces()
btMatrix3x3 m_cachedInertiaTopLeft
void addLinkConstraintTorque(int i, const btVector3 &t)
bool m_cachedInertiaValid
void setupSpherical(int i, btScalar mass, const btVector3 &inertia, int parent, const btQuaternion &rotParentToThis, const btVector3 &parentComToThisPivotOffset, const btVector3 &thisPivotToThisComOffset, bool disableParentCollision=false)
const btMultiBodyLinkCollider * getBaseCollider() const
void setJointPos(int i, btScalar q)
void setupPlanar(int i, btScalar mass, const btVector3 &inertia, int parent, const btQuaternion &rotParentToThis, const btVector3 &rotationAxis, const btVector3 &parentComToThisComOffset, bool disableParentCollision=false)
void setLinkDynamicType(const int i, int type)
static void spatialTransform(const btMatrix3x3 &rotation_matrix, const btVector3 &displacement, const btVector3 &top_in, const btVector3 &bottom_in, btVector3 &top_out, btVector3 &bottom_out)
void fillConstraintJacobianMultiDof(int link, const btVector3 &contact_point, const btVector3 &normal_ang, const btVector3 &normal_lin, btScalar *jac, btAlignedObjectArray< btScalar > &scratch_r, btAlignedObjectArray< btVector3 > &scratch_v, btAlignedObjectArray< btMatrix3x3 > &scratch_m) const
btTransform getBaseWorldTransform() const
btVector3 localPosToWorld(int i, const btVector3 &local_pos) const
bool isBaseStaticOrKinematic() const
void setupRevolute(int i, btScalar mass, const btVector3 &inertia, int parentIndex, const btQuaternion &rotParentToThis, const btVector3 &jointAxis, const btVector3 &parentComToThisPivotOffset, const btVector3 &thisPivotToThisComOffset, bool disableParentCollision=false)
bool m_kinematic_calculate_velocity
btMatrix3x3 m_cachedInertiaTopRight
btScalar getBaseMass() const
btAlignedObjectArray< btScalar > m_deltaV
void updateLinksDofOffsets()
virtual int calculateSerializeBufferSize() const
bool isLinkKinematic(const int i) const
void setupFixed(int i, btScalar mass, const btVector3 &inertia, int parent, const btQuaternion &rotParentToThis, const btVector3 &parentComToThisPivotOffset, const btVector3 &thisPivotToThisComOffset, bool deprecatedDisableParentCollision=true)
bool m_internalNeedsJointFeedback
the m_needsJointFeedback gets updated/computed during the stepVelocitiesMultiDof and it for internal ...
const btQuaternion & getParentToLocalRot(int i) const
btAlignedObjectArray< btScalar > m_splitV
const btVector3 & getBaseInertia() const
void addJointTorqueMultiDof(int i, int dof, btScalar Q)
const btQuaternion & getWorldToBaseRot() const
btVector3 m_baseConstraintForce
btVector3 localDirToWorld(int i, const btVector3 &local_dir) const
btScalar getJointVel(int i) const
bool isLinkStaticOrKinematic(const int i) const
void forwardKinematics(btAlignedObjectArray< btQuaternion > &world_to_local, btAlignedObjectArray< btVector3 > &local_origin)
void applyDeltaVeeMultiDof(const btScalar *delta_vee, btScalar multiplier)
const btVector3 getBaseVel() const
btScalar * getJointVelMultiDof(int i)
btMultiBody(int n_links, btScalar mass, const btVector3 &inertia, bool fixedBase, bool canSleep, bool deprecatedMultiDof=true)
void saveKinematicState(btScalar timeStep)
void compTreeLinkVelocities(btVector3 *omega, btVector3 *vel) const
void clearForcesAndTorques()
const btScalar & w() const
Return the w value.
const btScalar & z() const
Return the z value.
const btScalar & y() const
Return the y value.
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Set x,y,z and zero w.
const btScalar & x() const
Return the x value.
The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatr...
void serialize(struct btQuaternionData &dataOut) const
btQuaternion inverse() const
Return the inverse of this quaternion.
btQuaternion & normalize()
Normalize the quaternion Such that x^2 + y^2 + z^2 +w^2 = 1.
virtual btChunk * allocate(size_t size, int numElements)=0
virtual void * getUniquePointer(void *oldPtr)=0
virtual void serializeName(const char *ptr)=0
virtual const char * findNameForPointer(const void *ptr) const =0
virtual void finalizeChunk(btChunk *chunk, const char *structType, int chunkCode, void *oldPtr)=0
btVector3 can be used to represent 3D points and vectors.
const btScalar & z() const
Return the z value.
btScalar length() const
Return the length of the vector.
btVector3 cross(const btVector3 &v) const
Return the cross product between this and another vector.
btScalar dot(const btVector3 &v) const
Return the dot product.
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
btVector3 normalized() const
Return a normalized version of this vector.
const btScalar & x() const
Return the x value.
void serialize(struct btVector3Data &dataOut) const
const btScalar & y() const
Return the y value.
btQuaternion m_zeroRotParentToThis
class btMultiBodyLinkCollider * m_collider
btQuaternion m_cachedRotParentToThis
const btVector3 & getAxisTop(int dof) const
btScalar m_jointUpperLimit
const btVector3 & getAxisBottom(int dof) const
eFeatherstoneJointType m_jointType
btScalar m_jointLowerLimit
btSpatialMotionVector m_absFrameTotVelocity
btTransform m_cachedWorldTransform
btScalar m_jointMaxVelocity
btScalar m_jointTorque[6]
btSpatialMotionVector m_absFrameLocVelocity
btVector3 m_cachedRVector
These spatial algebra classes are used for btMultiBody, see BulletDynamics/Featherstone.
void addLinear(const btVector3 &linear)
void addVector(const btVector3 &angular, const btVector3 &linear)
const btVector3 & getAngular() const
const btVector3 & getLinear() const
void addAngular(const btVector3 &angular)
void setVector(const btVector3 &angular, const btVector3 &linear)
void setLinear(const btVector3 &linear)
const btVector3 & getLinear() const
void cross(const SpatialVectorType &b, SpatialVectorType &out) const
const btVector3 & getAngular() const
btScalar dot(const btSpatialForceVector &b) const
void setAngular(const btVector3 &angular)
void setVector(const btVector3 &angular, const btVector3 &linear)
btMatrix3x3 m_topRightMat
btMatrix3x3 m_bottomLeftMat
void setMatrix(const btMatrix3x3 &topLeftMat, const btMatrix3x3 &topRightMat, const btMatrix3x3 &bottomLeftMat)