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>
67 lines
2.7 KiB
C#
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]));
|
|
}
|
|
}
|
|
}
|