public void Execute(RenderContext context, KernelData data, ref KernelDefs ports) { if (data.SourceRigDefinition == default) { return; } if (data.DestinationRigDefinition == default) { return; } if (data.RemapTable == default) { return; } data.ProfileMarker.Begin(); // Fill the destination stream with default values. var destinationStream = AnimationStream.Create(data.DestinationRigDefinition, context.Resolve(ref ports.Output)); AnimationStreamUtils.SetDefaultValues(ref destinationStream); var sourceStream = AnimationStream.CreateReadOnly(data.SourceRigDefinition, context.Resolve(ports.Input)); Core.RigRemapper(data.RemapTable, ref destinationStream, ref sourceStream); data.ProfileMarker.End(); }
public void PositionConstraintInfluencedByWeight() { var buffer = new NativeArray <AnimatedData>(m_Rig.Value.Bindings.StreamSize, Allocator.Temp, NativeArrayOptions.UninitializedMemory); var stream = AnimationStream.Create(m_Rig, buffer); AnimationStreamUtils.SetDefaultValues(ref stream); var posConstraintData = Core.PositionConstraintData.Default(); posConstraintData.Index = 1; posConstraintData.SourcePositions = new NativeArray <float3>(1, Allocator.Temp, NativeArrayOptions.UninitializedMemory); posConstraintData.SourceOffsets = new NativeArray <float3>(1, Allocator.Temp, NativeArrayOptions.ClearMemory); posConstraintData.SourceWeights = new NativeArray <float>(1, Allocator.Temp, NativeArrayOptions.ClearMemory); posConstraintData.SourcePositions[0] = new float3(0f, 0f, 2f); posConstraintData.SourceWeights[0] = 1f; var defaultPos = stream.GetLocalToRootTranslation(posConstraintData.Index); for (int i = 0; i < 6; ++i) { float w = i / 5f; AnimationStreamUtils.SetDefaultValues(ref stream); Core.SolvePositionConstraint(ref stream, posConstraintData, w); float3 weightedPos = math.lerp(defaultPos, posConstraintData.SourcePositions[0], w); Assert.That(stream.GetLocalToRootTranslation(posConstraintData.Index), Is.EqualTo(weightedPos).Using(TranslationComparer)); } buffer.Dispose(); posConstraintData.SourcePositions.Dispose(); posConstraintData.SourceOffsets.Dispose(); posConstraintData.SourceWeights.Dispose(); }
public void Execute(RenderContext context, KernelData data, ref KernelDefs ports) { if (data.RigDefinition == BlobAssetReference <RigDefinition> .Null) { return; } data.ProfileMarker.Begin(); var inputStream = AnimationStream.CreateReadOnly(data.RigDefinition, context.Resolve(ports.Input)); var outputStream = AnimationStream.Create(data.RigDefinition, context.Resolve(ref ports.Output)); AnimationStreamUtils.MemCpy(ref outputStream, ref inputStream); var deltaRootX = new RigidTransform(inputStream.GetLocalToParentRotation(0), inputStream.GetLocalToParentTranslation(0)); context.Resolve(ref ports.DeltaRootX) = math.float4x4(deltaRootX); RigidTransform prevRootX = new RigidTransform(context.Resolve(ports.PrevRootX)); prevRootX.rot = math.normalizesafe(prevRootX.rot); context.Resolve(ref ports.RootX) = math.float4x4(math.mul(prevRootX, deltaRootX)); var defaultStream = AnimationStream.FromDefaultValues(outputStream.Rig); outputStream.SetLocalToParentTranslation(0, defaultStream.GetLocalToParentTranslation(0)); outputStream.SetLocalToParentRotation(0, defaultStream.GetLocalToParentRotation(0)); data.ProfileMarker.End(); }
public void TwoBoneIKInfluencedByHint() { var buffer = new NativeArray <AnimatedData>(m_Rig.Value.Bindings.StreamSize, Allocator.Temp, NativeArrayOptions.UninitializedMemory); var stream = AnimationStream.Create(m_Rig, buffer); AnimationStreamUtils.SetDefaultValues(ref stream); var ikData = Core.TwoBoneIKData.Default(); ikData.RootIndex = k_RootIndex; ikData.MidIndex = k_MidIndex; ikData.TipIndex = k_TipIndex; ikData.LimbLengths = new float2( math.distance(stream.GetLocalToRootTranslation(k_RootIndex), stream.GetLocalToRootTranslation(k_MidIndex)), math.distance(stream.GetLocalToRootTranslation(k_MidIndex), stream.GetLocalToRootTranslation(k_TipIndex))); ikData.HintWeight = 1f; // Bend considering target is above x axis var midPos1 = stream.GetLocalToRootTranslation(k_MidIndex); ikData.Target.pos = new float3(2f, 0.5f, 0f); ikData.Hint = midPos1 + new float3(0f, -2f, 0f); Core.SolveTwoBoneIK(ref stream, ikData, 1f); var midPos2 = stream.GetLocalToRootTranslation(k_MidIndex); Assert.Less(midPos2.y, 0f, "Expected midPos2.y to be less than zero"); Assert.AreEqual(midPos1.z, midPos2.z, $"Expected midPos2.z to be '{midPos1.z}' but was '{midPos2.z}'"); // Bend considering target is below x axis and hint is inverted ikData.Target.pos = new float3(2f, -0.5f, 0f); ikData.Hint = midPos2 + new float3(0f, 2f, 0f); Core.SolveTwoBoneIK(ref stream, ikData, 1f); var midPos3 = stream.GetLocalToRootTranslation(k_MidIndex); Assert.Greater(midPos3.y, 0f, "Expected midPos3.y to be greater than zero"); Assert.AreEqual(midPos1.z, midPos3.z, $"Expected midPos3.z to be '{midPos1.z}' but was '{midPos3.z}'"); // Move hint in z axis ikData.Hint += new float3(0f, 0f, 1f); Core.SolveTwoBoneIK(ref stream, ikData, 1f); var midPos4 = stream.GetLocalToRootTranslation(k_MidIndex); Assert.Greater(midPos4.y, 0f, "Expected midPos4.y to be greater than zero"); Assert.Greater(midPos4.z, 0f, "Expected midPos4.z to be greater than zero"); // Move hint in -z axis ikData.Hint.z *= -1f; Core.SolveTwoBoneIK(ref stream, ikData, 1f); var midPos5 = stream.GetLocalToRootTranslation(k_MidIndex); Assert.Greater(midPos5.y, 0f, "Expected midPos5.y to be greater than zero"); Assert.Less(midPos5.z, 0f, "Expected midPos5.z to be less than zero"); buffer.Dispose(); }
public void TwoBoneIKFollowsTarget() { var buffer = new NativeArray <AnimatedData>(m_Rig.Value.Bindings.StreamSize, Allocator.Temp, NativeArrayOptions.UninitializedMemory); var stream = AnimationStream.Create(m_Rig, buffer); AnimationStreamUtils.SetDefaultValues(ref stream); var ikData = Core.TwoBoneIKData.Default(); ikData.RootIndex = k_RootIndex; ikData.MidIndex = k_MidIndex; ikData.TipIndex = k_TipIndex; ikData.LimbLengths = new float2( math.distance(stream.GetLocalToRootTranslation(k_RootIndex), stream.GetLocalToRootTranslation(k_MidIndex)), math.distance(stream.GetLocalToRootTranslation(k_MidIndex), stream.GetLocalToRootTranslation(k_TipIndex))); ikData.Target.pos = new float3(0f, 1f, 0f); for (int i = 0; i < 5; ++i) { ikData.Target.pos.y += 0.3f; Core.SolveTwoBoneIK(ref stream, ikData, 1f); float3 rootToTip = math.normalize(stream.GetLocalToRootTranslation(k_TipIndex) - stream.GetLocalToRootTranslation(k_RootIndex)); float3 rootToTarget = math.normalize(ikData.Target.pos - stream.GetLocalToRootTranslation(k_RootIndex)); Assert.That(rootToTarget, Is.EqualTo(rootToTip).Using(TranslationComparer)); } buffer.Dispose(); }
public void Execute(RenderContext context, KernelData data, ref KernelDefs ports) { if (data.RigDefinition == default) { return; } data.ProfileMarker.Begin(); // Fill the destination stream with default values. var startStream = AnimationStream.CreateReadOnly(data.RigDefinition, context.Resolve(ports.Start)); var stopStream = AnimationStream.CreateReadOnly(data.RigDefinition, context.Resolve(ports.Stop)); var inputStream = AnimationStream.CreateReadOnly(data.RigDefinition, context.Resolve(ports.Input)); var outputStream = AnimationStream.Create(data.RigDefinition, context.Resolve(ref ports.Output)); AnimationStreamUtils.MemCpy(ref outputStream, ref inputStream); var startX = new RigidTransform(startStream.GetLocalToParentRotation(0), startStream.GetLocalToParentTranslation(0)); var stopX = new RigidTransform(stopStream.GetLocalToParentRotation(0), stopStream.GetLocalToParentTranslation(0)); var x = new RigidTransform(outputStream.GetLocalToParentRotation(0), outputStream.GetLocalToParentTranslation(0)); var cycleX = GetCycleX(x, startX, stopX, context.Resolve(ports.Cycle)); outputStream.SetLocalToParentRotation(0, cycleX.rot); outputStream.SetLocalToParentTranslation(0, cycleX.pos); data.ProfileMarker.End(); }
public void Execute(RenderContext context, KernelData data, ref KernelDefs ports) { if (data.RigDefinition == BlobAssetReference <RigDefinition> .Null) { return; } data.ProfileMarker.Begin(); // Fill the destination stream with default values. var prevStream = AnimationStream.CreateReadOnly(data.RigDefinition, context.Resolve(ports.Previous)); var currentStream = AnimationStream.CreateReadOnly(data.RigDefinition, context.Resolve(ports.Current)); var outputStream = AnimationStream.Create(data.RigDefinition, context.Resolve(ref ports.Output)); AnimationStreamUtils.MemCpy(ref outputStream, ref currentStream); // current = prev * delta // delta = Inv(prev) * current var prevX = new RigidTransform(prevStream.GetLocalToParentRotation(0), prevStream.GetLocalToParentTranslation(0)); var x = new RigidTransform(currentStream.GetLocalToParentRotation(0), currentStream.GetLocalToParentTranslation(0)); var deltaX = math.mul(math.inverse(prevX), x); outputStream.SetLocalToParentTranslation(0, deltaX.pos); outputStream.SetLocalToParentRotation(0, deltaX.rot); data.ProfileMarker.End(); }
public void Execute(RenderContext context, KernelData data, ref KernelDefs ports) { if (data.RigDefinition == BlobAssetReference <RigDefinition> .Null) { return; } data.ProfileMarker.Begin(); // Fill the destination stream with default values. var inputStream = AnimationStream.CreateReadOnly(data.RigDefinition, context.Resolve(ports.Input)); var outputStream = AnimationStream.Create(data.RigDefinition, context.Resolve(ref ports.Output)); AnimationStreamUtils.MemCpy(ref outputStream, ref inputStream); float deltaTime = context.Resolve(ports.DeltaTime) * data.SampleRate; var rootVelocity = new RigidTransform(outputStream.GetLocalToParentRotation(0), outputStream.GetLocalToParentTranslation(0)); rootVelocity.pos *= deltaTime; rootVelocity.rot.value.xyz *= (deltaTime / rootVelocity.rot.value.w); rootVelocity.rot.value.w = 1; rootVelocity.rot = math.normalize(rootVelocity.rot); outputStream.SetLocalToParentTranslation(0, rootVelocity.pos); outputStream.SetLocalToParentRotation(0, rootVelocity.rot); data.ProfileMarker.End(); }
public void Execute(RenderContext context, KernelData data, ref KernelDefs ports) { if (data.RigDefinition == default) { return; } data.ProfileMarker.Begin(); // Fill the destination stream with default values. var inputStream = AnimationStream.CreateReadOnly(data.RigDefinition, context.Resolve(ports.Input)); var outputStream = AnimationStream.Create(data.RigDefinition, context.Resolve(ref ports.Output)); AnimationStreamUtils.MemCpy(ref outputStream, ref inputStream); var defaultStream = AnimationStream.FromDefaultValues(data.RigDefinition); var motionTranslation = outputStream.GetLocalToRootTranslation(data.TranslationIndex); var motionRotation = outputStream.GetLocalToRootRotation(data.RotationIndex); var defaultRotation = defaultStream.GetLocalToRootRotation(data.RotationIndex); defaultRotation = mathex.mul(motionRotation, math.conjugate(defaultRotation)); defaultRotation = mathex.select(quaternion.identity, defaultRotation, math.dot(defaultRotation, defaultRotation) > math.FLT_MIN_NORMAL); ProjectMotionNode(motionTranslation, defaultRotation, out float3 motionProjTranslation, out quaternion motionProjRotation, (data.Configuration.Mask & ClipConfigurationMask.BankPivot) != 0); outputStream.SetLocalToRootTranslation(0, motionProjTranslation); outputStream.SetLocalToRootRotation(0, motionProjRotation); outputStream.SetLocalToRootTranslation(data.TranslationIndex, motionTranslation); outputStream.SetLocalToRootRotation(data.RotationIndex, motionRotation); data.ProfileMarker.End(); }
public void Execute(RenderContext ctx, KernelData data, ref KernelDefs ports) { var input = ctx.Resolve(ports.Input); var output = ctx.Resolve(ref ports.Output); if (input.Length != output.Length) { throw new InvalidOperationException($"AimConstrainNode: Input Length '{input.Length}' doesn't match Output Length '{output.Length}'"); } data.ProfilerMarker.Begin(); output.CopyFrom(input); var stream = AnimationStream.Create(data.RigDefinition, output); if (stream.IsNull) { throw new ArgumentNullException($"AimConstrainNode: Invalid output stream"); } var srcPositionPorts = ctx.Resolve(ports.SourcePositions); var srcOffsetPorts = ctx.Resolve(ports.SourceOffsets); var srcWeightPorts = ctx.Resolve(ports.SourceWeights); if (srcPositionPorts.Length != srcOffsetPorts.Length || srcOffsetPorts.Length != srcWeightPorts.Length) { throw new ArgumentException($"AimConstrainNode: SourcePositions, SourceOffsets and SourceWeights sizes must be the same"); } var srcPositionArray = new NativeArray <float3>(srcPositionPorts.Length, Allocator.Temp, NativeArrayOptions.UninitializedMemory); var srcOffsetArray = new NativeArray <quaternion>(srcOffsetPorts.Length, Allocator.Temp, NativeArrayOptions.UninitializedMemory); var srcWeightArray = new NativeArray <float>(srcWeightPorts.Length, Allocator.Temp, NativeArrayOptions.UninitializedMemory); srcPositionPorts.CopyTo(srcPositionArray); srcOffsetPorts.CopyTo(srcOffsetArray); srcWeightPorts.CopyTo(srcWeightArray); var localOffset = ctx.Resolve(ports.LocalOffset); var localOffsetQuat = math.lengthsq(localOffset) > 0f ? quaternion.Euler(localOffset, ctx.Resolve(ports.LocalOffsetRotationOrder)) : quaternion.identity; var constraintData = new Core.AimConstraintData { Index = data.Index, LocalOffset = localOffsetQuat, LocalAimAxis = data.LocalAimAxis, LocalAxesMask = data.LocalAxesMask, MinAngleLimit = math.radians(ctx.Resolve(ports.MinAngleLimit)), MaxAngleLimit = math.radians(ctx.Resolve(ports.MaxAngleLimit)), SourcePositions = srcPositionArray, SourceOffsets = srcOffsetArray, SourceWeights = srcWeightArray }; Core.SolveAimConstraint(ref stream, constraintData, ctx.Resolve(ports.Weight)); data.ProfilerMarker.End(); }
public void RotationConstraintFollowsSources() { var buffer = new NativeArray <AnimatedData>(m_Rig.Value.Bindings.StreamSize, Allocator.Temp, NativeArrayOptions.UninitializedMemory); var stream = AnimationStream.Create(m_Rig, buffer); AnimationStreamUtils.SetDefaultValues(ref stream); var rotConstraintData = Core.RotationConstraintData.Default(); rotConstraintData.Index = 1; rotConstraintData.SourceRotations = new NativeArray <quaternion>(2, Allocator.Temp, NativeArrayOptions.UninitializedMemory); rotConstraintData.SourceOffsets = new NativeArray <quaternion>(2, Allocator.Temp, NativeArrayOptions.UninitializedMemory); rotConstraintData.SourceWeights = new NativeArray <float>(2, Allocator.Temp, NativeArrayOptions.ClearMemory); for (int i = 0; i < 2; ++i) { rotConstraintData.SourceRotations[i] = quaternion.identity; rotConstraintData.SourceOffsets[i] = quaternion.identity; } var defaultRot = stream.GetLocalToRootRotation(rotConstraintData.Index); // w0 = 0, w1 = 0 Core.SolveRotationConstraint(ref stream, rotConstraintData, 1f); Assert.That(stream.GetLocalToRootRotation(rotConstraintData.Index), Is.EqualTo(defaultRot).Using(RotationComparer)); // Set source rotations rotConstraintData.SourceRotations[0] = quaternion.AxisAngle(new float3(0f, 0f, 1f), math.radians(70)); rotConstraintData.SourceRotations[1] = quaternion.AxisAngle(new float3(0f, 0f, 1f), math.radians(-20)); // w0 = 1, w1 = 0 AnimationStreamUtils.SetDefaultValues(ref stream); rotConstraintData.SourceWeights[0] = 1f; Core.SolveRotationConstraint(ref stream, rotConstraintData, 1f); Assert.That(stream.GetLocalToRootRotation(rotConstraintData.Index), Is.EqualTo(rotConstraintData.SourceRotations[0]).Using(RotationComparer)); // w0 = 0, w1 = 1 AnimationStreamUtils.SetDefaultValues(ref stream); rotConstraintData.SourceWeights[0] = 0f; rotConstraintData.SourceWeights[1] = 1f; Core.SolveRotationConstraint(ref stream, rotConstraintData, 1f); Assert.That(stream.GetLocalToRootRotation(rotConstraintData.Index), Is.EqualTo(rotConstraintData.SourceRotations[1]).Using(RotationComparer)); // w0 = 1, w1 = 1 AnimationStreamUtils.SetDefaultValues(ref stream); rotConstraintData.SourceWeights[0] = 1f; Core.SolveRotationConstraint(ref stream, rotConstraintData, 1f); var res = math.normalizesafe(mathex.add(rotConstraintData.SourceRotations[0].value * 0.5f, rotConstraintData.SourceRotations[1].value * 0.5f)); Assert.That(stream.GetLocalToRootRotation(rotConstraintData.Index), Is.EqualTo(res).Using(RotationComparer)); buffer.Dispose(); rotConstraintData.SourceRotations.Dispose(); rotConstraintData.SourceOffsets.Dispose(); rotConstraintData.SourceWeights.Dispose(); }
unsafe public static AnimationStream CreateReadOnly(BlobAssetReference <RigDefinition> rig, NativeArray <AnimatedData> buffer) { if (rig == default || buffer.Length == 0 || buffer.Length != rig.Value.Bindings.StreamSize) { return(AnimationStream.Null); } return(AnimationStream.Create(rig, buffer.GetUnsafeReadOnlyPtr())); }
public void Execute(RenderContext ctx, KernelData data, ref KernelDefs ports) { var input = ctx.Resolve(ports.Input); var output = ctx.Resolve(ref ports.Output); if (input.Length != output.Length) { throw new InvalidOperationException($"ParentConstrainNode: Input Length '{input.Length}' doesn't match Output Length '{output.Length}'"); } data.ProfilerMarker.Begin(); output.CopyFrom(input); var stream = AnimationStream.Create(data.RigDefinition, output); if (stream.IsNull) { throw new ArgumentNullException("ParentConstrainNode: Invalid output stream"); } var srcTxPorts = ctx.Resolve(ports.SourceTx); var srcOffsetPorts = ctx.Resolve(ports.SourceOffsets); var srcWeightPorts = ctx.Resolve(ports.SourceWeights); if (srcTxPorts.Length != srcOffsetPorts.Length || srcOffsetPorts.Length != srcWeightPorts.Length) { throw new ArgumentException("ParentConstrainNode: SourceTx, SourceOffsets and SourceWeights sizes must be the same"); } var srcTxArray = new NativeArray <RigidTransform>(srcTxPorts.Length, Allocator.Temp, NativeArrayOptions.UninitializedMemory); var srcOffsetArray = new NativeArray <RigidTransform>(srcOffsetPorts.Length, Allocator.Temp, NativeArrayOptions.UninitializedMemory); var srcWeightArray = new NativeArray <float>(srcWeightPorts.Length, Allocator.Temp, NativeArrayOptions.UninitializedMemory); srcWeightPorts.CopyTo(srcWeightArray); // TODO: Optimize for (int i = 0; i < srcTxPorts.Length; ++i) { srcTxArray[i] = math.RigidTransform(srcTxPorts[i]); srcOffsetArray[i] = math.RigidTransform(srcOffsetPorts[i]); } var constraintData = new Core.ParentConstraintData { Index = data.Index, LocalTranslationAxesMask = data.LocalTranslationAxesMask, LocalRotationAxesMask = data.LocalRotationAxesMask, SourceTx = srcTxArray, SourceOffsets = srcOffsetArray, SourceWeights = srcWeightArray }; Core.SolveParentConstraint(ref stream, constraintData, ctx.Resolve(ports.Weight)); data.ProfilerMarker.End(); }
public void Execute(RenderContext context, KernelData data, ref KernelDefs ports) { var stream = AnimationStream.Create(data.RigDefinition, context.Resolve(ref ports.Output)); if (stream.IsNull) { throw new System.InvalidOperationException("DefaultValuesNode ouput is invalid."); } data.ProfilerMarker.Begin(); AnimationStreamUtils.SetDefaultValues(ref stream); data.ProfilerMarker.End(); }
public void PositionConstraintFollowsSources() { var buffer = new NativeArray <AnimatedData>(m_Rig.Value.Bindings.StreamSize, Allocator.Temp, NativeArrayOptions.UninitializedMemory); var stream = AnimationStream.Create(m_Rig, buffer); AnimationStreamUtils.SetDefaultValues(ref stream); var posConstraintData = Core.PositionConstraintData.Default(); posConstraintData.Index = 1; posConstraintData.SourcePositions = new NativeArray <float3>(2, Allocator.Temp, NativeArrayOptions.UninitializedMemory); posConstraintData.SourceOffsets = new NativeArray <float3>(2, Allocator.Temp, NativeArrayOptions.ClearMemory); posConstraintData.SourceWeights = new NativeArray <float>(2, Allocator.Temp, NativeArrayOptions.ClearMemory); posConstraintData.SourcePositions[0] = new float3(2f, 0f, 0f); posConstraintData.SourcePositions[1] = new float3(-2f, 0f, 0f); var defaultPos = stream.GetLocalToRootTranslation(posConstraintData.Index); // w0 = 0, w1 = 0 Core.SolvePositionConstraint(ref stream, posConstraintData, 1f); Assert.That(stream.GetLocalToRootTranslation(posConstraintData.Index), Is.EqualTo(defaultPos).Using(TranslationComparer)); // w0 = 1, w1 = 0 AnimationStreamUtils.SetDefaultValues(ref stream); posConstraintData.SourceWeights[0] = 1f; Core.SolvePositionConstraint(ref stream, posConstraintData, 1f); Assert.That(stream.GetLocalToRootTranslation(posConstraintData.Index), Is.EqualTo(posConstraintData.SourcePositions[0]).Using(TranslationComparer)); // w0 = 0, w1 = 1 AnimationStreamUtils.SetDefaultValues(ref stream); posConstraintData.SourceWeights[0] = 0f; posConstraintData.SourceWeights[1] = 1f; Core.SolvePositionConstraint(ref stream, posConstraintData, 1f); Assert.That(stream.GetLocalToRootTranslation(posConstraintData.Index), Is.EqualTo(posConstraintData.SourcePositions[1]).Using(TranslationComparer)); // w0 = 1, w1 = 1 // since source positions are mirrored, we should simply evaluate to origin. AnimationStreamUtils.SetDefaultValues(ref stream); posConstraintData.SourceWeights[0] = 1f; Core.SolvePositionConstraint(ref stream, posConstraintData, 1f); Assert.That(stream.GetLocalToRootTranslation(posConstraintData.Index), Is.EqualTo(float3.zero).Using(TranslationComparer)); buffer.Dispose(); posConstraintData.SourcePositions.Dispose(); posConstraintData.SourceOffsets.Dispose(); posConstraintData.SourceWeights.Dispose(); }
public void Execute(RenderContext context, KernelData data, ref KernelDefs ports) { if (data.RigDefinition == BlobAssetReference <RigDefinition> .Null) { return; } data.ProfileMarker.Begin(); var inputStream = AnimationStream.CreateReadOnly(data.RigDefinition, context.Resolve(ports.Input)); var outputStream = AnimationStream.Create(data.RigDefinition, context.Resolve(ref ports.Output)); Core.WeightPose(ref outputStream, ref inputStream, context.Resolve(ports.WeightMasks)); data.ProfileMarker.End(); }
public void Execute(RenderContext context, KernelData data, ref KernelDefs ports) { if (data.RigDefinition == BlobAssetReference <RigDefinition> .Null) { return; } data.ProfileMarker.Begin(); // Fill the destination stream with default values. var inputStream = AnimationStream.CreateReadOnly(data.RigDefinition, context.Resolve(ports.Input)); var outputStream = AnimationStream.Create(data.RigDefinition, context.Resolve(ref ports.Output)); Core.InversePose(ref outputStream, ref inputStream); data.ProfileMarker.End(); }
public void Execute(RenderContext context, KernelData data, ref KernelDefs ports) { var outputStream = AnimationStream.Create(data.RigDefinition, context.Resolve(ref ports.Output)); if (outputStream.IsNull) { throw new System.InvalidOperationException($"MixerBeginNode Output is invalid."); } data.ProfileMixerBegin.Begin(); Core.MixerBegin(ref outputStream); context.Resolve(ref ports.SumWeight) = 0.0f; data.ProfileMixerBegin.End(); }
public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex) { var rigs = chunk.GetNativeArray(Rigs); var graphOutputArray = chunk.GetNativeArray(GraphOutputs); var floatsBuffer = chunk.GetBufferAccessor(Floats); for (int i = 0; i != graphOutputArray.Length; ++i) { var ecsStream = AnimationStream.Create( rigs[i].Value, floatsBuffer[i].AsNativeArray() ); var graphStream = AnimationStream.CreateReadOnly(rigs[i].Value, GraphValueResolver.Resolve(graphOutputArray[i].Buffer)); AnimationStreamUtils.MemCpy(ref ecsStream, ref graphStream); } }
public void Execute(RenderContext context, KernelData data, ref KernelDefs ports) { var outputStream = AnimationStream.Create(data.RigDefinition, context.Resolve(ref ports.Output)); if (outputStream.IsNull) { throw new System.InvalidOperationException($"MixerEndNode Output is invalid."); } var defaultPoseInputStream = AnimationStream.CreateReadOnly(data.RigDefinition, context.Resolve(ports.DefaultPoseInput)); var inputStream = AnimationStream.CreateReadOnly(data.RigDefinition, context.Resolve(ports.Input)); data.ProfileMixerEnd.Begin(); Core.MixerEnd(ref outputStream, ref inputStream, ref defaultPoseInputStream, context.Resolve(ports.SumWeight)); data.ProfileMixerEnd.End(); }
public void Execute(RenderContext context, KernelData data, ref KernelDefs ports) { var outputStream = AnimationStream.Create(data.RigDefinition, context.Resolve(ref ports.Output)); if (outputStream.IsNull) { throw new System.InvalidOperationException($"ChannelWeightMixerNode output is invalid."); } var inputStream0 = AnimationStream.CreateReadOnly(data.RigDefinition, context.Resolve(ports.Input0)); var inputStream1 = AnimationStream.CreateReadOnly(data.RigDefinition, context.Resolve(ports.Input1)); data.ProfileMarker.Begin(); var weight = context.Resolve(ports.Weight); var weightMasks = context.Resolve(ports.WeightMasks); if (Core.WeightDataSize(outputStream.Rig) != weightMasks.Length) { throw new System.InvalidOperationException($"ChannelWeightMixerNode: WeightMasks size does not match RigDefinition. WeightMasks size is '{weightMasks.Length}' but RigDefinition expects a size of '{Core.WeightDataSize(inputStream0.Rig)}'."); } if (inputStream0.IsNull && inputStream1.IsNull) { AnimationStreamUtils.SetDefaultValues(ref outputStream); } else if (inputStream0.IsNull && !inputStream1.IsNull) { AnimationStreamUtils.SetDefaultValues(ref outputStream); Core.Blend(ref outputStream, ref outputStream, ref inputStream1, weight, weightMasks); } else if (!inputStream0.IsNull && inputStream1.IsNull) { AnimationStreamUtils.SetDefaultValues(ref outputStream); Core.Blend(ref outputStream, ref inputStream0, ref outputStream, weight, weightMasks); } else { Core.Blend(ref outputStream, ref inputStream0, ref inputStream1, weight, weightMasks); } data.ProfileMarker.End(); }
public void AimConstraintInfluencedByWeight() { var buffer = new NativeArray <AnimatedData>(m_Rig.Value.Bindings.StreamSize, Allocator.Temp, NativeArrayOptions.UninitializedMemory); var stream = AnimationStream.Create(m_Rig, buffer); AnimationStreamUtils.SetDefaultValues(ref stream); var aimConstraintData = Core.AimConstraintData.Default(); aimConstraintData.Index = 1; aimConstraintData.LocalAimAxis = new float3(1f, 0f, 0f); aimConstraintData.SourcePositions = new NativeArray <float3>(1, Allocator.Temp, NativeArrayOptions.UninitializedMemory); aimConstraintData.SourceOffsets = new NativeArray <quaternion>(1, Allocator.Temp, NativeArrayOptions.UninitializedMemory); aimConstraintData.SourceWeights = new NativeArray <float>(1, Allocator.Temp, NativeArrayOptions.ClearMemory); RigidTransform defaultTx; stream.GetLocalToRootTR(aimConstraintData.Index, out defaultTx.pos, out defaultTx.rot); aimConstraintData.SourcePositions[0] = defaultTx.pos + new float3(1f, 3f, 0f); aimConstraintData.SourceOffsets[0] = quaternion.identity; aimConstraintData.SourceWeights[0] = 1f; float angle = 180f; RigidTransform constrainedTx; for (int i = 0; i < 6; ++i) { float w = i / 5f; AnimationStreamUtils.SetDefaultValues(ref stream); Core.SolveAimConstraint(ref stream, aimConstraintData, w); stream.GetLocalToRootTR(aimConstraintData.Index, out constrainedTx.pos, out constrainedTx.rot); float3 currAim = math.mul(constrainedTx.rot, aimConstraintData.LocalAimAxis); float3 src0Dir = math.normalize(aimConstraintData.SourcePositions[0] - constrainedTx.pos); float test = mathex.angle(currAim, src0Dir); Assert.Less(test, angle, "Angle between currAim and src0Dir should be smaller than last evaluation since constraint weight is greater"); angle = test; } }
public void ParentConstraintInfluencedByWeight() { var buffer = new NativeArray <AnimatedData>(m_Rig.Value.Bindings.StreamSize, Allocator.Temp, NativeArrayOptions.UninitializedMemory); var stream = AnimationStream.Create(m_Rig, buffer); AnimationStreamUtils.SetDefaultValues(ref stream); var parentConstraintData = Core.ParentConstraintData.Default(); parentConstraintData.Index = 1; parentConstraintData.SourceTx = new NativeArray <RigidTransform>(1, Allocator.Temp, NativeArrayOptions.UninitializedMemory); parentConstraintData.SourceOffsets = new NativeArray <RigidTransform>(1, Allocator.Temp, NativeArrayOptions.UninitializedMemory); parentConstraintData.SourceWeights = new NativeArray <float>(1, Allocator.Temp, NativeArrayOptions.UninitializedMemory); RigidTransform defaultTx; stream.GetLocalToRootTR(parentConstraintData.Index, out defaultTx.pos, out defaultTx.rot); parentConstraintData.SourceTx[0] = new RigidTransform(mathex.mul(defaultTx.rot, quaternion.AxisAngle(new float3(0f, 0f, 1f), math.radians(60))), defaultTx.pos + new float3(0f, 0f, 1f)); parentConstraintData.SourceOffsets[0] = RigidTransform.identity; parentConstraintData.SourceWeights[0] = 1f; for (int i = 0; i < 6; ++i) { float w = i / 5f; AnimationStreamUtils.SetDefaultValues(ref stream); Core.SolveParentConstraint(ref stream, parentConstraintData, w); float3 weightedPos = math.lerp(defaultTx.pos, parentConstraintData.SourceTx[0].pos, w); quaternion weightedRot = mathex.lerp(defaultTx.rot, parentConstraintData.SourceTx[0].rot, w); Assert.That(stream.GetLocalToRootTranslation(parentConstraintData.Index), Is.EqualTo(weightedPos).Using(TranslationComparer)); Assert.That(stream.GetLocalToRootRotation(parentConstraintData.Index), Is.EqualTo(weightedRot).Using(RotationComparer)); } buffer.Dispose(); parentConstraintData.SourceTx.Dispose(); parentConstraintData.SourceOffsets.Dispose(); parentConstraintData.SourceWeights.Dispose(); }
public void Execute(RenderContext context, KernelData data, ref KernelDefs ports) { var outputStream = AnimationStream.Create(data.RigDefinition, context.Resolve(ref ports.Output)); if (outputStream.IsNull) { throw new System.InvalidOperationException($"MixerAddNode Output is invalid."); } var addStream = AnimationStream.CreateReadOnly(data.RigDefinition, context.Resolve(ports.Add)); var inputStream = AnimationStream.CreateReadOnly(data.RigDefinition, context.Resolve(ports.Input)); var weight = context.Resolve(ports.Weight); var sumWeight = context.Resolve(ports.SumWeightInput); data.ProfileMixerAdd.Begin(); sumWeight = Core.MixerAdd(ref outputStream, ref inputStream, ref addStream, weight, sumWeight); context.Resolve(ref ports.SumWeightOutput) = sumWeight; data.ProfileMixerAdd.End(); }
public void Execute(RenderContext context, KernelData data, ref KernelDefs ports) { var outputStream = AnimationStream.Create(data.RigDefinition, context.Resolve(ref ports.Output)); if (outputStream.IsNull) { throw new System.InvalidOperationException($"NMixerNode Output is invalid."); } var inputArray = context.Resolve(ports.Inputs); var weightArray = context.Resolve(ports.Weights); if (inputArray.Length != weightArray.Length) { throw new System.InvalidOperationException($"NMixerNode: Inputs And Weight Port array length mismatch. Expecting '{weightArray.Length}' but was '{inputArray.Length}'."); } var sumWeight = 0.0f; data.ProfileNMixer.Begin(); Core.MixerBegin(ref outputStream); for (int i = 0; i < inputArray.Length; ++i) { var inputStream = AnimationStream.CreateReadOnly(data.RigDefinition, inputArray[i].ToNative(context)); if (!inputStream.IsNull) { sumWeight = Core.MixerAdd(ref outputStream, ref outputStream, ref inputStream, weightArray[i], sumWeight); } } var defaultPoseInputStream = AnimationStream.CreateReadOnly(data.RigDefinition, context.Resolve(ports.DefaultPoseInput)); Core.MixerEnd(ref outputStream, ref outputStream, ref defaultPoseInputStream, sumWeight); data.ProfileNMixer.End(); }
public void Execute(RenderContext context, KernelData data, ref KernelDefs ports) { if (data.RigDefinition == default) { throw new System.InvalidOperationException($"ClipNode has invalid RigDefinition."); } if (data.ClipInstance == default) { throw new System.InvalidOperationException($"ClipNode has invalid Clip."); } var outputStream = AnimationStream.Create(data.RigDefinition, context.Resolve(ref ports.Output)); if (outputStream.IsNull) { return; } data.ProfileSampleClip.Begin(); Core.EvaluateClip(data.ClipInstance, context.Resolve(ports.Time), ref outputStream, data.Additive); data.ProfileSampleClip.End(); }
public void Execute(RenderContext ctx, KernelData data, ref KernelDefs ports) { var input = ctx.Resolve(ports.Input); var output = ctx.Resolve(ref ports.Output); if (input.Length != output.Length) { throw new InvalidOperationException($"TwoBoneIKNode: Input Length '{input.Length}' does not match Output Length '{output.Length}'"); } data.ProfilerMarker.Begin(); output.CopyFrom(input); var stream = AnimationStream.Create(data.RigDefinition, output); if (stream.IsNull) { throw new ArgumentNullException("TwoBoneIKNode: Invalid output stream"); } var ikData = new Core.TwoBoneIKData { RootIndex = data.RootIndex, MidIndex = data.MidIndex, TipIndex = data.TipIndex, TargetOffset = data.TargetOffset, LimbLengths = data.LimbLengths, Target = new RigidTransform(ctx.Resolve(ports.Target)), Hint = ctx.Resolve(ports.Hint), TargetPositionWeight = ctx.Resolve(ports.TargetPositionWeight), TargetRotationWeight = ctx.Resolve(ports.TargetRotationWeight), HintWeight = ctx.Resolve(ports.HintWeight) }; Core.SolveTwoBoneIK(ref stream, ikData, ctx.Resolve(ports.Weight)); data.ProfilerMarker.End(); }
public void TwoBoneIKInfluencedByWeight() { var buffer = new NativeArray <AnimatedData>(m_Rig.Value.Bindings.StreamSize, Allocator.Temp, NativeArrayOptions.UninitializedMemory); var stream = AnimationStream.Create(m_Rig, buffer); AnimationStreamUtils.SetDefaultValues(ref stream); var ikData = Core.TwoBoneIKData.Default(); ikData.RootIndex = k_RootIndex; ikData.MidIndex = k_MidIndex; ikData.TipIndex = k_TipIndex; ikData.LimbLengths = new float2( math.distance(stream.GetLocalToRootTranslation(k_RootIndex), stream.GetLocalToRootTranslation(k_MidIndex)), math.distance(stream.GetLocalToRootTranslation(k_MidIndex), stream.GetLocalToRootTranslation(k_TipIndex))); ikData.Target.pos = new float3(2f, 0.5f, 0f); var tipPos1 = stream.GetLocalToRootTranslation(k_TipIndex); Core.SolveTwoBoneIK(ref stream, ikData, 1f); var tipPos2 = stream.GetLocalToRootTranslation(k_TipIndex); for (int i = 0; i < 6; ++i) { float w = i / 5f; AnimationStreamUtils.SetDefaultValues(ref stream); Core.SolveTwoBoneIK(ref stream, ikData, w); float3 weightedTipPos = math.lerp(tipPos1, tipPos2, w); float3 tipPos = stream.GetLocalToRootTranslation(k_TipIndex); Assert.That(weightedTipPos, Is.EqualTo(tipPos).Using(TranslationComparer)); } buffer.Dispose(); }
public void Execute(RenderContext context, KernelData data, ref KernelDefs ports) { var outputStream = AnimationStream.Create(data.RigDefinition, context.Resolve(ref ports.Output)); if (outputStream.IsNull) { throw new System.InvalidOperationException($"MixerNode Output is invalid."); } var inputStream1 = AnimationStream.CreateReadOnly(data.RigDefinition, context.Resolve(ports.Input0)); var inputStream2 = AnimationStream.CreateReadOnly(data.RigDefinition, context.Resolve(ports.Input1)); var weight = context.Resolve(in ports.Weight); data.ProfileMixPose.Begin(); if (inputStream1.IsNull && inputStream2.IsNull) { AnimationStreamUtils.SetDefaultValues(ref outputStream); } else if (inputStream1.IsNull && !inputStream2.IsNull) { AnimationStreamUtils.SetDefaultValues(ref outputStream); Core.Blend(ref outputStream, ref outputStream, ref inputStream2, weight); } else if (!inputStream1.IsNull && inputStream2.IsNull) { AnimationStreamUtils.SetDefaultValues(ref outputStream); Core.Blend(ref outputStream, ref inputStream1, ref outputStream, weight); } else { Core.Blend(ref outputStream, ref inputStream1, ref inputStream2, weight); } data.ProfileMixPose.End(); }
public void RotationConstraintInfluencedByWeight() { var buffer = new NativeArray <AnimatedData>(m_Rig.Value.Bindings.StreamSize, Allocator.Temp, NativeArrayOptions.UninitializedMemory); var stream = AnimationStream.Create(m_Rig, buffer); AnimationStreamUtils.SetDefaultValues(ref stream); var rotConstraintData = Core.RotationConstraintData.Default(); rotConstraintData.Index = 1; rotConstraintData.SourceRotations = new NativeArray <quaternion>(1, Allocator.Temp, NativeArrayOptions.UninitializedMemory); rotConstraintData.SourceOffsets = new NativeArray <quaternion>(1, Allocator.Temp, NativeArrayOptions.UninitializedMemory); rotConstraintData.SourceWeights = new NativeArray <float>(1, Allocator.Temp, NativeArrayOptions.UninitializedMemory); rotConstraintData.SourceRotations[0] = quaternion.AxisAngle(new float3(0f, 0f, 1f), math.radians(80)); rotConstraintData.SourceOffsets[0] = quaternion.identity; rotConstraintData.SourceWeights[0] = 1f; var defaultRot = stream.GetLocalToRootRotation(rotConstraintData.Index); for (int i = 0; i < 6; ++i) { float w = i / 5f; AnimationStreamUtils.SetDefaultValues(ref stream); Core.SolveRotationConstraint(ref stream, rotConstraintData, w); quaternion weightedRot = mathex.lerp(defaultRot, rotConstraintData.SourceRotations[0], w); Assert.That(stream.GetLocalToRootRotation(rotConstraintData.Index), Is.EqualTo(weightedRot).Using(RotationComparer)); } buffer.Dispose(); rotConstraintData.SourceRotations.Dispose(); rotConstraintData.SourceOffsets.Dispose(); rotConstraintData.SourceWeights.Dispose(); }