Created
May 31, 2025 22:46
-
-
Save mrkybe/efa70a9ddcba7b5bfe441dafce13e43c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Runtime.CompilerServices; | |
| using UnityEngine; | |
| // Marker Types | |
| public class WorldFrame { } | |
| public class GasFrame { } | |
| public class ShipFrame { } | |
| [Serializable] | |
| public readonly struct TVec3<TFrame> : IEquatable<TVec3<TFrame>> | |
| { | |
| // exactly the same memory layout as three floats: | |
| public readonly float x, y, z; | |
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | |
| public TVec3(float x, float y, float z) | |
| { | |
| this.x = x; | |
| this.y = y; | |
| this.z = z; | |
| } | |
| // zero-cost conversions: | |
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | |
| public static implicit operator Vector3(TVec3<TFrame> v) | |
| => new Vector3(v.x, v.y, v.z); | |
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | |
| public static explicit operator TVec3<TFrame>(Vector3 v) | |
| => new TVec3<TFrame>(v.x, v.y, v.z); | |
| // only same-frame math: | |
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | |
| public static TVec3<TFrame> operator +(TVec3<TFrame> a, TVec3<TFrame> b) | |
| => new TVec3<TFrame>(a.x + b.x, a.y + b.y, a.z + b.z); | |
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | |
| public static TVec3<TFrame> operator -(TVec3<TFrame> a, TVec3<TFrame> b) | |
| => new TVec3<TFrame>(a.x - b.x, a.y - b.y, a.z - b.z); | |
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | |
| public static TVec3<TFrame> operator *(TVec3<TFrame> v, float s) | |
| => new TVec3<TFrame>(v.x * s, v.y * s, v.z * s); | |
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | |
| public static TVec3<TFrame> operator /(TVec3<TFrame> v, float s) | |
| => new TVec3<TFrame>(v.x / s, v.y / s, v.z / s); | |
| // properties and utility methods: | |
| public float magnitude => MathF.Sqrt(x * x + y * y + z * z); | |
| public TVec3<TFrame> normalized | |
| => this / magnitude; | |
| public override string ToString() => $"{typeof(TFrame).Name}({x:F2},{y:F2},{z:F2})"; | |
| public bool Equals(TVec3<TFrame> other) | |
| => x == other.x && y == other.y && z == other.z; | |
| public override bool Equals(object obj) | |
| => obj is TVec3<TFrame> t && Equals(t); | |
| public override int GetHashCode() | |
| => HashCode.Combine(x, y, z); | |
| } | |
| public static class TypedVector3Extensions | |
| { | |
| /// <summary> | |
| /// Converts any TypedVector3<TFrame> from ship‐local into world coordinates. | |
| /// </summary> | |
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | |
| public static TVec3<ShipFrame> ToShip(this TVec3<WorldFrame> worldPos, SpaceShipMap shipMap) | |
| { | |
| return (TVec3<ShipFrame>)shipMap.transform.InverseTransformPoint(worldPos); | |
| } | |
| /// <summary> | |
| /// Converts any TypedVector3<TFrame> from ship‐local into world coordinates. | |
| /// </summary> | |
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | |
| public static TVec3<WorldFrame> ToWorld(this TVec3<ShipFrame> localPos, SpaceShipMap shipMap) | |
| { | |
| // assume SpaceShipMap.CellToWorld exists; swap in your actual method: | |
| Vector3 rawWorld = shipMap.transform.TransformPoint(localPos); | |
| // implicit cast back into TypedVector3<WorldFrame> | |
| return (TVec3<WorldFrame>)rawWorld; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
FWIW check out https://learn.microsoft.com/en-us/dotnet/standard/simd as such types have been expanded with many new method which improve gamedev UX as of recent versions.
As sad as it is, LLMs are really bad at writing performant C# code because they are skewed heavily by a lot of historically terrible code that lost relevance a decade ago. It's better off to ask it to think in Rust or C++ terms and then have it port that to C#. It helps to ask it to think like Stephen Toub as his name is seemed to be recognized best by the models and helps to bias them towards newer features quite consistently.