/// <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) { float w = jobWeight.Get(stream); if (w > 0f) { if (twistTransforms.Length == 0) { return; } AnimationStreamHandleUtility.ReadFloats(stream, twistWeights, weightBuffer); Quaternion twistRot = TwistRotation(axisMask, sourceInverseBindRotation * source.GetLocalRotation(stream)); Quaternion invTwistRot = Quaternion.Inverse(twistRot); for (int i = 0; i < twistTransforms.Length; ++i) { ReadWriteTransformHandle twistTransform = twistTransforms[i]; float twistWeight = Mathf.Clamp(weightBuffer[i], -1f, 1f); Quaternion rot = Quaternion.Lerp(Quaternion.identity, Mathf.Sign(twistWeight) < 0f ? invTwistRot : twistRot, Mathf.Abs(twistWeight)); twistTransform.SetLocalRotation(stream, Quaternion.Lerp(twistBindRotations[i], rot, w)); // Required to update handles with binding info. twistTransforms[i] = twistTransform; } } else { for (int i = 0; i < twistTransforms.Length; ++i) { AnimationRuntimeUtils.PassThrough(stream, twistTransforms[i]); } } }
public void ProcessAnimation(AnimationStream stream) { float jobWeight = stream.GetInputWeight(0); if (jobWeight > 0f) { int driver = (int)cache.GetRaw(driverIdx); var driverTx = new AffineTransform( sources[driver].GetPosition(stream), sources[driver].GetRotation(stream) ); int offset = 0; for (int i = 0; i < sources.Length; ++i) { if (i == driver) { continue; } var tx = driverTx * offsetTx[offset]; sources[i].SetPosition(stream, Vector3.Lerp(sources[i].GetPosition(stream), tx.translation, jobWeight)); sources[i].SetRotation(stream, Quaternion.Lerp(sources[i].GetRotation(stream), tx.rotation, jobWeight)); offset++; } } else { for (int i = 0; i < sources.Length; ++i) { AnimationRuntimeUtils.PassThrough(stream, sources[i]); } } }
public override DampedTransformJob Create(Animator animator, ref T data) { var job = new DampedTransformJob(); var cacheBuilder = new AnimationJobCacheBuilder(); job.driven = TransformHandle.Bind(animator, data.constrainedObject); job.source = TransformHandle.Bind(animator, data.source); var drivenTx = new AffineTransform(data.constrainedObject.position, data.constrainedObject.rotation); var sourceTx = new AffineTransform(data.source.position, data.source.rotation); job.localBindTx = sourceTx.InverseMul(drivenTx); job.prevDrivenTx = drivenTx; job.dampPositionIdx = cacheBuilder.Add(data.dampPosition); job.dampRotationIdx = cacheBuilder.Add(data.dampRotation); if (data.maintainAim && AnimationRuntimeUtils.SqrDistance(data.constrainedObject.position, data.source.position) > 0f) { job.aimBindAxis = Quaternion.Inverse(data.constrainedObject.rotation) * (sourceTx.translation - drivenTx.translation).normalized; } else { job.aimBindAxis = Vector3.zero; } job.cache = cacheBuilder.Build(); return(job); }
public void ProcessAnimation(AnimationStream stream) { float jobWeight = stream.GetInputWeight(0); if (jobWeight > 0f) { if (twistNodes.Length == 0) { return; } Quaternion twistRot = TwistRotation(axisMask, sourceInverseBindRotation * source.GetLocalRotation(stream)); Quaternion invTwistRot = Quaternion.Inverse(twistRot); for (int i = 0; i < twistNodes.Length; ++i) { float w = Mathf.Clamp(cache.GetRaw(twistWeightStartIdx, i), -1f, 1f); Quaternion rot = Quaternion.Lerp(Quaternion.identity, Mathf.Sign(w) < 0f ? invTwistRot : twistRot, Mathf.Abs(w)); twistNodes[i].SetLocalRotation(stream, Quaternion.Lerp(twistNodes[i].GetLocalRotation(stream), rot, jobWeight)); } } else { for (int i = 0; i < twistNodes.Length; ++i) { AnimationRuntimeUtils.PassThrough(stream, twistNodes[i]); } } }
/// <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) { float w = jobWeight.Get(stream); if (w > 0f) { // Retrieve root and tip rotation. Quaternion rootRotation = rootTarget.GetRotation(stream); Quaternion tipRotation = tipTarget.GetRotation(stream); // Interpolate rotation on chain. chain[0].SetRotation(stream, Quaternion.Lerp(chain[0].GetRotation(stream), rootRotation, w)); for (int i = 1; i < chain.Length - 1; ++i) { chain[i].SetRotation(stream, Quaternion.Lerp(chain[i].GetRotation(stream), rotations[i] * Quaternion.Lerp(rootRotation, tipRotation, weights[i]), w)); } chain[chain.Length - 1].SetRotation(stream, Quaternion.Lerp(chain[chain.Length - 1].GetRotation(stream), tipRotation, w)); #if UNITY_EDITOR // Update position of tip handle for easier visualization. rootTarget.SetPosition(stream, chain[0].GetPosition(stream)); tipTarget.SetPosition(stream, chain[chain.Length - 1].GetPosition(stream)); #endif } else { for (int i = 0; i < chain.Length; ++i) { AnimationRuntimeUtils.PassThrough(stream, chain[i]); } } }
public override DampedTransformJob Create(Animator animator, ref T data, Component component) { var job = new DampedTransformJob(); job.driven = ReadWriteTransformHandle.Bind(animator, data.constrainedObject); job.source = ReadOnlyTransformHandle.Bind(animator, data.sourceObject); var drivenTx = new AffineTransform(data.constrainedObject.position, data.constrainedObject.rotation); var sourceTx = new AffineTransform(data.sourceObject.position, data.sourceObject.rotation); job.localBindTx = sourceTx.InverseMul(drivenTx); job.prevDrivenTx = drivenTx; job.dampPosition = FloatProperty.Bind(animator, component, data.dampPositionFloatProperty); job.dampRotation = FloatProperty.Bind(animator, component, data.dampRotationFloatProperty); if (data.maintainAim && AnimationRuntimeUtils.SqrDistance(data.constrainedObject.position, data.sourceObject.position) > 0f) { job.aimBindAxis = Quaternion.Inverse(data.constrainedObject.rotation) * (sourceTx.translation - drivenTx.translation).normalized; } else { job.aimBindAxis = Vector3.zero; } return(job); }
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); Quaternion currentWRot = driven.GetRotation(stream); var accumTx = new AffineTransform(currentWPos, currentWRot); for (int i = 0; i < sources.Length; ++i) { var normalizedWeight = cache.GetRaw(sourceWeightStartIdx, i) * weightScale; if (normalizedWeight < k_Epsilon) { continue; } var sourceTx = new AffineTransform(sources[i].GetPosition(stream), sources[i].GetRotation(stream)); sourceTx *= sourceOffsets[i]; accumTx.rotation = Quaternion.Lerp(accumTx.rotation, sourceTx.rotation, normalizedWeight); accumTx.translation += (sourceTx.translation - currentWPos) * normalizedWeight; } // Convert accumTx to local space if (drivenParent.IsValid(stream)) { var parentTx = new AffineTransform(drivenParent.GetPosition(stream), drivenParent.GetRotation(stream)); accumTx = parentTx.InverseMul(accumTx); } Vector3 currentLPos = driven.GetLocalPosition(stream); Quaternion currentLRot = driven.GetLocalRotation(stream); if (Vector3.Dot(positionAxesMask, positionAxesMask) < 3f) { accumTx.translation = AnimationRuntimeUtils.Lerp(currentLPos, accumTx.translation, positionAxesMask); } if (Vector3.Dot(rotationAxesMask, rotationAxesMask) < 3f) { accumTx.rotation = Quaternion.Euler(AnimationRuntimeUtils.Lerp(currentLRot.eulerAngles, accumTx.rotation.eulerAngles, rotationAxesMask)); } driven.SetLocalPosition(stream, Vector3.Lerp(currentLPos, accumTx.translation, jobWeight)); driven.SetLocalRotation(stream, Quaternion.Lerp(currentLRot, accumTx.rotation, jobWeight)); } else { AnimationRuntimeUtils.PassThrough(stream, driven); } }
public void ProcessAnimation(AnimationStream stream) { float w = jobWeight.Get(stream); if (w > 0f) { AnimationStreamHandleUtility.ReadFloats(stream, sourceWeights, weightBuffer); float sumWeights = AnimationRuntimeUtils.Sum(weightBuffer); if (sumWeights < k_Epsilon) { AnimationRuntimeUtils.PassThrough(stream, driven); return; } float weightScale = sumWeights > 1f ? 1f / sumWeights : 1f; Vector3 currentWPos = driven.GetPosition(stream); Vector3 accumPos = currentWPos; for (int i = 0; i < sourceTransforms.Length; ++i) { var normalizedWeight = weightBuffer[i] * weightScale; if (normalizedWeight < k_Epsilon) { continue; } ReadOnlyTransformHandle sourceTransform = sourceTransforms[i]; accumPos += (sourceTransform.GetPosition(stream) + sourceOffsets[i] - currentWPos) * normalizedWeight; // Required to update handles with binding info. sourceTransforms[i] = sourceTransform; } // Convert accumPos to local space if (drivenParent.IsValid(stream)) { drivenParent.GetGlobalTR(stream, out Vector3 parentWPos, out Quaternion parentWRot); var parentTx = new AffineTransform(parentWPos, parentWRot); 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 + drivenOffset.Get(stream), w)); } 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 w = jobWeight.Get(stream); float streamDt = Mathf.Abs(stream.deltaTime); driven.GetGlobalTR(stream, out Vector3 drivenPos, out Quaternion drivenRot); if (w > 0f && streamDt > 0f) { source.GetGlobalTR(stream, out Vector3 sourcePos, out Quaternion sourceRot); var sourceTx = new AffineTransform(sourcePos, sourceRot); var targetTx = sourceTx * localBindTx; targetTx.translation = Vector3.Lerp(drivenPos, targetTx.translation, w); targetTx.rotation = Quaternion.Lerp(drivenRot, targetTx.rotation, w); var dampPosW = AnimationRuntimeUtils.Square(1f - dampPosition.Get(stream)); var dampRotW = AnimationRuntimeUtils.Square(1f - dampRotation.Get(stream)); bool doAimAjustements = Vector3.Dot(aimBindAxis, aimBindAxis) > 0f; while (streamDt > 0f) { float factoredDt = k_DampFactor * Mathf.Min(k_FixedDt, streamDt); prevDrivenTx.translation += (targetTx.translation - prevDrivenTx.translation) * dampPosW * factoredDt; prevDrivenTx.rotation *= Quaternion.Lerp( Quaternion.identity, Quaternion.Inverse(prevDrivenTx.rotation) * targetTx.rotation, dampRotW * factoredDt ); if (doAimAjustements) { var fromDir = prevDrivenTx.rotation * aimBindAxis; var toDir = sourceTx.translation - prevDrivenTx.translation; prevDrivenTx.rotation = Quaternion.AngleAxis(Vector3.Angle(fromDir, toDir), Vector3.Cross(fromDir, toDir).normalized) * prevDrivenTx.rotation; } streamDt -= k_FixedDt; } driven.SetGlobalTR(stream, prevDrivenTx.translation, prevDrivenTx.rotation); } else { prevDrivenTx.Set(drivenPos, drivenRot); AnimationRuntimeUtils.PassThrough(stream, driven); } }
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; 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 w = jobWeight.Get(stream); if (w > 0f) { for (int i = 0; i < chain.Length; ++i) { var handle = chain[i]; linkPositions[i] = handle.GetPosition(stream); chain[i] = handle; } int tipIndex = chain.Length - 1; if (AnimationRuntimeUtils.SolveFABRIK(ref linkPositions, ref linkLengths, target.GetPosition(stream) + targetOffset.translation, cache.GetRaw(toleranceIdx), maxReach, (int)cache.GetRaw(maxIterationsIdx))) { var chainRWeight = chainRotationWeight.Get(stream) * w; for (int i = 0; i < tipIndex; ++i) { var prevDir = chain[i + 1].GetPosition(stream) - chain[i].GetPosition(stream); var newDir = linkPositions[i + 1] - linkPositions[i]; var rot = chain[i].GetRotation(stream); chain[i].SetRotation(stream, Quaternion.Lerp(rot, QuaternionExt.FromToRotation(prevDir, newDir) * rot, chainRWeight)); } } chain[tipIndex].SetRotation( stream, Quaternion.Lerp( chain[tipIndex].GetRotation(stream), target.GetRotation(stream) * targetOffset.rotation, tipRotationWeight.Get(stream) * w ) ); } else { for (int i = 0; i < chain.Length; ++i) { AnimationRuntimeUtils.PassThrough(stream, chain[i]); } } }
public void ProcessAnimation(AnimationStream stream) { float w = jobWeight.Get(stream); if (w > 0f) { var driverIdx = driver.Get(stream); if (driverIdx != prevDriverIdx) { UpdateOffsets(driverIdx); } sources[driverIdx].GetGlobalTR(stream, out Vector3 driverWPos, out Quaternion driverWRot); var driverTx = new AffineTransform(driverWPos, driverWRot); int offset = 0; for (int i = 0; i < sources.Length; ++i) { if (i == driverIdx) { continue; } var tx = driverTx * offsetTx[offset]; var src = sources[i]; src.GetGlobalTR(stream, out Vector3 srcWPos, out Quaternion srcWRot); src.SetGlobalTR(stream, Vector3.Lerp(srcWPos, tx.translation, w), Quaternion.Lerp(srcWRot, tx.rotation, w)); offset++; sources[i] = src; } } else { for (int i = 0; i < sources.Length; ++i) { AnimationRuntimeUtils.PassThrough(stream, sources[i]); } } }
public void ProcessAnimation(AnimationStream stream) { float jobWeight = stream.GetInputWeight(0); if (jobWeight > 0f) { for (int i = 0; i < chain.Length; ++i) { linkPositions[i] = chain[i].GetPosition(stream); } int tipIndex = chain.Length - 1; if (AnimationRuntimeUtils.SolveFABRIK(linkPositions, linkLengths, target.GetPosition(stream) + targetOffset.translation, cache.GetRaw(toleranceIdx), maxReach, (int)cache.GetRaw(maxIterationsIdx))) { var chainRWeight = cache.GetRaw(chainRotationWeightIdx) * jobWeight; for (int i = 0; i < tipIndex; ++i) { var prevDir = chain[i + 1].GetPosition(stream) - chain[i].GetPosition(stream); var newDir = linkPositions[i + 1] - linkPositions[i]; chain[i].SetRotation(stream, QuaternionExt.FromToRotation(prevDir, newDir) * chain[i].GetRotation(stream)); } } chain[tipIndex].SetRotation( stream, Quaternion.Lerp( chain[tipIndex].GetRotation(stream), target.GetRotation(stream) * targetOffset.rotation, cache.GetRaw(tipRotationWeightIdx) * jobWeight ) ); } else { for (int i = 0; i < chain.Length; ++i) { AnimationRuntimeUtils.PassThrough(stream, chain[i]); } } }
public void ProcessAnimation(AnimationStream stream) { float jobWeight = stream.GetInputWeight(0); if (jobWeight > 0f) { var flags = (int)cache.GetRaw(optionsIdx); if ((flags & k_BlendTranslationMask) != 0) { Vector3 posBlend = Vector3.Lerp( sourceA.GetPosition(stream) + sourceAOffset.translation, sourceB.GetPosition(stream) + sourceBOffset.translation, cache.GetRaw(positionWeightIdx) ); driven.SetPosition(stream, Vector3.Lerp(driven.GetPosition(stream), posBlend, jobWeight)); } else { driven.SetLocalPosition(stream, driven.GetLocalPosition(stream)); } if ((flags & k_BlendRotationMask) != 0) { Quaternion rotBlend = Quaternion.Lerp( sourceA.GetRotation(stream) * sourceAOffset.rotation, sourceB.GetRotation(stream) * sourceBOffset.rotation, cache.GetRaw(rotationWeightIdx) ); driven.SetRotation(stream, Quaternion.Lerp(driven.GetRotation(stream), rotBlend, jobWeight)); } else { driven.SetLocalRotation(stream, driven.GetLocalRotation(stream)); } } else { AnimationRuntimeUtils.PassThrough(stream, driven); } }
public void ProcessAnimation(AnimationStream stream) { float jobWeight = stream.GetInputWeight(0); if (jobWeight > 0f) { AnimationRuntimeUtils.SolveTwoBoneIK( stream, root, mid, tip, target, hint, cache.GetRaw(targetPositionWeightIdx) * jobWeight, cache.GetRaw(targetRotationWeightIdx) * jobWeight, cache.GetRaw(hintWeightIdx) * jobWeight, linkLengths, targetOffset ); } else { AnimationRuntimeUtils.PassThrough(stream, root); AnimationRuntimeUtils.PassThrough(stream, mid); AnimationRuntimeUtils.PassThrough(stream, tip); } }
public void ProcessAnimation(AnimationStream stream) { float w = jobWeight.Get(stream); if (w > 0f) { if (blendPosition.Get(stream)) { Vector3 posBlend = Vector3.Lerp( sourceA.GetPosition(stream) + sourceAOffset.translation, sourceB.GetPosition(stream) + sourceBOffset.translation, positionWeight.Get(stream) ); driven.SetPosition(stream, Vector3.Lerp(driven.GetPosition(stream), posBlend, w)); } else { driven.SetLocalPosition(stream, driven.GetLocalPosition(stream)); } if (blendRotation.Get(stream)) { Quaternion rotBlend = Quaternion.Lerp( sourceA.GetRotation(stream) * sourceAOffset.rotation, sourceB.GetRotation(stream) * sourceBOffset.rotation, rotationWeight.Get(stream) ); driven.SetRotation(stream, Quaternion.Lerp(driven.GetRotation(stream), rotBlend, w)); } else { driven.SetLocalRotation(stream, driven.GetLocalRotation(stream)); } } else { AnimationRuntimeUtils.PassThrough(stream, driven); } }
public void ProcessAnimation(AnimationStream stream) { float w = jobWeight.Get(stream); if (w > 0f) { AnimationRuntimeUtils.SolveTwoBoneIK( stream, root, mid, tip, target, hint, targetPositionWeight.Get(stream) * w, targetRotationWeight.Get(stream) * w, hintWeight.Get(stream) * w, linkLengths, targetOffset ); } else { AnimationRuntimeUtils.PassThrough(stream, root); AnimationRuntimeUtils.PassThrough(stream, mid); AnimationRuntimeUtils.PassThrough(stream, tip); } }
public void ProcessAnimation(AnimationStream stream) { float jobWeight = stream.GetInputWeight(0); if (jobWeight > 0f) { var sourceTx = new AffineTransform(source.GetPosition(stream), source.GetRotation(stream)); var targetTx = sourceTx * localBindTx; var drivenPos = driven.GetPosition(stream); targetTx.translation = Vector3.Lerp(drivenPos, targetTx.translation, jobWeight); var factorDeltaTime = k_DampFactor * stream.deltaTime; var dampPosW = 1f - cache.GetRaw(dampPositionIdx); var finalPos = Vector3.Lerp(prevDrivenTx.translation, targetTx.translation, dampPosW * dampPosW * factorDeltaTime); var drivenRot = driven.GetRotation(stream); if (Vector3.Dot(aimBindAxis, aimBindAxis) > 0f) { var fromDir = drivenRot * aimBindAxis; var toDir = sourceTx.translation - finalPos; targetTx.rotation = Quaternion.AngleAxis(Vector3.Angle(fromDir, toDir), Vector3.Cross(fromDir, toDir).normalized) * drivenRot; } targetTx.rotation = Quaternion.Lerp(drivenRot, targetTx.rotation, jobWeight); var dampRotW = 1f - cache.GetRaw(dampRotationIdx); var finalRot = Quaternion.Lerp(prevDrivenTx.rotation, targetTx.rotation, dampRotW * dampRotW * factorDeltaTime); driven.SetPosition(stream, finalPos); driven.SetRotation(stream, finalRot); prevDrivenTx.translation = finalPos; prevDrivenTx.rotation = finalRot; } else { AnimationRuntimeUtils.PassThrough(stream, driven); } }
public void ProcessAnimation(AnimationStream stream) { float w = jobWeight.Get(stream); if (w > 0f) { AnimationStreamHandleUtility.ReadFloats(stream, sourceWeights, weightBuffer); float sumWeights = AnimationRuntimeUtils.Sum(weightBuffer); if (sumWeights < k_Epsilon) { return; } float weightScale = sumWeights > 1f ? 1f / sumWeights : 1f; Vector2 minMaxAngles = new Vector2(minLimit.Get(stream), maxLimit.Get(stream)); driven.GetGlobalTR(stream, out Vector3 currentWPos, out Quaternion currentWRot); Vector3 currentDir = currentWRot * aimAxis; Quaternion accumDeltaRot = QuaternionExt.zero; float accumWeights = 0f; for (int i = 0; i < sourceTransforms.Length; ++i) { var normalizedWeight = weightBuffer[i] * weightScale; if (normalizedWeight < k_Epsilon) { continue; } ReadOnlyTransformHandle sourceTransform = sourceTransforms[i]; var toDir = sourceTransform.GetPosition(stream) - currentWPos; if (toDir.sqrMagnitude < k_Epsilon) { continue; } var rotToSource = Quaternion.AngleAxis( Mathf.Clamp(Vector3.Angle(currentDir, toDir), minMaxAngles.x, minMaxAngles.y), Vector3.Cross(currentDir, toDir).normalized ); accumDeltaRot = QuaternionExt.Add( accumDeltaRot, QuaternionExt.Scale(sourceOffsets[i] * rotToSource, normalizedWeight) ); // Required to update handles with binding info. sourceTransforms[i] = sourceTransform; accumWeights += normalizedWeight; } accumDeltaRot = QuaternionExt.NormalizeSafe(accumDeltaRot); if (accumWeights < 1f) { accumDeltaRot = Quaternion.Lerp(Quaternion.identity, accumDeltaRot, accumWeights); } 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 = drivenOffset.Get(stream); if (Vector3.Dot(offset, offset) > 0f) { newRot *= Quaternion.Euler(offset); } driven.SetLocalRotation(stream, Quaternion.Lerp(currentLRot, newRot, w)); } 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); } }
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); } }
/// <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) { float w = jobWeight.Get(stream); if (w > 0f) { AnimationStreamHandleUtility.ReadFloats(stream, sourceWeights, weightBuffer); float sumWeights = AnimationRuntimeUtils.Sum(weightBuffer); if (sumWeights < k_Epsilon) { AnimationRuntimeUtils.PassThrough(stream, driven); return; } float weightScale = sumWeights > 1f ? 1f / sumWeights : 1f; float accumWeights = 0f; Quaternion accumRot = QuaternionExt.zero; for (int i = 0; i < sourceTransforms.Length; ++i) { var normalizedWeight = weightBuffer[i] * weightScale; if (normalizedWeight < k_Epsilon) { continue; } ReadOnlyTransformHandle sourceTransform = sourceTransforms[i]; accumRot = QuaternionExt.Add(accumRot, QuaternionExt.Scale(sourceTransform.GetRotation(stream) * sourceOffsets[i], normalizedWeight)); // Required to update handles with binding info. sourceTransforms[i] = sourceTransform; accumWeights += normalizedWeight; } accumRot = QuaternionExt.NormalizeSafe(accumRot); if (accumWeights < 1f) { accumRot = Quaternion.Lerp(driven.GetRotation(stream), accumRot, accumWeights); } // 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 = drivenOffset.Get(stream); if (Vector3.Dot(offset, offset) > 0f) { accumRot *= Quaternion.Euler(offset); } driven.SetLocalRotation(stream, Quaternion.Lerp(currentLRot, accumRot, w)); } else { AnimationRuntimeUtils.PassThrough(stream, driven); } }
public void ProcessAnimation(AnimationStream stream) { float w = jobWeight.Get(stream); if (w > 0f) { AnimationStreamHandleUtility.ReadFloats(stream, sourceWeights, weightBuffer); float sumWeights = AnimationRuntimeUtils.Sum(weightBuffer); if (sumWeights < k_Epsilon) { return; } float weightScale = sumWeights > 1f ? 1f / sumWeights : 1f; float accumWeights = 0f; var accumTx = new AffineTransform(Vector3.zero, QuaternionExt.zero); for (int i = 0; i < sourceTransforms.Length; ++i) { ReadOnlyTransformHandle sourceTransform = sourceTransforms[i]; var normalizedWeight = weightBuffer[i] * weightScale; if (normalizedWeight < k_Epsilon) { continue; } sourceTransform.GetGlobalTR(stream, out Vector3 srcWPos, out Quaternion srcWRot); var sourceTx = new AffineTransform(srcWPos, srcWRot); sourceTx *= sourceOffsets[i]; accumTx.translation += sourceTx.translation * normalizedWeight; accumTx.rotation = QuaternionExt.Add(accumTx.rotation, QuaternionExt.Scale(sourceTx.rotation, normalizedWeight)); // Required to update handles with binding info. sourceTransforms[i] = sourceTransform; accumWeights += normalizedWeight; } accumTx.rotation = QuaternionExt.NormalizeSafe(accumTx.rotation); if (accumWeights < 1f) { driven.GetGlobalTR(stream, out Vector3 currentWPos, out Quaternion currentWRot); accumTx.translation += currentWPos * (1f - accumWeights); accumTx.rotation = Quaternion.Lerp(currentWRot, accumTx.rotation, accumWeights); } // Convert accumTx to local space if (drivenParent.IsValid(stream)) { drivenParent.GetGlobalTR(stream, out Vector3 parentWPos, out Quaternion parentWRot); var parentTx = new AffineTransform(parentWPos, parentWRot); accumTx = parentTx.InverseMul(accumTx); } driven.GetLocalTRS(stream, out Vector3 currentLPos, out Quaternion currentLRot, out Vector3 currentLScale); if (Vector3.Dot(positionAxesMask, positionAxesMask) < 3f) { accumTx.translation = AnimationRuntimeUtils.Lerp(currentLPos, accumTx.translation, positionAxesMask); } if (Vector3.Dot(rotationAxesMask, rotationAxesMask) < 3f) { accumTx.rotation = Quaternion.Euler(AnimationRuntimeUtils.Lerp(currentLRot.eulerAngles, accumTx.rotation.eulerAngles, rotationAxesMask)); } driven.SetLocalTRS( stream, Vector3.Lerp(currentLPos, accumTx.translation, w), Quaternion.Lerp(currentLRot, accumTx.rotation, w), currentLScale ); } else { AnimationRuntimeUtils.PassThrough(stream, driven); } }
public void ProcessAnimation(AnimationStream stream) { float w = jobWeight.Get(stream); if (w > 0f) { AnimationStreamHandleUtility.ReadFloats(stream, sourceWeights, weightBuffer); float sumWeights = AnimationRuntimeUtils.Sum(weightBuffer); if (sumWeights < k_Epsilon) { AnimationRuntimeUtils.PassThrough(stream, driven); return; } float weightScale = sumWeights > 1f ? 1f / sumWeights : 1f; Vector2 minMaxAngles = new Vector2(minLimit.Get(stream), maxLimit.Get(stream)); var drivenWPos = driven.GetPosition(stream); var drivenLRot = driven.GetLocalRotation(stream); var drivenParentInvRot = Quaternion.Inverse(drivenParent.GetRotation(stream)); Quaternion accumDeltaRot = QuaternionExt.zero; var fromDir = drivenLRot * aimAxis; float accumWeights = 0f; for (int i = 0; i < sourceTransforms.Length; ++i) { var normalizedWeight = weightBuffer[i] * weightScale; if (normalizedWeight < k_Epsilon) { continue; } ReadOnlyTransformHandle sourceTransform = sourceTransforms[i]; var toDir = drivenParentInvRot * (sourceTransform.GetPosition(stream) - drivenWPos); if (toDir.sqrMagnitude < k_Epsilon) { continue; } var crossDir = Vector3.Cross(fromDir, toDir).normalized; if (Vector3.Dot(axesMask, axesMask) < 3f) { crossDir = AnimationRuntimeUtils.Select(Vector3.zero, crossDir, axesMask).normalized; if (Vector3.Dot(crossDir, crossDir) > k_Epsilon) { fromDir = AnimationRuntimeUtils.ProjectOnPlane(fromDir, crossDir); toDir = AnimationRuntimeUtils.ProjectOnPlane(toDir, crossDir); } else { toDir = fromDir; } } var rotToSource = Quaternion.AngleAxis( Mathf.Clamp(Vector3.Angle(fromDir, toDir), minMaxAngles.x, minMaxAngles.y), crossDir ); accumDeltaRot = QuaternionExt.Add( accumDeltaRot, QuaternionExt.Scale(sourceOffsets[i] * rotToSource, normalizedWeight) ); // Required to update handles with binding info. sourceTransforms[i] = sourceTransform; accumWeights += normalizedWeight; } accumDeltaRot = QuaternionExt.NormalizeSafe(accumDeltaRot); if (accumWeights < 1f) { accumDeltaRot = Quaternion.Lerp(Quaternion.identity, accumDeltaRot, accumWeights); } Quaternion newRot = accumDeltaRot * drivenLRot; if (Vector3.Dot(axesMask, axesMask) < 3f) { newRot = Quaternion.Euler(AnimationRuntimeUtils.Select(drivenLRot.eulerAngles, newRot.eulerAngles, axesMask)); } var offset = drivenOffset.Get(stream); if (Vector3.Dot(offset, offset) > 0f) { newRot *= Quaternion.Euler(offset); } driven.SetLocalRotation(stream, Quaternion.Lerp(drivenLRot, newRot, w)); } else { AnimationRuntimeUtils.PassThrough(stream, driven); } }