public bool Solve(FullBodyIK fullBodyIK)
{
if (_neckBone == null || !_neckBone.transformIsAlive ||
_headBone == null || !_headBone.transformIsAlive ||
_headBone.parentBone == null || !_headBone.parentBone.transformIsAlive)
{
return(false);
}
_SyncDisplacement(fullBodyIK);
float headPositionWeight = _headEffector.positionEnabled ? _headEffector.positionWeight : 0.0f;
float eyesPositionWeight = _eyesEffector.positionEnabled ? _eyesEffector.positionWeight : 0.0f;
if (headPositionWeight <= IKEpsilon && eyesPositionWeight <= IKEpsilon)
{
Quaternion parentWorldRotation = _neckBone.parentBone.worldRotation;
Quaternion parentBaseRotation;
SAFBIKQuatMult(out parentBaseRotation, ref parentWorldRotation, ref _neckBone.parentBone._worldToBaseRotation);
if (_internalValues.resetTransforms)
{
Quaternion tempRotation;
SAFBIKQuatMult(out tempRotation, ref parentBaseRotation, ref _neckBone._baseToWorldRotation);
_neckBone.worldRotation = tempRotation;
}
float headRotationWeight = _headEffector.rotationEnabled ? _headEffector.rotationWeight : 0.0f;
if (headRotationWeight > IKEpsilon)
{
Quaternion headEffectorWorldRotation = _headEffector.worldRotation;
Quaternion toRotation;
SAFBIKQuatMult(out toRotation, ref headEffectorWorldRotation, ref _headEffectorToWorldRotation);
if (headRotationWeight < 1.0f - IKEpsilon)
{
Quaternion fromRotation;
if (_internalValues.resetTransforms)
{
SAFBIKQuatMult(out fromRotation, ref parentBaseRotation, ref _headBone._baseToWorldRotation);
}
else
{
fromRotation = _headBone.worldRotation; // This is able to use _headBone.worldRotation directly.
}
_headBone.worldRotation = Quaternion.Lerp(fromRotation, toRotation, headRotationWeight);
}
else
{
_headBone.worldRotation = toRotation;
}
_HeadRotationLimit();
}
else
{
if (_internalValues.resetTransforms)
{
Quaternion tempRotation;
SAFBIKQuatMult(out tempRotation, ref parentBaseRotation, ref _headBone._baseToWorldRotation);
_headBone.worldRotation = tempRotation;
}
}
if (_internalValues.resetTransforms)
{
if (_isEnabledCustomEyes)
{
fullBodyIK._ResetCustomEyes();
}
else
{
_ResetEyes();
}
}
return(_internalValues.resetTransforms || (headRotationWeight > IKEpsilon));
}
_Solve(fullBodyIK);
return(true);
}