public void ProcessAnimation(AnimationStream stream) { jobWeight.Set(stream, 1f); var drivenPos = driven.GetLocalPosition(stream); var offset = drivenOffset.Get(stream); var lPos = drivenPos - offset; var parentTx = new AffineTransform(); if (drivenParent.IsValid(stream)) { drivenParent.GetGlobalTR(stream, out Vector3 parentWPos, out Quaternion parentWRot); parentTx = new AffineTransform(parentWPos, parentWRot); } var wPos = parentTx.Transform(lPos); for (int i = 0; i < sourceTransforms.Length; ++i) { sourceWeights[i].SetFloat(stream, 1f); ReadWriteTransformHandle sourceTransform = sourceTransforms[i]; sourceTransform.SetPosition(stream, wPos - sourceOffsets[i]); // Required to update handles with binding info. sourceTransforms[i] = sourceTransform; } }
/// <summary> /// Defines what to do when processing the animation. /// </summary> /// <param name="stream">The animation stream to work on.</param> public void ProcessAnimation(AnimationStream stream) { jobWeight.Set(stream, 1f); var lRot = driven.GetLocalRotation(stream); var offset = drivenOffset.Get(stream); if (Vector3.Dot(offset, offset) > 0f) { lRot *= Quaternion.Inverse(Quaternion.Euler(offset)); } var wRot = lRot; if (drivenParent.IsValid(stream)) { wRot = drivenParent.GetRotation(stream) * wRot; } for (int i = 0; i < sourceTransforms.Length; ++i) { sourceWeights[i].SetFloat(stream, 1f); ReadWriteTransformHandle sourceTransform = sourceTransforms[i]; sourceTransform.SetRotation(stream, wRot * sourceOffsets[i]); // Required to update handles with binding info. sourceTransforms[i] = sourceTransform; } }
public void ProcessAnimation(AnimationStream stream) { jobWeight.Set(stream, 1f); var lRot = driven.GetLocalRotation(stream); var offset = drivenOffset.Get(stream); if (Vector3.Dot(offset, offset) > 0f) { lRot *= Quaternion.Inverse(Quaternion.Euler(offset)); } var localToWorld = Quaternion.identity; var wPos = driven.GetPosition(stream); if (drivenParent.IsValid(stream)) { localToWorld = drivenParent.GetRotation(stream); } for (int i = 0; i < sourceTransforms.Length; ++i) { sourceWeights[i].SetFloat(stream, 1f); var sourceTransform = sourceTransforms[i]; sourceTransform.SetPosition(stream, wPos + localToWorld * sourceOffsets[i] * lRot * aimAxis); // Required to update handles with binding info. sourceTransforms[i] = sourceTransform; } }
public void ProcessAnimation(AnimationStream stream) { var w = jobWeight.Get(stream); if (w == 0f) { return; } var offset = ikOffset.Get(stream); var leftToePos = leftToe.GetPosition(stream); var rightToePos = rightToe.GetPosition(stream); var leftIkOffset = offset.x * w; var rightIkOffset = offset.y * w; leftToePos += new Vector3(0f, leftIkOffset, 0f); rightToePos += new Vector3(0f, rightIkOffset, 0f); var leftAnklePos = leftAnkle.GetPosition(stream); var rightAnklePos = rightAnkle.GetPosition(stream); var leftAnkleRot = leftAnkle.GetRotation(stream); var rightAnkleRot = rightAnkle.GetRotation(stream); var leftAnkleIkPos = new Vector3(leftAnklePos.x, leftAnklePos.y + leftIkOffset, leftAnklePos.z); var rightAnkleIkPos = new Vector3(rightAnklePos.x, rightAnklePos.y + rightIkOffset, rightAnklePos.z); var hipHeightOffset = (leftIkOffset + rightIkOffset) * 0.5f; var forwardBackBias = (leftIkOffset - rightIkOffset) * weightShiftHorizontal.Get(stream); float maxRotationOffset = maxFootRotationOffset.Get(stream); // TODO: (sunek) Rework weight shift to move towards actual lower foot? hipHeightOffset += Mathf.Abs(leftIkOffset - rightIkOffset) * weightShiftVertical.Get(stream); var standAngle = Quaternion.AngleAxis(weightShiftAngle.Get(stream), Vector3.up) * Vector3.forward; hips.SetPosition(stream, hips.GetPosition(stream) + new Vector3(standAngle.x * forwardBackBias, hipHeightOffset, standAngle.z * forwardBackBias)); // Figure out the normal rotation var leftNormalRot = Quaternion.LookRotation(Vector3.forward, normalLeftFoot.Get(stream)); var rightNormalRot = Quaternion.LookRotation(Vector3.forward, normalRightFoot.Get(stream)); // Clamp normal rotation var leftAngle = Quaternion.Angle(Quaternion.identity, leftNormalRot); var rightAngle = Quaternion.Angle(Quaternion.identity, rightNormalRot); if (leftAngle > maxRotationOffset && maxRotationOffset > 0f) { var fraction = maxRotationOffset / leftAngle; leftNormalRot = Quaternion.Lerp(Quaternion.identity, leftNormalRot, fraction); } if (rightAngle > maxRotationOffset && maxRotationOffset > 0f) { var fraction = maxRotationOffset / rightAngle; rightNormalRot = Quaternion.Lerp(Quaternion.identity, rightNormalRot, fraction); } // Apply rotation to ankle var leftToesMatrix = Matrix4x4.TRS(leftToePos, Quaternion.identity, Vector3.one); var rightToesMatrix = Matrix4x4.TRS(rightToePos, Quaternion.identity, Vector3.one); var leftToesNormalDeltaMatrix = Matrix4x4.TRS(leftToePos, leftNormalRot, Vector3.one) * leftToesMatrix.inverse; var rightToesNormalDeltaMatrix = Matrix4x4.TRS(rightToePos, rightNormalRot, Vector3.one) * rightToesMatrix.inverse; var leftAnkleMatrix = Matrix4x4.TRS(leftAnkleIkPos, leftAnkleRot, Vector3.one) * leftToesMatrix.inverse; var rightAnkleMatrix = Matrix4x4.TRS(rightAnkleIkPos, rightAnkleRot, Vector3.one) * rightToesMatrix.inverse; leftAnkleMatrix = leftToesNormalDeltaMatrix * leftAnkleMatrix * leftToesMatrix; rightAnkleMatrix = rightToesNormalDeltaMatrix * rightAnkleMatrix * rightToesMatrix; leftAnkleIkPos = leftAnkleMatrix.GetColumn(3); rightAnkleIkPos = rightAnkleMatrix.GetColumn(3); leftAnkleRot = Quaternion.Lerp(leftAnkleRot, leftAnkleMatrix.rotation, w); rightAnkleRot = Quaternion.Lerp(rightAnkleRot, rightAnkleMatrix.rotation, w); // Update ik position // TODO: (sunek) Consider combating leg overstretch var leftPosition = Vector3.Lerp(leftAnklePos, leftAnkleIkPos, w); var rightPosition = Vector3.Lerp(rightAnklePos, rightAnkleIkPos, w); leftEffector.SetPosition(stream, leftPosition); rightEffector.SetPosition(stream, rightPosition); leftEffector.SetRotation(stream, leftAnkleRot); rightEffector.SetRotation(stream, rightAnkleRot); }
public void ProcessAnimation(AnimationStream stream) { float w = jobWeight.Get(stream); if (w > 0f) { AffineTransform overrideTx; if (source.IsValid(stream)) { source.GetLocalTRS(stream, out Vector3 srcLPos, out Quaternion srcLRot, out _); var sourceLocalTx = new AffineTransform(srcLPos, srcLRot); var sourceToSpaceRot = cache.Get <Quaternion>(sourceToCurrSpaceRotIdx); overrideTx = Quaternion.Inverse(sourceToSpaceRot) * (sourceInvLocalBindTx * sourceLocalTx) * sourceToSpaceRot; } else { overrideTx = new AffineTransform(position.Get(stream), Quaternion.Euler(rotation.Get(stream))); } Space overrideSpace = (Space)cache.GetRaw(spaceIdx); var posW = positionWeight.Get(stream) * w; var rotW = rotationWeight.Get(stream) * w; switch (overrideSpace) { case Space.World: { driven.GetGlobalTR(stream, out Vector3 drivenWPos, out Quaternion drivenWRot); driven.SetGlobalTR( stream, Vector3.Lerp(drivenWPos, overrideTx.translation, posW), Quaternion.Lerp(drivenWRot, overrideTx.rotation, rotW) ); } break; case Space.Local: { driven.GetLocalTRS(stream, out Vector3 drivenLPos, out Quaternion drivenLRot, out Vector3 drivenLScale); driven.SetLocalTRS( stream, Vector3.Lerp(drivenLPos, overrideTx.translation, posW), Quaternion.Lerp(drivenLRot, overrideTx.rotation, rotW), drivenLScale ); } break; case Space.Pivot: { driven.GetLocalTRS(stream, out Vector3 drivenLPos, out Quaternion drivenLRot, out Vector3 drivenLScale); var drivenLocalTx = new AffineTransform(drivenLPos, drivenLRot); overrideTx = drivenLocalTx * overrideTx; driven.SetLocalTRS( stream, Vector3.Lerp(drivenLocalTx.translation, overrideTx.translation, posW), Quaternion.Lerp(drivenLocalTx.rotation, overrideTx.rotation, rotW), drivenLScale ); } break; default: break; } } else { AnimationRuntimeUtils.PassThrough(stream, driven); } }