using System.Collections.Generic; using System.Linq; using System.Xml.Serialization; using UnityEngine; using static StageStatic; /// <summary> /// Attached to prefab Def_Stage /// </summary> public class StageBehaviour : MonoBehaviour { /// <summary> /// Re-loads <see cref="StageStatic.stage"/> to display all <see cref="Fact">Facts</see>. /// </summary> void Start() { StageStatic.LoadInitStage(true /*StageStatic.stage.player_record.solved*/, gameObject); } public static List<TriangleFact> GenerateMMTCollider(GameObject obj = null) { bool debug = false; var t0 = System.DateTime.Now; List<TriangleFact> tris = new(); foreach (MeshCollider coll in FindObjectsOfType<MeshCollider>()) { if (!coll.sharedMesh.isReadable) continue; for (int i = 0; i < coll.sharedMesh.triangles.Length; i += 3) { tris.Add(new( new[] { _Transform(coll.sharedMesh.vertices[coll.sharedMesh.triangles[i + 0]], coll.transform.localToWorldMatrix), _Transform(coll.sharedMesh.vertices[coll.sharedMesh.triangles[i + 1]], coll.transform.localToWorldMatrix), _Transform(coll.sharedMesh.vertices[coll.sharedMesh.triangles[i + 2]], coll.transform.localToWorldMatrix), }, null) ); } } if (debug && obj != null) { var t1 = System.DateTime.Now - t0; Debug.Log($"{tris.Count} Tris in {t1.Milliseconds}"); Mesh mesh = new() { indexFormat = UnityEngine.Rendering.IndexFormat.UInt32, vertices = tris.SelectMany(t => t.Verticies).ToArray(), triangles = Enumerable.Range(0, tris.Count * 3).ToArray(), }; mesh.Optimize(); mesh.RecalculateNormals(); MeshFilter filter = obj.GetComponent<MeshFilter>(); filter.sharedMesh = mesh; } return tris; Vector3 _Transform(Vector3 vert, Matrix4x4 toworld) { Vector4 h = toworld * new Vector4(vert.x, vert.y, vert.z, 1f); return new Vector3(h.x, h.y, h.z); } } /// <summary> /// Resets changes made by <see cref="StageStatic.stage"/> and frees ressources. /// </summary> private void OnDestroy() { StageStatic.SetMode(Mode.Play); // no Mode.Create // StageStatic.stage.solution.hardreset(invoke_event: false); NO! keep in memory! // StageStatic.stage?.factState.hardreset(invoke_event: false); also keep? } /// <summary> /// Wrapps <see cref="SetMode(Mode, GameObject)"/>. Needed as endpoint for unity buttons. /// </summary> /// <param name="create"><c>SetMode(create ? Mode.Create : Mode.Play);</c></param> public void SetMode(bool create) { SetMode(create ? Mode.Create : Mode.Play); } /// <summary> /// Wrapps <see cref="StageStatic.SetMode(Mode, GameObject)"/>. Defaulting <paramref name="obj"/> to <see cref="this.gameObject"/>. /// </summary> /// \copydetails StageStatic.SetMode(Mode, GameObject) public void SetMode(Mode mode, GameObject obj = null) { obj ??= gameObject; StageStatic.SetMode(mode, obj); } }