Newer
Older
Marco Zimmer
committed
using System.Collections.Generic;
Marco Zimmer
committed
using UnityEngine;
using static StageStatic;
/// <summary>
/// Attached to prefab Def_Stage
/// </summary>
Marco Zimmer
committed
public class StageBehaviour : MonoBehaviour
{
/// <summary>
/// Re-loads <see cref="StageStatic.stage"/> to display all <see cref="Fact">Facts</see>.
/// </summary>
Marco Zimmer
committed
{
StageStatic.LoadInitStage(true /*StageStatic.stage.player_record.solved*/, gameObject);
GenerateMMTCollider(gameObject);
Marco Zimmer
committed
}
public static List<TriangleFact> GenerateMMTCollider(GameObject obj = null)
{
bool debug = false;
var t0 = System.DateTime.Now;
List<TriangleFact> tris = new();
foreach (BoxCollider coll in FindObjectsOfType<BoxCollider>())
Vector3[] minmax = new Vector3[]
{
coll.center - coll.size/2,
coll.center + coll.size/2,
};
_QuadAdd(0, 1, 3, 2);
_QuadAdd(1, 5, 7, 3);
_QuadAdd(5, 4, 6, 7);
_QuadAdd(4, 0, 2, 6);
_QuadAdd(2, 3, 7, 6);
_QuadAdd(0, 4, 5, 1);
void _QuadAdd(uint i, uint j, uint k, uint l)
{
_TrisAdd(i, k, j);
_TrisAdd(k, i, l);
}
void _TrisAdd(uint i, uint j, uint k)
_Transform(new Vector3(minmax[i>>0&1][0], minmax[i>>1&1][1], minmax[i>>2&1][2]), coll.transform.localToWorldMatrix),
_Transform(new Vector3(minmax[j>>0&1][0], minmax[j>>1&1][1], minmax[j>>2&1][2]), coll.transform.localToWorldMatrix),
_Transform(new Vector3(minmax[k>>0&1][0], minmax[k>>1&1][1], minmax[k>>2&1][2]), coll.transform.localToWorldMatrix),
}));
//foreach (MeshCollider coll in FindObjectsOfType<MeshCollider>())
//{
// if (!UseMe(coll)
// || !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),
// })
// );
// }
//}
Debug.Log($"{tris.Count} Tris in {t1.Milliseconds}ms");
Mesh mesh = new()
{
indexFormat = UnityEngine.Rendering.IndexFormat.UInt32,
vertices = tris.SelectMany(t => t.Verticies).ToArray(),
triangles = Enumerable.Range(0, tris.Count * 3).ToArray(),
};
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);
}
bool UseMe(Collider coll) => true; //TODO: filter for what we want
/// <summary>
/// Resets changes made by <see cref="StageStatic.stage"/> and frees ressources.
/// </summary>
Marco Zimmer
committed
private void OnDestroy()
{
// StageStatic.stage.solution.hardreset(invoke_event: false); NO! keep in memory!
// StageStatic.stage?.factState.hardreset(invoke_event: false); also keep?
Marco Zimmer
committed
}
/// Wrapps <see cref="SetMode(Mode, GameObject)"/> for <see cref="Mode.Create"/>. Needed as endpoint for unity buttons.
public void SetModeCreate()
=> SetMode(Mode.Create);
/// <summary>
/// Wrapps <see cref="SetMode(Mode, GameObject)"/> for <see cref="Mode.Play"/>. Needed as endpoint for unity buttons.
/// </summary>
public void SetModePlay()
=> SetMode(Mode.Play);
Marco Zimmer
committed
/// <summary>
/// Wrapps <see cref="StageStatic.SetMode(Mode, GameObject)"/>. Defaulting <paramref name="obj"/> to <see cref="this.gameObject"/>.
/// </summary>
/// \copydetails StageStatic.SetMode(Mode, GameObject)
Marco Zimmer
committed
public void SetMode(Mode mode, GameObject obj = null)
{
obj ??= gameObject;
StageStatic.SetMode(mode, obj);
}
}