Netcode Bootstrap
This commit is contained in:
+61
@@ -0,0 +1,61 @@
|
||||
|
||||
using Unity.Collections;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace Rukhanka.WaybackMachine
|
||||
{
|
||||
public struct AnimationEventHistoryData
|
||||
{
|
||||
public FixedString32Bytes name;
|
||||
public FixedString32Bytes stringParam;
|
||||
public int frameIndex;
|
||||
public uint nameHash;
|
||||
public float floatParam;
|
||||
public int intParam;
|
||||
public uint stringParamHash;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public AnimationEventHistoryData(in AnimationEventComponent aec, int frameIndex)
|
||||
{
|
||||
#if RUKHANKA_DEBUG_INFO
|
||||
name = aec.name;
|
||||
stringParam = aec.stringParam;
|
||||
#else
|
||||
name = default;
|
||||
stringParam = default;
|
||||
#endif
|
||||
nameHash = aec.nameHash;
|
||||
floatParam = aec.floatParam;
|
||||
intParam = aec.intParam;
|
||||
stringParamHash = aec.stringParamHash;
|
||||
this.frameIndex = frameIndex;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public string GetName()
|
||||
{
|
||||
#if RUKHANKA_DEBUG_INFO
|
||||
return name.ToString();
|
||||
#else
|
||||
return $"{nameHash}";
|
||||
#endif
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public string GetStringParam()
|
||||
{
|
||||
#if RUKHANKA_DEBUG_INFO
|
||||
return stringParam.ToString();
|
||||
#else
|
||||
return $"{stringParamHash}";
|
||||
#endif
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: db90f13b072970248951f3c66931feda
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 298480
|
||||
packageName: Rukhanka Animation System 2
|
||||
packageVersion: 2.9.0
|
||||
assetPath: Packages/com.rukhanka.animation/Rukhanka.Runtime/WaybackMachine/AnimationEventHistoryData.cs
|
||||
uploadId: 897522
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
|
||||
using System;
|
||||
using Rukhanka.Toolbox;
|
||||
using Unity.Burst;
|
||||
using Unity.Collections;
|
||||
using Unity.Collections.LowLevel.Unsafe;
|
||||
using Unity.Entities;
|
||||
using Unity.Mathematics;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace Rukhanka.WaybackMachine
|
||||
{
|
||||
public struct HistoryValue
|
||||
{
|
||||
public float value;
|
||||
public int frameIndex;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------//
|
||||
|
||||
[BurstCompile]
|
||||
public struct AnimationHistoryData: IDisposable
|
||||
{
|
||||
public FixedString128Bytes animationName;
|
||||
public int2 frameSpan;
|
||||
public Hash128 animationHash;
|
||||
public Hash128 avatarMaskHash;
|
||||
public AnimationBlendingMode blendMode;
|
||||
public float layerWeight;
|
||||
public int layerIndex;
|
||||
public uint motionId;
|
||||
public UnsafeList<HistoryValue> historyWeights;
|
||||
public UnsafeList<HistoryValue> historyAnimTime;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public AnimationHistoryData(in AnimationToProcessComponent atp, int frameIndex)
|
||||
{
|
||||
frameSpan = new int2(frameIndex, frameIndex);
|
||||
animationHash = atp.animation.IsCreated ? atp.animation.Value.hash : new Hash128();
|
||||
avatarMaskHash = atp.avatarMask.IsCreated ? atp.avatarMask.Value.hash : new Hash128();
|
||||
blendMode = atp.blendMode;
|
||||
layerWeight = atp.layerWeight;
|
||||
layerIndex = atp.layerIndex;
|
||||
motionId = atp.motionId;
|
||||
historyWeights = default;
|
||||
historyAnimTime = default;
|
||||
animationName = default;
|
||||
#if RUKHANKA_DEBUG_INFO
|
||||
if (atp.animation.IsCreated)
|
||||
{
|
||||
atp.animation.Value.name.CopyToWithTruncate(ref animationName);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public Hash128 ComputeHash()
|
||||
{
|
||||
var hasher = new xxHash3.StreamingState(false, 0xaabbccdd);
|
||||
hasher.Update(animationHash);
|
||||
hasher.Update(avatarMaskHash);
|
||||
hasher.Update(blendMode);
|
||||
hasher.Update(layerIndex);
|
||||
hasher.Update(layerWeight);
|
||||
hasher.Update(motionId);
|
||||
return new Hash128(hasher.DigestHash128());
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
historyWeights.Dispose();
|
||||
historyAnimTime.Dispose();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
[BurstCompile]
|
||||
public static float GetHistoryValueForFrame(in UnsafeList<HistoryValue> hvs, int frameIndex)
|
||||
{
|
||||
if (hvs.Length == 0)
|
||||
return 0;
|
||||
|
||||
var rv = hvs[0].value;
|
||||
for (int i = 0; i < hvs.Length; ++i)
|
||||
{
|
||||
var hv = hvs[i];
|
||||
rv = hv.value;
|
||||
if (hv.frameIndex >= frameIndex)
|
||||
break;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public string GetName()
|
||||
{
|
||||
#if RUKHANKA_DEBUG_INFO
|
||||
return animationName.ToString();
|
||||
#else
|
||||
return $"{animationHash}";
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 69ef9f23f2e5f1740b74b1ee3a2aab44
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 298480
|
||||
packageName: Rukhanka Animation System 2
|
||||
packageVersion: 2.9.0
|
||||
assetPath: Packages/com.rukhanka.animation/Rukhanka.Runtime/WaybackMachine/AnimationHistoryData.cs
|
||||
uploadId: 897522
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
|
||||
using Rukhanka.Toolbox;
|
||||
using Unity.Collections;
|
||||
using Unity.Mathematics;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace Rukhanka.WaybackMachine
|
||||
{
|
||||
public struct AnimatorControllerStateHistoryData
|
||||
{
|
||||
public FixedString32Bytes name;
|
||||
public int2 frameSpan;
|
||||
public int layerIndex;
|
||||
public int stateId;
|
||||
public uint motionId;
|
||||
public float weight;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public AnimatorControllerStateHistoryData(in AnimatorControllerLayerComponent aclc, int stateId, uint motionId, int frameIndex)
|
||||
{
|
||||
frameSpan = new (frameIndex, frameIndex);
|
||||
weight = 1;
|
||||
this.stateId = stateId;
|
||||
this.layerIndex = aclc.layerIndex;
|
||||
this.motionId = motionId;
|
||||
ref var sb = ref aclc.controller.Value.layers[aclc.layerIndex].states[stateId];
|
||||
name = default;
|
||||
#if RUKHANKA_DEBUG_INFO
|
||||
if (sb.name.Length > 0)
|
||||
{
|
||||
sb.name.CopyToWithTruncate(ref name);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public string GetName()
|
||||
{
|
||||
#if RUKHANKA_DEBUG_INFO
|
||||
return name.ToString();
|
||||
#else
|
||||
return $"{stateId}";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------//
|
||||
|
||||
public struct AnimatorControllerTransitionHistoryData
|
||||
{
|
||||
public FixedString64Bytes name;
|
||||
public int2 frameSpan;
|
||||
public int srcStateId;
|
||||
public int dstStateId;
|
||||
public int transitionId;
|
||||
public int layerIndex;
|
||||
public float2 weightRange;
|
||||
public int srcStateDataIndex;
|
||||
public int dstStateDataIndex;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public string GetName()
|
||||
{
|
||||
#if RUKHANKA_DEBUG_INFO
|
||||
return name.ToString();
|
||||
#else
|
||||
return $"{srcStateId}->{dstStateId}";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0e3634df630fd8242828ce80f088b592
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 298480
|
||||
packageName: Rukhanka Animation System 2
|
||||
packageVersion: 2.9.0
|
||||
assetPath: Packages/com.rukhanka.animation/Rukhanka.Runtime/WaybackMachine/AnimatorControllerHistoryData.cs
|
||||
uploadId: 897522
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
|
||||
using Unity.Collections;
|
||||
using Unity.Mathematics;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace Rukhanka.WaybackMachine
|
||||
{
|
||||
public struct AnimatorEventHistoryData
|
||||
{
|
||||
public FixedString32Bytes name;
|
||||
public int layerId;
|
||||
public int stateId;
|
||||
// History index of begin event for this event. -1 for state enter events
|
||||
public int beginHistoryIndex;
|
||||
public int2 frameRange;
|
||||
public AnimatorControllerEventComponent.EventType eventType;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public AnimatorEventHistoryData(in AnimatorControllerEventComponent acec, int frameIndex)
|
||||
{
|
||||
name = default;
|
||||
#if RUKHANKA_DEBUG_INFO
|
||||
name = acec.stateName;
|
||||
#endif
|
||||
eventType = acec.eventType;
|
||||
frameRange = new (frameIndex, frameIndex);
|
||||
layerId = acec.layerId;
|
||||
stateId = acec.stateId;
|
||||
beginHistoryIndex = -1;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public string GetName()
|
||||
{
|
||||
#if RUKHANKA_DEBUG_INFO
|
||||
return name.ToString();
|
||||
#else
|
||||
var prefix = "";
|
||||
if (eventType == AnimatorControllerEventComponent.EventType.StateEnter)
|
||||
prefix = "Enter ";
|
||||
if (eventType == AnimatorControllerEventComponent.EventType.StateExit)
|
||||
prefix = "Exit ";
|
||||
return $"{prefix}{layerId}:{stateId}";
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 25fb6d6e8df4db6499b010dce348b1b2
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 298480
|
||||
packageName: Rukhanka Animation System 2
|
||||
packageVersion: 2.9.0
|
||||
assetPath: Packages/com.rukhanka.animation/Rukhanka.Runtime/WaybackMachine/AnimatorEventHistoryData.cs
|
||||
uploadId: 897522
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
|
||||
using System;
|
||||
using Unity.Burst;
|
||||
using Unity.Collections;
|
||||
using Unity.Collections.LowLevel.Unsafe;
|
||||
using Unity.Entities;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace Rukhanka.WaybackMachine
|
||||
{
|
||||
[BurstCompile]
|
||||
public struct WaybackMachineData: IDisposable
|
||||
{
|
||||
public enum FPSMode
|
||||
{
|
||||
FPS120,
|
||||
FPS60,
|
||||
FPS30
|
||||
}
|
||||
|
||||
public FPSMode fpsMode;
|
||||
public int lastRecordedFrame;
|
||||
public NativeList<AnimationHistoryData> animHistory;
|
||||
public NativeList<AnimatorControllerStateHistoryData> controllerStateHistory;
|
||||
public NativeList<AnimatorControllerTransitionHistoryData> controllerTransitionHistory;
|
||||
public NativeList<AnimationEventHistoryData> animationEventHistory;
|
||||
public NativeList<AnimatorEventHistoryData> animatorEventHistory;
|
||||
|
||||
public NativeList<AnimationEventComponent> emittedAnimationEvents;
|
||||
public NativeList<AnimatorControllerEventComponent> emittedAnimatorEvents;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
foreach (var ah in animHistory)
|
||||
{
|
||||
ah.Dispose();
|
||||
}
|
||||
lastRecordedFrame = 0;
|
||||
animHistory.Clear();
|
||||
animationEventHistory.Clear();
|
||||
animatorEventHistory.Clear();
|
||||
controllerStateHistory.Clear();
|
||||
controllerTransitionHistory.Clear();
|
||||
|
||||
EndFrame();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void EndFrame()
|
||||
{
|
||||
emittedAnimationEvents.Clear();
|
||||
emittedAnimatorEvents.Clear();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void Construct()
|
||||
{
|
||||
fpsMode = FPSMode.FPS60;
|
||||
animHistory = new (0xff, Allocator.Persistent);
|
||||
animationEventHistory = new (0xff, Allocator.Persistent);
|
||||
animatorEventHistory = new (0xff, Allocator.Persistent);
|
||||
controllerStateHistory = new (0xff, Allocator.Persistent);
|
||||
controllerTransitionHistory = new (0xff, Allocator.Persistent);
|
||||
emittedAnimationEvents = new (0xff, Allocator.Persistent);
|
||||
emittedAnimatorEvents = new (0xff, Allocator.Persistent);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public float GetFrameDuration() => fpsMode switch
|
||||
{
|
||||
FPSMode.FPS30 => 1 / 30.0f,
|
||||
FPSMode.FPS60 => 1 / 60.0f,
|
||||
FPSMode.FPS120 => 1 / 120.0f,
|
||||
_ => 1 / 60.0f
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public long GetDataSize()
|
||||
{
|
||||
var rv = 0L;
|
||||
rv += animHistory.Length * UnsafeUtility.SizeOf<AnimationHistoryData>();
|
||||
foreach (var ah in animHistory)
|
||||
{
|
||||
rv += ah.historyWeights.Length * UnsafeUtility.SizeOf<HistoryValue>();
|
||||
rv += ah.historyAnimTime.Length * UnsafeUtility.SizeOf<HistoryValue>();
|
||||
}
|
||||
rv += controllerStateHistory.Length * UnsafeUtility.SizeOf<AnimatorControllerStateHistoryData>();
|
||||
rv += controllerTransitionHistory.Length * UnsafeUtility.SizeOf<AnimatorControllerTransitionHistoryData>();
|
||||
rv += animationEventHistory.Length * UnsafeUtility.SizeOf<AnimationEventHistoryData>();
|
||||
rv += animatorEventHistory.Length * UnsafeUtility.SizeOf<AnimatorEventHistoryData>();
|
||||
return rv;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (var ah in animHistory)
|
||||
{
|
||||
ah.Dispose();
|
||||
}
|
||||
animHistory.Dispose();
|
||||
animationEventHistory.Dispose();
|
||||
animatorEventHistory.Dispose();
|
||||
controllerStateHistory.Dispose();
|
||||
controllerTransitionHistory.Dispose();
|
||||
emittedAnimationEvents.Dispose();
|
||||
emittedAnimatorEvents.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------//
|
||||
|
||||
public struct RecordComponent: IComponentData
|
||||
{
|
||||
public NativeReference<WaybackMachineData> wbData;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------//
|
||||
|
||||
public struct PlaybackComponent: IComponentData
|
||||
{
|
||||
public NativeList<AnimationToProcessComponent> playbackData;
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 74b0c11583bee45488d703036960f3c9
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 298480
|
||||
packageName: Rukhanka Animation System 2
|
||||
packageVersion: 2.9.0
|
||||
assetPath: Packages/com.rukhanka.animation/Rukhanka.Runtime/WaybackMachine/WaybackMachineComponents.cs
|
||||
uploadId: 897522
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
using Rukhanka.WaybackMachine;
|
||||
using Unity.Burst;
|
||||
using Unity.Entities;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace Rukhanka
|
||||
{
|
||||
[DisableAutoCreation]
|
||||
[UpdateAfter(typeof(AnimationCullingSystem))]
|
||||
[UpdateBefore(typeof(AnimationEventEmitSystem))]
|
||||
public partial struct WaybackMachinePlaybackSystem: ISystem
|
||||
{
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
[BurstCompile]
|
||||
public void OnCreate(ref SystemState ss)
|
||||
{
|
||||
ss.RequireForUpdate<PlaybackComponent>();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
[BurstCompile]
|
||||
public void OnUpdate(ref SystemState ss)
|
||||
{
|
||||
var pc = SystemAPI.GetSingleton<PlaybackComponent>();
|
||||
var pce = SystemAPI.GetSingletonEntity<PlaybackComponent>();
|
||||
|
||||
if (!SystemAPI.HasBuffer<AnimationToProcessComponent>(pce))
|
||||
return;
|
||||
|
||||
var atps = SystemAPI.GetBuffer<AnimationToProcessComponent>(pce);
|
||||
atps.Clear();
|
||||
atps.AddRange(pc.playbackData.AsArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8aedb7e58c3175049833f483785cea1f
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 298480
|
||||
packageName: Rukhanka Animation System 2
|
||||
packageVersion: 2.9.0
|
||||
assetPath: Packages/com.rukhanka.animation/Rukhanka.Runtime/WaybackMachine/WaybackMachinePlaybackSystem.cs
|
||||
uploadId: 897522
|
||||
+281
@@ -0,0 +1,281 @@
|
||||
|
||||
using Rukhanka.Toolbox;
|
||||
using Rukhanka.WaybackMachine;
|
||||
using Unity;
|
||||
using Unity.Burst;
|
||||
using Unity.Collections;
|
||||
using Unity.Collections.LowLevel.Unsafe;
|
||||
using Unity.Entities;
|
||||
using Unity.Mathematics;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace Rukhanka
|
||||
{
|
||||
[DisableAutoCreation]
|
||||
public partial struct WaybackMachineRecordSystem: ISystem, ISystemStartStop
|
||||
{
|
||||
int frameCounter;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void OnStartRunning(ref SystemState ss)
|
||||
{
|
||||
frameCounter = 0;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void OnStopRunning(ref SystemState ss)
|
||||
{
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
[BurstCompile]
|
||||
public void OnCreate(ref SystemState ss)
|
||||
{
|
||||
ss.RequireForUpdate<RecordComponent>();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void RecordAnimation(AnimationToProcessComponent atp, ref RecordComponent rc, int frameIndex)
|
||||
{
|
||||
var ahs = rc.wbData.Value.animHistory;
|
||||
var curHistory = new AnimationHistoryData(atp, frameIndex);
|
||||
|
||||
// Search back for given animation in history
|
||||
var foundIndex = -1;
|
||||
for (var k = ahs.Length - 1; k >= 0; --k)
|
||||
{
|
||||
var ah = ahs[k];
|
||||
if (ah.frameSpan.y + 1 != frameIndex)
|
||||
continue;
|
||||
|
||||
if (ah.ComputeHash() == curHistory.ComputeHash())
|
||||
{
|
||||
foundIndex = k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundIndex < 0)
|
||||
{
|
||||
foundIndex = ahs.Length;
|
||||
curHistory.historyWeights = new (0xff, Allocator.Persistent);
|
||||
curHistory.historyAnimTime = new (0xff, Allocator.Persistent);
|
||||
ahs.Add(curHistory);
|
||||
}
|
||||
ref var historyElement = ref ahs.ElementAt(foundIndex);
|
||||
historyElement.frameSpan.y = frameIndex;
|
||||
|
||||
var whv = new HistoryValue() { value = atp.weight, frameIndex = frameIndex };
|
||||
historyElement.historyWeights.Add(whv);
|
||||
var thv = new HistoryValue() { value = atp.time, frameIndex = frameIndex };
|
||||
historyElement.historyAnimTime.Add(thv);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void RecordAnimationEvents(ref SystemState ss, Entity rce, ref RecordComponent rc)
|
||||
{
|
||||
if (!SystemAPI.HasBuffer<AnimationEventComponent>(rce))
|
||||
return;
|
||||
|
||||
var animEvents = rc.wbData.Value.emittedAnimationEvents;
|
||||
|
||||
// Record animation events
|
||||
for (var i = 0; i < animEvents.Length; ++i)
|
||||
{
|
||||
var aec = animEvents[i];
|
||||
var ehd = new AnimationEventHistoryData(aec, frameCounter);
|
||||
rc.wbData.Value.animationEventHistory.Add(ehd);
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void RecordAnimations(ref SystemState ss, Entity rce, ref RecordComponent rc)
|
||||
{
|
||||
if (!SystemAPI.HasBuffer<AnimationToProcessComponent>(rce))
|
||||
return;
|
||||
|
||||
var atps = SystemAPI.GetBuffer<AnimationToProcessComponent>(rce);
|
||||
for (var i = 0; i < atps.Length; ++i)
|
||||
{
|
||||
var atp = atps[i];
|
||||
RecordAnimation(atp, ref rc, frameCounter);
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void RecordAnimatorTransition(in AnimatorControllerLayerComponent aclc, ref RecordComponent rc, int si, int di)
|
||||
{
|
||||
if (aclc.rtd.activeTransition.id < 0)
|
||||
return;
|
||||
|
||||
ref var tb = ref aclc.controller.Value.layers[aclc.layerIndex].states[aclc.rtd.srcState.id].transitions[aclc.rtd.activeTransition.id];
|
||||
var std = new AnimatorControllerTransitionHistoryData
|
||||
{
|
||||
frameSpan = new (frameCounter, frameCounter),
|
||||
transitionId = aclc.rtd.activeTransition.id,
|
||||
layerIndex = aclc.layerIndex,
|
||||
dstStateId = aclc.rtd.dstState.id,
|
||||
srcStateId = aclc.rtd.srcState.id,
|
||||
weightRange = new float2(1) * aclc.rtd.activeTransition.normalizedDuration
|
||||
};
|
||||
|
||||
var cth = rc.wbData.Value.controllerTransitionHistory;
|
||||
|
||||
// Search for existing entry in history
|
||||
var i = cth.Length - 1;
|
||||
for (; i >= 0; --i)
|
||||
{
|
||||
var ct = cth[i];
|
||||
if (ct.srcStateId == std.srcStateId && ct.dstStateId == std.dstStateId && ct.frameSpan.y + 1 == frameCounter && std.layerIndex == ct.layerIndex)
|
||||
break;
|
||||
}
|
||||
|
||||
// If not found create new entry
|
||||
if (i < 0)
|
||||
{
|
||||
i = cth.Length;
|
||||
#if RUKHANKA_DEBUG_INFO
|
||||
tb.name.CopyToWithTruncate(ref std.name);
|
||||
#endif
|
||||
cth.Add(std);
|
||||
}
|
||||
ref var csv = ref cth.ElementAt(i);
|
||||
// If found update existing entry
|
||||
csv.frameSpan.y = frameCounter;
|
||||
csv.weightRange.y = aclc.rtd.activeTransition.normalizedDuration;
|
||||
csv.srcStateDataIndex = si;
|
||||
csv.dstStateDataIndex = di;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int RecordAnimatorState(in AnimatorControllerLayerComponent aclc, int stateId, uint motionId, ref RecordComponent rc)
|
||||
{
|
||||
if (stateId < 0)
|
||||
return -1;
|
||||
|
||||
var shd = new AnimatorControllerStateHistoryData(aclc, stateId, motionId, frameCounter);
|
||||
var csh = rc.wbData.Value.controllerStateHistory;
|
||||
|
||||
// Search for existing entry in history
|
||||
var i = csh.Length - 1;
|
||||
for (; i >= 0; --i)
|
||||
{
|
||||
var cs = csh[i];
|
||||
if (cs.stateId == shd.stateId &&
|
||||
cs.frameSpan.y + 1 == frameCounter &&
|
||||
cs.layerIndex == shd.layerIndex &&
|
||||
cs.motionId == shd.motionId)
|
||||
break;
|
||||
}
|
||||
|
||||
// If not found create new entry
|
||||
if (i < 0)
|
||||
{
|
||||
i = csh.Length;
|
||||
csh.Add(shd);
|
||||
}
|
||||
ref var csv = ref csh.ElementAt(i);
|
||||
// If found update existing entry
|
||||
csv.frameSpan.y = frameCounter;
|
||||
return i;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void RecordAnimatorStates(ref SystemState ss, Entity rce, ref RecordComponent rc)
|
||||
{
|
||||
if (!SystemAPI.HasBuffer<AnimatorControllerLayerComponent>(rce))
|
||||
return;
|
||||
|
||||
var aclcs = SystemAPI.GetBuffer<AnimatorControllerLayerComponent>(rce);
|
||||
for (var i = 0; i < aclcs.Length; ++i)
|
||||
{
|
||||
var aclc = aclcs[i];
|
||||
var srcStateDataIndex = RecordAnimatorState(aclc, aclc.rtd.srcState.id, aclc.rtd.srcState.motionId, ref rc);
|
||||
var dstStateDataIndex = RecordAnimatorState(aclc, aclc.rtd.dstState.id, aclc.rtd.dstState.motionId, ref rc);
|
||||
RecordAnimatorTransition(aclc, ref rc, srcStateDataIndex, dstStateDataIndex);
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void RecordAnimatorEvents(ref SystemState ss, Entity rce, ref RecordComponent rc)
|
||||
{
|
||||
if (!SystemAPI.HasBuffer<AnimatorControllerEventComponent>(rce))
|
||||
return;
|
||||
|
||||
var acecs = rc.wbData.Value.emittedAnimatorEvents;
|
||||
for (var i = 0; i < acecs.Length; ++i)
|
||||
{
|
||||
var acec = acecs[i];
|
||||
var aehd = new AnimatorEventHistoryData(acec, frameCounter);
|
||||
var k = -1;
|
||||
// For every frame update events append it to the previous to make continuous span
|
||||
if (aehd.eventType == AnimatorControllerEventComponent.EventType.StateUpdate)
|
||||
{
|
||||
k = rc.wbData.Value.animatorEventHistory.Length - 1;
|
||||
for (; k >= 0; --k)
|
||||
{
|
||||
ref var hd = ref rc.wbData.Value.animatorEventHistory.ElementAt(k);
|
||||
if (hd.stateId == aehd.stateId && hd.layerId == aehd.layerId && hd.eventType == AnimatorControllerEventComponent.EventType.StateUpdate)
|
||||
{
|
||||
hd.frameRange.y = frameCounter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find begin event for this event
|
||||
if (aehd.eventType != AnimatorControllerEventComponent.EventType.StateEnter)
|
||||
{
|
||||
var l = rc.wbData.Value.animatorEventHistory.Length - 1;
|
||||
for (; l >= 0; --l)
|
||||
{
|
||||
ref var hd = ref rc.wbData.Value.animatorEventHistory.ElementAt(l);
|
||||
if (hd.stateId == aehd.stateId && hd.layerId == aehd.layerId && hd.eventType == AnimatorControllerEventComponent.EventType.StateEnter)
|
||||
break;
|
||||
}
|
||||
|
||||
if (l >= 0)
|
||||
aehd.beginHistoryIndex = l;
|
||||
}
|
||||
|
||||
// If previous update event was not found, or we are dealing with other event type - add new entry
|
||||
if (k < 0)
|
||||
{
|
||||
rc.wbData.Value.animatorEventHistory.Add(aehd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
[BurstCompile]
|
||||
public unsafe void OnUpdate(ref SystemState ss)
|
||||
{
|
||||
var rcd = SystemAPI.GetSingletonRW<RecordComponent>();
|
||||
var rce = SystemAPI.GetSingletonEntity<RecordComponent>();
|
||||
|
||||
ref var rc = ref rcd.ValueRW;
|
||||
var ptr = rc.wbData.GetUnsafePtr();
|
||||
ptr->lastRecordedFrame = frameCounter;
|
||||
|
||||
RecordAnimatorStates(ref ss, rce, ref rc);
|
||||
RecordAnimationEvents(ref ss, rce, ref rc);
|
||||
RecordAnimatorEvents(ref ss, rce, ref rc);
|
||||
RecordAnimations(ref ss, rce, ref rc);
|
||||
|
||||
frameCounter++;
|
||||
rcd.ValueRW.wbData.Value.EndFrame();
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 729c69f8b5d43634e94eaf6c7349836a
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 298480
|
||||
packageName: Rukhanka Animation System 2
|
||||
packageVersion: 2.9.0
|
||||
assetPath: Packages/com.rukhanka.animation/Rukhanka.Runtime/WaybackMachine/WaybackMachineRecordSystem.cs
|
||||
uploadId: 897522
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
using Unity.Entities;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace Rukhanka
|
||||
{
|
||||
[DisableAutoCreation]
|
||||
[UpdateAfter(typeof(AnimationApplicationSystem))]
|
||||
public partial class WaybackMachineRecordSystemGroup: ComponentSystemGroup
|
||||
{
|
||||
protected override void OnCreate()
|
||||
{
|
||||
base.OnCreate();
|
||||
RateManager = new RateUtils.FixedRateCatchUpManager(1 / 60.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: abe7a9fbde95e53458f3d843255da216
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 298480
|
||||
packageName: Rukhanka Animation System 2
|
||||
packageVersion: 2.9.0
|
||||
assetPath: Packages/com.rukhanka.animation/Rukhanka.Runtime/WaybackMachine/WaybackMachineRecordSystemGroup.cs
|
||||
uploadId: 897522
|
||||
Reference in New Issue
Block a user