void _ComputeLocalAxis( FullBodyIK fullBodyIK )
{
// Compute _localAxisBasis for each bones.
if( this.transformIsAlive && (_parentBone != null && _parentBone.transformIsAlive) ) {
if( _localAxisFrom == _LocalAxisFrom.Parent ||
_parentBone._localAxisFrom == _LocalAxisFrom.Child ) {
Vector3 dir = _defaultLocalDirection;
if( dir.x != 0.0f || dir.y != 0.0f || dir.z != 0.0f ) {
if( _localAxisFrom == _LocalAxisFrom.Parent ) {
SAFBIKComputeBasisFrom( out _localAxisBasis, ref fullBodyIK.internalValues.defaultRootBasis, ref dir, _localDirectionAs );
}
if( _parentBone._localAxisFrom == _LocalAxisFrom.Child ) {
if( _parentBone._boneType == BoneType.Shoulder ) {
Bone shoulderBone = _parentBone;
Bone spineUBone = _parentBone._parentBone;
Bone neckBone = (fullBodyIK.headBones != null) ? fullBodyIK.headBones.neck : null;
if( neckBone != null && !neckBone.transformIsAlive ) {
neckBone = null;
}
if( fullBodyIK.internalValues.shoulderDirYAsNeck == -1 ) {
if( fullBodyIK.settings.shoulderDirYAsNeck == AutomaticBool.Auto ) {
if( spineUBone != null && neckBone != null ) {
Vector3 shoulderToSpineU = shoulderBone._defaultLocalDirection;
Vector3 shoulderToNeck = neckBone._defaultPosition - shoulderBone._defaultPosition;
if( SAFBIKVecNormalize( ref shoulderToNeck ) ) {
float shoulderToSpineUTheta = Mathf.Abs( Vector3.Dot( dir, shoulderToSpineU ) );
float shoulderToNeckTheta = Mathf.Abs( Vector3.Dot( dir, shoulderToNeck ) );
if( shoulderToSpineUTheta < shoulderToNeckTheta ) {
fullBodyIK.internalValues.shoulderDirYAsNeck = 0;
} else {
fullBodyIK.internalValues.shoulderDirYAsNeck = 1;
}
} else {
fullBodyIK.internalValues.shoulderDirYAsNeck = 0;
}
} else {
fullBodyIK.internalValues.shoulderDirYAsNeck = 0;
}
} else {
fullBodyIK.internalValues.shoulderDirYAsNeck = (fullBodyIK.settings.shoulderDirYAsNeck != AutomaticBool.Disable) ? 1 : 0;
}
}
Vector3 xDir, yDir, zDir;
xDir = (_parentBone._localDirectionAs == _DirectionAs.XMinus) ? -dir : dir;
if( fullBodyIK.internalValues.shoulderDirYAsNeck != 0 && neckBone != null ) {
yDir = neckBone._defaultPosition - shoulderBone._defaultPosition;
} else {
yDir = shoulderBone._defaultLocalDirection;
}
zDir = Vector3.Cross( xDir, yDir );
yDir = Vector3.Cross( zDir, xDir );
if( SAFBIKVecNormalize2( ref yDir, ref zDir ) ) {
_parentBone._localAxisBasis.SetColumn( ref xDir, ref yDir, ref zDir );
}
} else if( _parentBone._boneType == BoneType.Spine && _boneType != BoneType.Spine && _boneType != BoneType.Neck ) {
// Compute spine/neck only( Exclude shouder / arm ).
} else if( _parentBone._boneType == BoneType.Hips && _boneType != BoneType.Spine ) {
// Compute spine only( Exclude leg ).
} else {
if( _parentBone._boneType == BoneType.Hips ) {
Vector3 baseX = fullBodyIK.internalValues.defaultRootBasis.column0;
SAFBIKComputeBasisFromXYLockY( out _parentBone._localAxisBasis, ref baseX, ref dir );
} else if( _parentBone._boneType == BoneType.Spine || _parentBone._boneType == BoneType.Neck ) {
// Using parent axis for spine or neck. Preprocess for BodyIK.
if( _parentBone._parentBone != null ) {
Vector3 dirX = _parentBone._parentBone._localAxisBasis.column0;
SAFBIKComputeBasisFromXYLockY( out _parentBone._localAxisBasis, ref dirX, ref dir );
}
} else {
if( _localAxisFrom == _LocalAxisFrom.Parent && _localDirectionAs == _parentBone._localDirectionAs ) {
_parentBone._localAxisBasis = _localAxisBasis;
} else {
SAFBIKComputeBasisFrom( out _parentBone._localAxisBasis,
ref fullBodyIK.internalValues.defaultRootBasis, ref dir, _parentBone._localDirectionAs );
}
}
}
}
}
}
}
}