Jolt Physics
A multi core friendly Game Physics Engine
|
#include <CharacterVirtual.h>
Classes | |
struct | Contact |
struct | ExtendedUpdateSettings |
Settings struct with settings for ExtendedUpdate. More... | |
Public Types | |
using | TempContactList = Array< Contact, STLTempAllocator< Contact > > |
using | ContactList = Array< Contact > |
Public Types inherited from CharacterBase | |
enum class | EGroundState { OnGround , OnSteepGround , NotSupported , InAir } |
Public Member Functions | |
JPH_OVERRIDE_NEW_DELETE | CharacterVirtual (const CharacterVirtualSettings *inSettings, RVec3Arg inPosition, QuatArg inRotation, uint64 inUserData, PhysicsSystem *inSystem) |
CharacterVirtual (const CharacterVirtualSettings *inSettings, RVec3Arg inPosition, QuatArg inRotation, PhysicsSystem *inSystem) | |
Constructor without user data. More... | |
virtual | ~CharacterVirtual () override |
Destructor. More... | |
void | SetListener (CharacterContactListener *inListener) |
Set the contact listener. More... | |
CharacterContactListener * | GetListener () const |
Get the current contact listener. More... | |
void | SetCharacterVsCharacterCollision (CharacterVsCharacterCollision *inCharacterVsCharacterCollision) |
Set the character vs character collision interface. More... | |
Vec3 | GetLinearVelocity () const |
Get the linear velocity of the character (m / s) More... | |
void | SetLinearVelocity (Vec3Arg inLinearVelocity) |
Set the linear velocity of the character (m / s) More... | |
RVec3 | GetPosition () const |
Get the position of the character. More... | |
void | SetPosition (RVec3Arg inPosition) |
Set the position of the character. More... | |
Quat | GetRotation () const |
Get the rotation of the character. More... | |
void | SetRotation (QuatArg inRotation) |
Set the rotation of the character. More... | |
RVec3 | GetCenterOfMassPosition () const |
RMat44 | GetWorldTransform () const |
Calculate the world transform of the character. More... | |
RMat44 | GetCenterOfMassTransform () const |
Calculates the transform for this character's center of mass. More... | |
float | GetMass () const |
Character mass (kg) More... | |
void | SetMass (float inMass) |
float | GetMaxStrength () const |
Maximum force with which the character can push other bodies (N) More... | |
void | SetMaxStrength (float inMaxStrength) |
float | GetPenetrationRecoverySpeed () const |
This value governs how fast a penetration will be resolved, 0 = nothing is resolved, 1 = everything in one update. More... | |
void | SetPenetrationRecoverySpeed (float inSpeed) |
bool | GetEnhancedInternalEdgeRemoval () const |
Set to indicate that extra effort should be made to try to remove ghost contacts (collisions with internal edges of a mesh). This is more expensive but makes bodies move smoother over a mesh with convex edges. More... | |
void | SetEnhancedInternalEdgeRemoval (bool inApply) |
float | GetCharacterPadding () const |
Character padding. More... | |
uint | GetMaxNumHits () const |
Max num hits to collect in order to avoid excess of contact points collection. More... | |
void | SetMaxNumHits (uint inMaxHits) |
float | GetHitReductionCosMaxAngle () const |
Cos(angle) where angle is the maximum angle between two hits contact normals that are allowed to be merged during hit reduction. Default is around 2.5 degrees. Set to -1 to turn off. More... | |
void | SetHitReductionCosMaxAngle (float inCosMaxAngle) |
bool | GetMaxHitsExceeded () const |
Vec3 | GetShapeOffset () const |
An extra offset applied to the shape in local space. This allows applying an extra offset to the shape in local space. Note that setting it on the fly can cause the shape to teleport into collision. More... | |
void | SetShapeOffset (Vec3Arg inShapeOffset) |
uint64 | GetUserData () const |
Access to the user data, can be used for anything by the application. More... | |
void | SetUserData (uint64 inUserData) |
BodyID | GetInnerBodyID () const |
Optional inner rigid body that proxies the character in the world. Can be used to update body properties. More... | |
Vec3 | CancelVelocityTowardsSteepSlopes (Vec3Arg inDesiredVelocity) const |
void | Update (float inDeltaTime, Vec3Arg inGravity, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator) |
bool | CanWalkStairs (Vec3Arg inLinearVelocity) const |
bool | WalkStairs (float inDeltaTime, Vec3Arg inStepUp, Vec3Arg inStepForward, Vec3Arg inStepForwardTest, Vec3Arg inStepDownExtra, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator) |
bool | StickToFloor (Vec3Arg inStepDown, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator) |
void | ExtendedUpdate (float inDeltaTime, Vec3Arg inGravity, const ExtendedUpdateSettings &inSettings, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator) |
void | RefreshContacts (const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator) |
This function can be used after a character has teleported to determine the new contacts with the world. More... | |
void | UpdateGroundVelocity () |
bool | SetShape (const Shape *inShape, float inMaxPenetrationDepth, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator) |
void | SetInnerBodyShape (const Shape *inShape) |
Updates the shape of the inner rigid body. Should be called after a successful call to SetShape. More... | |
TransformedShape | GetTransformedShape () const |
Get the transformed shape that represents the volume of the character, can be used for collision checks. More... | |
void | CheckCollision (RVec3Arg inPosition, QuatArg inRotation, Vec3Arg inMovementDirection, float inMaxSeparationDistance, const Shape *inShape, RVec3Arg inBaseOffset, CollideShapeCollector &ioCollector, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter) const |
Get all contacts for the character at a particular location. When colliding with another character virtual, this pointer will be provided through CollideShapeCollector::SetUserContext before adding a hit. More... | |
virtual void | SaveState (StateRecorder &inStream) const override |
virtual void | RestoreState (StateRecorder &inStream) override |
const ContactList & | GetActiveContacts () const |
Access to the internal list of contacts that the character has found. More... | |
bool | HasCollidedWith (const BodyID &inBody) const |
Check if the character is currently in contact with or has collided with another body in the last time step. More... | |
bool | HasCollidedWith (const CharacterVirtual *inCharacter) const |
Check if the character is currently in contact with or has collided with another character in the last time step. More... | |
Public Member Functions inherited from CharacterBase | |
JPH_OVERRIDE_NEW_DELETE | CharacterBase (const CharacterBaseSettings *inSettings, PhysicsSystem *inSystem) |
Constructor. More... | |
virtual | ~CharacterBase ()=default |
Destructor. More... | |
void | SetMaxSlopeAngle (float inMaxSlopeAngle) |
Set the maximum angle of slope that character can still walk on (radians) More... | |
float | GetCosMaxSlopeAngle () const |
void | SetUp (Vec3Arg inUp) |
Set the up vector for the character. More... | |
Vec3 | GetUp () const |
bool | IsSlopeTooSteep (Vec3Arg inNormal) const |
Check if the normal of the ground surface is too steep to walk on. More... | |
const Shape * | GetShape () const |
Get the current shape that the character is using. More... | |
EGroundState | GetGroundState () const |
Current ground state. More... | |
bool | IsSupported () const |
Returns true if the player is supported by normal or steep ground. More... | |
RVec3 | GetGroundPosition () const |
Get the contact point with the ground. More... | |
Vec3 | GetGroundNormal () const |
Get the contact normal with the ground. More... | |
Vec3 | GetGroundVelocity () const |
Velocity in world space of ground. More... | |
const PhysicsMaterial * | GetGroundMaterial () const |
Material that the character is standing on. More... | |
BodyID | GetGroundBodyID () const |
BodyID of the object the character is standing on. Note may have been removed! More... | |
SubShapeID | GetGroundSubShapeID () const |
Sub part of the body that we're standing on. More... | |
uint64 | GetGroundUserData () const |
User data value of the body that we're standing on. More... | |
Public Member Functions inherited from RefTarget< CharacterBase > | |
RefTarget ()=default | |
Constructor. More... | |
RefTarget (const RefTarget &) | |
~RefTarget () | |
assert no one is referencing us More... | |
void | SetEmbedded () const |
RefTarget & | operator= (const RefTarget &) |
Assignment operator. More... | |
uint32 | GetRefCount () const |
Get current refcount of this object. More... | |
void | AddRef () const |
Add or release a reference to this object. More... | |
void | Release () const |
Public Member Functions inherited from NonCopyable | |
NonCopyable ()=default | |
NonCopyable (const NonCopyable &)=delete | |
void | operator= (const NonCopyable &)=delete |
Static Public Attributes | |
static bool | sDrawConstraints = false |
Draw the current state of the constraints for iteration 0 when creating them. More... | |
static bool | sDrawWalkStairs = false |
Draw the state of the walk stairs algorithm. More... | |
static bool | sDrawStickToFloor = false |
Draw the state of the stick to floor algorithm. More... | |
Additional Inherited Members | |
Static Public Member Functions inherited from CharacterBase | |
static const char * | sToString (EGroundState inState) |
Debug function to convert enum values to string. More... | |
Static Public Member Functions inherited from RefTarget< CharacterBase > | |
static int | sInternalGetRefCountOffset () |
INTERNAL HELPER FUNCTION USED BY SERIALIZATION. More... | |
Protected Attributes inherited from CharacterBase | |
PhysicsSystem * | mSystem |
RefConst< Shape > | mShape |
Vec3 | mUp |
Plane | mSupportingVolume |
float | mCosMaxSlopeAngle |
EGroundState | mGroundState = EGroundState::InAir |
BodyID | mGroundBodyID |
SubShapeID | mGroundBodySubShapeID |
RVec3 | mGroundPosition = RVec3::sZero() |
Vec3 | mGroundNormal = Vec3::sZero() |
Vec3 | mGroundVelocity = Vec3::sZero() |
RefConst< PhysicsMaterial > | mGroundMaterial = PhysicsMaterial::sDefault |
uint64 | mGroundUserData = 0 |
Protected Attributes inherited from RefTarget< CharacterBase > | |
atomic< uint32 > | mRefCount |
Current reference count. More... | |
Static Protected Attributes inherited from CharacterBase | |
static constexpr float | cNoMaxSlopeAngle = 0.9999f |
Static Protected Attributes inherited from RefTarget< CharacterBase > | |
static constexpr uint32 | cEmbedded |
A large value that gets added to the refcount to mark the object as embedded. More... | |
Runtime character object. This object usually represents the player. Contrary to the Character class it doesn't use a rigid body but moves doing collision checks only (hence the name virtual). The advantage of this is that you can determine when the character moves in the frame (usually this has to happen at a very particular point in the frame) but the downside is that other objects don't see this virtual character. In order to make this work it is recommended to pair a CharacterVirtual with a Character that moves along. This Character should be keyframed (or at least have no gravity) and move along with the CharacterVirtual so that other rigid bodies can collide with it.
using CharacterVirtual::ContactList = Array<Contact> |
CharacterVirtual::CharacterVirtual | ( | const CharacterVirtualSettings * | inSettings, |
RVec3Arg | inPosition, | ||
QuatArg | inRotation, | ||
uint64 | inUserData, | ||
PhysicsSystem * | inSystem | ||
) |
Constructor
inSettings | The settings for the character |
inPosition | Initial position for the character |
inRotation | Initial rotation for the character (usually only around the up-axis) |
inUserData | Application specific value |
inSystem | Physics system that this character will be added to |
|
inline |
Constructor without user data.
|
overridevirtual |
Destructor.
This function can be called prior to calling Update() to convert a desired velocity into a velocity that won't make the character move further onto steep slopes. This velocity can then be set on the character using SetLinearVelocity()
inDesiredVelocity | Velocity to clamp against steep walls |
bool CharacterVirtual::CanWalkStairs | ( | Vec3Arg | inLinearVelocity | ) | const |
This function will return true if the character has moved into a slope that is too steep (e.g. a vertical wall). You would call WalkStairs to attempt to step up stairs.
inLinearVelocity | The linear velocity that the player desired. This is used to determine if we're pushing into a step. |
void CharacterVirtual::CheckCollision | ( | RVec3Arg | inPosition, |
QuatArg | inRotation, | ||
Vec3Arg | inMovementDirection, | ||
float | inMaxSeparationDistance, | ||
const Shape * | inShape, | ||
RVec3Arg | inBaseOffset, | ||
CollideShapeCollector & | ioCollector, | ||
const BroadPhaseLayerFilter & | inBroadPhaseLayerFilter, | ||
const ObjectLayerFilter & | inObjectLayerFilter, | ||
const BodyFilter & | inBodyFilter, | ||
const ShapeFilter & | inShapeFilter | ||
) | const |
Get all contacts for the character at a particular location. When colliding with another character virtual, this pointer will be provided through CollideShapeCollector::SetUserContext before adding a hit.
inPosition | Position to test, note that this position will be corrected for the character padding. |
inRotation | Rotation at which to test the shape. |
inMovementDirection | A hint in which direction the character is moving, will be used to calculate a proper normal. |
inMaxSeparationDistance | How much distance around the character you want to report contacts in (can be 0 to match the character exactly). |
inShape | Shape to test collision with. |
inBaseOffset | All hit results will be returned relative to this offset, can be zero to get results in world position, but when you're testing far from the origin you get better precision by picking a position that's closer e.g. GetPosition() since floats are most accurate near the origin |
ioCollector | Collision collector that receives the collision results. |
inBroadPhaseLayerFilter | Filter that is used to check if the character collides with something in the broadphase. |
inObjectLayerFilter | Filter that is used to check if a character collides with a layer. |
inBodyFilter | Filter that is used to check if a character collides with a body. |
inShapeFilter | Filter that is used to check if a character collides with a subshape. |
void CharacterVirtual::ExtendedUpdate | ( | float | inDeltaTime, |
Vec3Arg | inGravity, | ||
const ExtendedUpdateSettings & | inSettings, | ||
const BroadPhaseLayerFilter & | inBroadPhaseLayerFilter, | ||
const ObjectLayerFilter & | inObjectLayerFilter, | ||
const BodyFilter & | inBodyFilter, | ||
const ShapeFilter & | inShapeFilter, | ||
TempAllocator & | inAllocator | ||
) |
This function combines Update, StickToFloor and WalkStairs. This function serves as an example of how these functions could be combined. Before calling, call SetLinearVelocity to update the horizontal/vertical speed of the character, typically this is:
inDeltaTime | Time step to simulate. |
inGravity | Gravity vector (m/s^2). This gravity vector is only used when the character is standing on top of another object to apply downward force. |
inSettings | A structure containing settings for the algorithm. |
inBroadPhaseLayerFilter | Filter that is used to check if the character collides with something in the broadphase. |
inObjectLayerFilter | Filter that is used to check if a character collides with a layer. |
inBodyFilter | Filter that is used to check if a character collides with a body. |
inShapeFilter | Filter that is used to check if a character collides with a subshape. |
inAllocator | An allocator for temporary allocations. All memory will be freed by the time this function returns. |
|
inline |
Access to the internal list of contacts that the character has found.
|
inline |
|
inline |
Calculates the transform for this character's center of mass.
|
inline |
Character padding.
|
inline |
Set to indicate that extra effort should be made to try to remove ghost contacts (collisions with internal edges of a mesh). This is more expensive but makes bodies move smoother over a mesh with convex edges.
|
inline |
Cos(angle) where angle is the maximum angle between two hits contact normals that are allowed to be merged during hit reduction. Default is around 2.5 degrees. Set to -1 to turn off.
|
inline |
Optional inner rigid body that proxies the character in the world. Can be used to update body properties.
|
inline |
Get the linear velocity of the character (m / s)
|
inline |
Get the current contact listener.
|
inline |
Character mass (kg)
|
inline |
Returns if we exceeded the maximum number of hits during the last collision check and had to discard hits based on distance. This can be used to find areas that have too complex geometry for the character to navigate properly. To solve you can either increase the max number of hits or simplify the geometry. Note that the character simulation will try to do its best to select the most relevant contacts to avoid the character from getting stuck.
|
inline |
Max num hits to collect in order to avoid excess of contact points collection.
|
inline |
Maximum force with which the character can push other bodies (N)
|
inline |
This value governs how fast a penetration will be resolved, 0 = nothing is resolved, 1 = everything in one update.
|
inline |
Get the position of the character.
|
inline |
Get the rotation of the character.
|
inline |
An extra offset applied to the shape in local space. This allows applying an extra offset to the shape in local space. Note that setting it on the fly can cause the shape to teleport into collision.
|
inline |
Get the transformed shape that represents the volume of the character, can be used for collision checks.
|
inline |
Access to the user data, can be used for anything by the application.
|
inline |
Calculate the world transform of the character.
|
inline |
Check if the character is currently in contact with or has collided with another body in the last time step.
|
inline |
Check if the character is currently in contact with or has collided with another character in the last time step.
void CharacterVirtual::RefreshContacts | ( | const BroadPhaseLayerFilter & | inBroadPhaseLayerFilter, |
const ObjectLayerFilter & | inObjectLayerFilter, | ||
const BodyFilter & | inBodyFilter, | ||
const ShapeFilter & | inShapeFilter, | ||
TempAllocator & | inAllocator | ||
) |
This function can be used after a character has teleported to determine the new contacts with the world.
|
overridevirtual |
Reimplemented from CharacterBase.
|
overridevirtual |
Reimplemented from CharacterBase.
|
inline |
Set the character vs character collision interface.
|
inline |
|
inline |
void CharacterVirtual::SetInnerBodyShape | ( | const Shape * | inShape | ) |
Updates the shape of the inner rigid body. Should be called after a successful call to SetShape.
|
inline |
Set the linear velocity of the character (m / s)
|
inline |
Set the contact listener.
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
Set the position of the character.
|
inline |
Set the rotation of the character.
bool CharacterVirtual::SetShape | ( | const Shape * | inShape, |
float | inMaxPenetrationDepth, | ||
const BroadPhaseLayerFilter & | inBroadPhaseLayerFilter, | ||
const ObjectLayerFilter & | inObjectLayerFilter, | ||
const BodyFilter & | inBodyFilter, | ||
const ShapeFilter & | inShapeFilter, | ||
TempAllocator & | inAllocator | ||
) |
Switch the shape of the character (e.g. for stance).
inShape | The shape to switch to. |
inMaxPenetrationDepth | When inMaxPenetrationDepth is not FLT_MAX, it checks if the new shape collides before switching shape. This is the max penetration we're willing to accept after the switch. |
inBroadPhaseLayerFilter | Filter that is used to check if the character collides with something in the broadphase. |
inObjectLayerFilter | Filter that is used to check if a character collides with a layer. |
inBodyFilter | Filter that is used to check if a character collides with a body. |
inShapeFilter | Filter that is used to check if a character collides with a subshape. |
inAllocator | An allocator for temporary allocations. All memory will be freed by the time this function returns. |
|
inline |
void CharacterVirtual::SetUserData | ( | uint64 | inUserData | ) |
bool CharacterVirtual::StickToFloor | ( | Vec3Arg | inStepDown, |
const BroadPhaseLayerFilter & | inBroadPhaseLayerFilter, | ||
const ObjectLayerFilter & | inObjectLayerFilter, | ||
const BodyFilter & | inBodyFilter, | ||
const ShapeFilter & | inShapeFilter, | ||
TempAllocator & | inAllocator | ||
) |
This function can be used to artificially keep the character to the floor. Normally when a character is on a small step and starts moving horizontally, the character will lose contact with the floor because the initial vertical velocity is zero while the horizontal velocity is quite high. To prevent the character from losing contact with the floor, we do an additional collision check downwards and if we find the floor within a certain distance, we project the character onto the floor.
inStepDown | Max amount to project the character downwards (if no floor is found within this distance, the function will return false) |
inBroadPhaseLayerFilter | Filter that is used to check if the character collides with something in the broadphase. |
inObjectLayerFilter | Filter that is used to check if a character collides with a layer. |
inBodyFilter | Filter that is used to check if a character collides with a body. |
inShapeFilter | Filter that is used to check if a character collides with a subshape. |
inAllocator | An allocator for temporary allocations. All memory will be freed by the time this function returns. |
void CharacterVirtual::Update | ( | float | inDeltaTime, |
Vec3Arg | inGravity, | ||
const BroadPhaseLayerFilter & | inBroadPhaseLayerFilter, | ||
const ObjectLayerFilter & | inObjectLayerFilter, | ||
const BodyFilter & | inBodyFilter, | ||
const ShapeFilter & | inShapeFilter, | ||
TempAllocator & | inAllocator | ||
) |
This is the main update function. It moves the character according to its current velocity (the character is similar to a kinematic body in the sense that you set the velocity and the character will follow unless collision is blocking the way). Note it's your own responsibility to apply gravity to the character velocity! Different surface materials (like ice) can be emulated by getting the ground material and adjusting the velocity and/or the max slope angle accordingly every frame.
inDeltaTime | Time step to simulate. |
inGravity | Gravity vector (m/s^2). This gravity vector is only used when the character is standing on top of another object to apply downward force. |
inBroadPhaseLayerFilter | Filter that is used to check if the character collides with something in the broadphase. |
inObjectLayerFilter | Filter that is used to check if a character collides with a layer. |
inBodyFilter | Filter that is used to check if a character collides with a body. |
inShapeFilter | Filter that is used to check if a character collides with a subshape. |
inAllocator | An allocator for temporary allocations. All memory will be freed by the time this function returns. |
void CharacterVirtual::UpdateGroundVelocity | ( | ) |
Use the ground body ID to get an updated estimate of the ground velocity. This function can be used if the ground body has moved / changed velocity and you want a new estimate of the ground velocity. It will not perform collision detection, so is less accurate than RefreshContacts but a lot faster.
bool CharacterVirtual::WalkStairs | ( | float | inDeltaTime, |
Vec3Arg | inStepUp, | ||
Vec3Arg | inStepForward, | ||
Vec3Arg | inStepForwardTest, | ||
Vec3Arg | inStepDownExtra, | ||
const BroadPhaseLayerFilter & | inBroadPhaseLayerFilter, | ||
const ObjectLayerFilter & | inObjectLayerFilter, | ||
const BodyFilter & | inBodyFilter, | ||
const ShapeFilter & | inShapeFilter, | ||
TempAllocator & | inAllocator | ||
) |
When stair walking is needed, you can call the WalkStairs function to cast up, forward and down again to try to find a valid position
inDeltaTime | Time step to simulate. |
inStepUp | The direction and distance to step up (this corresponds to the max step height) |
inStepForward | The direction and distance to step forward after the step up |
inStepForwardTest | When running at a high frequency, inStepForward can be very small and it's likely that you hit the side of the stairs on the way down. This could produce a normal that violates the max slope angle. If this happens, we test again using this distance from the up position to see if we find a valid slope. |
inStepDownExtra | An additional translation that is added when stepping down at the end. Allows you to step further down than up. Set to zero if you don't want this. Should be in the opposite direction of up. |
inBroadPhaseLayerFilter | Filter that is used to check if the character collides with something in the broadphase. |
inObjectLayerFilter | Filter that is used to check if a character collides with a layer. |
inBodyFilter | Filter that is used to check if a character collides with a body. |
inShapeFilter | Filter that is used to check if a character collides with a subshape. |
inAllocator | An allocator for temporary allocations. All memory will be freed by the time this function returns. |
|
inlinestatic |
Draw the current state of the constraints for iteration 0 when creating them.
|
inlinestatic |
Draw the state of the stick to floor algorithm.
|
inlinestatic |
Draw the state of the walk stairs algorithm.