95 lines
3.1 KiB
C#
95 lines
3.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Runtime.InteropServices;
|
|
using UnityEngine;
|
|
|
|
namespace CultMath.Unity;
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public readonly struct PlanetaryPageInputGpu
|
|
{
|
|
public PlanetaryPageInputGpu(Vector4 directionRadius, Vector4 sampling)
|
|
{
|
|
DirectionRadius = directionRadius;
|
|
Sampling = sampling;
|
|
}
|
|
|
|
public readonly Vector4 DirectionRadius;
|
|
public readonly Vector4 Sampling;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public readonly struct PlanetaryPageMetadataGpu
|
|
{
|
|
public PlanetaryPageMetadataGpu(Vector4 address, Vector4 layout, Vector4 bounds, Vector4 state)
|
|
{
|
|
Address = address;
|
|
Layout = layout;
|
|
Bounds = bounds;
|
|
State = state;
|
|
}
|
|
|
|
public readonly Vector4 Address;
|
|
public readonly Vector4 Layout;
|
|
public readonly Vector4 Bounds;
|
|
public readonly Vector4 State;
|
|
}
|
|
|
|
public readonly struct PlanetaryPageUpload
|
|
{
|
|
public PlanetaryPageUpload(
|
|
PlanetaryPageInputGpu[] inputs,
|
|
PlanetaryPageMetadataGpu[] metadata,
|
|
int outputSampleCount,
|
|
ulong contentVersion,
|
|
ulong presentationVersion)
|
|
{
|
|
Inputs = inputs;
|
|
Metadata = metadata;
|
|
OutputSampleCount = outputSampleCount;
|
|
ContentVersion = contentVersion;
|
|
PresentationVersion = presentationVersion;
|
|
}
|
|
|
|
public PlanetaryPageInputGpu[] Inputs { get; }
|
|
public PlanetaryPageMetadataGpu[] Metadata { get; }
|
|
public int OutputSampleCount { get; }
|
|
public ulong ContentVersion { get; }
|
|
public ulong PresentationVersion { get; }
|
|
}
|
|
|
|
public static class PlanetaryPageUploadBuilder
|
|
{
|
|
public static PlanetaryPageUpload Build(
|
|
in PlanetaryResidencySnapshot snapshot,
|
|
int interiorSize,
|
|
int borderSize,
|
|
float radius)
|
|
{
|
|
if (!float.IsFinite(radius) || radius <= 0) throw new ArgumentOutOfRangeException(nameof(radius));
|
|
var inputs = new List<PlanetaryPageInputGpu>();
|
|
var metadata = new PlanetaryPageMetadataGpu[snapshot.Tiles.Length];
|
|
foreach (var (resident, pageIndex) in snapshot.Tiles.Select((resident, index) => (resident, index)))
|
|
{
|
|
var layout = new PlanetaryPageLayout(resident.Tile, interiorSize, borderSize).Validate();
|
|
var content = PlanetaryGpuPageBuilder.BuildContent(layout, radius);
|
|
var outputOffset = inputs.Count;
|
|
foreach (var input in content.Inputs)
|
|
{
|
|
inputs.Add(new(
|
|
ToUnity(input.DirectionRadius),
|
|
ToUnity(input.Sampling)));
|
|
}
|
|
var commonMetadata = PlanetaryGpuPageBuilder.Metadata(content, outputOffset, resident.Blend);
|
|
metadata[pageIndex] = new(
|
|
ToUnity(commonMetadata.Address),
|
|
ToUnity(commonMetadata.Layout),
|
|
ToUnity(commonMetadata.Bounds),
|
|
ToUnity(commonMetadata.State));
|
|
}
|
|
return new(inputs.ToArray(), metadata, inputs.Count, snapshot.ContentVersion, snapshot.PresentationVersion);
|
|
}
|
|
|
|
private static Vector4 ToUnity(float4 value) => new(value.x, value.y, value.z, value.w);
|
|
}
|