Skip to content
Snippets Groups Projects
GenerateDemoFiles.cs 30 KiB
Newer Older
  • Learn to ignore specific revisions
  • MaZiFAU's avatar
    MaZiFAU committed
    using REST_JSON_API;
    using System;
    
    MaZiFAU's avatar
    MaZiFAU committed
    using System.Linq;
    
    using Unity.Mathematics;
    
    MaZiFAU's avatar
    MaZiFAU committed
    using UnityEngine;
    
    
    public class GenerateDemoFiles
    {
        public static void GenerateAll()
        {
    
            if (UnityEngine.Object.FindObjectOfType<GadgetBehaviour>(true) == null)
    
                Debug.LogError("Cannot GenerateDemoFiles without populated GadgetManager");
                return;
            }
    
            Debug.LogWarning("Generating and Overwriting Stage Files");
    
            Action[] DemoGeneration = new Action[]{
                GenerateTreeStage,
                GenerateRiverStage,
    
    MaZiFAU's avatar
    MaZiFAU committed
                GenerateSlingShotStage,
    
            };
    
            foreach (Action action in DemoGeneration)
                try
                {
                    action();
                    Debug.Log("Successfully executed " + action.Method.Name);
                }
                catch (Exception ex)
                {
                    Debug.LogError("Exception while executing " + action.Method.Name);
                    Debug.LogException(ex);
                }
    
    MaZiFAU's avatar
    MaZiFAU committed
        public static void GenerateSlingShotStage()
        {
    
            // SlingShot
            float angle = 45;
    
            float[,] slingshot = new float[,] {
                {
                  -24.32552f,
                  1.83532131f,
                  1.56619191f
                },
                {
                  -24.32552f,
                  0.7562289f,
                  1.56619227f
                },
                {
                  -24.32552f,
                  0.7562293f,
                  3.46392965f
                },
            };
    
            // set 
            Vector3 a = new Vector3(slingshot[0, 0], slingshot[0, 1], slingshot[0, 2]);
            Vector3 b = new Vector3(slingshot[1, 0], slingshot[1, 1], slingshot[1, 2]);
            Vector3 c = new Vector3(slingshot[2, 0], slingshot[2, 1], slingshot[2, 2]);
    
            c = (1 / Mathf.Tan(angle.ToRadians()) * (a - b).magnitude)
              * (c-b).normalized + b;
    
            slingshot[2, 0] = c.x;
            slingshot[2, 1] = c.y;
            slingshot[2, 2] = c.z;
    
    
    MaZiFAU's avatar
    MaZiFAU committed
            // Generate Stage
            StageStatic.LoadNewStage
            (
    
    MaZiFAU's avatar
    MaZiFAU committed
                category: "Demo Category",
                name: "SlingShot",
                scene: "RiverWorld",
                description: "Find the correct velocity for the SlingShot to bounce once on the island within range, such that the projectile lands on the other side.",
                local: false,
                forcelocal: true
            );
    
    
            //// Populate Solution
            float[,] coords = new float[,] {
                {
                   -25.2272873f,
                   -0.0546216965f,
                   -5.025429f
                },
                {
                    -27.42147f,
                    -0.008223057f,
                    -6.39225769f
                },
                {
                    -22.7489357f,
                    -0.161126614f,
                    -4.983921f
                },
                {
                    -23.9606457f,
                    -0.0313406f,
                    -6.32592f
                },
                {
                    -24.1699982f,
                    -0.0106577873f,
                    -4.862953f
                },
                {
                    -29.479023f,
                    -0.00494384766f,
                    -8.160179f
                },
                {
                    -22.68462f,
                    -0.00494480133f,
                    -9.776779f
                },
                {
                    -20.088747f,
                    -0.00494384766f,
                    -8.493519f
                },
                {
                    -33.77201f,
                    -0.00494432449f,
                    -9.721775f
                },
                {
                    -39.13363f,
                    -0.00494432449f,
                    -9.173346f
                },
                {
                    -5.162197f,
                    -0.01788807f,
                    -10.8270531f
                },
                {
                    -2.14803314f,
                    -0.00494384766f,
                    -12.0348969f
                },
                {
                    3.33150864f,
                    -0.00494432449f,
                    -15.5597382f
                },
                {
                    5.57119f,
                    -0.00609874725f,
                    -16.0912876f
                },
                {
                    7.786186f,
                    -0.00494480133f,
                    -15.6361771f
                },
                {
                    12.9067154f,
                    -0.02451706f,
                    -12.6005821f
                },
                {
                    13.9139938f,
                    -0.00585222244f,
                    -12.8295422f
                },
                {
                    14.9375687f,
                    -0.00494432449f,
                    -13.4600468f
                },
                {
                    18.0826569f,
                    -0.00494432449f,
                    -14.8706532f
                },
                {
                    20.7500458f,
                    -0.00614357f,
                    -14.5210171f
                },
                {
                    23.5185432f,
                    -0.00494432449f,
                    -12.6296406f
                },
                {
                    26.0413818f,
                    -0.00494432449f,
                    -10.1295071f
                },
                {
                    33.0014877f,
                    -0.00494384766f,
                    -11.9421864f
                },
                {
                    38.6853943f,
                    -0.0156846046f,
                    -16.7288418f
                },
                {
                    38.2561569f,
                    -0.00494432449f,
                    -38.421936f
                },
                {
                    -36.2956123f,
                    -0.00494432449f,
                    -39.43577f
                },
                {
                    -38.7866669f,
                    -0.00494432449f,
                    39.2549057f
                },
                {
                    39.66716f,
                    -0.00494432449f,
                    39.7287445f
                },
            };
    
            List<string> PIds = new();
            List<Vector3> verts = new();
            bool samestep = false;
            for (int i = 0; i < coords.GetLength(0); i++)
            {
                verts.Add(new Vector3(coords[i, 0], coords[i, 1], coords[i, 2]));
    
                PIds.Add(
                    StageStatic.stage.solution.Add(
                        new PointFact(verts.Last(), Vector3.up),
                        out _, samestep, null, null, true
                ));
                //StageStatic.stage.solution.ExposedSolutionFacts.Add(PIds.Last());
                samestep = true;
            }
    
            // island
            List<TriangleFact> Tris = new List<TriangleFact>();
            Tris.Add(new TriangleFact(new Vector3[] { verts[0], verts[3], verts[1] }));
            Tris.Add(new TriangleFact(new Vector3[] { verts[0], verts[4], verts[3] }));
            Tris.Add(new TriangleFact(new Vector3[] { verts[4], verts[2], verts[3] }));
    
            // landing Zone
            Vector3[] plane = verts
                .GetRange(5, verts.Count - 5 - 3)
                .OrderBy(v => Vector3.Dot(-Vector3.right, (v - verts[^3]).normalized))
                .ToArray();
    
            for (int i = 0; i < plane.Length-1; i++)
                Tris.Add(new TriangleFact(new Vector3[] { verts[^3], plane[i], plane[i + 1] }));
    
            // bottom
            Vector3 offset_bottom = new Vector3(0, -2, 0);
            Tris.Add(new TriangleFact(new Vector3[] { verts[^1], verts[^2], verts[^3] }.Select(v => v + offset_bottom).ToArray()));
            Tris.Add(new TriangleFact(new Vector3[] { verts[^1], verts[^3], verts[^4] }.Select(v => v + offset_bottom).ToArray()));
    
            // cleanup
            List<string> TrisID = new();
            for (int i = 0; i < Tris.Count; i++)
            {
                TrisID.Add(
                    StageStatic.stage.solution.Add(Tris[i], out _, samestep, null, null, true)
                );
                //StageStatic.stage.solution.ExposedSolutionFacts.Add(TrisID.Last());
            }
    
            string TriangleURI = StageStatic.stage.solution.Add( // for CannonBallScroll
                new ListFact(TrisID.ToArray(), null, new OMS(MMTConstants.TYPE_TO_OMS[typeof(TriangleFact)])),
                out bool _, true, null, null, true
            );
            //StageStatic.stage.solution.ExposedSolutionFacts.Add(TriangleURI);
    
            string GravURI = StageStatic.stage.solution.Add(
                new PointFact(new Vector3(0, -9.81f, 0), Vector3.down),
                out _, false, null, null);
    
            StageStatic.stage.solution.ExposedSolutionFacts.Add(GravURI);
    
    
            string BounceURI = StageStatic.stage.solution.Add(
                new RealLitFact(0.8f),
                out _, false, null, null);
            //StageStatic.stage.solution.ExposedSolutionFacts.Add(BounceURI);
    
    
            // insert slingshot
            for (int i = 0; i < slingshot.GetLength(0); i++)
            {
                verts.Add(new Vector3(slingshot[i, 0], slingshot[i, 1], slingshot[i, 2]));
    
                PIds.Add(
                    StageStatic.stage.solution.Add(
                        new PointFact(verts.Last(), Vector3.up),
                        out _, samestep, null, null, true
                ));
                StageStatic.stage.solution.ExposedSolutionFacts.Add(PIds.Last());
                samestep = true;
            }
    
    
    MaZiFAU's avatar
    MaZiFAU committed
            //// Set Solution
            //StageStatic.stage.solution.ValidationSet =
            //    new List<SolutionRecorder.SubSolution>
            //    { new SolutionRecorder.SubSolution(new HashSet<string> { target_Id }, null, null, new LineFactHightDirectionComparer()) };
    
            // Set Gadgets/ Scrolls
            StageStatic.stage.AllowedGadgets = null;
    
            StageStatic.stage.AllowedScrolls = new() { MMTConstants.ScrollRiverSimple, MMTConstants.ScrollRiver, MMTConstants.ScrollCannonBallT3D };
    
    
            StageStatic.stage.solution.ScrollOverwrites.Add(MMTConstants.ScrollCannonBallT3D, new[] {
                (GravURI, 2, false),
                (BounceURI, 3, false),
                (TriangleURI, 4, false),
            });
            StageStatic.stage.solution.ScrollOverwrites.Add(MMTConstants.ScrollRiver, new[] {
                (GravURI, 4, false),
            });
    
            StageStatic.stage.solution.ScrollOverwrites.Add(MMTConstants.ScrollRiverSimple, new[] {
                (GravURI, 2, true),
            });
    
    MaZiFAU's avatar
    MaZiFAU committed
    
            // Save
            StageStatic.SetMode(StageStatic.Mode.Create);
            StageStatic.stage.store(false, true);
        }
    
    
        public static void GenerateTreeStage()
    
        {
            // Params
            float minimalSolutionHight = 6;
    
            // Generate Stage
    
            StageStatic.LoadNewStage
    
                category: "Demo Category",
                name: "TechDemo A",
                scene: "RiverWorld",
                description: "Tree Stage",
    
    MaZiFAU's avatar
    MaZiFAU committed
                local: false,
                forcelocal: true
    
                buttom = new PointFact(Vector3.zero, Vector3.up),
                top = new PointFact(Vector3.zero + Vector3.up * minimalSolutionHight, Vector3.up);
    
            StageStatic.stage.solution.Add(buttom, out _, false, null, null);
            StageStatic.stage.solution.Add(top, out _, true, null, null);
    
            LineFact target = new LineFact(buttom.Id, top.Id);
    
            var target_Id = StageStatic.stage.solution.Add(target, out _, true, null, null);
    
            StageStatic.stage.solution.ValidationSet =
    
    MaZiFAU's avatar
    MaZiFAU committed
                new List<SolutionRecorder.SubSolution>
                { new SolutionRecorder.SubSolution(new HashSet<string> { target_Id }, null, null, new LineFactHightDirectionComparer()) };
    
            // Set Gadgets/ Scrolls
    
            StageStatic.stage.AllowedGadgets = null;
    
            StageStatic.stage.AllowedScrolls = null;
    
            StageStatic.SetMode(StageStatic.Mode.Create);
    
            StageStatic.stage.store(false, true);
    
        public static void GenerateRiverStage()
    
        {
            // Params
            float minimalSolutionHight = 6;
    
            // Generate Stage
    
            StageStatic.LoadNewStage
    
                category: "Demo Category",
                name: "TechDemo B",
                scene: "RiverWorld",
                description: "River Stage",
    
    MaZiFAU's avatar
    MaZiFAU committed
                local: false,
                forcelocal: true
    
    
            // Populate Solution
            PointFact
    
                buttom = new PointFact(Vector3.zero, Vector3.up),
                top = new PointFact(Vector3.zero + Vector3.up * minimalSolutionHight, Vector3.up);
    
            StageStatic.stage.solution.Add(buttom, out _, false, null, null);
            StageStatic.stage.solution.Add(top, out _, true, null, null);
    
            LineFact target = new LineFact(buttom.Id, top.Id);
    
            var target_Id = StageStatic.stage.solution.Add(target, out _, true, null, null);
    
    
            // Set Solution
            StageStatic.stage.solution.ValidationSet =
    
    MaZiFAU's avatar
    MaZiFAU committed
                new List<SolutionRecorder.SubSolution> {
                    new SolutionRecorder.SubSolution(new HashSet<string> { target_Id }, null, null, new LineFactHightDirectionComparer()),
                    new SolutionRecorder.SubSolution(new HashSet<string> { target_Id }, null, null, new LineSpanningOverRiverWorldComparer()),
                    new SolutionRecorder.SubSolution(null, new List<int> { 1 }, new List<int> { 0 }, new LineFactHightComparer()),
    
            // Set Gadgets/ Scrolls
    
            StageStatic.stage.AllowedGadgets = new() { new Pointer(), new Tape(), new AngleTool(), new LineTool(), new LotTool(), new Pendulum(), new Remover() }; //, new EqualCircleGadget(), new TestMiddlePoint() };
    
    MaZiFAU's avatar
    MaZiFAU committed
            StageStatic.stage.AllowedScrolls = new() {
                "http://mathhub.info/FrameIT/frameworld?OppositeLen",
                //"http://mathhub.info/FrameIT/frameworld?SupplementaryAngles",
                //"http://mathhub.info/FrameIT/frameworld?AngleSum",
                //"http://mathhub.info/FrameIT/frameworld?Pythagoras",
                //"http://mathhub.info/FrameIT/frameworld?CylinderVolumeScroll",
                //"http://mathhub.info/FrameIT/frameworld?CircleLineAngleToAngleScroll",
                //"http://mathhub.info/FrameIT/frameworld?Midpoint",
                //"http://mathhub.info/FrameIT/frameworld?CircleScroll",
                //"http://mathhub.info/FrameIT/frameworld?CircleLineAngleScroll",
                //"http://mathhub.info/FrameIT/frameworld?CircleAreaScroll",
                //"http://mathhub.info/FrameIT/frameworld?ConeVolumeScroll",
                //"http://mathhub.info/FrameIT/frameworld?TruncatedConeVolumeScroll",
            };
    
            // Save
    
            StageStatic.SetMode(StageStatic.Mode.Create);
    
            StageStatic.stage.store(false, true);
    
        public static void GenerateCanonBallStage2D()
    
        {
            // Params //List<Wall> walls, T starPos, T starVec, T gravity, int dimension
            int
                dim_const = 0,
    
            float Py_factor = 0.04905f;
            float Py_bounce = 0.8f;
    
    
            float3 StartPos_py = new(0.0f, 300.0f, 380.0f);
            float3 StartVec_py = new(0.0f, 150.0f, -490.0f);
            float3 Gravity_py = new(0.0f, -200f, 0.0f);
    
            (double x1, double x2, double y1, double y2)[] PythonParams = {
                (-1.0, 0.0, 401.0, 0.0 ),
                (0.0, -1.0, 0.01, 401.0 ),
                (400.0, -1.0, 400.01, 401.0),
                (-1.0, 400.0, 401.0, 400.0),
                (50.0, 200.0, 120.0, 270.0),
                (150.0, 100.0, 200.0, 100.0),
                (150.0, 285.0, 200.0, 200.0),
                (230.0, 360.0, 300.0, 300.0),
                (300.0, 100.0, 385.0, 150.0),
                (50.0, 50.0, 100.0, 135.0),
    
            };
    
            //Parse PythonParams
            Vector3
                StartPos = Vector3.zero,
                StartVec = Vector3.zero,
                Gravity = Vector3.zero;
    
    
            StartPos[0] = StartPos_py[0] * Py_factor;
            StartPos[1] = StartPos_py[1] * Py_factor;
            StartPos[2] = StartPos_py[2] * Py_factor;
    
            StartVec[0] = StartVec_py[0] * Py_factor;
            StartVec[1] = StartVec_py[1] * Py_factor;
            StartVec[2] = StartVec_py[2] * Py_factor;
    
            Gravity[0] = Gravity_py[0] * Py_factor;
            Gravity[1] = Gravity_py[1] * Py_factor;
            Gravity[2] = Gravity_py[2] * Py_factor;
    
    
            float[,,] Wall_parameter = new float[PythonParams.Length, 2, 2];
            for (uint i = 0; i < PythonParams.Length; i++)
            {
    
                Wall_parameter[i, 0, 0] = (float)(Py_factor * (PythonParams[i].x1));
                Wall_parameter[i, 0, 1] = (float)(Py_factor * (PythonParams[i].x2));
    
                Wall_parameter[i, 1, 0] = (float)(Py_factor * (PythonParams[i].y1));
                Wall_parameter[i, 1, 1] = (float)(Py_factor * (PythonParams[i].y2));
    
            }
    
            // Generate Stage
    
            StageStatic.LoadNewStage
    
                scene: "RiverWorld",
    
    MaZiFAU's avatar
    MaZiFAU committed
                local: false,
                forcelocal: true
    
            );
    
            // Populate Solution
    
                new PointFact(StartPos, Vector3.up),
    
                out _, false, null, null);
            StageStatic.stage.solution.ExposedSolutionFacts.Add(BallURI);
    
            string VecURI = StageStatic.stage.solution.Add(
    
                new PointFact(StartVec, StartVec.normalized),
    
                out _, false, null, null);
            StageStatic.stage.solution.ExposedSolutionFacts.Add(VecURI);
    
            string GravURI = StageStatic.stage.solution.Add(
    
                new PointFact(Gravity, Gravity.normalized),
    
                out _, false, null, null);
            StageStatic.stage.solution.ExposedSolutionFacts.Add(GravURI);
    
            string BounceURI = StageStatic.stage.solution.Add(
    
                new RealLitFact(Py_bounce),
    
                out _, false, null, null);
            StageStatic.stage.solution.ExposedSolutionFacts.Add(BounceURI);
    
            List<LineFact> Walls = new();
    
            for (int i = 0; i < PythonParams.Length; i++)
            {
                Vector3 tmpVec = Vector3.zero;
    
    
                tmpVec[dim_A] = Wall_parameter[i, 0, 1];
                tmpVec[dim_B] = Wall_parameter[i, 0, 0];
    
                PointFact topA = new(tmpVec, Vector3.up);
    
                string topAURI = StageStatic.stage.solution.Add(topA, out _, false, null, null);
    
    
                tmpVec[dim_A] = Wall_parameter[i, 1, 1];
                tmpVec[dim_B] = Wall_parameter[i, 1, 0];
    
                PointFact topB = new(tmpVec, Vector3.up);
    
                string topBURI = StageStatic.stage.solution.Add(topB, out _, true, null, null);
    
    
                LineFact topology = new(topAURI, topBURI);
    
                string lineURI = StageStatic.stage.solution.Add(topology, out _, true, null, null);
    
                StageStatic.stage.solution.ExposedSolutionFacts.Add(lineURI);
    
            }
    
            // Set Solution
    
    MaZiFAU's avatar
    MaZiFAU committed
            #region  CannonBallScroll
    
            //StageStatic.stage.solution.Add( // for CannonBallScroll
            //    new ListFact(Walls.Select(w => w.Topology.Id).ToArray(), null, new OMS(MMTConstants.TYPE_TO_OMS[typeof(LineFact)]), StageStatic.stage.solution),
            //    out bool _, true, null, null
            //);
    
    MaZiFAU's avatar
    MaZiFAU committed
            // special case for Prototype
    
            SOMDoc[] RRRRTupel = new SOMDoc[Walls.Count];
    
    MaZiFAU's avatar
    MaZiFAU committed
            for (int i = 0; i < Walls.Count; i++)
            {
    
                RRRRTupel[i] =
                    SOMDoc.MakeTupel(
    
    MaZiFAU's avatar
    MaZiFAU committed
                        new[] {
    
    MaZiFAU's avatar
    MaZiFAU committed
                            SOMDoc.MakeTupel(new OMLIT<float>[] { new((float)PythonParams[i].x1), new((float)PythonParams[i].x2) }),
                            SOMDoc.MakeTupel(new OMLIT<float>[] { new((float)PythonParams[i].y1), new((float)PythonParams[i].y2) }),
    
    MaZiFAU's avatar
    MaZiFAU committed
            }
    
    MaZiFAU's avatar
    MaZiFAU committed
            string RRRRURI = StageStatic.stage.solution.Add(
    
                new ListFact(null, RRRRTupel, null),
    
    MaZiFAU's avatar
    MaZiFAU committed
                out bool _, true, null, null
            );
            #endregion CannonBallScroll
    
    
            CanonBallProblemCalculator2D calc = new(Walls, StartPos, StartVec, Gravity, Py_bounce, dim_const, dim_A, dim_B, StageStatic.stage.solution);
    
            StageStatic.stage.solution.ExposedSolutionFacts.AddRange(calc.Result_FuncCall_Id);
    
            //string attacheFactURI = StageStatic.stage.solution.Add(
            //    new AttachedPositionFunction(BallURI, calc.Result_FuncCall_Id.ToArray(), StageStatic.stage.solution),
            //    out _, true, null, null);
            //StageStatic.stage.solution.ExposedSolutionFacts.Add(attacheFactURI);
    
    
            //TODO: ~attach funcs + ~cheat?
            //StageStatic.stage.solution.ValidationSet =
            //        new List<SolutionOrganizer.SubSolution> {
            //        new SolutionOrganizer.SubSolution(new HashSet<string> { target_Id }, null, null, new LineFactHightDirectionComparer()),
            //        new SolutionOrganizer.SubSolution(new HashSet<string> { target_Id }, null, null, new LineSpanningOverRiverWorldComparer()),
            //        new SolutionOrganizer.SubSolution(null, new List<int> { 1 }, new List<int> { 0 }, new LineFactHightComparer()),
            //        };
    
            // Set Gadgets/ Scrolls
            StageStatic.stage.AllowedGadgets = null;
    
            StageStatic.stage.AllowedScrolls = new() { MMTConstants.ScrollCannonBall2D };
    
    MaZiFAU's avatar
    MaZiFAU committed
            StageStatic.stage.solution.ScrollOverwrites.Add(MMTConstants.ScrollCannonBall2D, new[] {
                (BallURI, 0, true),
                (VecURI, 1, true),
                (GravURI, 2, true),
                (BounceURI, 3, true),
                (RRRRURI, 4, true),
            });
    
    
            // Save
            StageStatic.SetMode(StageStatic.Mode.Create);
            StageStatic.stage.store(false, true);
        }
    
        public static void GenerateCanonBallStage3D()
        {
            // Params //List<Wall> walls, T starPos, T starVec, T gravity, int dimension
            int
                dim_G = 1,
                dim_A = 2,
                dim_B = 0;
    
            float Py_factor = 0.04905f;
    
    
            float3 StartPos_py = new(380, 0, 300);
            float3 StartVec_py = new(-490, 100, 150);
            float3 Gravity_py = new(0, 0, -200);
    
            double[,,] PythonWalls = new double[,,] {
                {
                    { 0, 0, 0 },
                    { 400, 0, 0 },
                    { 400, 0, 400 },
                    { 0, 0, 400 },
                },{
                    { 0, 400, 0 },
                    { 400, 400, 0 },
                    { 400, 400, 400 },
                    { 0, 400, 400 },
                },{
                    { 250, 0, 0 },
                    { 300, 0, 0 },
                    { 300, 400, 0 },
                    { 250, 400, 0 },
                },{
                    { 0, 0, 0 },
                    { 0, 0, 400 },
                    { 0, 400, 400 },
                    { 0, 400, 0 },
                },{
                    { 400, 0, 0 },
                    { 400, 0, 400 },
                    { 400, 400, 400 },
                    { 400, 400, 0 },
                },{
                    { 0, 0, 400 },
                    { 400, 0, 400 },
                    { 400, 400, 400 },
                    { 0, 400, 400 },
                },{
                    { 300, 0, 0 },
                    { 400, 0, 0 },
                    { 400, 400, 0},
                    { 300, 400, 0},
                },{
                    { 0, 0, 0 },
                    { 250, 0, 0 },
                    { 250, 400, 0 },
                    { 0, 400, 0 },
                },{
                    { 50, 0, 200 },
                    { 120.7, 0, 270.7 },
                    { 120.7, 200, 270.7 },
                    { 50, 200, 200 },
                },{
                    { 150, 0, 100 },
                    { 200, 0, 100 },
                    { 200, 200, 100 },
                    { 150, 200, 100 },
                },{
                    { 150, 0, 286.6 },
                    { 200, 0, 200 },
                    { 200, 200, 200 },
                    { 150, 200, 286.6 },
                },{
                    { 230.7, 0, 340 },
                    { 300, 0, 300 },
                    { 300, 200, 300 },
                    { 230.7, 200, 340 },
                },{
                    { 300, 0, 100 },
                    { 386.6, 0, 150 },
                    { 386.6, 200, 150 },
                    { 300, 200, 100 },
                },{
                    { 50, 0, 50 },
                    { 100, 0, 136.6 },
                    { 100, 200, 136.6 },
                    { 50, 200, 50 },
            }};
    
            //Parse PythonParams
            Vector3
                StartPos = Vector3.zero,
                StartVec = Vector3.zero,
                Gravity = Vector3.zero;
    
            StartPos[dim_A] = StartPos_py[0] * Py_factor;
            StartPos[dim_B] = StartPos_py[1] * Py_factor;
            StartPos[dim_G] = StartPos_py[2] * Py_factor;
    
            StartVec[dim_A] = StartVec_py[0] * Py_factor;
            StartVec[dim_B] = StartVec_py[1] * Py_factor;
            StartVec[dim_G] = StartVec_py[2] * Py_factor;
    
            Gravity[dim_A] = Gravity_py[0] * Py_factor;
            Gravity[dim_B] = Gravity_py[1] * Py_factor;
            Gravity[dim_G] = Gravity_py[2] * Py_factor;
    
            float[,,] Wall_parameter = new float[PythonWalls.GetLength(0), PythonWalls.GetLength(1), PythonWalls.GetLength(2)];
            for (int i = 0; i < PythonWalls.GetLength(0); i++)
                for (int j = 0; j < PythonWalls.GetLength(1); j++)
                    for (int k = 0; k < PythonWalls.GetLength(2); k++)
                        Wall_parameter[i, j, k] = (float)(PythonWalls[i, j, k] * Py_factor);
    
            // Generate Stage
    
            StageStatic.LoadNewStage
    
                category: "CanonBall",
                name: "CanonBall 3D",
                scene: "RiverWorld",
                description: "CanonBall 3D Test",
    
    MaZiFAU's avatar
    MaZiFAU committed
                local: false,
                forcelocal: true
    
            string BallURI = StageStatic.stage.solution.Add(
    
                new PointFact(StartPos, Vector3.up),
    
                out _, false, null, null);
    
            StageStatic.stage.solution.ExposedSolutionFacts.Add(BallURI);
    
            string VecURI = StageStatic.stage.solution.Add(
    
                new PointFact(StartVec, StartVec.normalized),
    
                out _, false, null, null);
            StageStatic.stage.solution.ExposedSolutionFacts.Add(VecURI);
    
    
            string GravURI = StageStatic.stage.solution.Add(
    
                new PointFact(Gravity, Gravity.normalized),
    
                out _, false, null, null);
            StageStatic.stage.solution.ExposedSolutionFacts.Add(GravURI);
    
            string BounceURI = StageStatic.stage.solution.Add(
    
                new RealLitFact(Py_bounce),
    
                out _, false, null, null);
            StageStatic.stage.solution.ExposedSolutionFacts.Add(BounceURI);
    
            List<QuadFact> Walls = new();
    
            List<TriangleFact> Trieangles = new();
    
            for (int i = 0; i < Wall_parameter.GetLength(0); i++)
            {
    
                Vector3[] corners = new Vector3[4];
    
                string[] edge = new string[4];
    
                for (int j = 0; j < Wall_parameter.GetLength(1); j++)
                {
    
                    Vector3 tmpVec = Vector3.zero;
    
                    tmpVec[dim_A] = Wall_parameter[i, j, 0];
                    tmpVec[dim_B] = Wall_parameter[i, j, 1];
                    tmpVec[dim_G] = Wall_parameter[i, j, 2];
    
                    corners[j] = tmpVec;
    
                    PointFact edge_point = new(tmpVec, Vector3.up);
    
                    edge[j] = StageStatic.stage.solution.Add(edge_point, out _, false, null, null);
                }
    
    
                QuadFact topology = new(edge);
    
                string quadURI = StageStatic.stage.solution.Add(topology, out _, true, null, null);
                StageStatic.stage.solution.ExposedSolutionFacts.Add(quadURI);
    
    
                TriangleFact top0 = new(new[] { corners[0], corners[1], corners[2] });
    
                string top0URI = StageStatic.stage.solution.Add(top0, out _, true, null, null);
                StageStatic.stage.solution.ExposedSolutionFacts.Add(top0URI);
    
    
                TriangleFact top1 = new(new[] { corners[2], corners[3], corners[0] });
    
                string top1URI = StageStatic.stage.solution.Add(top1, out _, true, null, null);
                StageStatic.stage.solution.ExposedSolutionFacts.Add(top1URI);
    
    
                Trieangles.Add(top0);
                Trieangles.Add(top1);
    
    MaZiFAU's avatar
    MaZiFAU committed
            string TriangleURI = StageStatic.stage.solution.Add( // for CannonBallScroll
    
                new ListFact(Trieangles.Select(q => q.Id).ToArray(), null, new OMS(MMTConstants.TYPE_TO_OMS[typeof(TriangleFact)])),
    
                out bool _, true, null, null
            );
    
    
            // special case for Prototype
            SOMDoc[] RRRRTupel = new SOMDoc[Walls.Count];
            for (int i = 0; i < Walls.Count; i++)
            {
                RRRRTupel[i] = SOMDoc.MakeTupel(
                    Walls[i].Pids.Select(p => new OMS(p)).ToArray()
                );
            }
    
    MaZiFAU's avatar
    MaZiFAU committed
            string QuadURI = StageStatic.stage.solution.Add(
    
                new ListFact(null, RRRRTupel, null),
    
                out bool _, true, null, null
            );
            #endregion CannonBallScroll
    
            CanonBallProblemCalculator3D calc = new(Walls, StartPos, StartVec, Gravity, Py_bounce, dim_G, dim_A, dim_B, StageStatic.stage.solution);
    
    MaZiFAU's avatar
    MaZiFAU committed
            StageStatic.stage.solution.ExposedSolutionFacts.AddRange(calc.Result_FuncCall_Id);
    
            //StageStatic.stage.solution.Add( // for reference
            //    new ListFact(calc.Result_FuncCall_Id.ToArray(), null, new OMS("Tuple((txt)x(t->t^)x(t^->fact))"), StageStatic.stage.solution),
            //    out bool _, true, null, null
            //);
    
            //string attacheFactURI = StageStatic.stage.solution.Add(
            //    new AttachedPositionFunction(BallURI, calc.Result_FuncCall_Id.ToArray(), StageStatic.stage.solution),
            //    out _, true, null, null);
            //StageStatic.stage.solution.ExposedSolutionFacts.Add(attacheFactURI);
    
            //TODO: ~attach funcs + ~cheat?
    
            //StageStatic.stage.solution.ValidationSet =
            //        new List<SolutionOrganizer.SubSolution> {
            //        new SolutionOrganizer.SubSolution(new HashSet<string> { target_Id }, null, null, new LineFactHightDirectionComparer()),
            //        new SolutionOrganizer.SubSolution(new HashSet<string> { target_Id }, null, null, new LineSpanningOverRiverWorldComparer()),
            //        new SolutionOrganizer.SubSolution(null, new List<int> { 1 }, new List<int> { 0 }, new LineFactHightComparer()),
            //        };
    
            // Set Gadgets/ Scrolls
            StageStatic.stage.AllowedGadgets = null;
    
            StageStatic.stage.AllowedScrolls = new() { MMTConstants.ScrollCannonBall3D, MMTConstants.ScrollCannonBallT3D };
    
    MaZiFAU's avatar
    MaZiFAU committed
            StageStatic.stage.solution.ScrollOverwrites.Add(MMTConstants.ScrollCannonBall3D, new[] {
                (BallURI, 0, true),
                (VecURI, 1, true),
                (GravURI, 2, true),
                (BounceURI, 3, true),
                (QuadURI, 4, true),
            });
            StageStatic.stage.solution.ScrollOverwrites.Add(MMTConstants.ScrollCannonBallT3D, new[] {
                (BallURI, 0, true),
                (VecURI, 1, true),
                (GravURI, 2, true),
                (BounceURI, 3, true),
                (TriangleURI, 4, true),
            });
    
    
            // Save
            StageStatic.SetMode(StageStatic.Mode.Create);
            StageStatic.stage.store(false, true);
        }