Select Git revision
JSONManager.cs
-
Marco Zimmer authoredMarco Zimmer authored
FactSpawner.cs 18.87 KiB
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using TMPro;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.ProBuilder.Shapes;
using static CommunicationEvents;
public class FactSpawner : MonoBehaviour
{
public GameObject
TestPoint,
Line,
Ray,
Angle,
Ring,
Prism,
Cone,
Rectangle,
Circle,
SimpleCircle,
Triangle,
Sphere,
ActualSphere,
Cuboid,
TriangularPrism,
Cylinder,
Pyramid
;
private void OnEnable()
{
AddFactEvent.AddListener(SpawnFactRepresentation);
AnimateNonExistingFactEvent.AddListener(AnimateNonExistingFactTrigger);
StartT0Event.AddListener(AnimateFunctionCalls);
}
private void OnDisable()
{
AddFactEvent.RemoveListener(SpawnFactRepresentation);
AnimateNonExistingFactEvent.RemoveListener(AnimateNonExistingFactTrigger);
StartT0Event.RemoveListener(AnimateFunctionCalls);
}
public void SpawnFactRepresentation(Fact fact)
{
switch (fact)
{
case PointFact PointFact:
SpawnPoint(PointFact); break;
case TestPointFact TestPointFact:
SpawnTestPoint(TestPointFact); break;
case LineFact LineFact:
SpawnLine(LineFact); break;
//case RightAngleFact AngleFact: //needed for Hint System
case AbstractAngleFact AngleFact:
SpawnAngle(AngleFact); break;
case RayFact RayFact:
SpawnRay(RayFact); break;
case CircleFact CircleFact:
SpawnRingAndCircle(CircleFact); break;
case QuadFact QuadFact:
SpawnQuad(QuadFact); break;
case TriangleFact TrisFact:
SpawnTris(TrisFact); break;
case ConeVolumeFact ConeVolumeFact:
SpawnCone(ConeVolumeFact); break;
case TruncatedConeVolumeFact TruncatedConeVolumeFact:
SpawnTruncatedCone(TruncatedConeVolumeFact); break;
case RectangleFact rectangleFact:
SpawnRectangle(rectangleFact); break;
case SimpleCircleFact simpleCircleFact:
SpawnSimpleCircle(simpleCircleFact); break;
case TriangleFact2 triangleFact:
SpawnTriangle(triangleFact); break;
case SphereFact sphereFact:
SpawnSphere(sphereFact); break;
case CuboidFact cuboidFact:
SpawnCuboid(cuboidFact); break;
case PrismFact prismFact:
SpawnTriangularPrism(prismFact); break;
case CylinderFact cylinderFact:
SpawnCylinderFact(cylinderFact); break;
case PyramidFact pyramidFact:
SpawnPyramid(pyramidFact); break;
default: break;
};
}
public void SpawnCuboid(CuboidFact fact){
GameObject cuboid = GameObject.Instantiate(Cuboid);
fact.WorldRepresentation = cuboid.GetComponent<FactObject3D>();
fact.WorldRepresentation.Fact = fact;
cuboid.transform.SetPositionAndRotation(fact.Position, fact.Rotation);
cuboid.transform.localScale = Vector3.Scale(cuboid.transform.localScale, fact.LocalScale);
cuboid.GetComponentInChildren<TextMeshPro>().text = fact.GetLabel(StageStatic.stage.factState) + " = " + System.Math.Round(fact.Volume, 2) + "m³";
}
public void SpawnCylinderFact(CylinderFact fact){
GameObject cylinder = GameObject.Instantiate(Cylinder);
fact.WorldRepresentation = cylinder.GetComponent<FactObject3D>();
fact.WorldRepresentation.Fact = fact;
cylinder.transform.SetPositionAndRotation(fact.Position, fact.Rotation);
cylinder.transform.localScale = Vector3.Scale(cylinder.transform.localScale, fact.LocalScale);
cylinder.GetComponentInChildren<TextMeshPro>().text = fact.GetLabel(StageStatic.stage.factState) + " = " + System.Math.Round(fact.Volume, 2) + "m³";
}
public void SpawnSphere(SphereFact fact){
GameObject sphere = GameObject.Instantiate(ActualSphere);
fact.WorldRepresentation = sphere.GetComponent<FactObject3D>();
fact.WorldRepresentation.Fact = fact;
sphere.transform.SetPositionAndRotation(fact.Position, Quaternion.identity);
sphere.transform.localScale = Vector3.Scale(sphere.transform.localScale, fact.LocalScale);
sphere.GetComponentInChildren<TextMeshPro>().text = fact.GetLabel(StageStatic.stage.factState) + " = " + System.Math.Round(fact.Volume, 2) + "m³";
}
public void SpawnRectangle(RectangleFact fact){
GameObject rectangle = GameObject.Instantiate(Rectangle);
rectangle.transform.SetPositionAndRotation(fact.Position, fact.Rotation);
rectangle.transform.localScale = Vector3.Scale(rectangle.transform.localScale, fact.LocalScale);
rectangle.GetComponentInChildren<TextMeshPro>().text = fact.GetLabel(StageStatic.stage.factState) + " = " + System.Math.Round(fact.Area, 2) + "m²";
}
public void SpawnSimpleCircle(SimpleCircleFact fact){
GameObject simpleCircle = GameObject.Instantiate(SimpleCircle);
simpleCircle.transform.SetPositionAndRotation(fact.Position, fact.Rotation);
simpleCircle.transform.localScale = Vector3.Scale(simpleCircle.transform.localScale, fact.LocalScale);
}
public void SpawnTriangle(TriangleFact2 fact)
{
GameObject triangle = GameObject.Instantiate(Triangle);
fact.WorldRepresentation = triangle.GetComponent<FactObject3D>();
fact.WorldRepresentation.Fact = fact;
triangle.transform.SetPositionAndRotation(fact.Position, fact.Rotation);
// triangle.transform.localScale = Vector3.Scale(triangle.transform.localScale, fact.LocalScale);
triangle.GetComponentInChildren<TextMeshPro>().text = fact.GetLabel(StageStatic.stage.factState) + " = " + System.Math.Round(fact.Area, 2) + "m²";
TriangleGenerator[] triangelGenerators = triangle.GetComponentsInChildren<TriangleGenerator>();
foreach (var gen in triangelGenerators)
{
gen.ab = Vector3.Distance(fact.A, fact.B);
gen.height = Vector3.Distance(fact.c, fact.C);
gen.c = fact.cPosition;
}
}
public void SpawnTriangularPrism(PrismFact fact)
{
GameObject prism = GameObject.Instantiate(TriangularPrism);
fact.WorldRepresentation = prism.GetComponent<FactObject3D>();
fact.WorldRepresentation.Fact = fact;
prism.transform.SetPositionAndRotation(fact.Position, fact.Rotation);
// triangle.transform.localScale = Vector3.Scale(triangle.transform.localScale, fact.LocalScale);
prism.GetComponentInChildren<TextMeshPro>().text = fact.GetLabel(StageStatic.stage.factState) + " = " + System.Math.Round(fact.Volume, 2) + "m³";
TriangluarPrismGenerator[] triangelGenerators = prism.GetComponentsInChildren<TriangluarPrismGenerator>();
foreach (var gen in triangelGenerators)
{
gen.triangle_ab = Vector3.Distance(fact.A, fact.B);
gen.triangle_height = Vector3.Distance(fact.c, fact.C);
gen.triangle_c = fact.cPosition;
gen.prism_height = Vector3.Distance(fact.A, fact.D);
}
}
public void SpawnPyramid(PyramidFact fact)
{
GameObject pyramid = GameObject.Instantiate(Pyramid);
fact.WorldRepresentation = pyramid.GetComponent<FactObject3D>();
fact.WorldRepresentation.Fact = fact;
pyramid.transform.SetPositionAndRotation(fact.Position, fact.Rotation);
// triangle.transform.localScale = Vector3.Scale(triangle.transform.localScale, fact.LocalScale);
pyramid.GetComponentInChildren<TextMeshPro>().text = fact.GetLabel(StageStatic.stage.factState) + " = " + System.Math.Round(fact.Volume, 2) + "m³";
PyramidGenerator[] pyramidGenerators = pyramid.GetComponentsInChildren<PyramidGenerator>();
foreach (var gen in pyramidGenerators)
{
gen.ab = fact.ab;
gen.bc = fact.bc;
gen.d_offset = fact.D_offset;
}
}
public void SpawnPoint(PointFact fact)
{
GameObject point = GameObject.Instantiate(Sphere);
fact.WorldRepresentation = point.GetComponent<FactObject3D>();
fact.WorldRepresentation.Fact = fact;
point.transform.SetPositionAndRotation(fact.Position, fact.Rotation);
}
public void SpawnTestPoint(TestPointFact fact)
{
GameObject point = GameObject.Instantiate(TestPoint);
fact.WorldRepresentation = point.GetComponent<FactObject3D>();
fact.WorldRepresentation.Fact = fact;
point.transform.SetPositionAndRotation(fact.Position, fact.Rotation);
}
public void SpawnLine(LineFact fact)
{
//Change FactRepresentation to Line
GameObject line = GameObject.Instantiate(Line);
fact.WorldRepresentation = line.GetComponentInChildren<FactObject3D>();
fact.WorldRepresentation.Fact = fact;
//Place the Line in the centre of the two points
line.transform.position = fact.Position;
//Change scale and rotation, so that the two points are connected by the line
//and without affecting Scale of the Text
line.transform.GetChild(0).localScale = fact.LocalScale;
line.transform.GetChild(0).rotation = fact.Rotation;
line.GetComponentInChildren<TextMeshPro>().text =
fact.GetLabel(StageStatic.stage.factState) + " = " + System.Math.Round(fact.Distance, 2) + " m";
}
public void SpawnRay(RayFact fact)
{
//Change FactRepresentation to Line
GameObject line = GameObject.Instantiate(Ray);
fact.WorldRepresentation = line.GetComponentInChildren<FactObject3D>();
fact.WorldRepresentation.Fact = fact;
//Place the Line in the centre of the two points
line.transform.position = fact.Position;
//Change scale and rotation, so that the two points are connected by the line
//and without affecting Scale of the Text
line.transform.GetChild(0).localScale = fact.LocalScale;
line.transform.GetChild(0).rotation = fact.Rotation;
}
//Spawn an angle: point with id = angleFact.Pid2 is the point where the angle gets applied
public void SpawnAngle(AbstractAngleFact fact)
{
//Change FactRepresentation to Angle
GameObject angle = GameObject.Instantiate(Angle);
fact.WorldRepresentation = angle.GetComponentInChildren<FactObject3D>();
fact.WorldRepresentation.Fact = fact;
angle.transform.SetPositionAndRotation(fact.Position, fact.Rotation);
//Set text of angle
TextMeshPro[] texts = angle.GetComponentsInChildren<TextMeshPro>();
foreach (TextMeshPro t in texts)
{
//Change Text not to the id, but to the angle-value (from both sides)
t.text = System.Math.Round((float)fact.angle, 2) + "°";
}
//Generate angle mesh
CircleSegmentGenerator[] segments = angle.GetComponentsInChildren<CircleSegmentGenerator>();
foreach (CircleSegmentGenerator c in segments)
c.setAngle((float)fact.angle);
}
public void SpawnRingAndCircle(CircleFact fact)
{
var ringAndCircleGO = new GameObject("RingAndCircle");
SpawnRing(fact, ringAndCircleGO.transform);
SpawnCircle(fact, ringAndCircleGO.transform);
ringAndCircleGO.transform.SetPositionAndRotation(fact.Position, fact.Rotation);
fact.WorldRepresentation = ringAndCircleGO.AddComponent<FactObject3D>();
fact.WorldRepresentation.Fact = fact;
}
public void SpawnRing(CircleFact circleFact, Transform parent = null)
{
GameObject ring = GameObject.Instantiate(Ring, parent);
TorusGenerator[] tori = ring.GetComponentsInChildren<TorusGenerator>();
foreach (var torus in tori)
torus.torusRadius = circleFact.radius + (float)Math3d.vectorPrecission;
}
public void SpawnCircle(CircleFact circleFact, Transform parent = null)
{
GameObject circle = Instantiate(Circle, parent);
//Set radius
circle.transform.localScale = Vector3.Scale(circle.transform.localScale, circleFact.LocalScale);
}
public void SpawnQuad(QuadFact fact)
{
GameObject prism = GameObject.Instantiate(Prism);
fact.WorldRepresentation = prism.GetComponentInChildren<FactObject3D>();
fact.WorldRepresentation.Fact = fact;
prism.transform.SetPositionAndRotation(fact.Position, fact.Rotation);
PrismGenerator[] prisms = prism.GetComponentsInChildren<PrismGenerator>();
foreach (var gen in prisms)
gen.Vertices = fact.Points.Select(p => p.Position).ToArray();
}
public void SpawnTris(TriangleFact fact)
{
GameObject prism = GameObject.Instantiate(Prism);
fact.WorldRepresentation = prism.GetComponentInChildren<FactObject3D>();
fact.WorldRepresentation.Fact = fact;
prism.transform.SetPositionAndRotation(fact.Position, fact.Rotation);
PrismGenerator[] prisms = prism.GetComponentsInChildren<PrismGenerator>();
foreach (var gen in prisms)
gen.Vertices = fact.Verticies;
}
public void SpawnCone(ConeVolumeFact fact)
{
GameObject prism = GameObject.Instantiate(Cone);
fact.WorldRepresentation = prism.GetComponentInChildren<FactObject3D>();
fact.WorldRepresentation.Fact = fact;
prism.transform.SetPositionAndRotation(fact.Position, fact.Rotation);
ConeGenerator[] prisms = prism.GetComponentsInChildren<ConeGenerator>();
foreach (var gen in prisms)
{
gen.topPosition = fact.Point.Position - fact.Circle.Position;
gen.topRadius = 0f;
gen.bottomRadius = fact.Circle.radius;
}
}
public void SpawnTruncatedCone(TruncatedConeVolumeFact fact)
{
GameObject prism = GameObject.Instantiate(Cone);
fact.WorldRepresentation = prism.GetComponentInChildren<FactObject3D>();
fact.WorldRepresentation.Fact = fact;
prism.transform.SetPositionAndRotation(fact.Position, fact.Rotation);
ConeGenerator[] prisms = prism.GetComponentsInChildren<ConeGenerator>();
foreach (var gen in prisms)
{
gen.topPosition = fact.CircleTop.Position - fact.CircleBase.Position;
gen.topRadius = fact.CircleTop.radius;
gen.bottomRadius = fact.CircleBase.radius;
}
}
public void AnimateNonExistingFactTrigger(Fact fact)
{
StartCoroutine(_BlossomAndDie(fact));
IEnumerator _BlossomAndDie(Fact fact)
{
SpawnFactRepresentation(fact);
yield return new WaitForSeconds(GlobalBehaviour.HintAnimationDuration);
RemoveFactEvent.Invoke(fact);
fact.freeAutoLabel(StageStatic.stage.factState);
}
}
public void AnimateFunctionCalls()
{
float MaxAnimationDuration = 10f;
StartCoroutine(_AnimateFunctionCalls());
IEnumerator _AnimateFunctionCalls()
{
float trigger_time = Time.time;
Queue<FunctionCallFact> FCFs = new(
StageStatic.stage.factState.MyFactSpace.Values
.Where(f => f is FunctionCallFact)
.Select(f => f as FunctionCallFact)
.OrderBy(f => f.Domain.t_0)
);
FCFs.TryDequeue(out FunctionCallFact up_next);
while (up_next != null)
{
float curren_time = Time.time - trigger_time;
while (up_next != null && up_next.Domain.t_0 <= curren_time)
{
if (up_next.Domain.t_n <= curren_time)
{
FCFs.TryDequeue(out up_next);
continue;
}
StartCoroutine(__BlossomDragAndDie(up_next));
FCFs.TryDequeue(out up_next);
}
yield return null;
}
#pragma warning disable CS8321 // Die lokale Funktion ist deklariert, wird aber nie verwendet.
IEnumerator __BlossomAndDiePerFrame(FunctionCallFact FCF)
{
float current_time = Time.time - trigger_time;
while (current_time <= FCF.Domain.t_n
&& current_time <= FCF.Domain.t_0 + MaxAnimationDuration)
{
object[] result = FCF.Call(current_time);
List<Fact> factlist = new();
foreach (object i in result)
Fact.MakeFact(factlist, i, null, true);
foreach (Fact fact in factlist)
SpawnFactRepresentation(fact);
yield return null;
foreach (Fact fact in factlist)
{
RemoveFactEvent.Invoke(fact);
fact.freeAutoLabel(StageStatic.stage.factState);
}
current_time = Time.time - trigger_time;
}
}
#pragma warning restore CS8321 // Die lokale Funktion ist deklariert, wird aber nie verwendet.
IEnumerator __BlossomDragAndDie(FunctionCallFact FCF)
{
List<Fact> factlist = new();
object[] result = FCF.Call(FCF.Domain.t_0);
foreach (object i in result)
Fact.MakeFact(factlist, i, null, true);
foreach (Fact fact in factlist)
SpawnFactRepresentation(fact);
float current_time = Time.time - trigger_time;
while (current_time <= FCF.Domain.t_n
&& current_time <= FCF.Domain.t_0 + MaxAnimationDuration)
{
List<Fact> factlist_media = new();
object[] result_media = FCF.Call(current_time);
foreach (object i in result_media)
Fact.MakeFact(factlist_media, i, null, true);
for (int i = 0; i < math.min(factlist.Count, factlist_media.Count); i++)
{
//factlist[i].WorldRepresentation.Fact = factlist_media[i]; //TODO? viable? => FactWrapper.FactUpdated()
factlist[i].WorldRepresentation.transform.SetPositionAndRotation(
factlist_media[i].Position,
factlist_media[i].Rotation
);
factlist_media[i].freeAutoLabel(StageStatic.stage.factState);
}
yield return null;
current_time = Time.time - trigger_time;
}
foreach (Fact fact in factlist)
{
RemoveFactEvent.Invoke(fact);
fact.freeAutoLabel(StageStatic.stage.factState);
}
}
}
}
}