public void ProcessAnimation(AnimationStream stream) { float jobWeight = stream.GetInputWeight(0); if (jobWeight > 0f) { AffineTransform overrideTx; if (source.IsValid(stream)) { var sourceLocalTx = new AffineTransform(source.GetLocalPosition(stream), source.GetLocalRotation(stream)); var sourceToSpaceRot = cache.Get <Quaternion>(sourceToCurrSpaceRotIdx); overrideTx = Quaternion.Inverse(sourceToSpaceRot) * (sourceInvLocalBindTx * sourceLocalTx) * sourceToSpaceRot; } else { overrideTx = new AffineTransform(cache.Get <Vector3>(positionIdx), Quaternion.Euler(cache.Get <Vector3>(rotationIdx))); } Space overrideSpace = (Space)cache.GetRaw(spaceIdx); var posW = cache.GetRaw(positionWeightIdx) * jobWeight; var rotW = cache.GetRaw(rotationWeightIdx) * jobWeight; switch (overrideSpace) { case Space.World: driven.SetPosition(stream, Vector3.Lerp(driven.GetPosition(stream), overrideTx.translation, posW)); driven.SetRotation(stream, Quaternion.Lerp(driven.GetRotation(stream), overrideTx.rotation, rotW)); break; case Space.Local: driven.SetLocalPosition(stream, Vector3.Lerp(driven.GetLocalPosition(stream), overrideTx.translation, posW)); driven.SetLocalRotation(stream, Quaternion.Lerp(driven.GetLocalRotation(stream), overrideTx.rotation, rotW)); break; case Space.Pivot: var drivenLocalTx = new AffineTransform(driven.GetLocalPosition(stream), driven.GetLocalRotation(stream)); overrideTx = drivenLocalTx * overrideTx; driven.SetLocalPosition(stream, Vector3.Lerp(drivenLocalTx.translation, overrideTx.translation, posW)); driven.SetLocalRotation(stream, Quaternion.Lerp(drivenLocalTx.rotation, overrideTx.rotation, rotW)); break; default: break; } } else { AnimationRuntimeUtils.PassThrough(stream, driven); } }
public void ProcessAnimation(AnimationStream stream) { float jobWeight = stream.GetInputWeight(0); if (jobWeight > 0f) { float sumWeights = AnimationRuntimeUtils.Sum(cache, sourceWeightStartIdx, sources.Length); if (sumWeights < k_Epsilon) { return; } float weightScale = sumWeights > 1f ? 1f / sumWeights : 1f; Quaternion currentWRot = driven.GetRotation(stream); Quaternion accumRot = currentWRot; for (int i = 0; i < sources.Length; ++i) { var normalizedWeight = cache.GetRaw(sourceWeightStartIdx, i) * weightScale; if (normalizedWeight < k_Epsilon) { continue; } accumRot = Quaternion.Lerp(accumRot, sources[i].GetRotation(stream) * sourceOffsets[i], normalizedWeight); } // Convert accumRot to local space if (drivenParent.IsValid(stream)) { accumRot = Quaternion.Inverse(drivenParent.GetRotation(stream)) * accumRot; } Quaternion currentLRot = driven.GetLocalRotation(stream); if (Vector3.Dot(axesMask, axesMask) < 3f) { accumRot = Quaternion.Euler(AnimationRuntimeUtils.Lerp(currentLRot.eulerAngles, accumRot.eulerAngles, axesMask)); } var offset = cache.Get <Vector3>(drivenOffsetIdx); if (Vector3.Dot(offset, offset) > 0f) { accumRot *= Quaternion.Euler(offset); } driven.SetLocalRotation(stream, Quaternion.Lerp(currentLRot, accumRot, jobWeight)); } else { AnimationRuntimeUtils.PassThrough(stream, driven); } }
public void ProcessAnimation(AnimationStream stream) { float jobWeight = stream.GetInputWeight(0); if (jobWeight > 0f) { float sumWeights = AnimationRuntimeUtils.Sum(cache, sourceWeightStartIdx, sources.Length); if (sumWeights < k_Epsilon) { return; } float weightScale = sumWeights > 1f ? 1f / sumWeights : 1f; Vector3 currentWPos = driven.GetPosition(stream); Vector3 accumPos = currentWPos; for (int i = 0; i < sources.Length; ++i) { var normalizedWeight = cache.GetRaw(sourceWeightStartIdx, i) * weightScale; if (normalizedWeight < k_Epsilon) { continue; } accumPos += (sources[i].GetPosition(stream) + sourceOffsets[i] - currentWPos) * normalizedWeight; } // Convert accumPos to local space if (drivenParent.IsValid(stream)) { var parentTx = new AffineTransform(drivenParent.GetPosition(stream), drivenParent.GetRotation(stream)); accumPos = parentTx.InverseTransform(accumPos); } Vector3 currentLPos = driven.GetLocalPosition(stream); if (Vector3.Dot(axesMask, axesMask) < 3f) { accumPos = AnimationRuntimeUtils.Lerp(currentLPos, accumPos, axesMask); } driven.SetLocalPosition(stream, Vector3.Lerp(currentLPos, accumPos + cache.Get <Vector3>(drivenOffsetIdx), jobWeight)); } else { AnimationRuntimeUtils.PassThrough(stream, driven); } }
public void ProcessAnimation(AnimationStream stream) { float jobWeight = stream.GetInputWeight(0); if (jobWeight > 0f) { float sumWeights = AnimationRuntimeUtils.Sum(cache, sourceWeightStartIdx, sources.Length); if (sumWeights < k_Epsilon) { return; } float weightScale = sumWeights > 1f ? 1f / sumWeights : 1f; Vector2 minMaxAngles = cache.Get <Vector2>(limitsIdx); Vector3 currentWPos = driven.GetPosition(stream); Quaternion currentWRot = driven.GetRotation(stream); Vector3 currentDir = currentWRot * aimAxis; Quaternion accumDeltaRot = Quaternion.identity; for (int i = 0; i < sources.Length; ++i) { var normalizedWeight = cache.GetRaw(sourceWeightStartIdx, i) * weightScale; if (normalizedWeight < k_Epsilon) { continue; } var toDir = sources[i].GetPosition(stream) - currentWPos; var rotToSource = Quaternion.AngleAxis( Mathf.Clamp(Vector3.Angle(currentDir, toDir), minMaxAngles.x, minMaxAngles.y), Vector3.Cross(currentDir, toDir).normalized ); accumDeltaRot = Quaternion.Lerp(accumDeltaRot, sourceOffsets[i] * rotToSource, normalizedWeight); } Quaternion newRot = accumDeltaRot * currentWRot; // Convert newRot to local space if (drivenParent.IsValid(stream)) { newRot = Quaternion.Inverse(drivenParent.GetRotation(stream)) * newRot; } Quaternion currentLRot = driven.GetLocalRotation(stream); if (Vector3.Dot(axesMask, axesMask) < 3f) { newRot = Quaternion.Euler(AnimationRuntimeUtils.Lerp(currentLRot.eulerAngles, newRot.eulerAngles, axesMask)); } var offset = cache.Get <Vector3>(drivenOffset); if (Vector3.Dot(offset, offset) > 0f) { newRot *= Quaternion.Euler(offset); } driven.SetLocalRotation(stream, Quaternion.Lerp(currentLRot, newRot, jobWeight)); } else { AnimationRuntimeUtils.PassThrough(stream, driven); } }
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); } }