void _PresolveHips()
{
Assert( _internalValues != null && _internalValues.animatorEnabled );
var temp = _solverInternal;
Assert( temp != null );
if( _hipsEffector == null ) {
return;
}
bool rotationEnabled = _hipsEffector.rotationEnabled && _hipsEffector.rotationWeight > IKEpsilon;
bool positionEnabled = _hipsEffector.positionEnabled && _hipsEffector.pull > IKEpsilon; // Note: Not positionWeight.
if( !rotationEnabled && !positionEnabled ) {
return;
}
Matrix3x3 centerLegBasis = temp.centerLegBasis;
if( rotationEnabled ) {
Quaternion centerLegRotationTo = _hipsEffector.worldRotation * Inverse( _hipsEffector._defaultRotation );
Quaternion centerLegRotationFrom;
SAFBIKMatGetRot( out centerLegRotationFrom, ref centerLegBasis );
Quaternion centerLegRotation = centerLegRotationTo * Inverse( centerLegRotationFrom );
if( _hipsEffector.rotationWeight < 1.0f - IKEpsilon ) {
centerLegRotation = Quaternion.Lerp( Quaternion.identity, centerLegRotation, _hipsEffector.rotationWeight );
}
temp.LowerRotation( -1, ref centerLegRotation, true );
centerLegBasis = temp.centerLegBasis;
}
if( positionEnabled ) {
// Note: _hidden_worldPosition is contained positionWeight.
Vector3 hipsEffectorWorldPosition = _hipsEffector._hidden_worldPosition;
Vector3 centerLegPos;
SAFBIKMatMultVecPreSubAdd( out centerLegPos, ref centerLegBasis, ref _defaultCenterLegPos, ref _hipsEffector._defaultPosition, ref hipsEffectorWorldPosition );
Vector3 translate = centerLegPos - temp.centerLegPos;
if( _hipsEffector.pull < 1.0f - IKEpsilon ) {
translate *= _hipsEffector.pull;
}
temp.Translate( ref translate );
}
}