public void Update()
{
_UpdateInternalValues();
if( _effectors != null ) {
int effectorLength = _effectors.Length;
for( int i = 0; i != effectorLength; ++i ) {
if( _effectors[i] != null ) {
_effectors[i].PrepareUpdate();
}
}
}
internalValues.ClearDegugPoints();
_Bones_PrepareUpdate();
_Bones_SyncDisplacement();
if( internalValues.resetTransforms || internalValues.continuousSolverEnabled ) {
_ComputeBaseHipsTransform();
}
// Feedback bonePositions to effectorPositions.
// (for AnimatorEnabled only.)
if( _effectors != null ) {
int effectorLength = _effectors.Length;
for( int i = 0; i != effectorLength; ++i ) {
Effector effector = _effectors[i];
if( effector != null ) {
// todo: Optimize. (for BodyIK)
// LimbIK : bending / end
// BodyIK : wrist / foot / neck
// FingerIK : nothing
if( effector.effectorType == EffectorType.Eyes ||
effector.effectorType == EffectorType.HandFinger ) { // Optimize.
#if SAFULLBODYIK_DEBUG
effector._hidden_worldPosition = new Vector3();
#endif
} else {
float weight = effector.positionEnabled ? effector.positionWeight : 0.0f;
Vector3 destPosition = (weight > IKEpsilon) ? effector.worldPosition : new Vector3();
if( weight < 1.0f - IKEpsilon ) {
Vector3 sourcePosition = destPosition; // Failsafe.
if( !internalValues.animatorEnabled && (internalValues.resetTransforms || internalValues.continuousSolverEnabled) ) {
if( effector.effectorLocation == EffectorLocation.Hips ) {
sourcePosition = internalValues.baseHipsPos; // _ComputeBaseHipsTransform()
} else {
Effector hipsEffector = (bodyEffectors != null) ? bodyEffectors.hips : null;
if( hipsEffector != null ) {
SAFBIKMatMultVecPreSubAdd(
out sourcePosition,
ref internalValues.baseHipsBasis,
ref effector._defaultPosition,
ref hipsEffector._defaultPosition,
ref internalValues.baseHipsPos );
}
}
} else { // for Animation.
if( effector.bone != null && effector.bone.transformIsAlive ) {
sourcePosition = effector.bone.worldPosition;
}
}
if( weight > IKEpsilon ) {
effector._hidden_worldPosition = Vector3.Lerp( sourcePosition, destPosition, weight );
} else {
effector._hidden_worldPosition = sourcePosition;
}
} else {
effector._hidden_worldPosition = destPosition;
}
}
}
}
}
// Presolve locations.
if( _limbIK != null ) {
int limbIKLength = _limbIK.Length;
for( int i = 0; i != limbIKLength; ++i ) {
if( _limbIK[i] != null ) {
_limbIK[i].PresolveBeinding();
}
}
}
if( _bodyIK != null ) {
if( _bodyIK.Solve() ) {
_Bones_WriteToTransform();
}
}
// todo: Force overwrite _hidden_worldPosition (LimbIK, arms)
// settings.
// public bool legAlwaysSolveEnabled = true;
// public bool armAlwaysSolveEnabled = false;
if( _limbIK != null || _headIK != null ) {
_Bones_PrepareUpdate();
bool isSolved = false;
bool isHeadSolved = false;
if( _limbIK != null ) {
int limbIKLength = _limbIK.Length;
for( int i = 0; i != limbIKLength; ++i ) {
if( _limbIK[i] != null ) {
isSolved |= _limbIK[i].Solve();
}
}
}
if( _headIK != null ) {
isHeadSolved = _headIK.Solve( this );
isSolved |= isHeadSolved;
}
if( isHeadSolved && _isNeedFixShoulderWorldTransform ) {
if( leftArmBones.shoulder != null ) {
leftArmBones.shoulder.forcefix_worldRotation();
}
if( rightArmBones.shoulder != null ) {
rightArmBones.shoulder.forcefix_worldRotation();
}
}
if( isSolved ) {
_Bones_WriteToTransform();
}
}
if( _fingerIK != null ) {
_Bones_PrepareUpdate();
bool isSolved = false;
int fingerIKLength = _fingerIK.Length;
for( int i = 0; i != fingerIKLength; ++i ) {
if( _fingerIK[i] != null ) {
isSolved |= _fingerIK[i].Solve();
}
}
if( isSolved ) {
_Bones_WriteToTransform();
}
}
}