summaryrefslogtreecommitdiff
path: root/src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBody.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBody.h')
-rw-r--r--src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBody.h257
1 files changed, 257 insertions, 0 deletions
diff --git a/src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBody.h b/src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBody.h
new file mode 100644
index 000000000..8968fb0cb
--- /dev/null
+++ b/src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBody.h
@@ -0,0 +1,257 @@
+#ifndef BT_REDUCED_SOFT_BODY_H
+#define BT_REDUCED_SOFT_BODY_H
+
+#include "../btSoftBody.h"
+#include "LinearMath/btAlignedObjectArray.h"
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btMatrix3x3.h"
+#include "LinearMath/btTransform.h"
+
+// Reduced deformable body is a simplified deformable object embedded in a rigid frame.
+class btReducedDeformableBody : public btSoftBody
+{
+ public:
+ //
+ // Typedefs
+ //
+ typedef btAlignedObjectArray<btVector3> TVStack;
+ // typedef btAlignedObjectArray<btMatrix3x3> tBlockDiagMatrix;
+ typedef btAlignedObjectArray<btScalar> tDenseArray;
+ typedef btAlignedObjectArray<btAlignedObjectArray<btScalar> > tDenseMatrix;
+
+ private:
+ // flag to turn off the reduced modes
+ bool m_rigidOnly;
+
+ // Flags for transform. Once transform is applied, users cannot scale the mesh or change its total mass.
+ bool m_transform_lock;
+
+ // scaling factors
+ btScalar m_rhoScale; // mass density scale
+ btScalar m_ksScale; // stiffness scale
+
+ // projection matrix
+ tDenseMatrix m_projPA; // Eqn. 4.11 from Rahul Sheth's thesis
+ tDenseMatrix m_projCq;
+ tDenseArray m_STP;
+ tDenseArray m_MrInvSTP;
+
+ TVStack m_localMomentArm; // Sq + x0
+
+ btVector3 m_internalDeltaLinearVelocity;
+ btVector3 m_internalDeltaAngularVelocity;
+ tDenseArray m_internalDeltaReducedVelocity;
+
+ btVector3 m_linearVelocityFromReduced; // contribution to the linear velocity from reduced velocity
+ btVector3 m_angularVelocityFromReduced; // contribution to the angular velocity from reduced velocity
+ btVector3 m_internalDeltaAngularVelocityFromReduced;
+
+ protected:
+ // rigid frame
+ btScalar m_mass; // total mass of the rigid frame
+ btScalar m_inverseMass; // inverse of the total mass of the rigid frame
+ btVector3 m_linearVelocity;
+ btVector3 m_angularVelocity;
+ btScalar m_linearDamping; // linear damping coefficient
+ btScalar m_angularDamping; // angular damping coefficient
+ btVector3 m_linearFactor;
+ btVector3 m_angularFactor;
+ // btVector3 m_invInertiaLocal;
+ btMatrix3x3 m_invInertiaLocal;
+ btTransform m_rigidTransformWorld;
+ btMatrix3x3 m_invInertiaTensorWorldInitial;
+ btMatrix3x3 m_invInertiaTensorWorld;
+ btMatrix3x3 m_interpolateInvInertiaTensorWorld;
+ btVector3 m_initialCoM; // initial center of mass (original of the m_rigidTransformWorld)
+
+ // damping
+ btScalar m_dampingAlpha;
+ btScalar m_dampingBeta;
+
+ public:
+ //
+ // Fields
+ //
+
+ // reduced space
+ int m_nReduced;
+ int m_nFull;
+ tDenseMatrix m_modes; // modes of the reduced deformable model. Each inner array is a mode, outer array size = n_modes
+ tDenseArray m_reducedDofs; // Reduced degree of freedom
+ tDenseArray m_reducedDofsBuffer; // Reduced degree of freedom at t^n
+ tDenseArray m_reducedVelocity; // Reduced velocity array
+ tDenseArray m_reducedVelocityBuffer; // Reduced velocity array at t^n
+ tDenseArray m_reducedForceExternal; // reduced external force
+ tDenseArray m_reducedForceElastic; // reduced internal elastic force
+ tDenseArray m_reducedForceDamping; // reduced internal damping force
+ tDenseArray m_eigenvalues; // eigenvalues of the reduce deformable model
+ tDenseArray m_Kr; // reduced stiffness matrix
+
+ // full space
+ TVStack m_x0; // Rest position
+ tDenseArray m_nodalMass; // Mass on each node
+ btAlignedObjectArray<int> m_fixedNodes; // index of the fixed nodes
+ int m_nodeIndexOffset; // offset of the node index needed for contact solver when there are multiple reduced deformable body in the world.
+
+ // contacts
+ btAlignedObjectArray<int> m_contactNodesList;
+
+ //
+ // Api
+ //
+ btReducedDeformableBody(btSoftBodyWorldInfo* worldInfo, int node_count, const btVector3* x, const btScalar* m);
+
+ ~btReducedDeformableBody() {}
+
+ //
+ // initializing helpers
+ //
+ void internalInitialization();
+
+ void setReducedModes(int num_modes, int full_size);
+
+ void setMassProps(const tDenseArray& mass_array);
+
+ void setInertiaProps();
+
+ void setRigidVelocity(const btVector3& v);
+
+ void setRigidAngularVelocity(const btVector3& omega);
+
+ void setStiffnessScale(const btScalar ks);
+
+ void setMassScale(const btScalar rho);
+
+ void setFixedNodes(const int n_node);
+
+ void setDamping(const btScalar alpha, const btScalar beta);
+
+ void disableReducedModes(const bool rigid_only);
+
+ virtual void setTotalMass(btScalar mass, bool fromfaces = false);
+
+ //
+ // various internal updates
+ //
+ virtual void transformTo(const btTransform& trs);
+ virtual void transform(const btTransform& trs);
+ // caution:
+ // need to use scale before using transform, because the scale is performed in the local frame
+ // (i.e., may have some rotation already, but the m_rigidTransformWorld doesn't have this info)
+ virtual void scale(const btVector3& scl);
+
+ private:
+ void updateRestNodalPositions();
+
+ void updateInitialInertiaTensor(const btMatrix3x3& rotation);
+
+ void updateLocalInertiaTensorFromNodes();
+
+ void updateInertiaTensor();
+
+ void updateModesByRotation(const btMatrix3x3& rotation);
+
+ public:
+ void updateLocalMomentArm();
+
+ void predictIntegratedTransform(btScalar dt, btTransform& predictedTransform);
+
+ // update the external force projection matrix
+ void updateExternalForceProjectMatrix(bool initialized);
+
+ void endOfTimeStepZeroing();
+
+ void applyInternalVelocityChanges();
+
+ //
+ // position and velocity update related
+ //
+
+ // compute reduced degree of freedoms
+ void updateReducedDofs(btScalar solverdt);
+
+ // compute reduced velocity update (for explicit time stepping)
+ void updateReducedVelocity(btScalar solverdt);
+
+ // map to full degree of freedoms
+ void mapToFullPosition(const btTransform& ref_trans);
+
+ // compute full space velocity from the reduced velocity
+ void mapToFullVelocity(const btTransform& ref_trans);
+
+ // compute total angular momentum
+ const btVector3 computeTotalAngularMomentum() const;
+
+ // get a single node's full space velocity from the reduced velocity
+ const btVector3 computeNodeFullVelocity(const btTransform& ref_trans, int n_node) const;
+
+ // get a single node's all delta velocity
+ const btVector3 internalComputeNodeDeltaVelocity(const btTransform& ref_trans, int n_node) const;
+
+ //
+ // rigid motion related
+ //
+ void applyDamping(btScalar timeStep);
+
+ void applyCentralImpulse(const btVector3& impulse);
+
+ void applyTorqueImpulse(const btVector3& torque);
+
+ void proceedToTransform(btScalar dt, bool end_of_time_step);
+
+ //
+ // force related
+ //
+
+ // apply impulse to the rigid frame
+ void internalApplyRigidImpulse(const btVector3& impulse, const btVector3& rel_pos);
+
+ // apply impulse to nodes in the full space
+ void internalApplyFullSpaceImpulse(const btVector3& impulse, const btVector3& rel_pos, int n_node, btScalar dt);
+
+ // apply nodal external force in the full space
+ void applyFullSpaceNodalForce(const btVector3& f_ext, int n_node);
+
+ // apply gravity to the rigid frame
+ void applyRigidGravity(const btVector3& gravity, btScalar dt);
+
+ // apply reduced elastic force
+ void applyReducedElasticForce(const tDenseArray& reduce_dofs);
+
+ // apply reduced damping force
+ void applyReducedDampingForce(const tDenseArray& reduce_vel);
+
+ // calculate the impulse factor
+ virtual btMatrix3x3 getImpulseFactor(int n_node);
+
+ // get relative position from a node to the CoM of the rigid frame
+ btVector3 getRelativePos(int n_node);
+
+ //
+ // accessors
+ //
+ bool isReducedModesOFF() const;
+ btScalar getTotalMass() const;
+ btTransform& getRigidTransform();
+ const btVector3& getLinearVelocity() const;
+ const btVector3& getAngularVelocity() const;
+
+ #if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0
+ void clampVelocity(btVector3& v) const {
+ v.setX(
+ fmax(-BT_CLAMP_VELOCITY_TO,
+ fmin(BT_CLAMP_VELOCITY_TO, v.getX()))
+ );
+ v.setY(
+ fmax(-BT_CLAMP_VELOCITY_TO,
+ fmin(BT_CLAMP_VELOCITY_TO, v.getY()))
+ );
+ v.setZ(
+ fmax(-BT_CLAMP_VELOCITY_TO,
+ fmin(BT_CLAMP_VELOCITY_TO, v.getZ()))
+ );
+ }
+ #endif
+};
+
+#endif // BT_REDUCED_SOFT_BODY_H \ No newline at end of file