From c00ee0e9e33f63a9084b01255523ca21ab9368d2 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Thu, 16 Jul 2026 01:06:07 +0100 Subject: [PATCH] Bind volume programs to authoritative document time --- .../org.gamecult.eve.unity-scene/README.md | 4 ++ .../Fields/EveUnityFieldsVolumeRenderer.cs | 42 +++++++++++++++++++ .../EveFieldsUnitySceneProjectionTests.cs | 30 +++++++++++++ .../org.gamecult.eve.unity-scene/package.json | 2 +- 4 files changed, 77 insertions(+), 1 deletion(-) diff --git a/packages/org.gamecult.eve.unity-scene/README.md b/packages/org.gamecult.eve.unity-scene/README.md index 84f394d..42ebd93 100644 --- a/packages/org.gamecult.eve.unity-scene/README.md +++ b/packages/org.gamecult.eve.unity-scene/README.md @@ -75,3 +75,7 @@ native scene and the provider volume through the same camera pipeline. Providers may advertise per-layer resolution scales, mipmap use, and filtering through `layerTargetDescriptors`; the Unity lowerer applies those native target requirements without assigning gameplay or product meaning to the layer keys. +`documentFloatBindings` maps standard document scalars to logical float ports as +`source=port,scale,offset`. This lets animated native programs consume +provider-authoritative simulation time without making the client clock an +authority. diff --git a/packages/org.gamecult.eve.unity-scene/Runtime/Fields/EveUnityFieldsVolumeRenderer.cs b/packages/org.gamecult.eve.unity-scene/Runtime/Fields/EveUnityFieldsVolumeRenderer.cs index c7e5c2a..52e26f3 100644 --- a/packages/org.gamecult.eve.unity-scene/Runtime/Fields/EveUnityFieldsVolumeRenderer.cs +++ b/packages/org.gamecult.eve.unity-scene/Runtime/Fields/EveUnityFieldsVolumeRenderer.cs @@ -237,6 +237,48 @@ namespace GameCult.Eve.UnityScene.Fields (float)((viewport.MinY + viewport.MaxY) * 0.5), (float)width, (float)height)); + foreach (var binding in ParseBindings(Prop(field, "documentFloatBindings"))) + { + if (TryEvaluateDocumentFloatBinding( + document, + binding.Key, + binding.Value, + out var port, + out var value)) + SetFloatPort(port, value); + } + } + + public static bool TryEvaluateDocumentFloatBinding( + EveFieldsSplatsDocument? document, + string source, + string descriptor, + out string port, + out float value) + { + port = ""; + value = 0f; + if (document == null) return false; + var values = (descriptor ?? "").Split(','); + if (values.Length != 3 || + string.IsNullOrWhiteSpace(values[0]) || + !TryFloat(values[1].Trim(), out var scale) || + !TryFloat(values[2].Trim(), out var offset)) + return false; + + double sourceValue; + switch ((source ?? "").Trim()) + { + case "simulationTimeSeconds": + sourceValue = document.SimulationTimeSeconds; + break; + default: + return false; + } + + port = values[0].Trim(); + value = (float)(sourceValue * scale + offset); + return float.IsFinite(value); } private void EnsureTargets(EveUnityFieldVolumeProjection field) diff --git a/packages/org.gamecult.eve.unity-scene/Tests/Editor/EveFieldsUnitySceneProjectionTests.cs b/packages/org.gamecult.eve.unity-scene/Tests/Editor/EveFieldsUnitySceneProjectionTests.cs index 1268480..3845648 100644 --- a/packages/org.gamecult.eve.unity-scene/Tests/Editor/EveFieldsUnitySceneProjectionTests.cs +++ b/packages/org.gamecult.eve.unity-scene/Tests/Editor/EveFieldsUnitySceneProjectionTests.cs @@ -137,6 +137,36 @@ namespace GameCult.Eve.UnityScene.Tests Assert.That(target.FilterMode, Is.EqualTo(FilterMode.Trilinear)); } + [Test] + public void VolumeRendererBindsAuthoritativeDocumentTimeToLogicalPort() + { + var document = new EveFieldsSplatsDocument { SimulationTimeSeconds = 12.5 }; + + Assert.That( + EveUnityFieldsVolumeRenderer.TryEvaluateDocumentFloatBinding( + document, + "simulationTimeSeconds", + "flowScroll,0.025,-0.1", + out var port, + out var value), + Is.True); + Assert.That(port, Is.EqualTo("flowScroll")); + Assert.That(value, Is.EqualTo(0.2125f).Within(0.00001f)); + } + + [Test] + public void VolumeRendererRejectsUnknownDocumentFloatSource() + { + Assert.That( + EveUnityFieldsVolumeRenderer.TryEvaluateDocumentFloatBinding( + new EveFieldsSplatsDocument(), + "unityTime", + "flowScroll,1,0", + out _, + out _), + Is.False); + } + [Test] public void PackageContainsGenericFieldsShader() { diff --git a/packages/org.gamecult.eve.unity-scene/package.json b/packages/org.gamecult.eve.unity-scene/package.json index 5f43b5f..a969c41 100644 --- a/packages/org.gamecult.eve.unity-scene/package.json +++ b/packages/org.gamecult.eve.unity-scene/package.json @@ -1,7 +1,7 @@ { "name": "org.gamecult.eve.unity-scene", "displayName": "Eve Unity Scene Lowering", - "version": "0.3.47", + "version": "0.3.48", "unity": "6000.0", "description": "Provider-agnostic Unity scene shell for gamecult.eve.surface.v1 interactive world surfaces.", "dependencies": {