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); } }