0 Generic Solver Overview
The generic solver is a wrapper around the IKINEMA Core Solver and manages the IK Demand Generation solver configuration.
The node exposes each IK Task to the user allowing them to specify the IK position/rotation demand for each task 'type' and settings that affect the behavior and the final solve.
Given the IK demands per task, the IKINEMA Rig settings, and the input animation data at a given frame, the IKINEMA solver acts to pose the rig to allow the IK Tasks to meet their generated demands.
1 General Procedure
1.1 On Initialization
1.1.1 Construct the GenericSolver
The Generic Solver can be constructed using one of the following:
(a) GenericSolver(const GameRig& Rig, const char* LicensePath, char** ErrorMessage);
(b) GenericSolver(const GameRig& Rig, const char* LicensePath, char** ErrorMessage, IKArray& RestTransforms);
(c) GenericSolver(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.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 GenericSolver class.
For the basic setup, at each frame you need to:
- Set IK Demands for the RTGameTasks (section 1.2.1)
For more advanced behaviours, the RTGameTask interface can be accessed to configure the tasks. Acessing the RTGameTask interface can be done through the GenericSolver class
Advanced setup that could take place on animation update are
- Dynamically drive the task alpha (section 1.2.2)
- Dynamically drive solver/task/bone Rig settings (section 1.2.3)
- Dynamically drive RTGameTask settings that affect target generation
For advanced setup, the RTGameTask interface can be accessed from the GenericSolver 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 GenericSolver interface or through the RTGameTask interface.
The GenericSolver 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 and lookat task.
GenericSolver::SetTaskTargetAndAlpha(int TaskIndex, const Transform& Target, Real PositionAlpha, Real RotationAlpha)
GenericSolver::SetLookAtTargetAndAlpha(int TaskIndex, const Vector& LookAtTarget, Real RotationAlpha, const Vector PositionTarget, Real PositionAlpha)
Note: The targets passed in should be in either solver or world space depending on user defined GenericSolver::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 GenericSolver::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 solver/task/bone settings (optional)
There are a number of parameters that can be modified at runtime to alter behavior.
GenericSolver::SetSolverProperties(const SolverSettings& Settings)
GenericSolver::SetTaskProperties(int RTTaskIndex, const GameTask& Settings)
GenericSolver::SetBalanceTaskProperties(const RigBalanceTask&, BalanceType);
GenericSolver::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.4 Call to Solve
Once the task targets, alphas and any other solver/task/rig configuration has taken place the GenericSolver 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.