Class DynamicAnimControl

All Implemented Interfaces:
PhysicsCollisionListener, PhysicsControl, PhysicsTickListener, com.jme3.export.Savable, com.jme3.scene.control.Control, com.jme3.util.clone.JmeCloneable, Cloneable

public class DynamicAnimControl extends DacLinks implements PhysicsCollisionListener
Before adding this Control to a Spatial, configure it by invoking DacConfiguration.link(java.lang.String, float, com.jme3.bullet.animation.RangeOfMotion) for each bone that should have its own rigid body. Leave unlinked bones near the root of the skeleton to form the torso of the ragdoll.

When you add the Control to a Spatial, it generates a ragdoll consisting of a rigid body for the torso and another for each linked bone. It also creates a PhysicsJoint connecting each rigid body to its parent in the link hierarchy. The mass of each rigid body and the range-of-motion of each joint can be reconfigured on the fly.

Each link is either dynamic (driven by forces and torques) or kinematic (unperturbed by forces and torques). Transitions from dynamic to kinematic can be immediate or gradual.

  • Field Details

    • logger35

      public static final Logger logger35
      message logger for this class
  • Constructor Details

    • DynamicAnimControl

      public DynamicAnimControl()
      Instantiate an enabled Control without any linked bones or attachments (torso only).
  • Method Details

    • addCollisionListener

      public void addCollisionListener(RagdollCollisionListener listener)
      Add a collision listener to this Control.
      Parameters:
      listener - the listener to register (not null, alias created)
    • amputateSubtree

      public void amputateSubtree(BoneLink rootLink, float blendInterval)
      Begin blending the specified BoneLink and all its descendants into an amputated state. This has the effect of hiding those links.
      Parameters:
      rootLink - the root of the subtree to amputate (not null, belongs to this control)
      blendInterval - the duration of the blend interval (in seconds, ≥0)
    • animateSubtree

      public void animateSubtree(PhysicsLink rootLink, float blendInterval)
      Begin blending the specified link and all its descendants to kinematic animation.
      Parameters:
      rootLink - the root of the subtree to bind (not null, belongs to this control)
      blendInterval - the duration of the blend interval (in seconds, ≥0)
    • bindSubtree

      public void bindSubtree(PhysicsLink rootLink, float blendInterval)
      Begin blending the specified link and all its descendants into bind pose.
      Parameters:
      rootLink - the root of the subtree to bind (not null, belongs to this control)
      blendInterval - the duration of the blend interval (in seconds, ≥0)
    • blendToKinematicMode

      public void blendToKinematicMode(float blendInterval, com.jme3.math.Transform endModelTransform)
      Begin blending all links to purely kinematic mode, driven by animation.

      Allowed only when the Control IS added to a Spatial.

      Parameters:
      blendInterval - the duration of the blend interval (in seconds, ≥0)
      endModelTransform - the desired local transform for the controlled spatial when the blend completes (alias created) or null for no change to the local transform
    • blendToKinematicMode

      public void blendToKinematicMode(KinematicSubmode submode, float blendInterval, com.jme3.math.Transform endModelTransform)
      Begin blending all links to purely kinematic mode.

      Allowed only when the Control IS added to a Spatial.

      Parameters:
      submode - enum value (not null)
      blendInterval - the duration of the blend interval (in seconds, ≥0)
      endModelTransform - the desired local transform for the controlled spatial when the blend completes (alias created) or null for no change to the local transform
    • centerOfMass

      public float centerOfMass(com.jme3.math.Vector3f storeLocation, com.jme3.math.Vector3f storeVelocity)
      Calculate the ragdoll's total mass and center of mass, excluding released attachments.

      Allowed only when the Control IS added to a Spatial.

      Parameters:
      storeLocation - storage for the location of the center (in physics-space coordinates, modified if not null)
      storeVelocity - storage for the velocity of the center (psu/second in physics-space coordinates, modified if not null)
      Returns:
      the total mass (>0)
    • dropAttachments

      public void dropAttachments()
      Release (to gravity) all unreleased attachments.
    • findManagerForVertex

      public PhysicsLink findManagerForVertex(String vertexSpecifier, com.jme3.math.Vector3f storeWorldLocation, com.jme3.math.Vector3f storeLocalLocation)
      Find the link that manages the specified vertex and optionally calculate the location of that vertex.

      A software skin update must precede any request for vertex locations. TODO use the Wes library to avoid this limitation?

      Parameters:
      vertexSpecifier - a String of the form "index/geometry" or "index/geometry/bone" (not null, not empty)
      storeWorldLocation - storage for location in physics-space coordinates (modified if not null)
      storeLocalLocation - storage for location in the local coordinates of the link's body (modified if not null)
      Returns:
      the pre-existing link (not null)
    • fixToWorld

      public IKJoint fixToWorld(PhysicsLink link, boolean disableForRagdoll)
      Add an IK joint that will fix the specified link in its current position. Its location can be altered via the joint's TranslationMotor.

      Allowed only when the Control IS added to a Spatial and all links are ready for dynamic mode.

      Parameters:
      link - which link to fix (not null)
      disableForRagdoll - true→disable the Constraint when entering ragdoll mode, false→unaffected by ragdoll mode
      Returns:
      a new joint, with the link body at the B end
    • freezeSubtree

      public void freezeSubtree(PhysicsLink rootLink, boolean forceKinematic)
      Immediately freeze the specified link and all its descendants. Note: recursive!

      Allowed only when the Control IS added to a Spatial.

      Parameters:
      rootLink - the root of the subtree to freeze (not null, belongs to this control)
      forceKinematic - true→force link to kinematic mode, false→preserve link modes
    • getBlendListener

      public CompletionListener<DynamicAnimControl> getBlendListener()
      Access the blend listener.
      Returns:
      the pre-existing instance, or null of none
    • kineticEnergy

      public double kineticEnergy()
      Calculate the ragdoll's total kinetic energy, excluding released attachments.
      Returns:
      the total kinetic energy, or NaN if any link isn't in dynamic mode
    • mechanicalEnergy

      public double mechanicalEnergy()
      Calculate the ragdoll's total mechanical energy, excluding released attachments.
      Returns:
      the total mechanical energy, or NaN if any link isn't in dynamic mode
    • listIKJoints

      public IKJoint[] listIKJoints()
      Enumerate IK joints managed by this Control.
      Returns:
      a new array of pre-existing joints (not null, not empty)
    • moveToBody

      public IKJoint moveToBody(PhysicsLink link, com.jme3.math.Vector3f pivotInLinkBody, PhysicsRigidBody goalBody, com.jme3.math.Vector3f pivotInGoalBody)
      Add an IK joint that will cause the specified link to move until its pivot location coincides with that of the specified goal body.
      Parameters:
      link - which link to move (not null)
      pivotInLinkBody - the pivot location (in the link body's local coordinates, not null, unaffected)
      goalBody - a rigid body that represents the goal (not null, alias created)
      pivotInGoalBody - the pivot location (in the goal's local coordinates, not null, unaffected)
      Returns:
      a new joint, with the link body at the A end and the goal at the B end, which will be disabled by ragdoll mode (not null)
    • moveToWorld

      public IKJoint moveToWorld(PhysicsLink link, com.jme3.math.Vector3f pivotInLinkBody, com.jme3.math.Vector3f goalInWorld)
      Add an IK joint that will cause the specified link to move until a fixed pivot location coincides with the specified goal location.
      Parameters:
      link - which link to move (not null)
      pivotInLinkBody - the pivot location (in the link body's local coordinates, not null, unaffected)
      goalInWorld - the goal location (in physics-space coordinates, not null, unaffected)
      Returns:
      a new joint, with the link body at the A end, which will be disabled by ragdoll mode (not null)
    • pinToSelf

      public IKJoint pinToSelf(PhysicsLink linkA, PhysicsLink linkB, com.jme3.math.Vector3f pivotInA, com.jme3.math.Vector3f pivotInB)
      Add an IK joint that will restrict the specified links to pivoting around each other.

      Allowed only when the Control IS added to a Spatial and all links are ready for dynamic mode.

      Parameters:
      linkA - the first link to pin (not null)
      linkB - the 2nd link to pin (not null)
      pivotInA - the pivot location in the A's scaled local coordinates (not null, unaffected)
      pivotInB - the pivot location in the B's scaled local coordinates (not null, unaffected)
      Returns:
      a new joint with A's body at the A end, which will be disabled by ragdoll mode (not null)
    • pinToWorld

      public IKJoint pinToWorld(PhysicsLink link, boolean disableForRagdoll)
      Add an IK joint that restricts the specified link to rotating around a pin location. The pin is initially located at the link's center. Its location can be altered via the joint's TranslationMotor.

      Allowed only when the Control IS added to a Spatial and all links are ready for dynamic mode.

      Parameters:
      link - which link to pin (not null)
      disableForRagdoll - true→disable the joint when entering ragdoll mode, false→unaffected by ragdoll mode
      Returns:
      a new joint, with the link body at the B end
    • pinToWorld

      public IKJoint pinToWorld(PhysicsLink link, com.jme3.math.Vector3f pivotInWorld)
      Add an IK joint that restricts the specified link to rotating around the specified location.

      Allowed only when the Control IS added to a Spatial and all links are ready for dynamic mode.

      Parameters:
      link - which link to pin (not null)
      pivotInWorld - the pin location (in physics-space coordinates, not null, unaffected)
      Returns:
      a new joint, with the link body at the A end, which will be disabled by ragdoll mode
    • saveCurrentPose

      public void saveCurrentPose()
      Record the current bone transforms for use in a kinematic reset.
    • setBlendListener

      public void setBlendListener(CompletionListener<DynamicAnimControl> listener)
      Replace the current blend listener. Note that the listener is automatically removed after each invocation, so typically this method is re-invoked before each blend.
      Parameters:
      listener - the desired listener, or null for none
    • setContactResponseSubtree

      public void setContactResponseSubtree(PhysicsLink rootLink, boolean desiredResponse)
      Alter the contact-response setting of the specified link and all its descendants (excluding released attachments). Note: recursive!

      Allowed only when the Control IS added to a Spatial.

      Parameters:
      rootLink - the root of the subtree to modify (not null, belongs to this control)
      desiredResponse - true for the usual rigid-body response, false for ghost-like response
    • setDynamicChain

      public void setDynamicChain(PhysicsLink startLink, int chainLength, com.jme3.math.Vector3f uniformAcceleration, boolean lockAll)
      Immediately put the specified link and all its ancestors (excluding the torso) into dynamic mode. Note: recursive!

      Allowed only when the Control IS added to a Spatial and all links are ready for dynamic mode.

      Parameters:
      startLink - the start of the chain to modify (not null)
      chainLength - the maximum number of links to modify (≥0)
      uniformAcceleration - the uniform acceleration vector (in physics-space coordinates, not null, unaffected)
      lockAll - true to lock all axes of links (except the torso)
    • setDynamicSubtree

      public void setDynamicSubtree(PhysicsLink rootLink, com.jme3.math.Vector3f uniformAcceleration, boolean lockAll)
      Immediately put the specified link and all its descendants (excluding released attachments) into dynamic mode. Note: recursive!

      Allowed only when the Control IS added to a Spatial.

      Parameters:
      rootLink - the root of the subtree to modify (not null, belongs to this control)
      uniformAcceleration - the uniform acceleration vector (in physics-space coordinates, not null, unaffected)
      lockAll - true to lock all axes of links (except the torso)
    • setKinematicMode

      public void setKinematicMode()
      Immediately put all links into purely kinematic mode. The transform of the controlled spatial is unaffected.

      Allowed only when the Control IS added to a Spatial.

    • setKinematicMode

      public void setKinematicMode(KinematicSubmode submode)
      Immediately put all links into purely kinematic mode. The transform of the controlled spatial is unaffected.

      Allowed only when the Control IS added to a Spatial.

      Parameters:
      submode - enum value (not null)
    • setRagdollMode

      public void setRagdollMode()
      Immediately put all links and IK joints into ragdoll mode.

      Allowed only when the Control IS added to a Spatial and all links are ready for dynamic mode.

    • addPhysics

      protected void addPhysics()
      Add all managed physics objects to the PhysicsSpace.
      Overrides:
      addPhysics in class DacLinks
    • cloneFields

      public void cloneFields(com.jme3.util.clone.Cloner cloner, Object original)
      Callback from Cloner to convert this shallow-cloned Control into a deep-cloned one, using the specified Cloner and original to resolve copied fields.
      Specified by:
      cloneFields in interface com.jme3.util.clone.JmeCloneable
      Overrides:
      cloneFields in class DacLinks
      Parameters:
      cloner - the Cloner that's cloning this Control (not null, modified)
      original - the instance from which this Control was shallow-cloned (not null, unaffected)
    • read

      public void read(com.jme3.export.JmeImporter importer) throws IOException
      De-serialize this Control from the specified importer, for example when loading from a J3O file.
      Specified by:
      read in interface com.jme3.export.Savable
      Overrides:
      read in class DacLinks
      Parameters:
      importer - (not null)
      Throws:
      IOException - from the importer
    • removePhysics

      protected void removePhysics()
      Remove all managed physics objects from the PhysicsSpace.
      Overrides:
      removePhysics in class DacLinks
    • update

      public void update(float tpf)
      Update this Control. Invoked once per frame during the logical-state update, provided the control is added to a scene. Do not invoke directly from user code.
      Specified by:
      update in interface com.jme3.scene.control.Control
      Overrides:
      update in class DacLinks
      Parameters:
      tpf - the time interval between frames (in seconds, ≥0)
    • write

      public void write(com.jme3.export.JmeExporter exporter) throws IOException
      Serialize this Control to the specified exporter, for example when saving to a J3O file.
      Specified by:
      write in interface com.jme3.export.Savable
      Overrides:
      write in class DacLinks
      Parameters:
      exporter - (not null)
      Throws:
      IOException - from the exporter
    • collision

      public void collision(PhysicsCollisionEvent event)
      For internal use only: callback for collision events.
      Specified by:
      collision in interface PhysicsCollisionListener
      Parameters:
      event - (not null)