Class BetterCharacterControl

All Implemented Interfaces:
PhysicsControl, PhysicsTickListener, Savable, Control, JmeCloneable, Cloneable

public class BetterCharacterControl extends AbstractPhysicsControl implements PhysicsTickListener, JmeCloneable
Intended to replace the CharacterControl class.

A rigid body with cylinder collision shape is used and its velocity is set continuously. A ray test is used to test whether the character is on the ground.

The character keeps their own local coordinate system which adapts based on the gravity working on the character, so it will always stand upright.

Motion in the local X-Z plane is damped.

  • Field Details

    • logger

      protected static final Logger logger
    • rigidBody

      protected PhysicsRigidBody rigidBody
    • radius

      protected float radius
    • height

      protected float height
    • mass

      protected float mass
      mass of this character (>0)
    • duckedFactor

      protected float duckedFactor
      relative height when ducked (1=full height)
    • localUp

      protected final Vector3f localUp
      local up direction, derived from gravity
    • localForward

      protected final Vector3f localForward
      Local absolute z-forward direction, derived from gravity and UNIT_Z, updated continuously when gravity changes.
    • localLeft

      protected final Vector3f localLeft
      Local left direction, derived from up and forward.
    • localForwardRotation

      protected final Quaternion localForwardRotation
      Local z-forward quaternion for the "local absolute" z-forward direction.
    • viewDirection

      protected final Vector3f viewDirection
      a Z-forward vector based on the view direction and the local X-Z plane.
    • location

      protected final Vector3f location
      spatial location, corresponds to RigidBody location.
    • rotation

      protected final Quaternion rotation
      spatial rotation, a Z-forward rotation based on the view direction and local X-Z plane.
      See Also:
    • rotatedViewDirection

      protected final Vector3f rotatedViewDirection
    • walkDirection

      protected final Vector3f walkDirection
    • jumpForce

      protected final Vector3f jumpForce
    • physicsDamping

      protected float physicsDamping
      X-Z motion damping factor (0→no damping, 1=no external forces, default=0.9)
    • scale

      protected final Vector3f scale
    • velocity

      protected final Vector3f velocity
    • jump

      protected boolean jump
    • onGround

      protected boolean onGround
    • ducked

      protected boolean ducked
    • wantToUnDuck

      protected boolean wantToUnDuck
  • Constructor Details

    • BetterCharacterControl

      protected BetterCharacterControl()
      No-argument constructor needed by SavableClassUtil. Do not invoke directly!
    • BetterCharacterControl

      public BetterCharacterControl(float radius, float height, float mass)
      Instantiate an enabled control with the specified properties.

      The final height when ducking must be larger than 2x radius. The jumpForce will be set to an upward force of 5x mass.

      radius - the radius of the character's collision shape (>0)
      height - the height of the character's collision shape (>2*radius)
      mass - the character's mass (≥0)
  • Method Details

    • 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 graph. Do not invoke directly from user code.
      Specified by:
      update in interface Control
      update in class AbstractPhysicsControl
      tpf - the time interval between frames (in seconds, ≥0)
    • render

      public void render(RenderManager rm, ViewPort vp)
      Render this control. Invoked once per view port per frame, provided the control is added to a scene. Should be invoked only by a subclass or by the RenderManager.
      Specified by:
      render in interface Control
      render in class AbstractPhysicsControl
      rm - the render manager (not null)
      vp - the view port to render (not null)
    • prePhysicsTick

      public void prePhysicsTick(PhysicsSpace space, float tpf)
      Callback from Bullet, invoked just before the physics is stepped.
      Specified by:
      prePhysicsTick in interface PhysicsTickListener
      space - the space that is about to be stepped (not null)
      tpf - the time per physics step (in seconds, ≥0)
    • physicsTick

      public void physicsTick(PhysicsSpace space, float tpf)
      Callback from Bullet, invoked just after the physics has been stepped.
      Specified by:
      physicsTick in interface PhysicsTickListener
      space - the space that was just stepped (not null)
      tpf - the time per physics step (in seconds, ≥0)
    • warp

      public void warp(Vector3f vec)
      Move the character somewhere. Note the character also warps to the location of the spatial when the control is added.
      vec - the desired character location (not null)
    • jump

      public void jump()
      Makes the character jump with the set jump force.
    • setJumpForce

      public void setJumpForce(Vector3f jumpForce)
      Alter the jump force. The jump force is local to the character's coordinate system, which normally is always z-forward (in world coordinates, parent coordinates when set to applyLocalPhysics)
      jumpForce - the desired jump force (not null, unaffected, default=5*mass in +Y direction)
    • getJumpForce

      public Vector3f getJumpForce()
      Access the jump force.
      the pre-existing vector (not null)
    • isOnGround

      public boolean isOnGround()
      Test whether the character is supported. Uses a ray test from the center of the character and might return false even if the character is not falling yet.
      true if on the ground, otherwise false
    • setDucked

      public void setDucked(boolean enabled)
      Toggle character ducking. When ducked the characters capsule collision shape height will be multiplied by duckedFactor to make the capsule smaller. When unducking, the character will check with a ray test if it can in fact unduck and only do so when it's possible. You can test the state using isDucked().
      enabled - true→duck, false→unduck
    • isDucked

      public boolean isDucked()
      Check if the character is ducking, either due to user input or due to unducking being impossible at the moment (obstacle above).
      true if ducking, otherwise false
    • setDuckedFactor

      public void setDuckedFactor(float factor)
      Alter the height multiplier for ducking.
      factor - the factor by which the height should be multiplied when ducking (≥0, ≤1)
    • getDuckedFactor

      public float getDuckedFactor()
      Read the height multiplier for ducking.
      the factor (≥0, ≤1)
    • setWalkDirection

      public void setWalkDirection(Vector3f vec)
      Alter the character's the walk direction. This parameter is framerate independent and the character will move continuously in the direction given by the vector with the speed given by the vector length in m/s.
      vec - The movement direction and speed in m/s
    • getWalkDirection

      public Vector3f getWalkDirection()
      Read the walk velocity. The length of the vector defines the speed.
      the pre-existing vector (not null)
    • setViewDirection

      public void setViewDirection(Vector3f vec)
      Alter the character's view direction. Note this only defines the orientation in the local X-Z plane.
      vec - a direction vector (not null, unaffected)
    • getViewDirection

      public Vector3f getViewDirection()
      Access the view direction. This need not agree with the spatial's forward direction.
      the pre-existing vector (not null)
    • resetForward

      public void resetForward(Vector3f vec)
      Realign the local forward vector to given direction vector, if null is supplied Vector3f.UNIT_Z is used. The input vector must be perpendicular to gravity vector. This normally only needs to be invoked when the gravity direction changed continuously and the local forward vector is off due to drift. E.g. after walking around on a sphere "planet" for a while and then going back to a Y-up coordinate system the local Z-forward might not be 100% aligned with the Z axis.
      vec - the desired forward vector (perpendicular to the gravity vector, may be null, default=0,0,1)
    • getVelocity

      public Vector3f getVelocity()
      Access the character's linear velocity in physics-space coordinates.
      the pre-existing vector (not null)
    • setGravity

      public void setGravity(Vector3f gravity)
      Alter the gravity acting on this character. Note that this also realigns the local coordinate system of the character so that continuous changes in gravity direction are possible while maintaining a sensible control over the character.
      gravity - an acceleration vector (not null, unaffected)
    • getGravity

      public Vector3f getGravity()
      Copy the character's gravity vector.
      a new acceleration vector (not null)
    • getGravity

      public Vector3f getGravity(Vector3f store)
      Copy the character's gravity vector.
      store - storage for the result (modified if not null)
      an acceleration vector (either the provided storage or a new vector, not null)
    • setPhysicsDamping

      public void setPhysicsDamping(float physicsDamping)
      Alter how much motion in the local X-Z plane is damped.
      physicsDamping - the desired damping factor (0→no damping, 1=no external forces, default=0.9)
    • getPhysicsDamping

      public float getPhysicsDamping()
      Read how much motion in the local X-Z plane is damped.
      the damping factor (0→no damping, 1=no external forces)
    • setHeightPercent

      protected void setHeightPercent(float percent)
      Alter the height of collision shape.
      percent - the desired height, as a percentage of the full height
    • checkOnGround

      protected void checkOnGround()
      Test whether the character is on the ground, by means of a ray test.
    • checkCanUnDuck

      protected boolean checkCanUnDuck()
      This checks if the character can go from ducked to unducked state by doing a ray test.
      true if able to unduck, otherwise false
    • getShape

      protected CollisionShape getShape()
      Create a collision shape based on the scale parameter. The new shape is a compound shape containing an offset capsule.
      a new compound shape (not null)
    • getFinalHeight

      protected float getFinalHeight()
      Calculate the character's scaled height.
      the height
    • getFinalRadius

      protected float getFinalRadius()
      Calculate the character's scaled radius.
      the radius
    • updateLocalCoordinateSystem

      protected void updateLocalCoordinateSystem()
      Updates the local coordinate system from the localForward and localUp vectors, adapts localForward, sets localForwardRotation quaternion to local Z-forward rotation.
    • updateLocalViewDirection

      protected void updateLocalViewDirection()
      Updates the local X-Z view direction and the corresponding rotation quaternion for the spatial.
    • calculateNewForward

      protected final void calculateNewForward(Quaternion rotation, Vector3f direction, Vector3f worldUpVector)
      This method works similar to Camera.lookAt but where lookAt sets the priority on the direction, this method sets the priority on the up vector so that the result direction vector and rotation is guaranteed to be perpendicular to the up vector.
      rotation - The rotation to set the result on or null to create a new Quaternion, this will be set to the new "z-forward" rotation if not null
      direction - The direction to base the new look direction on, will be set to the new direction
      worldUpVector - The up vector to use, the result direction will be perpendicular to this
    • setPhysicsLocation

      protected void setPhysicsLocation(Vector3f vec)
      Translate the character to the specified location.
      Specified by:
      setPhysicsLocation in class AbstractPhysicsControl
      vec - desired location (not null, unaffected)
    • setPhysicsRotation

      protected void setPhysicsRotation(Quaternion quat)
      Rotate the physics object to the specified orientation.

      We don't set the actual physics rotation but the view rotation here. It might actually be altered by the calculateNewForward method.

      Specified by:
      setPhysicsRotation in class AbstractPhysicsControl
      quat - desired orientation (not null, unaffected)
    • addPhysics

      protected void addPhysics(PhysicsSpace space)
      Add all managed physics objects to the specified space.
      Specified by:
      addPhysics in class AbstractPhysicsControl
      space - which physics space to add to (not null)
    • removePhysics

      protected void removePhysics(PhysicsSpace space)
      Remove all managed physics objects from the specified space.
      Specified by:
      removePhysics in class AbstractPhysicsControl
      space - which physics space to remove from (not null)
    • createSpatialData

      protected void createSpatialData(Spatial spat)
      Create spatial-dependent data. Invoked when this control is added to a spatial.
      Specified by:
      createSpatialData in class AbstractPhysicsControl
      spat - the controlled spatial (not null, alias created)
    • removeSpatialData

      protected void removeSpatialData(Spatial spat)
      Destroy spatial-dependent data. Invoked when this control is removed from a spatial.
      Specified by:
      removeSpatialData in class AbstractPhysicsControl
      spat - the previously controlled spatial (not null)
    • jmeClone

      public Object jmeClone()
      Create a shallow clone for the JME cloner.
      Specified by:
      jmeClone in interface JmeCloneable
      a new control (not null)
    • write

      public void write(JmeExporter ex) throws IOException
      Serialize this control, for example when saving to a J3O file.
      Specified by:
      write in interface Savable
      write in class AbstractPhysicsControl
      ex - exporter (not null)
      IOException - from exporter
    • read

      public void read(JmeImporter im) throws IOException
      De-serialize this control, for example when loading from a J3O file.
      Specified by:
      read in interface Savable
      read in class AbstractPhysicsControl
      im - importer (not null)
      IOException - from importer