Exemple #1
0
    /// <summary>
    /// Initializes a new gravity frame from maze frame fitted splines.
    /// </summary>
    /// <param name="mazeFrame">Maze frame.</param>
    /// <param name="mazeFrameSplines">Maze frame fitted splines.</param>
    /// <param name="closebyDistFac"> Units of max(mazeFrame.Scale) at which nodes are considered close by.</param>
    /// <param name="junctionDistFac"> Units of max(mazeFrame.Scale) at which nodes are considered close to junction.</param>
    public GravityFrameController(MazeFrame mazeFrame, MazeFrameSplines mazeFrameSplines, float junctionDistFac, float planeSize)
    {
        //float currCloseByDist = mazeFrame.Scale.ComponentMax() * closebyDistFac;
        float currJunctionDist = mazeFrame.Scale.ComponentMax() * junctionDistFac;

        GenerateGravityFrameFromSplines(mazeFrame, mazeFrameSplines, currJunctionDist, planeSize);
    }
Exemple #2
0
 private void DestroyCurrentLevel()
 {
     if (!LevelIsPresent)
     {
         return;
     }
     mazeFrame              = null;
     mazeFrameSplines       = null;
     gravityFrameController = null;
     Destroy(mazeObjects);
     if (player != null)
     {
         player.SetActive(false);
     }
     if (cameraRig != null)
     {
         cameraRig.SetActive(false);
     }
     if (endPortal != null)
     {
         endPortal.SetActive(false);
     }
     if (cubeOfDeath != null)
     {
         Destroy(cubeOfDeath);
     }
     if (mindWarpTriggers != null)
     {
         Destroy(mindWarpTriggers);
     }
     //Destroy(player);
     //Destroy(cameraRig);
     //Destroy(cubeOfDeath);
     //Destroy(endPortal);
 }
    public void PopulateWithSplineFittedShape(MazeFrame mazeFrame, ref MazeFrameSplines mazeFrameSplines, ref GameObject mazeObjects, Vector3 resize, string baseShape)
    {
        int objPerCurveSegment = 2;

        // First, fit splines to maze path segments
        mazeFrameSplines = new MazeFrameSplines(mazeFrame);

        // Set color list to use for paths
        List <Color> colorList = new List <Color>();

        GetColorBasedOnPathIndex(new List <int>(1), ref colorList);

        // Create parent object to hold maze objects
        mazeObjects       = new GameObject("mazeObjects");
        mazeObjects.layer = 10;
        mazeObjects.transform.position = Vector3.zero;
        mazeObjects.transform.rotation = Quaternion.identity;
        // Load and resize prefab
        //string prefabObjName = baseShape + "/" + baseShape + "-20-" + objN;
        string     prefabObjName        = baseShape + "/" + baseShape + "-20-1";
        GameObject prefabInst           = Instantiate(Resources.Load("Prefabs/" + prefabObjName) as GameObject);
        Vector3    mazeObjectPrefabSize = prefabInst.GetComponent <MeshRenderer>().bounds.size;

        if (!resize.ComponentsAreApproxEqualTo(mazeObjectPrefabSize))
        {
            Utilities.MeshResize(prefabInst, Vector3.Scale(resize, prefabInst.GetComponent <MeshRenderer>().bounds.size.ComponentInverse()));
            mazeObjectPrefabSize = prefabInst.GetComponent <MeshRenderer>().bounds.size;
        }
        // Create objects and add meshes to fit
        StartCoroutine(CreateSplineFittedMeshesCoroutine(mazeObjects, mazeFrameSplines, prefabInst, objPerCurveSegment, colorList));
        //CreateSplineFittedMeshesCoroutine(mazeObjects, mazeFrameSplines, prefabInst, objPerCurveSegment, colorList);

        //// Add lights to the sides
        //GameObject mazeLightObjects = new GameObject("mazeLightObjects");
        //mazeLightObjects.transform.position = Vector3.zero;
        //mazeLightObjects.transform.rotation = Quaternion.identity;
        //// Load prefab
        //string prefabLightName = "PathObjectLightBar";
        //GameObject prefabLightInst = Instantiate(Resources.Load("Prefabs/" + prefabLightName) as GameObject);
        //float spacing = 1f;
        //// Add lights
        //AddPathObjectLights(mazeLightObjects, mazeFrameSplines, prefabLightInst, spacing, mazeObjectPrefabSize, colorList);
    }
