3 * Class representing an articulated rigid body. Stores the body's
4 * current state, allows forces and torques to be set, handles
5 * timestepping and implements Featherstone's algorithm.
8 * Copyright (C) Stephen Thompson, <stephen@solarflare.org.uk>, 2011-2013
9 * Portions written By Erwin Coumans: connection to LCP solver, various multibody constraints, replacing Eigen math library by Bullet LinearMath and a dedicated 6x6 matrix inverse (solveImatrix)
10 * Portions written By Jakub Stepien: support for multi-DOF constraints, introduction of spatial algebra and several other improvements
12 This software is provided 'as-is', without any express or implied warranty.
13 In no event will the authors be held liable for any damages arising from the use of this software.
14 Permission is granted to anyone to use this software for any purpose,
15 including commercial applications, and to alter it and redistribute it freely,
16 subject to the following restrictions:
18 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.
19 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
20 3. This notice may not be removed or altered from any source distribution.
24 #ifndef BT_MULTIBODY_H
25 #define BT_MULTIBODY_H
27 #include "LinearMath/btScalar.h"
28 #include "LinearMath/btVector3.h"
29 #include "LinearMath/btQuaternion.h"
30 #include "LinearMath/btMatrix3x3.h"
31 #include "LinearMath/btAlignedObjectArray.h"
33 ///serialization data, don't change them if you are not familiar with the details of the serialization mechanisms
34 #ifdef BT_USE_DOUBLE_PRECISION
35 #define btMultiBodyData btMultiBodyDoubleData
36 #define btMultiBodyDataName "btMultiBodyDoubleData"
37 #define btMultiBodyLinkData btMultiBodyLinkDoubleData
38 #define btMultiBodyLinkDataName "btMultiBodyLinkDoubleData"
40 #define btMultiBodyData btMultiBodyFloatData
41 #define btMultiBodyDataName "btMultiBodyFloatData"
42 #define btMultiBodyLinkData btMultiBodyLinkFloatData
43 #define btMultiBodyLinkDataName "btMultiBodyLinkFloatData"
44 #endif //BT_USE_DOUBLE_PRECISION
46 #include "btMultiBodyLink.h"
47 class btMultiBodyLinkCollider;
49 ATTRIBUTE_ALIGNED16(class)
53 BT_DECLARE_ALIGNED_ALLOCATOR();
59 btMultiBody(int n_links, // NOT including the base
60 btScalar mass, // mass of base
61 const btVector3 &inertia, // inertia of base, in base frame; assumed diagonal
62 bool fixedBase, // whether the base is fixed (true) or can move (false)
63 bool canSleep, bool deprecatedMultiDof = true);
65 virtual ~btMultiBody();
67 //note: fixed link collision with parent is always disabled
68 void setupFixed(int i, //linkIndex
70 const btVector3 &inertia,
72 const btQuaternion &rotParentToThis,
73 const btVector3 &parentComToThisPivotOffset,
74 const btVector3 &thisPivotToThisComOffset, bool deprecatedDisableParentCollision = true);
76 void setupPrismatic(int i,
78 const btVector3 &inertia,
80 const btQuaternion &rotParentToThis,
81 const btVector3 &jointAxis,
82 const btVector3 &parentComToThisPivotOffset,
83 const btVector3 &thisPivotToThisComOffset,
84 bool disableParentCollision);
86 void setupRevolute(int i, // 0 to num_links-1
88 const btVector3 &inertia,
90 const btQuaternion &rotParentToThis, // rotate points in parent frame to this frame, when q = 0
91 const btVector3 &jointAxis, // in my frame
92 const btVector3 &parentComToThisPivotOffset, // vector from parent COM to joint axis, in PARENT frame
93 const btVector3 &thisPivotToThisComOffset, // vector from joint axis to my COM, in MY frame
94 bool disableParentCollision = false);
96 void setupSpherical(int i, // linkIndex, 0 to num_links-1
98 const btVector3 &inertia,
100 const btQuaternion &rotParentToThis, // rotate points in parent frame to this frame, when q = 0
101 const btVector3 &parentComToThisPivotOffset, // vector from parent COM to joint axis, in PARENT frame
102 const btVector3 &thisPivotToThisComOffset, // vector from joint axis to my COM, in MY frame
103 bool disableParentCollision = false);
105 void setupPlanar(int i, // 0 to num_links-1
107 const btVector3 &inertia,
109 const btQuaternion &rotParentToThis, // rotate points in parent frame to this frame, when q = 0
110 const btVector3 &rotationAxis,
111 const btVector3 &parentComToThisComOffset, // vector from parent COM to this COM, in PARENT frame
112 bool disableParentCollision = false);
114 const btMultibodyLink &getLink(int index) const
116 return m_links[index];
119 btMultibodyLink &getLink(int index)
121 return m_links[index];
124 void setBaseCollider(btMultiBodyLinkCollider * collider) //collider can be NULL to disable collision for the base
126 m_baseCollider = collider;
128 const btMultiBodyLinkCollider *getBaseCollider() const
130 return m_baseCollider;
132 btMultiBodyLinkCollider *getBaseCollider()
134 return m_baseCollider;
137 const btMultiBodyLinkCollider *getLinkCollider(int index) const
139 if (index >= 0 && index < getNumLinks())
141 return getLink(index).m_collider;
146 btMultiBodyLinkCollider *getLinkCollider(int index)
148 if (index >= 0 && index < getNumLinks())
150 return getLink(index).m_collider;
157 // input: link num from 0 to num_links-1
158 // output: link num from 0 to num_links-1, OR -1 to mean the base.
160 int getParent(int link_num) const;
163 // get number of m_links, masses, moments of inertia
166 int getNumLinks() const { return m_links.size(); }
167 int getNumDofs() const { return m_dofCount; }
168 int getNumPosVars() const { return m_posVarCnt; }
169 btScalar getBaseMass() const { return m_baseMass; }
170 const btVector3 &getBaseInertia() const { return m_baseInertia; }
171 btScalar getLinkMass(int i) const;
172 const btVector3 &getLinkInertia(int i) const;
175 // change mass (incomplete: can only change base mass and inertia at present)
178 void setBaseMass(btScalar mass) { m_baseMass = mass; }
179 void setBaseInertia(const btVector3 &inertia) { m_baseInertia = inertia; }
182 // get/set pos/vel/rot/omega for the base link
185 const btVector3 &getBasePos() const
189 const btVector3 getBaseVel() const
191 return btVector3(m_realBuf[3], m_realBuf[4], m_realBuf[5]);
193 const btQuaternion &getWorldToBaseRot() const
198 const btVector3 &getInterpolateBasePos() const
200 return m_basePos_interpolate;
202 const btQuaternion &getInterpolateWorldToBaseRot() const
204 return m_baseQuat_interpolate;
207 // rotates world vectors into base frame
208 btVector3 getBaseOmega() const { return btVector3(m_realBuf[0], m_realBuf[1], m_realBuf[2]); } // in world frame
210 void setBasePos(const btVector3 &pos)
213 if(!isBaseKinematic())
214 m_basePos_interpolate = pos;
217 void setInterpolateBasePos(const btVector3 &pos)
219 m_basePos_interpolate = pos;
222 void setBaseWorldTransform(const btTransform &tr)
224 setBasePos(tr.getOrigin());
225 setWorldToBaseRot(tr.getRotation().inverse());
228 btTransform getBaseWorldTransform() const
231 tr.setOrigin(getBasePos());
232 tr.setRotation(getWorldToBaseRot().inverse());
236 void setInterpolateBaseWorldTransform(const btTransform &tr)
238 setInterpolateBasePos(tr.getOrigin());
239 setInterpolateWorldToBaseRot(tr.getRotation().inverse());
242 btTransform getInterpolateBaseWorldTransform() const
245 tr.setOrigin(getInterpolateBasePos());
246 tr.setRotation(getInterpolateWorldToBaseRot().inverse());
250 void setBaseVel(const btVector3 &vel)
252 m_realBuf[3] = vel[0];
253 m_realBuf[4] = vel[1];
254 m_realBuf[5] = vel[2];
257 void setWorldToBaseRot(const btQuaternion &rot)
259 m_baseQuat = rot; //m_baseQuat asumed to ba alias!?
260 if(!isBaseKinematic())
261 m_baseQuat_interpolate = rot;
264 void setInterpolateWorldToBaseRot(const btQuaternion &rot)
266 m_baseQuat_interpolate = rot;
269 void setBaseOmega(const btVector3 &omega)
271 m_realBuf[0] = omega[0];
272 m_realBuf[1] = omega[1];
273 m_realBuf[2] = omega[2];
276 void saveKinematicState(btScalar timeStep);
279 // get/set pos/vel for child m_links (i = 0 to num_links-1)
282 btScalar getJointPos(int i) const;
283 btScalar getJointVel(int i) const;
285 btScalar *getJointVelMultiDof(int i);
286 btScalar *getJointPosMultiDof(int i);
288 const btScalar *getJointVelMultiDof(int i) const;
289 const btScalar *getJointPosMultiDof(int i) const;
291 void setJointPos(int i, btScalar q);
292 void setJointVel(int i, btScalar qdot);
293 void setJointPosMultiDof(int i, const double *q);
294 void setJointVelMultiDof(int i, const double *qdot);
295 void setJointPosMultiDof(int i, const float *q);
296 void setJointVelMultiDof(int i, const float *qdot);
299 // direct access to velocities as a vector of 6 + num_links elements.
300 // (omega first, then v, then joint velocities.)
302 const btScalar *getVelocityVector() const
304 return &m_realBuf[0];
307 const btScalar *getDeltaVelocityVector() const
312 const btScalar *getSplitVelocityVector() const
316 /* btScalar * getVelocityVector()
323 // get the frames of reference (positions and orientations) of the child m_links
324 // (i = 0 to num_links-1)
327 const btVector3 &getRVector(int i) const; // vector from COM(parent(i)) to COM(i), in frame i's coords
328 const btQuaternion &getParentToLocalRot(int i) const; // rotates vectors in frame parent(i) to vectors in frame i.
329 const btVector3 &getInterpolateRVector(int i) const; // vector from COM(parent(i)) to COM(i), in frame i's coords
330 const btQuaternion &getInterpolateParentToLocalRot(int i) const; // rotates vectors in frame parent(i) to vectors in frame i.
333 // transform vectors in local frame of link i to world frame (or vice versa)
335 btVector3 localPosToWorld(int i, const btVector3 &local_pos) const;
336 btVector3 localDirToWorld(int i, const btVector3 &local_dir) const;
337 btVector3 worldPosToLocal(int i, const btVector3 &world_pos) const;
338 btVector3 worldDirToLocal(int i, const btVector3 &world_dir) const;
341 // transform a frame in local coordinate to a frame in world coordinate
343 btMatrix3x3 localFrameToWorld(int i, const btMatrix3x3 &local_frame) const;
347 // set external forces and torques. Note all external forces/torques are given in the WORLD frame.
350 void clearForcesAndTorques();
351 void clearConstraintForces();
353 void clearVelocities();
355 void addBaseForce(const btVector3 &f)
359 void addBaseTorque(const btVector3 &t) { m_baseTorque += t; }
360 void addLinkForce(int i, const btVector3 &f);
361 void addLinkTorque(int i, const btVector3 &t);
363 void addBaseConstraintForce(const btVector3 &f)
365 m_baseConstraintForce += f;
367 void addBaseConstraintTorque(const btVector3 &t) { m_baseConstraintTorque += t; }
368 void addLinkConstraintForce(int i, const btVector3 &f);
369 void addLinkConstraintTorque(int i, const btVector3 &t);
371 void addJointTorque(int i, btScalar Q);
372 void addJointTorqueMultiDof(int i, int dof, btScalar Q);
373 void addJointTorqueMultiDof(int i, const btScalar *Q);
375 const btVector3 &getBaseForce() const { return m_baseForce; }
376 const btVector3 &getBaseTorque() const { return m_baseTorque; }
377 const btVector3 &getLinkForce(int i) const;
378 const btVector3 &getLinkTorque(int i) const;
379 btScalar getJointTorque(int i) const;
380 btScalar *getJointTorqueMultiDof(int i);
383 // dynamics routines.
386 // timestep the velocities (given the external forces/torques set using addBaseForce etc).
387 // also sets up caches for calcAccelerationDeltas.
389 // Note: the caller must provide three vectors which are used as
390 // temporary scratch space. The idea here is to reduce dynamic
391 // memory allocation: the same scratch vectors can be re-used
392 // again and again for different Multibodies, instead of each
393 // btMultiBody allocating (and then deallocating) their own
394 // individual scratch buffers. This gives a considerable speed
395 // improvement, at least on Windows (where dynamic memory
396 // allocation appears to be fairly slow).
399 void computeAccelerationsArticulatedBodyAlgorithmMultiDof(btScalar dt,
400 btAlignedObjectArray<btScalar> & scratch_r,
401 btAlignedObjectArray<btVector3> & scratch_v,
402 btAlignedObjectArray<btMatrix3x3> & scratch_m,
403 bool isConstraintPass,
404 bool jointFeedbackInWorldSpace,
405 bool jointFeedbackInJointFrame
408 ///stepVelocitiesMultiDof is deprecated, use computeAccelerationsArticulatedBodyAlgorithmMultiDof instead
409 //void stepVelocitiesMultiDof(btScalar dt,
410 // btAlignedObjectArray<btScalar> & scratch_r,
411 // btAlignedObjectArray<btVector3> & scratch_v,
412 // btAlignedObjectArray<btMatrix3x3> & scratch_m,
413 // bool isConstraintPass = false)
415 // computeAccelerationsArticulatedBodyAlgorithmMultiDof(dt, scratch_r, scratch_v, scratch_m, isConstraintPass, false, false);
418 // calcAccelerationDeltasMultiDof
419 // input: force vector (in same format as jacobian, i.e.:
420 // 3 torque values, 3 force values, num_links joint torque values)
421 // output: 3 omegadot values, 3 vdot values, num_links q_double_dot values
422 // (existing contents of output array are replaced)
423 // calcAccelerationDeltasMultiDof must have been called first.
424 void calcAccelerationDeltasMultiDof(const btScalar *force, btScalar *output,
425 btAlignedObjectArray<btScalar> &scratch_r,
426 btAlignedObjectArray<btVector3> &scratch_v) const;
428 void applyDeltaVeeMultiDof2(const btScalar *delta_vee, btScalar multiplier)
430 for (int dof = 0; dof < 6 + getNumDofs(); ++dof)
432 m_deltaV[dof] += delta_vee[dof] * multiplier;
435 void applyDeltaSplitVeeMultiDof(const btScalar *delta_vee, btScalar multiplier)
437 for (int dof = 0; dof < 6 + getNumDofs(); ++dof)
439 m_splitV[dof] += delta_vee[dof] * multiplier;
444 applyDeltaVeeMultiDof(&m_splitV[0], 1);
446 void substractSplitV()
448 applyDeltaVeeMultiDof(&m_splitV[0], -1);
450 for (int dof = 0; dof < 6 + getNumDofs(); ++dof)
455 void processDeltaVeeMultiDof2()
457 applyDeltaVeeMultiDof(&m_deltaV[0], 1);
459 for (int dof = 0; dof < 6 + getNumDofs(); ++dof)
465 void applyDeltaVeeMultiDof(const btScalar *delta_vee, btScalar multiplier)
467 //for (int dof = 0; dof < 6 + getNumDofs(); ++dof)
468 // printf("%.4f ", delta_vee[dof]*multiplier);
472 //for (int dof = 0; dof < 6 + getNumDofs(); ++dof)
474 // sum += delta_vee[dof]*multiplier*delta_vee[dof]*multiplier;
476 //btScalar l = btSqrt(sum);
478 //if (l>m_maxAppliedImpulse)
480 // multiplier *= m_maxAppliedImpulse/l;
483 for (int dof = 0; dof < 6 + getNumDofs(); ++dof)
485 m_realBuf[dof] += delta_vee[dof] * multiplier;
486 btClamp(m_realBuf[dof], -m_maxCoordinateVelocity, m_maxCoordinateVelocity);
490 // timestep the positions (given current velocities).
491 void stepPositionsMultiDof(btScalar dt, btScalar *pq = 0, btScalar *pqd = 0);
493 // predict the positions
494 void predictPositionsMultiDof(btScalar dt);
500 // This routine fills out a contact constraint jacobian for this body.
501 // the 'normal' supplied must be -n for body1 or +n for body2 of the contact.
502 // 'normal' & 'contact_point' are both given in world coordinates.
504 void fillContactJacobianMultiDof(int link,
505 const btVector3 &contact_point,
506 const btVector3 &normal,
508 btAlignedObjectArray<btScalar> &scratch_r,
509 btAlignedObjectArray<btVector3> &scratch_v,
510 btAlignedObjectArray<btMatrix3x3> &scratch_m) const { fillConstraintJacobianMultiDof(link, contact_point, btVector3(0, 0, 0), normal, jac, scratch_r, scratch_v, scratch_m); }
512 //a more general version of fillContactJacobianMultiDof which does not assume..
513 //.. that the constraint in question is contact or, to be more precise, constrains linear velocity only
514 void fillConstraintJacobianMultiDof(int link,
515 const btVector3 &contact_point,
516 const btVector3 &normal_ang,
517 const btVector3 &normal_lin,
519 btAlignedObjectArray<btScalar> &scratch_r,
520 btAlignedObjectArray<btVector3> &scratch_v,
521 btAlignedObjectArray<btMatrix3x3> &scratch_m) const;
526 void setCanSleep(bool canSleep)
530 m_canSleep = canSleep;
534 bool getCanSleep() const
539 bool getCanWakeup() const
544 void setCanWakeup(bool canWakeup)
546 m_canWakeup = canWakeup;
554 void checkMotionAndSleepIfRequired(btScalar timestep);
556 bool hasFixedBase() const;
558 bool isBaseKinematic() const;
560 bool isBaseStaticOrKinematic() const;
562 // set the dynamic type in the base's collision flags.
563 void setBaseDynamicType(int dynamicType);
565 void setFixedBase(bool fixedBase)
567 m_fixedBase = fixedBase;
569 setBaseDynamicType(btCollisionObject::CF_STATIC_OBJECT);
571 setBaseDynamicType(btCollisionObject::CF_DYNAMIC_OBJECT);
574 int getCompanionId() const
576 return m_companionId;
578 void setCompanionId(int id)
580 //printf("for %p setCompanionId(%d)\n",this, id);
584 void setNumLinks(int numLinks) //careful: when changing the number of m_links, make sure to re-initialize or update existing m_links
586 m_links.resize(numLinks);
589 btScalar getLinearDamping() const
591 return m_linearDamping;
593 void setLinearDamping(btScalar damp)
595 m_linearDamping = damp;
597 btScalar getAngularDamping() const
599 return m_angularDamping;
601 void setAngularDamping(btScalar damp)
603 m_angularDamping = damp;
606 bool getUseGyroTerm() const
608 return m_useGyroTerm;
610 void setUseGyroTerm(bool useGyro)
612 m_useGyroTerm = useGyro;
614 btScalar getMaxCoordinateVelocity() const
616 return m_maxCoordinateVelocity;
618 void setMaxCoordinateVelocity(btScalar maxVel)
620 m_maxCoordinateVelocity = maxVel;
623 btScalar getMaxAppliedImpulse() const
625 return m_maxAppliedImpulse;
627 void setMaxAppliedImpulse(btScalar maxImp)
629 m_maxAppliedImpulse = maxImp;
631 void setHasSelfCollision(bool hasSelfCollision)
633 m_hasSelfCollision = hasSelfCollision;
635 bool hasSelfCollision() const
637 return m_hasSelfCollision;
640 void finalizeMultiDof();
642 void useRK4Integration(bool use) { m_useRK4 = use; }
643 bool isUsingRK4Integration() const { return m_useRK4; }
644 void useGlobalVelocities(bool use) { m_useGlobalVelocities = use; }
645 bool isUsingGlobalVelocities() const { return m_useGlobalVelocities; }
647 bool isPosUpdated() const
651 void setPosUpdated(bool updated)
653 __posUpdated = updated;
656 //internalNeedsJointFeedback is for internal use only
657 bool internalNeedsJointFeedback() const
659 return m_internalNeedsJointFeedback;
661 void forwardKinematics(btAlignedObjectArray<btQuaternion>& world_to_local, btAlignedObjectArray<btVector3> & local_origin);
663 void compTreeLinkVelocities(btVector3 * omega, btVector3 * vel) const;
665 void updateCollisionObjectWorldTransforms(btAlignedObjectArray<btQuaternion> & world_to_local, btAlignedObjectArray<btVector3> & local_origin);
666 void updateCollisionObjectInterpolationWorldTransforms(btAlignedObjectArray<btQuaternion> & world_to_local, btAlignedObjectArray<btVector3> & local_origin);
668 virtual int calculateSerializeBufferSize() const;
670 ///fills the dataBuffer and returns the struct name (and 0 on failure)
671 virtual const char *serialize(void *dataBuffer, class btSerializer *serializer) const;
673 const char *getBaseName() const
677 ///memory of setBaseName needs to be manager by user
678 void setBaseName(const char *name)
683 ///users can point to their objects, userPointer is not used by Bullet
684 void *getUserPointer() const
686 return m_userObjectPointer;
689 int getUserIndex() const
694 int getUserIndex2() const
698 ///users can point to their objects, userPointer is not used by Bullet
699 void setUserPointer(void *userPointer)
701 m_userObjectPointer = userPointer;
704 ///users can point to their objects, userPointer is not used by Bullet
705 void setUserIndex(int index)
710 void setUserIndex2(int index)
712 m_userIndex2 = index;
715 static void spatialTransform(const btMatrix3x3 &rotation_matrix, // rotates vectors in 'from' frame to vectors in 'to' frame
716 const btVector3 &displacement, // vector from origin of 'from' frame to origin of 'to' frame, in 'to' coordinates
717 const btVector3 &top_in, // top part of input vector
718 const btVector3 &bottom_in, // bottom part of input vector
719 btVector3 &top_out, // top part of output vector
720 btVector3 &bottom_out); // bottom part of output vector
722 void setLinkDynamicType(const int i, int type);
724 bool isLinkStaticOrKinematic(const int i) const;
726 bool isLinkKinematic(const int i) const;
728 bool isLinkAndAllAncestorsStaticOrKinematic(const int i) const;
730 bool isLinkAndAllAncestorsKinematic(const int i) const;
732 void setSleepThreshold(btScalar sleepThreshold)
734 m_sleepEpsilon = sleepThreshold;
737 void setSleepTimeout(btScalar sleepTimeout)
739 this->m_sleepTimeout = sleepTimeout;
744 btMultiBody(const btMultiBody &); // not implemented
745 void operator=(const btMultiBody &); // not implemented
747 void solveImatrix(const btVector3 &rhs_top, const btVector3 &rhs_bot, btScalar result[6]) const;
748 void solveImatrix(const btSpatialForceVector &rhs, btSpatialMotionVector &result) const;
750 void updateLinksDofOffsets()
752 int dofOffset = 0, cfgOffset = 0;
753 for (int bidx = 0; bidx < m_links.size(); ++bidx)
755 m_links[bidx].m_dofOffset = dofOffset;
756 m_links[bidx].m_cfgOffset = cfgOffset;
757 dofOffset += m_links[bidx].m_dofCount;
758 cfgOffset += m_links[bidx].m_posVarCount;
762 void mulMatrix(const btScalar *pA, const btScalar *pB, int rowsA, int colsA, int rowsB, int colsB, btScalar *pC) const;
765 btMultiBodyLinkCollider *m_baseCollider; //can be NULL
766 const char *m_baseName; //memory needs to be manager by user!
768 btVector3 m_basePos; // position of COM of base (world frame)
769 btVector3 m_basePos_interpolate; // position of interpolated COM of base (world frame)
770 btQuaternion m_baseQuat; // rotates world points into base frame
771 btQuaternion m_baseQuat_interpolate;
773 btScalar m_baseMass; // mass of the base
774 btVector3 m_baseInertia; // inertia of the base (in local frame; diagonal)
776 btVector3 m_baseForce; // external force applied to base. World frame.
777 btVector3 m_baseTorque; // external torque applied to base. World frame.
779 btVector3 m_baseConstraintForce; // external force applied to base. World frame.
780 btVector3 m_baseConstraintTorque; // external torque applied to base. World frame.
782 btAlignedObjectArray<btMultibodyLink> m_links; // array of m_links, excluding the base. index from 0 to num_links-1.
787 // 0 6 + num_links v (base_omega; base_vel; joint_vels) MULTIDOF [sysdof x sysdof for D matrices (TOO MUCH!) + pos_delta which is sys-cfg sized]
788 // 6+num_links num_links D
793 // num_links num_links h_bottom
797 // 0 num_links+1 rot_from_parent
799 btAlignedObjectArray<btScalar> m_splitV;
800 btAlignedObjectArray<btScalar> m_deltaV;
801 btAlignedObjectArray<btScalar> m_realBuf;
802 btAlignedObjectArray<btVector3> m_vectorBuf;
803 btAlignedObjectArray<btMatrix3x3> m_matrixBuf;
805 btMatrix3x3 m_cachedInertiaTopLeft;
806 btMatrix3x3 m_cachedInertiaTopRight;
807 btMatrix3x3 m_cachedInertiaLowerLeft;
808 btMatrix3x3 m_cachedInertiaLowerRight;
809 bool m_cachedInertiaValid;
817 btScalar m_sleepTimer;
818 btScalar m_sleepEpsilon;
819 btScalar m_sleepTimeout;
821 void *m_userObjectPointer;
826 btScalar m_linearDamping;
827 btScalar m_angularDamping;
829 btScalar m_maxAppliedImpulse;
830 btScalar m_maxCoordinateVelocity;
831 bool m_hasSelfCollision;
834 int m_dofCount, m_posVarCnt;
836 bool m_useRK4, m_useGlobalVelocities;
837 //for global velocities, see 8.3.2B Proposed resolution in Jakub Stepien PhD Thesis
838 //https://drive.google.com/file/d/0Bz3vEa19XOYGNWdZWGpMdUdqVmZ5ZVBOaEh4ZnpNaUxxZFNV/view?usp=sharing
840 ///the m_needsJointFeedback gets updated/computed during the stepVelocitiesMultiDof and it for internal usage only
841 bool m_internalNeedsJointFeedback;
843 //If enabled, calculate the velocity based on kinematic transform changes. Currently only implemented for the base.
844 bool m_kinematic_calculate_velocity;
847 struct btMultiBodyLinkDoubleData
849 btQuaternionDoubleData m_zeroRotParentToThis;
850 btVector3DoubleData m_parentComToThisPivotOffset;
851 btVector3DoubleData m_thisPivotToThisComOffset;
852 btVector3DoubleData m_jointAxisTop[6];
853 btVector3DoubleData m_jointAxisBottom[6];
855 btVector3DoubleData m_linkInertia; // inertia of the base (in local frame; diagonal)
856 btVector3DoubleData m_absFrameTotVelocityTop;
857 btVector3DoubleData m_absFrameTotVelocityBottom;
858 btVector3DoubleData m_absFrameLocVelocityTop;
859 btVector3DoubleData m_absFrameLocVelocityBottom;
867 double m_jointPos[7];
868 double m_jointVel[6];
869 double m_jointTorque[6];
871 double m_jointDamping;
872 double m_jointFriction;
873 double m_jointLowerLimit;
874 double m_jointUpperLimit;
875 double m_jointMaxForce;
876 double m_jointMaxVelocity;
880 btCollisionObjectDoubleData *m_linkCollider;
884 struct btMultiBodyLinkFloatData
886 btQuaternionFloatData m_zeroRotParentToThis;
887 btVector3FloatData m_parentComToThisPivotOffset;
888 btVector3FloatData m_thisPivotToThisComOffset;
889 btVector3FloatData m_jointAxisTop[6];
890 btVector3FloatData m_jointAxisBottom[6];
891 btVector3FloatData m_linkInertia; // inertia of the base (in local frame; diagonal)
892 btVector3FloatData m_absFrameTotVelocityTop;
893 btVector3FloatData m_absFrameTotVelocityBottom;
894 btVector3FloatData m_absFrameLocVelocityTop;
895 btVector3FloatData m_absFrameLocVelocityBottom;
904 float m_jointTorque[6];
906 float m_jointDamping;
907 float m_jointFriction;
908 float m_jointLowerLimit;
909 float m_jointUpperLimit;
910 float m_jointMaxForce;
911 float m_jointMaxVelocity;
915 btCollisionObjectFloatData *m_linkCollider;
919 ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
920 struct btMultiBodyDoubleData
922 btVector3DoubleData m_baseWorldPosition;
923 btQuaternionDoubleData m_baseWorldOrientation;
924 btVector3DoubleData m_baseLinearVelocity;
925 btVector3DoubleData m_baseAngularVelocity;
926 btVector3DoubleData m_baseInertia; // inertia of the base (in local frame; diagonal)
932 btMultiBodyLinkDoubleData *m_links;
933 btCollisionObjectDoubleData *m_baseCollider;
936 ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
937 struct btMultiBodyFloatData
939 btVector3FloatData m_baseWorldPosition;
940 btQuaternionFloatData m_baseWorldOrientation;
941 btVector3FloatData m_baseLinearVelocity;
942 btVector3FloatData m_baseAngularVelocity;
944 btVector3FloatData m_baseInertia; // inertia of the base (in local frame; diagonal)
949 btMultiBodyLinkFloatData *m_links;
950 btCollisionObjectFloatData *m_baseCollider;