Fully working Replay in Observation Scene
This commit is contained in:
+3973
-162
File diff suppressed because it is too large
Load Diff
@@ -2,11 +2,10 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System;
|
||||
using System.Reactive;
|
||||
using UnityEngine.UI;
|
||||
using Postgrest;
|
||||
using Cysharp.Threading.Tasks;
|
||||
|
||||
namespace GhostSystem
|
||||
{
|
||||
@@ -40,6 +39,8 @@ namespace GhostSystem
|
||||
private bool sceneIdReady = false;
|
||||
private string loadedSceneId;
|
||||
|
||||
private DateTime latestLoadedTimestamp;
|
||||
|
||||
[Serializable]
|
||||
public class TrackedObjectBinding
|
||||
{
|
||||
@@ -72,59 +73,106 @@ namespace GhostSystem
|
||||
TryInitializeReplay();
|
||||
}
|
||||
|
||||
private async void TryInitializeReplay()
|
||||
private async UniTaskVoid TryInitializeReplay()
|
||||
{
|
||||
if (!supabaseReady || !sceneIdReady) return;
|
||||
|
||||
SceneId = loadedSceneId;
|
||||
|
||||
await LoadFrames();
|
||||
await LoadAllFrames();
|
||||
StartReplay();
|
||||
_ = PeriodicUpdateFrames();
|
||||
}
|
||||
|
||||
public async Task LoadFrames()
|
||||
public async UniTask LoadAllFrames()
|
||||
{
|
||||
Debug.Log("SceneId used in query: " + SceneId);
|
||||
Debug.Log("StartTime filter: " + dateSelector.selectedDateTime().ToString("o"));
|
||||
|
||||
objectTracks.Clear();
|
||||
int batchSize = 1000;
|
||||
int offset = 0;
|
||||
bool more = true;
|
||||
List<FrameModel> allFrames = new();
|
||||
|
||||
while (more)
|
||||
{
|
||||
var query = SupabaseManager.instance.supabase
|
||||
.From<FrameModel>()
|
||||
.Filter("scene_id", Postgrest.Constants.Operator.Equals, SceneId)
|
||||
.Filter("timestamp", Postgrest.Constants.Operator.GreaterThanOrEqual, dateSelector.selectedDateTime().ToString("o"))
|
||||
.Order("timestamp", Postgrest.Constants.Ordering.Ascending)
|
||||
.Limit(batchSize) // Limit, wie viele Frames in einem Batch geladen werden. (Standardmäßig 1000)
|
||||
.Offset(offset); // Um zu wissen, wo der nçhste Batch anfängt
|
||||
|
||||
if (!string.IsNullOrEmpty(UserFilter))
|
||||
query = query.Filter("user_id", Postgrest.Constants.Operator.Equals, UserFilter);
|
||||
|
||||
var result = await query.Get();
|
||||
if (result.Models.Count == 0) break;
|
||||
allFrames.AddRange(result.Models);
|
||||
offset += batchSize;
|
||||
more = result.Models.Count == batchSize;
|
||||
}
|
||||
|
||||
foreach (var frame in allFrames)
|
||||
{
|
||||
if (!objectTracks.ContainsKey(frame.ObjectId))
|
||||
objectTracks[frame.ObjectId] = new List<FrameModel>();
|
||||
objectTracks[frame.ObjectId].Add(frame);
|
||||
}
|
||||
|
||||
if (allFrames.Count > 1)
|
||||
{
|
||||
latestLoadedTimestamp = allFrames.Last().TimestampParsed;
|
||||
totalDuration = (float)(latestLoadedTimestamp - allFrames.First().TimestampParsed).TotalSeconds;
|
||||
firstTimestamp = allFrames.First().TimestampParsed.ToLongTimeString();
|
||||
lastTimestamp = latestLoadedTimestamp.ToLongTimeString();
|
||||
}
|
||||
|
||||
Debug.LogWarning($"Loaded {allFrames.Count} frames across {objectTracks.Count} objects.");
|
||||
}
|
||||
|
||||
private async UniTaskVoid PeriodicUpdateFrames() // lädt alle 10 s neue Frames nach, falls verfügbar
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
await UniTask.Delay(TimeSpan.FromSeconds(10));
|
||||
await LoadNewFramesAfter(latestLoadedTimestamp);
|
||||
}
|
||||
}
|
||||
|
||||
private async UniTask LoadNewFramesAfter(DateTime afterTime) // lädt einen neuen Batch nach.
|
||||
{
|
||||
var query = SupabaseManager.instance.supabase
|
||||
.From<FrameModel>()
|
||||
.Filter("scene_id", Postgrest.Constants.Operator.Equals, SceneId)
|
||||
.Filter("timestamp", Postgrest.Constants.Operator.GreaterThan, afterTime.ToString("o"))
|
||||
.Order("timestamp", Postgrest.Constants.Ordering.Ascending);
|
||||
|
||||
if (!string.IsNullOrEmpty(UserFilter))
|
||||
query = query.Filter("user_id", Postgrest.Constants.Operator.Equals, UserFilter);
|
||||
|
||||
var result = await query.Get();
|
||||
var frames = result.Models;
|
||||
Debug.LogError("Frames: " + frames.Count);
|
||||
var newFrames = result.Models;
|
||||
|
||||
objectTracks.Clear();
|
||||
foreach (var frame in frames)
|
||||
foreach (var frame in newFrames)
|
||||
{
|
||||
if (!objectTracks.ContainsKey(frame.ObjectId))
|
||||
objectTracks[frame.ObjectId] = new List<FrameModel>();
|
||||
|
||||
objectTracks[frame.ObjectId].Add(frame);
|
||||
//Debug.Log($"Loaded frame: {frame.ObjectId} at {frame.Timestamp}");
|
||||
Debug.Log($"Loaded frame: {frame.ObjectId} at {frame.TimestampParsed} Pos: {frame.Position}");
|
||||
Debug.Log($"Parsed timestamp: {frame.Timestamp} -> {frame.TimestampParsed.ToString("o")}" + "Pos JSON: " + frame.PositionJson);
|
||||
|
||||
}
|
||||
Debug.LogWarning("Got the Data!");
|
||||
Debug.LogWarning(objectTracks.Count);
|
||||
|
||||
// Gesamtzeit berechnen (in Sekunden)
|
||||
if (frames.Count > 1)
|
||||
if (newFrames.Count > 0)
|
||||
{
|
||||
totalDuration = (float)(frames.Last().TimestampParsed - frames.First().TimestampParsed).TotalSeconds;
|
||||
firstTimestamp = frames.First().TimestampParsed.ToLongTimeString();
|
||||
lastTimestamp = frames.Last().TimestampParsed.ToLongTimeString();
|
||||
latestLoadedTimestamp = newFrames.Last().TimestampParsed;
|
||||
totalDuration = (float)(latestLoadedTimestamp - objectTracks.Values.SelectMany(f => f).First().TimestampParsed).TotalSeconds;
|
||||
}
|
||||
|
||||
Debug.Log($"Appended {newFrames.Count} new frames.");
|
||||
}
|
||||
|
||||
|
||||
public void StartReplay() // Für das Play UI-Element, um das Replay zu starten
|
||||
{
|
||||
isPlaying = true;
|
||||
@@ -147,8 +195,7 @@ namespace GhostSystem
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!isPlaying || objectTracks.Count == 0)
|
||||
return;
|
||||
if (!isPlaying || objectTracks.Count == 0) return;
|
||||
|
||||
playbackTime += Time.deltaTime * PlaybackSpeed;
|
||||
|
||||
@@ -166,12 +213,10 @@ namespace GhostSystem
|
||||
|
||||
foreach (var binding in TrackedObjects)
|
||||
{
|
||||
if (!objectTracks.ContainsKey(binding.objectId))
|
||||
continue;
|
||||
if (!objectTracks.ContainsKey(binding.objectId)) continue;
|
||||
|
||||
var frames = objectTracks[binding.objectId];
|
||||
if (frames.Count < 2)
|
||||
continue;
|
||||
if (frames.Count < 2) continue;
|
||||
|
||||
FrameModel a = null, b = null;
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ public class DateSelector : MonoBehaviour
|
||||
|
||||
public void SetYear(int yearIndex)
|
||||
{
|
||||
selectedYear = yearIndex; // Achtung: ggf. +Offset je nach Dropdown-Inhalt
|
||||
selectedYear = yearIndex + 2025; // Achtung: ggf. +Offset je nach Dropdown-Inhalt
|
||||
}
|
||||
|
||||
public void SetMonth(int monthIndex)
|
||||
@@ -33,7 +33,7 @@ public class DateSelector : MonoBehaviour
|
||||
|
||||
public void SetMinute(int minuteIndex)
|
||||
{
|
||||
selectedMinute = minuteIndex; // 0–59
|
||||
selectedMinute = minuteIndex * 5; // 0–59
|
||||
}
|
||||
public DateTime selectedDateTime()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user