diff --git a/Aetheria.State.Freeze/Aetheria.State.Freeze.csproj b/Aetheria.State.Freeze/Aetheria.State.Freeze.csproj
index 1e5102696..77ae79ca2 100644
--- a/Aetheria.State.Freeze/Aetheria.State.Freeze.csproj
+++ b/Aetheria.State.Freeze/Aetheria.State.Freeze.csproj
@@ -9,7 +9,7 @@
-
+
diff --git a/Aetheria.State.Freeze/Program.cs b/Aetheria.State.Freeze/Program.cs
index 249ea460d..be47c0585 100644
--- a/Aetheria.State.Freeze/Program.cs
+++ b/Aetheria.State.Freeze/Program.cs
@@ -2,11 +2,18 @@ using System.Diagnostics;
using System.Text.Json;
using System.Text.Json.Serialization;
using Aetheria.State;
-using GameCult.Geometry;
+using CultMath;
using GameCult.Aetheria.State.Verse;
using MessagePack;
+using MessagePack.Formatters;
+using MessagePack.Resolvers;
+MessagePackSerializer.DefaultOptions = MessagePackSerializerOptions.Standard.WithResolver(
+ CompositeResolver.Create(
+ new IMessagePackFormatter[] { new CultMathFloat2Formatter(), new CultMathFloat3Formatter() },
+ new IFormatterResolver[] { StandardResolver.Instance }));
var options = FreezeOptions.Parse(args);
+VerifyCultMathVectorSerializationCompatibility();
Directory.CreateDirectory(options.OutputDirectory);
Directory.CreateDirectory(Path.GetDirectoryName(options.StatePath) ?? ".");
@@ -841,14 +848,27 @@ static YmirFixtureSphereCastHit[] ToFixtureSphereCastHits(IReadOnlyList
+{
+ public void Serialize(ref MessagePackWriter writer, float2 value, MessagePackSerializerOptions options)
+ {
+ writer.WriteArrayHeader(2);
+ writer.Write(value.x);
+ writer.Write(value.y);
+ }
+
+ public float2 Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
+ {
+ var count = reader.ReadArrayHeader();
+ if (count != 2) throw new MessagePackSerializationException($"Expected float2 array length 2, got {count}.");
+ return new float2(reader.ReadSingle(), reader.ReadSingle());
+ }
+}
+
+internal sealed class CultMathFloat3Formatter : IMessagePackFormatter
+{
+ public void Serialize(ref MessagePackWriter writer, float3 value, MessagePackSerializerOptions options)
+ {
+ writer.WriteArrayHeader(3);
+ writer.Write(value.x);
+ writer.Write(value.y);
+ writer.Write(value.z);
+ }
+
+ public float3 Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
+ {
+ var count = reader.ReadArrayHeader();
+ if (count != 3) throw new MessagePackSerializationException($"Expected float3 array length 3, got {count}.");
+ return new float3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
+ }
+}
+
[MessagePackObject]
internal sealed class YmirQueryFixtureSet
{
@@ -1167,12 +1233,12 @@ internal sealed class YmirQueryFixturePayload
[Key(0)] public float? DeltaTime { get; set; }
[Key(1)] public float? Radius { get; set; }
[Key(2)] public float? Distance { get; set; }
- [Key(3)] public CultVec2? Center2 { get; set; }
- [Key(4)] public CultVec3? Center3 { get; set; }
- [Key(5)] public CultVec2? Origin2 { get; set; }
- [Key(6)] public CultVec3? Origin3 { get; set; }
- [Key(7)] public CultVec2? Direction2 { get; set; }
- [Key(8)] public CultVec3? Direction3 { get; set; }
+ [Key(3)] public float2? Center2 { get; set; }
+ [Key(4)] public float3? Center3 { get; set; }
+ [Key(5)] public float2? Origin2 { get; set; }
+ [Key(6)] public float3? Origin3 { get; set; }
+ [Key(7)] public float2? Direction2 { get; set; }
+ [Key(8)] public float3? Direction3 { get; set; }
[Key(9)] public YmirFixtureWorld? World { get; set; }
[Key(10)] public YmirFixtureSphereBody[] SphereBodies { get; set; } = Array.Empty();
[Key(11)] public YmirFixtureCircleOverlapHit[] CircleOverlapHits { get; set; } = Array.Empty();
@@ -1194,9 +1260,9 @@ internal sealed class YmirFixtureWorld
internal sealed class YmirFixtureBody
{
[Key(0)] public string Id { get; set; } = "";
- [Key(1)] public CultVec2 Position { get; set; }
- [Key(2)] public CultVec2 Velocity { get; set; }
- [Key(3)] public CultVec2 Direction { get; set; }
+ [Key(1)] public float2 Position { get; set; }
+ [Key(2)] public float2 Velocity { get; set; }
+ [Key(3)] public float2 Direction { get; set; }
[Key(4)] public float AngularVelocity { get; set; }
[Key(5)] public float Torque { get; set; }
[Key(6)] public float MomentOfInertia { get; set; }
@@ -1210,7 +1276,7 @@ internal sealed class YmirFixtureBody
internal sealed class YmirFixtureSphereBody
{
[Key(0)] public string Id { get; set; } = "";
- [Key(1)] public CultVec3 Position { get; set; }
+ [Key(1)] public float3 Position { get; set; }
[Key(2)] public float Radius { get; set; }
}
@@ -1218,7 +1284,7 @@ internal sealed class YmirFixtureSphereBody
internal sealed class YmirFixtureField
{
[Key(0)] public string Id { get; set; } = "";
- [Key(1)] public CultVec2 Position { get; set; }
+ [Key(1)] public float2 Position { get; set; }
[Key(2)] public float Strength { get; set; }
[Key(3)] public float Radius { get; set; }
}
@@ -1228,8 +1294,8 @@ internal sealed class YmirFixtureContact
{
[Key(0)] public string BodyA { get; set; } = "";
[Key(1)] public string BodyB { get; set; } = "";
- [Key(2)] public CultVec2 Point { get; set; }
- [Key(3)] public CultVec2 Normal { get; set; }
+ [Key(2)] public float2 Point { get; set; }
+ [Key(3)] public float2 Normal { get; set; }
[Key(4)] public float Penetration { get; set; }
[Key(5)] public float RelativeSpeed { get; set; }
}
@@ -1238,8 +1304,8 @@ internal sealed class YmirFixtureContact
internal sealed class YmirFixtureCircleOverlapHit
{
[Key(0)] public string BodyId { get; set; } = "";
- [Key(1)] public CultVec2 Point { get; set; }
- [Key(2)] public CultVec2 Normal { get; set; }
+ [Key(1)] public float2 Point { get; set; }
+ [Key(2)] public float2 Normal { get; set; }
[Key(3)] public float Penetration { get; set; }
[Key(4)] public float Distance { get; set; }
}
@@ -1248,8 +1314,8 @@ internal sealed class YmirFixtureCircleOverlapHit
internal sealed class YmirFixtureSphereOverlapHit
{
[Key(0)] public string BodyId { get; set; } = "";
- [Key(1)] public CultVec3 Point { get; set; }
- [Key(2)] public CultVec3 Normal { get; set; }
+ [Key(1)] public float3 Point { get; set; }
+ [Key(2)] public float3 Normal { get; set; }
[Key(3)] public float Penetration { get; set; }
[Key(4)] public float Distance { get; set; }
}
@@ -1258,8 +1324,8 @@ internal sealed class YmirFixtureSphereOverlapHit
internal sealed class YmirFixtureCircleCastHit
{
[Key(0)] public string BodyId { get; set; } = "";
- [Key(1)] public CultVec2 Point { get; set; }
- [Key(2)] public CultVec2 Normal { get; set; }
+ [Key(1)] public float2 Point { get; set; }
+ [Key(2)] public float2 Normal { get; set; }
[Key(3)] public float Distance { get; set; }
}
@@ -1267,8 +1333,8 @@ internal sealed class YmirFixtureCircleCastHit
internal sealed class YmirFixtureSphereCastHit
{
[Key(0)] public string BodyId { get; set; } = "";
- [Key(1)] public CultVec3 Point { get; set; }
- [Key(2)] public CultVec3 Normal { get; set; }
+ [Key(1)] public float3 Point { get; set; }
+ [Key(2)] public float3 Normal { get; set; }
[Key(3)] public float Distance { get; set; }
}
diff --git a/Aetheria.State/Aetheria.State.csproj b/Aetheria.State/Aetheria.State.csproj
index c323cf1fb..4664b628e 100644
--- a/Aetheria.State/Aetheria.State.csproj
+++ b/Aetheria.State/Aetheria.State.csproj
@@ -19,6 +19,7 @@
+
();
QueryGravityInfluences(zone, viewport, brushes);
@@ -807,7 +808,7 @@ namespace GameCult.Aetheria.State.Verse
public static int QueryGravityInfluences(
AetheriaRuntimeZoneSnapshotCommit? zone,
- rect viewport,
+ CultRect viewport,
List brushes)
{
if (brushes == null) throw new ArgumentNullException(nameof(brushes));
@@ -906,7 +907,7 @@ namespace GameCult.Aetheria.State.Verse
public static AetheriaRuntimeDaemonBodyView[] QueryBodyViews(
AetheriaRuntimeZoneSnapshotCommit? zone,
- rect viewport)
+ CultRect viewport)
{
var views = new List();
QueryBodyViews(zone, viewport, views);
@@ -930,15 +931,15 @@ namespace GameCult.Aetheria.State.Verse
public static int QueryBodyViews(
AetheriaRuntimeZoneSnapshotCommit? zone,
- rect viewport,
+ CultRect viewport,
List views)
{
- return QueryBodyViews(zone, (rect?)viewport, views);
+ return QueryBodyViews(zone, (CultRect?)viewport, views);
}
private static int QueryBodyViews(
AetheriaRuntimeZoneSnapshotCommit? zone,
- rect? viewport,
+ CultRect? viewport,
List views)
{
if (views == null) throw new ArgumentNullException(nameof(views));
@@ -1196,7 +1197,7 @@ namespace GameCult.Aetheria.State.Verse
AetheriaRuntimeZoneSnapshotCommit? zone,
int observerEntityIndex,
double minimumInfoGathered,
- rect viewport)
+ CultRect viewport)
{
var currentEntityIndex = TryParseEntityIndex(run?.CurrentEntityKey);
return QueryPresentationEntityIndices(
@@ -1223,7 +1224,7 @@ namespace GameCult.Aetheria.State.Verse
AetheriaRuntimeZoneSnapshotCommit? zone,
int observerEntityIndex,
double minimumInfoGathered,
- rect viewport,
+ CultRect viewport,
List entityIndices)
{
var currentEntityIndex = TryParseEntityIndex(run?.CurrentEntityKey);
@@ -1251,7 +1252,7 @@ namespace GameCult.Aetheria.State.Verse
AetheriaRuntimeZoneSnapshotCommit? zone,
int observerEntityIndex,
double minimumInfoGathered,
- rect viewport)
+ CultRect viewport)
{
var entityIndices = new List();
var currentEntityIndex = TryParseEntityIndex(currentEntityKey);
@@ -1270,7 +1271,7 @@ namespace GameCult.Aetheria.State.Verse
AetheriaRuntimeZoneSnapshotCommit? zone,
int observerEntityIndex,
double minimumInfoGathered,
- rect viewport)
+ CultRect viewport)
{
var entityIndices = new List();
QueryPresentationEntityIndices(
@@ -1299,7 +1300,7 @@ namespace GameCult.Aetheria.State.Verse
AetheriaRuntimeZoneSnapshotCommit? zone,
int observerEntityIndex,
double minimumInfoGathered,
- rect viewport,
+ CultRect viewport,
List entityIndices)
{
var currentEntityIndex = TryParseEntityIndex(currentEntityKey);
@@ -1317,7 +1318,7 @@ namespace GameCult.Aetheria.State.Verse
AetheriaRuntimeZoneSnapshotCommit? zone,
int observerEntityIndex,
double minimumInfoGathered,
- rect viewport,
+ CultRect viewport,
List entityIndices)
{
if (entityIndices == null) throw new ArgumentNullException(nameof(entityIndices));
@@ -1368,7 +1369,7 @@ namespace GameCult.Aetheria.State.Verse
AetheriaRuntimeZoneSnapshotCommit? zone,
IReadOnlyList? controlledEntityIndices,
double minimumInfoGathered,
- rect viewport)
+ CultRect viewport)
{
var entityIndices = new List();
QueryObjectsViewportEntityIndices(zone, controlledEntityIndices, minimumInfoGathered, viewport, entityIndices);
@@ -1379,7 +1380,7 @@ namespace GameCult.Aetheria.State.Verse
AetheriaRuntimeZoneSnapshotCommit? zone,
IReadOnlyList? controlledEntityIndices,
double minimumInfoGathered,
- rect viewport,
+ CultRect viewport,
List entityIndices)
{
if (entityIndices == null) throw new ArgumentNullException(nameof(entityIndices));
@@ -1454,7 +1455,7 @@ namespace GameCult.Aetheria.State.Verse
AetheriaRuntimeZoneSnapshotCommit? zone,
IReadOnlyList? controlledEntityIndices,
double minimumInfoGathered,
- rect viewport)
+ CultRect viewport)
{
var entities = new List();
QueryObjectsViewport(zone, controlledEntityIndices, minimumInfoGathered, viewport, entities);
@@ -1465,7 +1466,7 @@ namespace GameCult.Aetheria.State.Verse
AetheriaRuntimeZoneSnapshotCommit? zone,
IReadOnlyList? controlledEntityIndices,
double minimumInfoGathered,
- rect viewport,
+ CultRect viewport,
List entities)
{
if (entities == null) throw new ArgumentNullException(nameof(entities));
@@ -1761,7 +1762,7 @@ namespace GameCult.Aetheria.State.Verse
foreach (var brush in QueryGravityInfluences(
zone,
- new rect((float)positionX, (float)positionZ, (float)positionX, (float)positionZ)))
+ new CultRect((float)positionX, (float)positionZ, (float)positionX, (float)positionZ)))
{
var dx = positionX - brush.CenterX;
var dz = positionZ - brush.CenterZ;
@@ -1896,7 +1897,7 @@ namespace GameCult.Aetheria.State.Verse
return source;
}
- private static bool IntersectsCircle(rect viewport, double centerX, double centerY, double radius)
+ private static bool IntersectsCircle(CultRect viewport, double centerX, double centerY, double radius)
{
if (radius <= 0)
return false;
@@ -1918,12 +1919,12 @@ namespace GameCult.Aetheria.State.Verse
return ContainsPoint(rect.ToAetheriaXyRect(), x, z);
}
- private static bool ContainsPoint(rect viewport, double x, double y)
+ private static bool ContainsPoint(CultRect viewport, double x, double y)
{
return viewport.Contains(new float2((float)x, (float)y));
}
- private static rect ToRuntimeRect(AetheriaRuntimeXzRect unityViewport)
+ private static CultRect ToRuntimeRect(AetheriaRuntimeXzRect unityViewport)
{
return unityViewport.ToAetheriaXyRect();
}
diff --git a/Packages/org.gamecult.aetheria.state/Runtime/GameCult.Aetheria.State.Unity.asmdef b/Packages/org.gamecult.aetheria.state/Runtime/GameCult.Aetheria.State.Unity.asmdef
index 5b9752053..4433f1de6 100644
--- a/Packages/org.gamecult.aetheria.state/Runtime/GameCult.Aetheria.State.Unity.asmdef
+++ b/Packages/org.gamecult.aetheria.state/Runtime/GameCult.Aetheria.State.Unity.asmdef
@@ -5,6 +5,7 @@
"GameCult.Eve.Surface",
"GameCult.Eve.PluginFields",
"GameCult.Mesh",
+ "GameCult.Geometry",
"CultMath",
"MessagePack"
],