The IKINEMA foot placement class is an extension of the Generic Solver.
It adds supoprts commonly sought after behaviors out of the box such as:
- Full body Foot Placement
- Full body lookat
- Full body Aiming and Weapon wielding
1 General Procedure
1.1 On Initialization
1.1.1 Construct the Foot Placement node
The Foot Placement node can be constructed using one of the following:
(a) FootPlacement(const GameRig& Rig, const char* LicensePath, char** ErrorMessage);
(b) FootPlacement(const GameRig& Rig, const char* LicensePath, char** ErrorMessage, IKArray& RestTransforms);
(c) FootPlacement(const GameRig& Rig, const char* LicensePath, char** ErrorMessage, IKArrayView& PoseView);
In (a) the solver will be initialized from the rest pose of the character stored in the IKINEMA Rig.
In (b) and (c) the solver will be initialized with a pose passed in by the user. This can be in the form of an FIK::IKArray or an FIK::IKArrayView. The pose passed in must correspond to the poses of the bones included in the FIK::GameRig.
1.1.2 Configure Node Behavoiurs
This can be done at initialization if the behaviour will not change once initialized or driven dynamically at runtime.
The behavior settings grouped as member structs in the FootPlacement class and are as follows:
Description: Control the maximum extension of a ray tracing element away from the task bone location in the input animation
Access Using: FootPlacement::GetLegExtensionParams()
Set Using: FootPlacement::SetLegExtensionParams(const LimitLegExtensionParams& LegExtParams)
- Mode (enum):
- UseFKAsMaxTarg: When triggered, the ray tracing task target will be clamped to the task bone location in the input animation
- UseMaxLegExtAsTarg: When triggered, the ray tracing task target will be clamped to the task bone location in the input animation offset by the MaxLegExtension parameter
- Default Value: Enum Disabled
- MaxLegExtension (Real):
- Description: Specifies the max threshold a ray tracing element can pull away from the task bone location in the input animation. If the Mode is UseMaxLegExtAsTarg, the ray tracing task target will be clamped to the task bone location in the input animation offset by the MaxLegExtension setting.
- Default Value: 0.f
Setting the MaxLegExtension to 10 and 30. As this value increases when the behavior is enabled, the distance the ray tracing elements can pull is increased.
Description: The hip multiplier parameters control offsetting the non-ray tracing tasks included in the rig depending on the demands of the ray tracing elements. In a typical setup, this acts to offset the upper body of the biped to allow the feet to make good contact with the terrain.
Access Using: FootPlacement::GetHipMultiplierParams()
Set Using: FootPlacement::SetHipMultiplierParams(const HipMultiplierParams& HipMultipliers)
- MaxHipMultiplier (real)
- Description: Increasing this value will scale the amount non ray tracing tasks are shifted downwards if the ray tracing tasks need to pull downwards to reach the terrain.
- Default Value: 1.0f
- MinHipMultiplier (real)
- Description: Increasing this value will scale the amount non ray tracing tasks are shifted updates if the ray tracing tasks need to pull up to reach the terrain
- Default Value: 1.0f
A well tuned MaxHipMultiplier will ensure the non ray tracing tasks are offset to allow the ray tracing tasks to make good contact with the terrain.
Description: The foot stabilization params control the reverse foot and foot stabilization behaviors. These behaviors require a 2 ray trace task per foot setup for a biped character.
The reverse foot behavior will trigger when the character is facing up a slope. In this situation, the heel of the foot will be rotated upwards to generate a more realistic pose.
The foot stabilization behavior will trigger when the character is on step like terrain. The behavior will ensure the heel and toe are kept level when one of the tasks is local to the upper part of the step and the other tasks is positioned near the lower part
Access Using: FootStabilizationParams& GetFootStabilizationParams()
Set Using: void SetFootStabilizationParams(const FootStabilizationParams& FootStabParams)
- Disabled: Neither reverse foot or foot stabilization are active
- OnlyEnableReverseFoot: Only the reverse foot behavior will be triggered
- Enabled: Both reverse foot and footstabilization will be triggered
- ReverseFootFactor (Real)
- Description: Controls the extent of the reverse foot behavior. Increasing this value will increase the amount the heel is rotated by.
- Default Value: 1.f
- ReverseFootSmoothness (Real)
- Description: This is a blending factor on the speed of the heel rotation when the reverse foot behavior is triggered.
- Default Value: 1.f
- StabilizationThresholdScale (Real)
- Description: Controls the treshold used to determine when the behaviors should be triggered
- Default Value: 1.f
The above image is an example of the foot stabilization behavior. It keeps the toe and heel level when in step like scenarios.
The above illustrates the reverse foot behavior which triggers on sloped terrain. The heel of the character is 'unstuck' from the terrain and rotated upwards. The amount the heel is rotated is controlled by the ReverseFootFactor and the speed it is rotated by when triggered is controlled by the ReverseFootSmoothness
1.2 On Animation Update
To achieve the basic solve at every frame after the solver has been constructed and configured, the IK Demand for tasks with non zero alpha must be specified. If the Task alpha is zero the IK Demand is automatically generated and taken from the task bone location in the input animation.
Setting basic RTGameTask parameters needed for solving at runtime can be done through the FootPlacement class.
For the basic setup, at each frame you need to:
- Set IK Demands for the RTGameTasks (section 1.2.1)
- For ray-casting tasks (eg. feet tasks) do a ray-cast in engine from the task bone location and pass the Impact Point and Impact Normal back to the solver.
For more advanced behaviours, the RTGameTask interface can be accessed to configure the tasks. Acessing the RTGameTask interface can be done through the FootPlacement class
Advanced setup that could take place on animation update are
- Dynamically drive the task alpha (section 1.2.2)
- Dynamically configure behaviour settings (section 1.2.3)
- Dynamically drive solver/task/bone Rig settings (section 1.2.4)
- Dynamically drive RTGameTask settings that affect target generation
For advanced setup, the RTGameTask interface can be accessed from the FootPlacement class with the following calls:
RTGameTask& GetTaskInstance(int TaskIndex)
RTGameTask& GetTaskInstance(const IKString& TaskName)
RTGameTask* GetTaskInstancePtr(const IKString& TaskName)
RTGameTask* TaskInstancePtr(int TaskIndex)
1.2.1 Assign IK Demands to tasks
This can be done through the FootPlacement interface or through the RTGameTask interface.
The FootPlacement interface allows for setting the basic parameters of a task. For more detailed setup the RTGameTask interface can be used.
The following are bulk setters to achieve the basic behaviour for a standard task, look at task and ray trace task.
FootPlacement::SetTaskTargetAndAlpha(int TaskIndex, const Transform& Target, Real PositionAlpha, Real RotationAlpha)
FootPlacement::SetLookAtTargetAndAlpha(int TaskIndex, const Vector& LookAtTarget, Real RotationAlpha, const Vector PositionTarget, Real PositionAlpha)
FootPlacement::SetTaskRayTraceParams(int TaskIndex, const Vector& ImpactPoint, const Vector& ImpactNormal, Real PositionAlpha, Real RotationAlpha)
To setup the ray tracing task, you must do a ray cast In-Engine from the task bone location and pass the impact point and impact normal of the resulting collision to the above setter. This will allow the ray casting feet tasks to be morphed to the terrain while and the non-ray tracing tasks will be offset to give the full body foot placement foot behavior.
Note: The targets passed in should be in either solver or world space depending on user defined FootPlacement::ExpectedTargetSpace. If the solver is expecting world space targets, at each frame you will need to pass the solver the transform that converts from world to solver space.
This can be done with FootPlacement::SetWorldToSolverTransform(const Transform& Transform)
1.2.2 Assign Position/Rotation alpha to tasks (optional)
The Position/Rotation alpha are a blending factor used when generating the final Position/Rotation targets passed to the solver.
At a value of 0, the generated target will be taken from task bone location in the input animation.
At a value of 1, the generated target will be the user defined values. A value in between 0-1 is an interpolation between the two.
Dynamically driving the task alpha parameters is necessary in situations where blending in and out of the animation is required.
1.2.3 Configure supported behaviors
The settings discussed in 1.1.2 can be driven at runtime if desired.
1.2.4 Configure solver/task/bone settings (optional)
There are a number of parameters that can be modified at runtime to alter behavior.
FootPlacement::SetSolverProperties(const SolverSettings& Settings)
FootPlacement::SetTaskProperties(int RTTaskIndex, const GameTask& Settings)
FootPlacement::SetBalanceTaskProperties(const RigBalanceTask&, BalanceType);
FootPlacement::SetBoneProperties(int RigBoneIndex, const RigBone& Settings)
Driving the task settings of the IKINEMA Rig at runtime can also be done through accessing a RTGameTask and modifying the GameTask/RigTask member variables.
1.2.5 Call to Solve
Once the task targets, alphas, behavior and any other solver/task/rig configuration has taken place the FootPlacement node has been configured to perform a solve.
The animation data at the frame in which the call to solve happens should be passed in to the call to solve as either an IKArray or IKArrayView
The solve can be performed with the following calls:
This will call the core solver to generate a Pose that allows the IK Tasks to meet their specified demands depending on IKINEMA Rig settings.
The generated pose is passed back to the user.
The footplacement class inherits functionality from the generic solver to allow visualising the task targets as the solver sees them.
The following calls can be used to retrieve the task targets from the solver. This should be done after a call to solve so that the task targets used in the solve are retrieved.
These calls will return an array of transforms which are the target for each task as seen by the solver. These targets are always in solver space.