using Cryville.Common.Collections.Specialized; using System; namespace Cryville.Crtr.Event { public class RealtimeMotionValue { Type _type; public Vector AbsoluteValue; public Vector RelativeValue; public IntKeyedDictionary RelativeNodes; internal byte CloneTypeFlag; public RealtimeMotionValue Init(Vector init) { _type = init.GetType(); RelativeNodes = new IntKeyedDictionary(); AbsoluteValue = init; RelativeValue = (Vector)Activator.CreateInstance(_type); return this; } public RealtimeMotionValue Clone() { return new RealtimeMotionValue() { _type = _type, AbsoluteValue = AbsoluteValue.Clone(), RelativeValue = RelativeValue.Clone(), RelativeNodes = RelativeNodes, }; } public void CopyTo(RealtimeMotionValue dest, bool cloneNodes) { AbsoluteValue.CopyTo(dest.AbsoluteValue); RelativeValue.CopyTo(dest.RelativeValue); if (cloneNodes) { dest.ReturnAllRelativeNodes(); foreach (var node in RelativeNodes) { var dnode = MotionNodePool.Shared.Rent(_type); node.Value.CopyTo(dnode); dest.RelativeNodes.Add(node.Key, dnode); } } else dest.RelativeNodes = RelativeNodes; } public void ReturnAllRelativeNodes() { foreach (var node in RelativeNodes) { MotionNodePool.Shared.Return(_type, node.Value); } RelativeNodes.Clear(); } public MotionNode GetRelativeNode(short id) { RelativeNodes.TryGetValue(id, out MotionNode result); return result; } public void SetRelativeNode(MotionNode node) { if (!RelativeNodes.TryGetValue(node.Id, out MotionNode cnode)) { cnode = MotionNodePool.Shared.Rent(_type); cnode.Id = node.Id; RelativeNodes.Add(node.Id, cnode); } node.Time?.CopyTo(cnode.Time); node.EndTime?.CopyTo(cnode.EndTime); node.Value?.CopyTo(cnode.Value); } /// /// Computes the motion value. /// /// The vector type of the value. /// The result. public void Compute(ref T result) where T : Vector { AbsoluteValue.CopyTo(result); result.ApplyFrom(RelativeValue); } } }