Exemple #4
0
    /// <summary>
    /// Generate  gravity frame from splines fitted to maze frame.
    /// </summary>
    /// <param name="mazeFrameSplines">Splines fitted to maze frames.</param>
    ///// <param name="closebyDist"> Distance at which nodes are considered close by.</param>
    /// <param name="junctionDist"> Distance at which nodes are considered close to junction.</param>
    private void GenerateGravityFrameFromSplines(MazeFrame mazeFrame, MazeFrameSplines mazeFrameSplines, float junctionDist, float planeWidth)
    {
        // Generate gravity frame based on maze frame fitted splines
        int nodeCount = 0;

        foreach (MazeFrameSplines.SplineSegment splineSeg in mazeFrameSplines.SplineSegments)
        {
            nodeCount += splineSeg.spline.NSamplesToUse;
        }
        gravityFrame = new List <GravityNode>(nodeCount);

        // Generate sub frame to use later
        List <List <GravityNode> > segmentSubFrame = new List <List <GravityNode> >(mazeFrameSplines.SplineSegments.Count);

        // Create nodes for each splines
        for (int iSpline = 0; iSpline < mazeFrameSplines.SplineSegments.Count; iSpline++)
        {
            segmentSubFrame.Add(new List <GravityNode>(mazeFrameSplines.SplineSegments[iSpline].spline.NSamplesToUse));
            GravityNode prevNode = null;
            for (int i = 0; i < mazeFrameSplines.SplineSegments[iSpline].spline.NSamplesToUse; i++)
            {
                Vector3   currPos     = mazeFrameSplines.SplineSegments[iSpline].spline.GetPointOnSpline(mazeFrameSplines.SplineSegments[iSpline].spline.SampleIndToT(i));
                Vector3   currTang    = mazeFrameSplines.SplineSegments[iSpline].spline.GetTangentToPointOnSpline(mazeFrameSplines.SplineSegments[iSpline].spline.SampleIndToT(i)).normalized;
                Vector3   currNorm    = mazeFrameSplines.SplineSegments[iSpline].spline.DefaultGetNormalAtT(mazeFrameSplines.SplineSegments[iSpline].spline.SampleIndToT(i)).normalized;
                Vector3   cross       = Vector3.Cross(currTang, currNorm);
                Vector3[] planePoints = new Vector3[2] {
                    currPos + (cross * (planeWidth / 2f)), currPos - (cross * (planeWidth / 2f))
                };
                GravityNode node = new GravityNode(currPos, iSpline + "-" + currPos.ToString(), planePoints);
                if (prevNode != null)
                {
                    node.neighbors.Add(prevNode);
                    prevNode.neighbors.Add(node);
                }
                // Determine if near junction
                if (mazeFrameSplines.SplineSegments[iSpline].startNeighbors.Count > 0)
                {
                    if (Vector3.Distance(currPos, mazeFrameSplines.SplineSegments[iSpline].spline.GetPointOnSpline(0)) < junctionDist)
                    {
                        node.nearJunction = true;
                    }
                }
                if (mazeFrameSplines.SplineSegments[iSpline].endNeighbors.Count > 0)
                {
                    if (Vector3.Distance(currPos, mazeFrameSplines.SplineSegments[iSpline].spline.GetPointOnSpline(1)) < junctionDist)
                    {
                        node.nearJunction = true;
                    }
                }
                // Add to frame
                gravityFrame.Add(node);
                prevNode = node;
                // Add spline segment sub-frame as well
                segmentSubFrame[iSpline].Add(node);
            }
        }
        // Create closeby list from, and connect, neighboring splines
        for (int iSeg = 0; iSeg < mazeFrameSplines.SplineSegments.Count; iSeg++)
        {
            // Add frame to its own closeby
            List <GravityNode> currSubFrame = segmentSubFrame[iSeg];
            foreach (GravityNode node in currSubFrame)
            {
                node.closeby.AddRange(currSubFrame);
            }

            // Start/end of spline
            List <List <MazeFrameSplines.SplineSegment> > segList = new List <List <MazeFrameSplines.SplineSegment> >(2)
            {
                mazeFrameSplines.SplineSegments[iSeg].startNeighbors, mazeFrameSplines.SplineSegments[iSeg].endNeighbors
            };
            for (int iStartEnd = 0; iStartEnd <= 1; iStartEnd++)
            {
                foreach (MazeFrameSplines.SplineSegment neighSeg in segList[iStartEnd])
                {
                    // Get sub frame index
                    List <GravityNode> neighSegSF = segmentSubFrame[mazeFrameSplines.SplineSegments.IndexOf(neighSeg)];

                    // Add to closeby list
                    foreach (GravityNode node in currSubFrame)
                    {
                        node.closeby.AddRange(neighSegSF);
                    }

                    // Connect start/end
                    switch (iStartEnd)
                    {
                    case 0:
                    {
                        if (Vector3.Distance(currSubFrame[0].position, neighSegSF[0].position) <
                            Vector3.Distance(currSubFrame[0].position, neighSegSF[neighSegSF.Count - 1].position))
                        {
                            currSubFrame[0].neighbors.Add(neighSegSF[0]);
                        }
                        else
                        {
                            currSubFrame[0].neighbors.Add(neighSegSF[neighSegSF.Count - 1]);
                        }
                        break;
                    }

                    case 1:
                    {
                        if (Vector3.Distance(currSubFrame[currSubFrame.Count - 1].position, neighSegSF[0].position) <
                            Vector3.Distance(currSubFrame[currSubFrame.Count - 1].position, neighSegSF[neighSegSF.Count - 1].position))
                        {
                            currSubFrame[currSubFrame.Count - 1].neighbors.Add(neighSegSF[0]);
                        }
                        else
                        {
                            currSubFrame[currSubFrame.Count - 1].neighbors.Add(neighSegSF[neighSegSF.Count - 1]);
                        }
                        break;
                    }
                    }
                }
            }
        }
    }
    private IEnumerator CreateSplineFittedMeshesCoroutine(GameObject mazeObjects, MazeFrameSplines mazeFrameSplines, GameObject prefabInst, int objPerCurveSegment, List <Color> colorList)
    {
        MazeObjectsPlaced = 0;
        // First, setup the shared materials that will be modified.
        Dictionary <int, Material> materials = new Dictionary <int, Material>();

        foreach (MazeFrameSplines.SplineSegment seg in mazeFrameSplines.SplineSegments)
        {
            if (seg.shortestPathInd.Count == 1)
            {
                if (materials.ContainsKey(seg.shortestPathInd[0]))
                {
                    continue;
                }
                Material mat = Object.Instantiate(prefabInst.GetComponent <MeshRenderer>().material);
                mat.SetColor("_EmissionColor", GetColorBasedOnPathIndex(seg.shortestPathInd, ref colorList));
                materials.Add(seg.shortestPathInd[0], mat);
            }
        }
        Material materialBlack = Object.Instantiate(prefabInst.GetComponent <MeshRenderer>().material);

        materialBlack.SetColor("_EmissionColor", Color.black);
        //List<Color> colorList = new List<Color>();
        //Dictionary<List<int>, Material> materials = new Dictionary<List<int>, Material>();
        //foreach (MazeFrameSplines.SplineSegment seg in mazeFrameSplines.SplineSegments)
        //{
        //    if (materials.ContainsListKeyWithContents(seg.shortestPathInd)) { continue; }
        //    Material mat = Object.Instantiate(prefabInst.GetComponent<MeshRenderer>().material);
        //    mat.SetColor("_EmissionColor", GetColorBasedOnPathIndex(seg.shortestPathInd, ref colorList));
        //    materials.Add(seg.shortestPathInd, mat);
        //}

        // Per spline, create gameobject holding the mesh
        //Dictionary<string, GameObject> processedPrefabInstances = new Dictionary<string, GameObject>();
        int count = 0;

        foreach (MazeFrameSplines.SplineSegment segment in mazeFrameSplines.SplineSegments)
        {
            GameObject obj           = Object.Instantiate(prefabInst, mazeObjects.transform) as GameObject;
            string     junctionAffix = "";
            if (segment.isJunction)
            {
                junctionAffix = "junction_" + segment.JunctionID + "_";
            }
            obj.name  = junctionAffix + "spline_" + segment.spline.startPoint.ToString() + "_" + segment.spline.endPoint.ToString();
            obj.layer = 10;

            // Attached SplineFittedMesh script and initilaze with prefab
            obj.AddComponent(typeof(SplineFittedMesh));
            SplineFittedMesh splineMesh = obj.GetComponent <SplineFittedMesh>();
            splineMesh.SetSplineAxis(Vector3.forward);
            splineMesh.SetSpline(segment.spline);
            splineMesh.SetNMeshesPerSegment(objPerCurveSegment);
            Mesh[] meshes;
            if (mazeFrameSplines.ShortestPathInd.Count > 1)
            {
                meshes = new Mesh[] { Instantiate(obj.GetComponent <MeshFilter>().mesh), Instantiate(obj.GetComponent <MeshFilter>().mesh) };
            }
            else
            {
                meshes = new Mesh[] { Instantiate(obj.GetComponent <MeshFilter>().mesh) };
            }
            splineMesh.SetMeshBase(meshes);

            // Set segment color to first color if only one path, or determine multiple colors below
            if (mazeFrameSplines.ShortestPathInd.Count == 1)
            {
                obj.GetComponent <MeshRenderer>().sharedMaterial = materials[0];
            }
            else
            {
                // Determine segment color based on start/end neighbors if segment color itself is ambigious
                Material[] mats = new Material[2];
                if (segment.shortestPathInd.Count == 1)
                {
                    mats[0] = materials[segment.shortestPathInd[0]];
                    mats[1] = materials[segment.shortestPathInd[0]];
                }
                else
                {
                    // Start
                    if (segment.shortestPathIndAtStart.Count == 1)
                    {
                        mats[0] = materials[segment.shortestPathIndAtStart[0]];
                    }
                    else
                    {
                        if (segment.shortestPathIndAtEnd.Count == 1)
                        {
                            mats[0] = materials[segment.shortestPathIndAtEnd[0]];
                        }
                        else
                        {
                            mats[0] = materialBlack;
                        }
                    }
                    // End
                    if (segment.shortestPathIndAtEnd.Count == 1)
                    {
                        mats[1] = materials[segment.shortestPathIndAtEnd[0]];
                    }
                    else
                    {
                        if (segment.shortestPathIndAtStart.Count == 1)
                        {
                            mats[1] = materials[segment.shortestPathIndAtStart[0]];
                        }
                        else
                        {
                            mats[1] = materialBlack;
                        }
                    }
                }
                if (mats[0] == materialBlack && mats[1] == materialBlack &&
                    segment.shortestPathIndAtStart.EqualContents(segment.shortestPathIndAtEnd) &&
                    segment.shortestPathIndAtStart.Count == 2 && segment.shortestPathIndAtEnd.Count == 2)
                {
                    mats[0] = materials[segment.shortestPathInd[0]];
                    mats[1] = materials[segment.shortestPathInd[1]];
                }
                // Assign to object
                obj.GetComponent <MeshRenderer>().sharedMaterials = mats;
            }

            // Increment global counter
            MazeObjectsPlaced++;

            // Yield
            count++;
            if ((count % 200) == 0)
            {
                yield return(null);
            }
        }
        // Destroy processed prefab instances
        Object.Destroy(prefabInst);
    }
    public void PlaceCubeOfDeath(ref GameObject cubeParent, Vector3 position, Vector3 scale, Vector3 mazeFrameScale, MazeFrameSplines mazeFrameSplines)
    {
        if (cubeParent != null)
        {
            Object.Destroy(cubeParent);
            cubeParent = null;
        }
        cubeParent = new GameObject("CubesOfDeath");
        GameObject cube = Object.Instantiate(Resources.Load("Prefabs/" + "CubeOfDeath"), cubeParent.transform) as GameObject;

        cube.transform.position   = position;
        cube.transform.localScale = Vector3.zero;
        cube.name = "CubeOfDeath";
        CubeOfDeathController cubeOfDeathController = cube.GetComponent <CubeOfDeathController>();

        CubeOfDeathController.MazeScale        = mazeFrameScale;
        CubeOfDeathController.MazeFrameSplines = mazeFrameSplines;
        CubeOfDeathController.cubeScale        = scale;
        cubeOfDeathController.Activate();
        //cube.SetActive(true);
    }
    private void AddPathObjectLights(GameObject mazeLightObjects, MazeFrameSplines mazeFrameSplines, GameObject prefabInst, float spacing, Vector3 mazeObjectPrefabSize, List <Color> colorList)
    {
        // First, setup the shared materials that will be modified.
        Dictionary <int, Material> materials = new Dictionary <int, Material>();

        foreach (MazeFrameSplines.SplineSegment seg in mazeFrameSplines.SplineSegments)
        {
            if (seg.shortestPathInd.Count == 1)
            {
                if (materials.ContainsKey(seg.shortestPathInd[0]))
                {
                    continue;
                }
                Material mat = Object.Instantiate(prefabInst.GetComponent <MeshRenderer>().material);
                mat.SetColor("_EmissionColor", GetColorBasedOnPathIndex(seg.shortestPathInd, ref colorList));
                materials.Add(seg.shortestPathInd[0], mat);
            }
        }
        Material materialBlack = Object.Instantiate(Resources.Load("Materials/" + "PathObjectLight")) as Material;

        materialBlack.SetColor("_EmissionColor", Color.black);

        // Per spline, create lights
        Vector3 lightSize = prefabInst.GetComponent <MeshRenderer>().bounds.size;
        int     count     = 0;

        foreach (MazeFrameSplines.SplineSegment segment in mazeFrameSplines.SplineSegments)
        {
            // Create parent object
            GameObject parent = new GameObject("segment" + count);
            parent.transform.parent   = mazeLightObjects.transform;
            parent.transform.position = Vector3.zero;
            parent.transform.rotation = Quaternion.identity;
            parent.AddComponent <MeshFilter>();
            parent.AddComponent <MeshRenderer>();
            // Set color based on shortest path ind.
            if (segment.shortestPathInd.Count == 1)
            {
                parent.GetComponent <MeshRenderer>().sharedMaterial = materials[segment.shortestPathInd[0]];
            }
            else
            {
                parent.GetComponent <MeshRenderer>().sharedMaterial = materialBlack;
            }


            // Determine total number of lights to place, and place them equally spaced
            int   nLights     = Mathf.RoundToInt(segment.spline.SplineTotalDistance / (lightSize.z + spacing));
            float currSpacing = (segment.spline.SplineTotalDistance - (lightSize.z * nLights)) / nLights;

            // Place lights
            for (int iLight = 0; iLight < nLights; iLight++)
            {
                // Get current spline vectors and set base position/rotation of light
                float      currDist      = ((lightSize.z + currSpacing) / 2f) + iLight * (lightSize.z + currSpacing);
                float      currT         = segment.spline.GetTAtDistance(currDist);
                Vector3    currTangent   = segment.spline.GetTangentToPointOnSpline(currT);
                Vector3    currNormal    = segment.spline.DefaultGetNormalAtT(currT);
                Vector3    currReference = Vector3.Cross(currNormal, currTangent).normalized;
                Quaternion baseRotation  = Quaternion.LookRotation(currTangent);
                Vector3    basePosition  = segment.spline.GetPointOnSpline(currT);
                Vector3    offset        = ((mazeObjectPrefabSize.x / 2f) + (lightSize.x / 2f)) * currReference;

                // Place light object left/right
                foreach (Vector3 currOffset in new Vector3[] { -offset, offset })
                {
                    GameObject obj = Object.Instantiate(prefabInst, basePosition + currOffset, baseRotation, parent.transform) as GameObject;

                    // Set color based on shortest path ind.
                    if (segment.shortestPathInd.Count == 1)
                    {
                        obj.GetComponent <MeshRenderer>().sharedMaterial = materials[segment.shortestPathInd[0]];
                    }
                    else
                    {
                        obj.GetComponent <MeshRenderer>().sharedMaterial = materialBlack;
                    }

                    // Increment global counter
                    MazeObjectsPlaced++;
                }
            }
            // Merge into one object
            Utilities.MergeChildrenOfParent(parent, true, true, true);
            count++;
        }
        // Destroy processed prefab instances
        Object.Destroy(prefabInst);
    }
 public void PopulateWithSplineFittedBars(MazeFrame mazeFrame, ref MazeFrameSplines mazeFrameSplines, ref GameObject mazeObjects, Vector3 resize)
 {
     PopulateWithSplineFittedShape(mazeFrame, ref mazeFrameSplines, ref mazeObjects, resize, "MazeBar");
 }