Add provider-independent Unity fields capture

This commit is contained in:
Meta Vens 2026-07-10 15:59:20 +01:00
commit 093eb80d6c
4 changed files with 80 additions and 3 deletions

View file

@ -8,7 +8,7 @@
"org.gamecult.cultlib": "https://github.com/GameCult/CultLib.git?path=/unity/org.gamecult.cultlib#cultlib-unity-source-v1.0.3-r2",
"org.gamecult.eve.plugin-fields": "https://github.com/GameCult/EvePlugins.git?path=/plugins/eve-plugin-fields/unity/org.gamecult.eve.plugin-fields#eve-plugin-fields-unity-v0.1.1",
"org.gamecult.eve.surface": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.surface#eveunity-surface-v0.1.0",
"org.gamecult.eve.unity-scene": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.1.3",
"org.gamecult.eve.unity-scene": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.1.4",
"org.gamecult.eve.unity-uitoolkit": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-uitoolkit#eveunity-uitoolkit-v0.1.0"
},
"testables": [

View file

@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using GameCult.Eve.PluginFields;
using GameCult.Eve.UnityScene.Fields;
using NUnit.Framework;
@ -37,5 +38,75 @@ namespace GameCult.Eve.UnityScene.Tests
Assert.That(render.GetParameters()[0].ParameterType, Is.EqualTo(typeof(IEveFieldsSplatsDocument)));
Assert.That(typeof(EveFieldsSplatLayerRenderer).GetField("GlobalTextureName"), Is.Null);
}
[Test]
public void RasterizerProducesProviderIndependentFieldsCapture()
{
var host = new GameObject("eve-fields-capture");
var rasterizer = host.AddComponent<EveFieldsSplatRasterizer>();
var output = rasterizer.Render(new CaptureDocument(), 64, 64);
Assert.That(output, Is.Not.Null);
var previous = RenderTexture.active;
RenderTexture.active = output;
var readback = new Texture2D(64, 64, TextureFormat.RGBAFloat, false, true);
readback.ReadPixels(new Rect(0, 0, 64, 64), 0, 0);
readback.Apply();
RenderTexture.active = previous;
Assert.That(readback.GetPixels().Any(pixel => pixel.r > 0.01f), Is.True);
var outputPath = Path.GetFullPath(Path.Combine(Application.dataPath, "../../artifacts/fields-surface/latest/unity-fields.png"));
Directory.CreateDirectory(Path.GetDirectoryName(outputPath));
File.WriteAllBytes(outputPath, readback.EncodeToPNG());
UnityEngine.Object.DestroyImmediate(readback);
UnityEngine.Object.DestroyImmediate(host);
}
private sealed class CaptureDocument : IEveFieldsSplatsDocument
{
public string Schema => EveFieldsSchemas.Splats;
public long FrameId => 1;
public double SimulationTimeSeconds => 0;
public IEveFieldsViewport Viewport { get; } = new CaptureViewport();
public IReadOnlyList<IEveFieldsSplatLayer> Layers { get; } = Array.Empty<IEveFieldsSplatLayer>();
public IEveFieldsSplatSoa Splats { get; } = new CaptureSplats();
}
private sealed class CaptureViewport : IEveFieldsViewport
{
public double MinX => -1;
public double MinY => -1;
public double MaxX => 1;
public double MaxY => 1;
}
private sealed class CaptureSplats : IEveFieldsSplatSoa
{
private static readonly double[] One = { 1d };
private static readonly double[] Zero = { 0d };
private static readonly int[] ZeroInt = { 0 };
public int Count => 1;
public IReadOnlyList<double> CenterX => Zero;
public IReadOnlyList<double> CenterY => Zero;
public IReadOnlyList<double> HalfExtentX => One;
public IReadOnlyList<double> HalfExtentY => One;
public IReadOnlyList<double> RotationCos => One;
public IReadOnlyList<double> RotationSin => Zero;
public IReadOnlyList<int> Channel => ZeroInt;
public IReadOnlyList<int> Falloff => ZeroInt;
public IReadOnlyList<double> ValueR => One;
public IReadOnlyList<double> ValueG => Zero;
public IReadOnlyList<double> ValueB => Zero;
public IReadOnlyList<double> ValueA => One;
public IReadOnlyList<string> SourceKey { get; } = new[] { "capture" };
public IReadOnlyList<int> LayerIndex => ZeroInt;
public IReadOnlyList<int> SourceKind => ZeroInt;
public IReadOnlyList<double> FrequencyX => One;
public IReadOnlyList<double> FrequencyY => One;
public IReadOnlyList<double> PhaseX => Zero;
public IReadOnlyList<double> PhaseY => Zero;
public IReadOnlyList<double> AnimationSpeed => Zero;
public IReadOnlyList<double> SourceFlags => Zero;
}
}
}

View file

@ -45,7 +45,13 @@
"field.surface2d",
"gravity.surface"
],
"projectionAdapter": "EveFieldsSplatRasterizer"
"projectionAdapter": "EveFieldsSplatRasterizer",
"evidencePaths": [
"Runtime/Fields/EveFieldsSplatRasterizer.cs",
"Runtime/Fields/EveFieldsSplatLayerRenderer.cs",
"Tests/Editor/EveFieldsUnitySceneProjectionTests.cs",
"artifacts/fields-surface/latest/unity-fields.png"
]
},
{
"pluginId": "sai.vn",

View file

@ -1,7 +1,7 @@
{
"name": "org.gamecult.eve.unity-scene",
"displayName": "Eve Unity Scene Lowering",
"version": "0.1.3",
"version": "0.1.4",
"unity": "2021.3",
"description": "Provider-agnostic Unity scene shell for gamecult.eve.surface.v1 interactive world surfaces.",
"dependencies": {