using UnityEngine;
namespace MyInfoMate.Vr.Scene
{
///
/// Conversion glTF → Unity. Le seul endroit du projet où elle existe.
///
/// glTF est en main droite, Y-up, unités en mètres. Unity est en main
/// gauche. Passer de l'un à l'autre demande d'inverser un axe horizontal.
///
/// Le décor, lui, est converti par glTFast à l'import. Les coordonnées du
/// manifeste, elles, ne passent par aucun importeur. Si les deux conversions
/// ne sont pas la même, les objets placés sont en miroir par rapport au décor
/// — et c'est invisible sur une scène symétrique, donc découvert tard.
///
/// D'où : la valeur par défaut est celle que documente
/// glTFast, mais elle se vérifie avec calibration.glb (voir
/// ), elle ne se suppose pas. Si le test montre
/// un miroir, c'est cette seule ligne qui change.
///
public static class GltfSpace
{
public enum Convention
{
NegateX,
NegateZ
}
public static Convention Axis = Convention.NegateX;
public static Vector3 ToUnity(Vector3 p) =>
Axis == Convention.NegateX
? new Vector3(-p.x, p.y, p.z)
: new Vector3(p.x, p.y, -p.z);
///
/// Une réflexion inverse le sens des rotations : l'axe est réfléchi et
/// l'angle change de signe. Sur un quaternion, ça revient à inverser le signe
/// des deux composantes que la réflexion ne touche pas.
///
public static Quaternion ToUnity(Quaternion q) =>
Axis == Convention.NegateX
? new Quaternion(q.x, -q.y, -q.z, q.w)
: new Quaternion(-q.x, -q.y, q.z, q.w);
/// Les coordonnées du manifeste arrivent en tableaux JSON.
public static Vector3 Position(float[] v) => ToUnity(new Vector3(v[0], v[1], v[2]));
public static Quaternion Rotation(float[] q) =>
ToUnity(new Quaternion(q[0], q[1], q[2], q[3]));
/// L'échelle est invariante par réflexion — pas de conversion.
public static Vector3 Scale(float[] s) => new Vector3(s[0], s[1], s[2]);
}
}