champions-of-luneraria/Assets/Luneraria/View/LuneSpace.cs
Martin Stickelbroeck 8a72cb165a U2B World Geometry
G1-Karte in Unity (Assets/Luneraria/Scenes/G1_Map.unity), reproduzierbar
gebaut aus dem Godot-Weltgenerator (gebacken), den FBX-Modellen aus U2A und der
Karte des C#-Kerns.

- tools/godot-golden/world_export.gd: backt Gelände (Raster, Farben, Lauf- und
  Standhöhen), Lanebeläge, Plattform, Brücke, Randsteine, Basen, Landmarken,
  Vegetation, Adern, Grottentreppen, Aufstellungsbereiche und Licht. Braucht
  einen echten Renderer (HEADLESS=0); prüft auf Headless-Einheitstransformationen.
- LuneWorldBuilder: Meshes (GUID-stabil), Szene, Licht, Himmel, Post-Processing,
  16 Türme, 2 Ancients und die Grotte aus LuneMap mit Teammaterialien.
- Materialsystem: Luneraria/Surface (Gelände, Kluft-Oberflächen, Fluss, Adern,
  Kristall, G2-Werte mit Teamvarianten und Vertex-AO) und Luneraria/Pad;
  LuneMaterialSet.Dress wie Godots dress.
- View-Assembly: LuneSpace (Unity = (-x, h, y)), LuneGround, LuneCameraMath,
  LuneBuildingView (Zustände intakt bis Ruine).
- Vergleichsbilder mit den Kameraeinstellungen der Godot-G2-Aufnahmen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 16:01:25 +02:00

67 lines
2.7 KiB
C#

using System;
using Luneraria.Core;
using UnityEngine;
namespace Luneraria.View
{
/// <summary>
/// Map and Godot coordinates in Unity. The core works on the map plane (x, y); Godot shows a
/// map point at (x, height, y) in a right-handed frame. Unity is left-handed, so x flips:
/// Unity = (-x, height, y). The FBX pipeline uses the same conversion (docs/port/U2-WORLD.md),
/// so models, world and camera line up, and the picture is Godot's, not its mirror image.
/// </summary>
public static class LuneSpace
{
public static Vector3 World(Vec2 map, float height)
{
return new Vector3(-map.X, height, map.Y);
}
public static Vec2 Map(Vector3 world)
{
return new Vec2(-world.x, world.z);
}
public static Vector3 FromGodot(Vector3 godot)
{
return new Vector3(-godot.x, godot.y, godot.z);
}
public static Vector3 Direction(Vec2 map)
{
return new Vector3(-map.X, 0f, map.Y);
}
/// <summary>Rotation that turns a model's front (+Z) towards a map direction.</summary>
public static Quaternion Facing(Vec2 direction)
{
Vector3 v = Direction(direction);
return v.sqrMagnitude < 1e-12f ? Quaternion.identity : Quaternion.LookRotation(v.normalized, Vector3.up);
}
/// <summary>The core's facing angle (atan2(dx, dy), Godot's rotation.y) as a rotation.</summary>
public static Quaternion Facing(double angle)
{
return Facing(new Vec2(Math.Sin(angle), Math.Cos(angle)));
}
/// <summary>
/// A Godot transform (basis columns x, y, z and origin, as written by the world bake) in
/// Unity: S M S with S = diag(-1, 1, 1). Returns position, rotation and scale; the bake
/// only contains rotations with positive scale along the basis axes.
/// </summary>
public static void FromGodot(float[] t, int offset, out Vector3 position, out Quaternion rotation, out Vector3 scale)
{
var x = new Vector3(t[offset + 0], t[offset + 1], t[offset + 2]);
var y = new Vector3(t[offset + 3], t[offset + 4], t[offset + 5]);
var z = new Vector3(t[offset + 6], t[offset + 7], t[offset + 8]);
// Columns of S B S: -(S bx), S by, S bz.
Vector3 ux = -FromGodot(x);
Vector3 uy = FromGodot(y);
Vector3 uz = FromGodot(z);
scale = new Vector3(ux.magnitude, uy.magnitude, uz.magnitude);
rotation = Quaternion.LookRotation(uz / Mathf.Max(scale.z, 1e-8f), uy / Mathf.Max(scale.y, 1e-8f));
position = FromGodot(new Vector3(t[offset + 9], t[offset + 10], t[offset + 11]));
}
}
}