SA.FullBodyIK._LimitYZ C# (CSharp) Method

_LimitYZ() public static method

public static _LimitYZ ( bool isRight, Vector3 &dir, float limitYMinus, float limitYPlus, float limitZMinus, float limitZPlus ) : bool
isRight bool
dir Vector3
limitYMinus float
limitYPlus float
limitZMinus float
limitZPlus float
return bool
		public static bool _LimitYZ(
			bool isRight,
			ref Vector3 dir,					// dirX
			float limitYMinus,					// Y-
			float limitYPlus,					// Y+
			float limitZMinus,					// Z-
			float limitZPlus )					// Z+
		{
			bool isYPlus = (dir.y >= 0.0f);
			bool isZPlus = (dir.z >= 0.0f);
			float yLimit = isYPlus ? limitYPlus : limitYMinus;
			float zLimit = isZPlus ? limitZPlus : limitZMinus;

			bool isLimited = false;
			if( yLimit <= IKEpsilon && zLimit <= IKEpsilon ) {
				Vector3 limitedDir = isRight ? new Vector3( 1.0f, 0.0f, 0.0f ) : new Vector3( -1.0f, 0.0f, 0.0f );
				Vector3 temp = limitedDir - dir;
				if( Mathf.Abs( temp.x ) > IKEpsilon || Mathf.Abs( temp.y ) > IKEpsilon || Mathf.Abs( temp.z ) > IKEpsilon ) {
					dir = limitedDir;
					isLimited = true;
				}
			} else {
				float inv_yLimit = (yLimit >= IKEpsilon) ? (1.0f / yLimit) : 0.0f;
				float inv_zLimit = (zLimit >= IKEpsilon) ? (1.0f / zLimit) : 0.0f;
				float localY = dir.y * inv_yLimit;
				float localZ = dir.z * inv_zLimit;
				float localLen = SAFBIKSqrt( dir.x * dir.x + localY * localY + localZ * localZ );

				float inv_localLen = (localLen > IKEpsilon) ? (1.0f / localLen) : 0.0f;
				float nrm_localY = localY * inv_localLen; // Counts as sinTheta
				float nrm_localZ = localZ * inv_localLen; // Counts as cosTheta

				if( localLen > 1.0f ) { // Outer circle.
					if( !isLimited ) {
						isLimited = true;
						localY = nrm_localY;
						localZ = nrm_localZ;
					}
				}

				float worldY = isLimited ? (localY * yLimit) : dir.y;
				float worldZ = isLimited ? (localZ * zLimit) : dir.z;

				bool isInverse = ((dir.x >= 0.0f) != isRight);

				if( isLimited ) {
					float limitSinSq = (worldY * worldY + worldZ * worldZ);
					float limitSin = SAFBIKSqrt( limitSinSq );
					float limitCos = SAFBIKSqrt( 1.0f - limitSin * limitSin );
					dir.x = isRight ? limitCos : -limitCos;
					dir.y = worldY;
					dir.z = worldZ;
				} else if( isInverse ) {
					isLimited = true;
					dir.x = -dir.x;
				}
			}

			return isLimited;
		}
FullBodyIK