Last active 1765432298

Angablade revised this gist 1765432298. Go to revision

1 file changed, 133 insertions

framegen.cs(file created)

@@ -0,0 +1,133 @@
1 + using System;
2 + using System.Collections.Generic;
3 + using System.Linq;
4 + using Vintagestory.API.MathTools;
5 + using VSClientOptimizer.Config;
6 + using VSClientOptimizer.Math;
7 + using VSClientOptimizer.Interpolation;
8 +
9 + namespace VSClientOptimizer.Performance
10 + {
11 + /// <summary>
12 + /// Frame Generation - Creates intermediate frames between real frames for smoother motion
13 + /// Similar to AMD FSR Frame Generation or NVIDIA DLSS 3 Frame Generation
14 + /// </summary>
15 + public class FrameGenerator
16 + {
17 + private Queue<FrameSnapshot> frameHistory = new Queue<FrameSnapshot>();
18 + private const int MaxFrameHistory = 3;
19 + private float generationMultiplier = 2.0f;
20 + private bool useMotionVectors = true;
21 +
22 + public class FrameSnapshot
23 + {
24 + public long TimestampMs;
25 + public Dictionary<long, EntityPositionSnapshot> EntityStates;
26 +
27 + public FrameSnapshot(long timestamp)
28 + {
29 + TimestampMs = timestamp;
30 + EntityStates = new Dictionary<long, EntityPositionSnapshot>();
31 + }
32 + }
33 +
34 + public FrameGenerator(float multiplier, bool useMotion)
35 + {
36 + generationMultiplier = System.Math.Max(1.0f, System.Math.Min(4.0f, multiplier)); // Clamp 1-4x
37 + useMotionVectors = useMotion;
38 + }
39 +
40 + public void AddFrame(long timestamp, Dictionary<long, EntityPositionSnapshot> states)
41 + {
42 + var snapshot = new FrameSnapshot(timestamp);
43 + foreach (var kvp in states)
44 + {
45 + snapshot.EntityStates[kvp.Key] = kvp.Value;
46 + }
47 +
48 + frameHistory.Enqueue(snapshot);
49 + if (frameHistory.Count > MaxFrameHistory)
50 + frameHistory.Dequeue();
51 + }
52 +
53 + public List<FrameSnapshot> GenerateIntermediateFrames()
54 + {
55 + var generatedFrames = new List<FrameSnapshot>();
56 +
57 + if (frameHistory.Count < 2 || generationMultiplier <= 1.0f)
58 + return generatedFrames;
59 +
60 + var frames = frameHistory.ToArray();
61 + var lastFrame = frames[frames.Length - 2];
62 + var currentFrame = frames[frames.Length - 1];
63 +
64 + long timeDiff = currentFrame.TimestampMs - lastFrame.TimestampMs;
65 + if (timeDiff <= 0) return generatedFrames;
66 +
67 + // Generate intermediate frames
68 + int intermediateCount = (int)(generationMultiplier - 1);
69 + for (int i = 1; i <= intermediateCount; i++)
70 + {
71 + float t = i / generationMultiplier;
72 + long interpTime = lastFrame.TimestampMs + (long)(timeDiff * t);
73 +
74 + var interpFrame = new FrameSnapshot(interpTime);
75 +
76 + // Interpolate each entity's state
77 + foreach (var entityId in lastFrame.EntityStates.Keys)
78 + {
79 + if (currentFrame.EntityStates.TryGetValue(entityId, out var currentState) &&
80 + lastFrame.EntityStates.TryGetValue(entityId, out var lastState))
81 + {
82 + var interpState = InterpolateEntityState(lastState, currentState, t);
83 + interpFrame.EntityStates[entityId] = interpState;
84 + }
85 + }
86 +
87 + generatedFrames.Add(interpFrame);
88 + }
89 +
90 + return generatedFrames;
91 + }
92 +
93 + private EntityPositionSnapshot InterpolateEntityState(
94 + EntityPositionSnapshot from,
95 + EntityPositionSnapshot to,
96 + float t)
97 + {
98 + // Position interpolation
99 + Vector3 fromPos = new Vector3(from.Position.X, from.Position.Y, from.Position.Z);
100 + Vector3 toPos = new Vector3(to.Position.X, to.Position.Y, to.Position.Z);
101 +
102 + Vector3 interpPos;
103 + if (useMotionVectors && (from.Velocity.X != 0 || from.Velocity.Y != 0 || from.Velocity.Z != 0))
104 + {
105 + // Use motion vectors for smoother interpolation
106 + double deltaTime = (to.TimestampMs - from.TimestampMs) / 1000.0;
107 + Vector3 motionPredicted = fromPos + (from.Velocity * (deltaTime * t));
108 + interpPos = Vector3.Lerp(Vector3.Lerp(fromPos, toPos, t), motionPredicted, 0.3f);
109 + }
110 + else
111 + {
112 + interpPos = Vector3.Lerp(fromPos, toPos, t);
113 + }
114 +
115 + // Rotation interpolation
116 + Rotation3 fromRot = new Rotation3(from.Rotation.X, from.Rotation.Y, from.Rotation.Z);
117 + Rotation3 toRot = new Rotation3(to.Rotation.X, to.Rotation.Y, to.Rotation.Z);
118 + Rotation3 interpRot = Rotation3.Lerp(fromRot, toRot, t);
119 +
120 + // Velocity interpolation
121 + Vector3 interpVel = Vector3.Lerp(from.Velocity, to.Velocity, t);
122 +
123 + long interpTime = from.TimestampMs + (long)((to.TimestampMs - from.TimestampMs) * t);
124 +
125 + return new EntityPositionSnapshot(
126 + new Vec3d(interpPos.X, interpPos.Y, interpPos.Z),
127 + new Vec3f(interpRot.Pitch, interpRot.Yaw, interpRot.Roll),
128 + interpTime,
129 + interpVel
130 + );
131 + }
132 + }
133 + }
Newer Older