Migrate Aetheria geometry ownership
This commit is contained in:
parent
04c0b77c94
commit
26948f81b6
6 changed files with 119 additions and 49 deletions
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Aetheria.State\Aetheria.State.csproj" />
|
||||
<ProjectReference Include="..\..\CultLib\src\GameCult.Geometry\GameCult.Geometry.csproj" />
|
||||
<ProjectReference Include="..\..\CultMath\src\CultMath\CultMath.csproj" />
|
||||
<Compile Include="..\Assets\Scripts\ServerShared\YmirPhysicsContracts.cs" Link="YmirPhysicsContracts.cs" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -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<YmirSphe
|
|||
.ToArray();
|
||||
}
|
||||
|
||||
static CultVec2 ToFixtureVec2(YmirVec2 value)
|
||||
static float2 ToFixtureVec2(YmirVec2 value)
|
||||
{
|
||||
return new CultVec2(value.x, value.y);
|
||||
return new float2(value.x, value.y);
|
||||
}
|
||||
|
||||
static CultVec3 ToFixtureVec3(YmirVec3 value)
|
||||
static float3 ToFixtureVec3(YmirVec3 value)
|
||||
{
|
||||
return new CultVec3(value.x, value.y, value.z);
|
||||
return new float3(value.x, value.y, value.z);
|
||||
}
|
||||
|
||||
static void VerifyCultMathVectorSerializationCompatibility()
|
||||
{
|
||||
var old2 = MessagePackSerializer.Serialize(new LegacyFixtureVec2(1.25f, -2.5f));
|
||||
var current2 = MessagePackSerializer.Serialize(new float2(1.25f, -2.5f));
|
||||
if (!old2.AsSpan().SequenceEqual(current2))
|
||||
throw new InvalidOperationException("CultMath.float2 changed the frozen MessagePack vector layout.");
|
||||
|
||||
var old3 = MessagePackSerializer.Serialize(new LegacyFixtureVec3(1.25f, -2.5f, 4.75f));
|
||||
var current3 = MessagePackSerializer.Serialize(new float3(1.25f, -2.5f, 4.75f));
|
||||
if (!old3.AsSpan().SequenceEqual(current3))
|
||||
throw new InvalidOperationException("CultMath.float3 changed the frozen MessagePack vector layout.");
|
||||
}
|
||||
|
||||
static YmirWorld YmirWorldOf(params YmirPhysicsBody[] bodies)
|
||||
|
|
@ -1143,6 +1163,52 @@ internal sealed class FreezeArtifact
|
|||
public string MessagePack { get; set; } = "";
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
internal readonly record struct LegacyFixtureVec2(
|
||||
[property: Key(0)] float x,
|
||||
[property: Key(1)] float y);
|
||||
|
||||
[MessagePackObject]
|
||||
internal readonly record struct LegacyFixtureVec3(
|
||||
[property: Key(0)] float x,
|
||||
[property: Key(1)] float y,
|
||||
[property: Key(2)] float z);
|
||||
|
||||
internal sealed class CultMathFloat2Formatter : IMessagePackFormatter<float2>
|
||||
{
|
||||
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<float3>
|
||||
{
|
||||
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<YmirFixtureSphereBody>();
|
||||
[Key(11)] public YmirFixtureCircleOverlapHit[] CircleOverlapHits { get; set; } = Array.Empty<YmirFixtureCircleOverlapHit>();
|
||||
|
|
@ -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; }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
<ProjectReference Include="$(CultLibRoot)\src\GameCult.Mesh\GameCult.Mesh.csproj" />
|
||||
<ProjectReference Include="$(CultLibRoot)\src\GameCult.Networking\GameCult.Networking.csproj" />
|
||||
<ProjectReference Include="..\..\CultMath\src\CultMath\CultMath.csproj" />
|
||||
<ProjectReference Include="$(CultLibRoot)\src\GameCult.Geometry\GameCult.Geometry.csproj" />
|
||||
<ProjectReference Include="$(EveUnityRoot)\packages\org.gamecult.eve.surface\GameCult.Eve.Surface.csproj"
|
||||
AdditionalProperties="CultLibRoot=$(CultLibRoot)" />
|
||||
<ProjectReference Include="..\..\EvePlugins\plugins\eve-plugin-fields\GameCult.Eve.PluginFields.csproj"
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
"com.unity.modules.uielements": "1.0.0",
|
||||
"com.unity.render-pipelines.universal": "17.4.0",
|
||||
"org.gamecult.cultlib": "https://github.com/GameCult/CultLib.git?path=/unity/org.gamecult.cultlib#cultlib-unity-v1.0.43",
|
||||
"org.gamecult.geometry": "file:../../CultLib/unity/org.gamecult.geometry",
|
||||
"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.2.3",
|
||||
"org.gamecult.eve.surface": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.surface#eveunity-surface-v0.2.4",
|
||||
"org.gamecult.eve.unity-scene": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.3.103",
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using CultMath;
|
||||
using GameCult.Geometry;
|
||||
using MessagePack;
|
||||
|
||||
#nullable enable
|
||||
|
|
@ -33,9 +34,9 @@ namespace GameCult.Aetheria.State.Verse
|
|||
public double MaxX { get; }
|
||||
public double MaxZ { get; }
|
||||
|
||||
public rect ToAetheriaXyRect()
|
||||
public CultRect ToAetheriaXyRect()
|
||||
{
|
||||
return new rect(
|
||||
return new CultRect(
|
||||
(float)MinX,
|
||||
(float)MinZ,
|
||||
(float)MaxX,
|
||||
|
|
@ -790,7 +791,7 @@ namespace GameCult.Aetheria.State.Verse
|
|||
|
||||
public static AetheriaRuntimeGravityInfluenceBrush[] QueryGravityInfluences(
|
||||
AetheriaRuntimeZoneSnapshotCommit? zone,
|
||||
rect viewport)
|
||||
CultRect viewport)
|
||||
{
|
||||
var brushes = new List<AetheriaRuntimeGravityInfluenceBrush>();
|
||||
QueryGravityInfluences(zone, viewport, brushes);
|
||||
|
|
@ -807,7 +808,7 @@ namespace GameCult.Aetheria.State.Verse
|
|||
|
||||
public static int QueryGravityInfluences(
|
||||
AetheriaRuntimeZoneSnapshotCommit? zone,
|
||||
rect viewport,
|
||||
CultRect viewport,
|
||||
List<AetheriaRuntimeGravityInfluenceBrush> 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<AetheriaRuntimeDaemonBodyView>();
|
||||
QueryBodyViews(zone, viewport, views);
|
||||
|
|
@ -930,15 +931,15 @@ namespace GameCult.Aetheria.State.Verse
|
|||
|
||||
public static int QueryBodyViews(
|
||||
AetheriaRuntimeZoneSnapshotCommit? zone,
|
||||
rect viewport,
|
||||
CultRect viewport,
|
||||
List<AetheriaRuntimeDaemonBodyView> views)
|
||||
{
|
||||
return QueryBodyViews(zone, (rect?)viewport, views);
|
||||
return QueryBodyViews(zone, (CultRect?)viewport, views);
|
||||
}
|
||||
|
||||
private static int QueryBodyViews(
|
||||
AetheriaRuntimeZoneSnapshotCommit? zone,
|
||||
rect? viewport,
|
||||
CultRect? viewport,
|
||||
List<AetheriaRuntimeDaemonBodyView> 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<int> 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<int>();
|
||||
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<int>();
|
||||
QueryPresentationEntityIndices(
|
||||
|
|
@ -1299,7 +1300,7 @@ namespace GameCult.Aetheria.State.Verse
|
|||
AetheriaRuntimeZoneSnapshotCommit? zone,
|
||||
int observerEntityIndex,
|
||||
double minimumInfoGathered,
|
||||
rect viewport,
|
||||
CultRect viewport,
|
||||
List<int> 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<int> entityIndices)
|
||||
{
|
||||
if (entityIndices == null) throw new ArgumentNullException(nameof(entityIndices));
|
||||
|
|
@ -1368,7 +1369,7 @@ namespace GameCult.Aetheria.State.Verse
|
|||
AetheriaRuntimeZoneSnapshotCommit? zone,
|
||||
IReadOnlyList<int>? controlledEntityIndices,
|
||||
double minimumInfoGathered,
|
||||
rect viewport)
|
||||
CultRect viewport)
|
||||
{
|
||||
var entityIndices = new List<int>();
|
||||
QueryObjectsViewportEntityIndices(zone, controlledEntityIndices, minimumInfoGathered, viewport, entityIndices);
|
||||
|
|
@ -1379,7 +1380,7 @@ namespace GameCult.Aetheria.State.Verse
|
|||
AetheriaRuntimeZoneSnapshotCommit? zone,
|
||||
IReadOnlyList<int>? controlledEntityIndices,
|
||||
double minimumInfoGathered,
|
||||
rect viewport,
|
||||
CultRect viewport,
|
||||
List<int> entityIndices)
|
||||
{
|
||||
if (entityIndices == null) throw new ArgumentNullException(nameof(entityIndices));
|
||||
|
|
@ -1454,7 +1455,7 @@ namespace GameCult.Aetheria.State.Verse
|
|||
AetheriaRuntimeZoneSnapshotCommit? zone,
|
||||
IReadOnlyList<int>? controlledEntityIndices,
|
||||
double minimumInfoGathered,
|
||||
rect viewport)
|
||||
CultRect viewport)
|
||||
{
|
||||
var entities = new List<AetheriaRuntimeDaemonObjectViewportEntity>();
|
||||
QueryObjectsViewport(zone, controlledEntityIndices, minimumInfoGathered, viewport, entities);
|
||||
|
|
@ -1465,7 +1466,7 @@ namespace GameCult.Aetheria.State.Verse
|
|||
AetheriaRuntimeZoneSnapshotCommit? zone,
|
||||
IReadOnlyList<int>? controlledEntityIndices,
|
||||
double minimumInfoGathered,
|
||||
rect viewport,
|
||||
CultRect viewport,
|
||||
List<AetheriaRuntimeDaemonObjectViewportEntity> 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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
"GameCult.Eve.Surface",
|
||||
"GameCult.Eve.PluginFields",
|
||||
"GameCult.Mesh",
|
||||
"GameCult.Geometry",
|
||||
"CultMath",
|
||||
"MessagePack"
|
||||
],
|
||||
|
|
|
|||
Loading…
Reference in a new issue