Beispiel #1
0
		public override void OnLatePostScan()
		{
			if (!Application.isPlaying)
			{
				return;
			}
			this.RemoveObstacles();
			NavGraph[] graphs = AstarPath.active.graphs;
			RVOSimulator rvosimulator = UnityEngine.Object.FindObjectOfType<RVOSimulator>();
			if (rvosimulator == null)
			{
				throw new NullReferenceException("No RVOSimulator could be found in the scene. Please add one to any GameObject");
			}
			Simulator simulator = rvosimulator.GetSimulator();
			for (int i = 0; i < graphs.Length; i++)
			{
				RecastGraph recastGraph = graphs[i] as RecastGraph;
				if (recastGraph != null)
				{
					foreach (RecastGraph.NavmeshTile ng in recastGraph.GetTiles())
					{
						this.AddGraphObstacles(simulator, ng);
					}
				}
				else
				{
					INavmesh navmesh = graphs[i] as INavmesh;
					if (navmesh != null)
					{
						this.AddGraphObstacles(simulator, navmesh);
					}
				}
			}
			simulator.UpdateObstacles();
		}
	public void SetGraph (RecastGraph graph) {
		this.graph = graph;

		if (graph == null)
			return;

		dirtyTiles = new bool[graph.tileXCount*graph.tileZCount];
		anyDirtyTiles = false;
	}
Beispiel #3
0
        public static Transform addFlag(Vector3 point)
        {
            RecastGraph newGraph = LevelNavigation.addGraph();
            FlagData    flagData = new FlagData(string.Empty, 64, true);

            LevelNavigation.flags.Add(new Flag(point, newGraph, flagData));
            LevelNavigation.flagData.Add(flagData);
            return(LevelNavigation.flags[LevelNavigation.flags.Count - 1].model);
        }
Beispiel #4
0
    public void CreateDebugMesh()
    {
        RecastGraph graph = target as RecastGraph;

        meshRenderer = GameObject.Find("RecastGraph_" + graph.guid.ToString());

        if (meshRenderer == null || meshFilter == null || navmeshRender == null || navmeshRenderer == null)
        {
            if (meshRenderer == null)
            {
                meshRenderer           = new GameObject("RecastGraph_" + graph.guid.ToString());
                meshRenderer.hideFlags = /*HideFlags.NotEditable |*/ HideFlags.DontSave;
            }

            if (meshRenderer.GetComponent <NavMeshRenderer>() == null)
            {
                meshRenderer.AddComponent <NavMeshRenderer>();
            }

            MeshFilter filter;
            if ((filter = meshRenderer.GetComponent <MeshFilter>()) == null)
            {
                filter = meshRenderer.AddComponent <MeshFilter>();
            }

            navmeshRenderer = meshRenderer.GetComponent <MeshRenderer>();
            if (navmeshRenderer == null)
            {
                navmeshRenderer                = meshRenderer.AddComponent <MeshRenderer>();
                navmeshRenderer.castShadows    = false;
                navmeshRenderer.receiveShadows = false;
            }

            if (filter.sharedMesh == null)
            {
                navmeshRender     = new Mesh();
                filter.sharedMesh = navmeshRender;
            }
            else
            {
                navmeshRender = filter.sharedMesh;
            }

            navmeshRender.name = "Navmesh_" + graph.guid.ToString();
        }

        if (navmeshMaterial == null)
        {
            navmeshMaterial = AssetDatabase.LoadAssetAtPath(AstarPathEditor.editorAssets + "/Materials/Navmesh.mat", typeof(Material)) as Material;
            if (navmeshMaterial == null)
            {
                Debug.LogWarning("Could not find navmesh material at path " + AstarPathEditor.editorAssets + "/Materials/Navmesh.mat");
            }
            navmeshRenderer.material = navmeshMaterial;
        }
    }
Beispiel #5
0
    public void UpdateDebugMesh(AstarPath astar)
    {
#if UNITY_3_5
        CreateDebugMesh();

        meshRenderer.transform.position   = Vector3.zero;
        meshRenderer.transform.localScale = Vector3.one;
#endif

        RecastGraph graph = target as RecastGraph;

        if (graph != null && graph.nodes != null && graph.vectorVertices != null)
        {
            if (navmeshRender == null)
            {
                navmeshRender = new Mesh();
            }

            navmeshRender.Clear();

            navmeshRender.vertices = graph.vectorVertices;

            int[]   tris    = new int[graph.nodes.Length * 3];
            Color[] vColors = new Color[graph.vectorVertices.Length];

            for (int i = 0; i < graph.nodes.Length; i++)
            {
                MeshNode node = graph.nodes[i] as MeshNode;
                tris[i * 3]     = node.v1;
                tris[i * 3 + 1] = node.v2;
                tris[i * 3 + 2] = node.v3;
                Color col = Mathfx.IntToColor(node.area, 1F);
                vColors[node.v1] = col;
                vColors[node.v2] = col;
                vColors[node.v3] = col;
            }
            navmeshRender.triangles = tris;
            navmeshRender.colors    = vColors;

            //meshRenderer.transform.position = graph.forcedBoundsCenter-graph.forcedBoundsSize*0.5F;
            //meshRenderer.transform.localScale = Int3.Precision*Voxelize.CellScale;
            navmeshRender.RecalculateNormals();
            navmeshRender.RecalculateBounds();

            if (navmeshMaterial == null)
            {
                navmeshMaterial = AssetDatabase.LoadAssetAtPath(AstarPathEditor.editorAssets + "/Materials/Navmesh.mat", typeof(Material)) as Material;
            }

            navmeshRender.hideFlags = HideFlags.HideAndDontSave;

#if UNITY_3_5
            navmeshRenderer.material = navmeshMaterial;
#endif
        }
    }
 public void SetGraph(RecastGraph graph)
 {
     this.graph = graph;
     if (graph == null)
     {
         return;
     }
     this.dirtyTiles    = new bool[graph.tileXCount * graph.tileZCount];
     this.anyDirtyTiles = false;
 }
Beispiel #7
0
    bool ConfigNavMeshSurface(RecastGraph recast, ref NavMeshSurface surface)
    {
        #region set agent
        var agentTypeID = int.MinValue;
        var count       = NavMesh.GetSettingsCount();
        for (var i = 0; i < count; i++)
        {
            var settings = NavMesh.GetSettingsByIndex(i);
            if (Mathf.Abs(settings.agentRadius - recast.characterRadius) > Mathf.Epsilon)
            {
                continue;
            }
            if (Mathf.Abs(settings.agentHeight - recast.walkableHeight) > Mathf.Epsilon)
            {
                continue;
            }
            if (Mathf.Abs(settings.agentClimb - recast.walkableClimb) > Mathf.Epsilon)
            {
                continue;
            }
            if (Mathf.Abs(settings.agentSlope - recast.maxSlope) > Mathf.Epsilon)
            {
                continue;
            }
            agentTypeID = settings.agentTypeID;
        }
        if (agentTypeID == int.MinValue)
        {
            return(false);
        }
        surface.agentTypeID = agentTypeID;
        #endregion

        surface.collectObjects = CollectObjects.Volume;
        surface.size           = recast.forcedBoundsSize;
        surface.center         = recast.forcedBoundsCenter;
        surface.layerMask      = recast.mask;
        surface.useGeometry    = NavMeshCollectGeometry.RenderMeshes;
        if (recast.rasterizeColliders)
        {
            surface.useGeometry = NavMeshCollectGeometry.PhysicsColliders;
        }

        #region TODO: set area
        // RecastMeshObj?
        #endregion

        surface.overrideVoxelSize = true;
        surface.voxelSize         = recast.cellSize;
        surface.overrideTileSize  = true;
        surface.tileSize          = recast.editorTileSize;

        return(true);
    }
Beispiel #8
0
    public void UpdateDebugMesh(AstarPath astar)
    {
        CreateDebugMesh();
        RecastGraph graph = target as RecastGraph;

        //if (graph.useCRecast) {
        meshRenderer.transform.position   = Vector3.zero;
        meshRenderer.transform.localScale = Vector3.one;
        //} else {
        //meshRenderer.transform.position = graph.forcedBounds.min;
        //meshRenderer.transform.localScale = new Vector3(graph.cellSize * 100, 1, graph.cellSize * 100);
        //}

        if (graph != null && graph.nodes != null && graph.vectorVertices != null)
        {
            navmeshRender.Clear();

            navmeshRender.vertices = graph.vectorVertices;
            //Vector3[] vs = new Vector3[graph.vertices.Length];
            //for (int i=0;i<graph.vertices.Length;i++) {
            //	vs[i] = graph.vertices[i];
            //}
            //navmeshRender.vertices = vs;

            int[]   tris    = new int[graph.nodes.Length * 3];
            Color[] vColors = new Color[graph.vectorVertices.Length];

            for (int i = 0; i < graph.nodes.Length; i++)
            {
                MeshNode node = graph.nodes[i] as MeshNode;
                tris[i * 3]     = node.v1;
                tris[i * 3 + 1] = node.v2;
                tris[i * 3 + 2] = node.v3;
                Color col = Mathfx.IntToColor(node.area, 1F);
                vColors[node.v1] = col;
                vColors[node.v2] = col;
                vColors[node.v3] = col;
            }
            navmeshRender.triangles = tris;
            navmeshRender.colors    = vColors;

            //meshRenderer.transform.position = graph.forcedBoundsCenter-graph.forcedBoundsSize*0.5F;
            //meshRenderer.transform.localScale = Int3.Precision*Voxelize.CellScale;
            navmeshRender.RecalculateNormals();
            navmeshRender.RecalculateBounds();

            if (navmeshMaterial == null)
            {
                navmeshMaterial = AssetDatabase.LoadAssetAtPath(AstarPathEditor.editorAssets + "/Materials/Navmesh.mat", typeof(Material)) as Material;
            }
            navmeshRenderer.material = navmeshMaterial;
        }
    }
Beispiel #9
0
 // Token: 0x060005D9 RID: 1497 RVA: 0x00035D54 File Offset: 0x00034154
 public TileHandler(RecastGraph graph)
 {
     if (graph == null)
     {
         throw new ArgumentNullException("'graph' cannot be null");
     }
     if (graph.GetTiles() == null)
     {
         throw new ArgumentException("graph has no tiles. Please scan the graph before creating a TileHandler");
     }
     this.activeTileTypes     = new TileHandler.TileType[graph.tileXCount * graph.tileZCount];
     this.activeTileRotations = new int[this.activeTileTypes.Length];
     this.activeTileOffsets   = new int[this.activeTileTypes.Length];
     this.reloadedInBatch     = new bool[this.activeTileTypes.Length];
     this._graph = graph;
 }
Beispiel #10
0
 public static void updateBounds()
 {
     LevelNavigation._bounds = new List <Bounds>();
     for (int i = 0; i < AstarPath.active.graphs.Length; i++)
     {
         RecastGraph recastGraph = (RecastGraph)AstarPath.active.graphs[i];
         if (recastGraph != null)
         {
             RecastGraph.NavmeshTile[] tiles = recastGraph.GetTiles();
             if (tiles != null && tiles.Length > 0)
             {
                 LevelNavigation.bounds.Add(new Bounds(recastGraph.forcedBoundsCenter, recastGraph.forcedBoundsSize + LevelNavigation.BOUNDS_SIZE));
             }
         }
     }
 }
Beispiel #11
0
 // has the nav mesh already been generated from tagged geometry and the data cached for load on level begin
 public static bool HasNavMeshBeenCorrectlyAutoGenerated()
 {
     if (null != AstarPath.active && 1 == AstarPath.active.graphs.Length && AstarPath.active.graphs[0] is RecastGraph) // we need a single recast
     {
         RecastGraph recast = AstarPath.active.graphs[0] as RecastGraph;
         if (!recast.generateFromInputMesh) // it should NOT be marked for generation from a pre built input mesh
         {
             // we need data for the neav mesh
             if (AstarPath.active.astarData.cacheStartup && AstarPath.active.astarData.data_cachedStartup != null && AstarPath.active.astarData.data_cachedStartup.Length > 0)
             {
                 return(true);
             }
         }
     }
     return(false);
 }
Beispiel #12
0
 // Token: 0x060023BB RID: 9147 RVA: 0x000C63D4 File Offset: 0x000C47D4
 public Flag(Vector3 newPoint, RecastGraph newGraph, FlagData newData)
 {
     this._point         = newPoint;
     this._model         = ((GameObject)UnityEngine.Object.Instantiate(Resources.Load("Edit/Flag"))).transform;
     this.model.name     = "Flag";
     this.model.position = this.point;
     this.model.parent   = LevelNavigation.models;
     this._area          = this.model.FindChild("Area").GetComponent <LineRenderer>();
     this._bounds        = this.model.FindChild("Bounds").GetComponent <LineRenderer>();
     this.navmesh        = this.model.FindChild("Navmesh").GetComponent <MeshFilter>();
     this.width          = 0f;
     this.height         = 0f;
     this._graph         = newGraph;
     this.data           = newData;
     this.setupGraph();
     this.buildMesh();
 }
Beispiel #13
0
 // set up the default values for a nav mesh
 static private void SetNavMeshDefaults(RecastGraph recastGraph, Vector3 center, Vector3 boundingBox, bool isMultiTileRequired)
 {
     recastGraph.characterRadius = NavMeshCharacterRadius; // the larger this is, the larger the borders around the nav mesh will be
     recastGraph.cellSize        = 0.5f;                   // 0.2f; // a lower value for this generates a curved border around objects (which means character gets stuck less, as no sharp corners)
     recastGraph.walkableClimb   = 1.0f;
     recastGraph.maxSlope        = 45.0f;
     recastGraph.showMeshOutline = true;
     recastGraph.contourMaxError = 1f; // the smaller this is the closer the edge of the nav mesh will match the edge of geo, a large value
     // will mean the edge of the nav mesh will be straight even if their is a jagged edge to the geo
     recastGraph.mask               = (1 << LayerMask.NameToLayer("Ground")) | (1 << LayerMask.NameToLayer("Obstacle"));
     recastGraph.excludeMask        = (1 << LayerMask.NameToLayer("Obstacle"));
     recastGraph.forcedBoundsCenter = center;
     recastGraph.forcedBoundsSize   = boundingBox;
     if (!isMultiTileRequired)
     {
         recastGraph.SetUpNavMeshToFitOnOneTile();
     }
 }
Beispiel #14
0
 public TileHandler(RecastGraph graph)
 {
     if (graph == null)
     {
         throw new ArgumentNullException("graph");
     }
     if (graph.GetTiles() == null)
     {
         Debug.LogWarning("Creating a TileHandler for a graph with no tiles. Please scan the graph before creating a TileHandler");
     }
     this.tileXCount          = graph.tileXCount;
     this.tileZCount          = graph.tileZCount;
     this.activeTileTypes     = new TileHandler.TileType[this.tileXCount * this.tileZCount];
     this.activeTileRotations = new int[this.activeTileTypes.Length];
     this.activeTileOffsets   = new int[this.activeTileTypes.Length];
     this.reloadedInBatch     = new bool[this.activeTileTypes.Length];
     this._graph = graph;
 }
Beispiel #15
0
    static public void SetAPPToUseInputMesh(bool singleInput)
    {
        if (AstarPath.active == null)
        {
            EB.Debug.LogError("LevelHelperEditor::SetAPPToUseInputMesh AStar object not found!");
            return;
        }

        AstarPath.active.astarData.data_cachedStartup = null;
        AstarPath.active.astarData.cacheStartup       = false;
        AstarPath.active.showNavGraphs = false;
        RecastGraph recastGraph = (RecastGraph)AstarPath.active.astarData.FindGraphOfType(typeof(RecastGraph));

        if (null != recastGraph)
        {
            recastGraph.generateFromInputMesh = true;
            recastGraph.isSingleInputMesh     = singleInput;
        }
    }
Beispiel #16
0
        public override void OnLatePostScan()
        {
            if (!Application.isPlaying)
            {
                return;
            }

            Profiler.BeginSample("Update RVO Obstacles From Graphs");
            RemoveObstacles();
            NavGraph[]   graphs = AstarPath.active.graphs;
            RVOSimulator rvosim = RVOSimulator.active;

            if (rvosim == null)
            {
                throw new System.NullReferenceException("No RVOSimulator could be found in the scene. Please add one to any GameObject");
            }

            // Remember which simulator these obstacles were added to
            lastSim = rvosim.GetSimulator();

            for (int i = 0; i < graphs.Length; i++)
            {
                RecastGraph recast  = graphs[i] as RecastGraph;
                INavmesh    navmesh = graphs[i] as INavmesh;
                GridGraph   grid    = graphs[i] as GridGraph;
                if (recast != null)
                {
                    foreach (var tile in recast.GetTiles())
                    {
                        AddGraphObstacles(lastSim, tile);
                    }
                }
                else if (navmesh != null)
                {
                    AddGraphObstacles(lastSim, navmesh);
                }
                else if (grid != null)
                {
                    AddGraphObstacles(lastSim, grid);
                }
            }
            Profiler.EndSample();
        }
Beispiel #17
0
 private void checkGroundTag()
 {
     try
     {
         RecastGraph recastGraph = AstarPath.active.astarData.recastGraph;
         this.node            = recastGraph.GetNearest(base.transform.position).node;
         this.ugroundTag      = this.node.Tag;
         this.playerGroundTag = (int)this.ugroundTag;
     }
     catch
     {
     }
     if (this.remotePlayer)
     {
         this.isSwimming = this.netAnimator.GetBool("swimmingBool");
     }
     else
     {
         this.isSwimming = LocalPlayer.FpCharacter.swimming;
     }
 }
 public void removeSmallRegions()
 {
     AstarPath.RegisterSafeUpdate(delegate
     {
         int[] sizes             = new int[10000];
         RecastGraph recastGraph = AstarPath.active.astarData.recastGraph;
         recastGraph.GetNodes(delegate(GraphNode node)
         {
             sizes[(int)((UIntPtr)node.Area)]++;
             return(true);
         });
         int largest = 0;
         for (int i = 0; i < sizes.Length; i++)
         {
             largest = ((sizes[i] <= sizes[largest]) ? largest : i);
         }
         recastGraph.GetNodes(delegate(GraphNode node)
         {
             bool flag = false;
             using (List <uint> .Enumerator enumerator = Scene.MutantControler.mostCommonArea.GetEnumerator())
             {
                 while (enumerator.MoveNext())
                 {
                     int num = (int)enumerator.Current;
                     if ((long)num == (long)((ulong)node.Area))
                     {
                         flag = true;
                     }
                 }
             }
             if ((ulong)node.Area != (ulong)((long)largest) && !flag)
             {
                 node.Walkable = false;
             }
             return(true);
         });
         AstarPath.active.FloodFill();
     });
 }
Beispiel #19
0
        public static RecastGraph addGraph()
        {
            RecastGraph recastGraph = (RecastGraph)AstarPath.active.astarData.AddGraph(typeof(RecastGraph));

            recastGraph.cellSize                = 0.1f;
            recastGraph.cellHeight              = 0.1f;
            recastGraph.useTiles                = true;
            recastGraph.editorTileSize          = 128;
            recastGraph.minRegionSize           = 64f;
            recastGraph.walkableHeight          = 2f;
            recastGraph.walkableClimb           = 0.75f;
            recastGraph.characterRadius         = 0.5f;
            recastGraph.maxSlope                = 75f;
            recastGraph.maxEdgeLength           = 16f;
            recastGraph.contourMaxError         = 2f;
            recastGraph.terrainSampleSize       = 1;
            recastGraph.rasterizeTrees          = false;
            recastGraph.rasterizeMeshes         = false;
            recastGraph.rasterizeColliders      = true;
            recastGraph.colliderRasterizeDetail = 4f;
            recastGraph.mask = RayMasks.BLOCK_NAVMESH;
            return(recastGraph);
        }
Beispiel #20
0
        public override void OnLatePostScan()
        {
            if (!Application.isPlaying)
            {
                return;
            }
            this.RemoveObstacles();
            NavGraph[]   graphs = AstarPath.active.graphs;
            RVOSimulator active = RVOSimulator.active;

            if (active == null)
            {
                throw new NullReferenceException("No RVOSimulator could be found in the scene. Please add one to any GameObject");
            }
            this.lastSim = active.GetSimulator();
            for (int i = 0; i < graphs.Length; i++)
            {
                RecastGraph recastGraph = graphs[i] as RecastGraph;
                INavmesh    navmesh     = graphs[i] as INavmesh;
                GridGraph   gridGraph   = graphs[i] as GridGraph;
                if (recastGraph != null)
                {
                    foreach (NavmeshTile ng in recastGraph.GetTiles())
                    {
                        this.AddGraphObstacles(this.lastSim, ng);
                    }
                }
                else if (navmesh != null)
                {
                    this.AddGraphObstacles(this.lastSim, navmesh);
                }
                else if (gridGraph != null)
                {
                    this.AddGraphObstacles(this.lastSim, gridGraph);
                }
            }
        }
Beispiel #21
0
    public void OnPopulateZones(PopulateZonesPlayingEvent evt)
    {
        if (scanOnStartup && AStarPathfindingUtils.WillNavMeshBeBuiltFromInputMeshOnLevelBegin())
        {
            if (!astarData.cacheStartup || astarData.data_cachedStartup == null)
            {
                LevelHelper helper = GameObject.FindObjectOfType(typeof(LevelHelper)) as LevelHelper;
                if (helper != null)
                {
                    AStarPathfindingUtils.CreateRecastNavMeshForInputMeshes(helper.transform.Find(ZoneHelper.ZonesRootName), helper.isOverworldNavMeshRequired);
                    Scan();
                    EventManager.instance.Raise(new NavMeshScanEvent());
                }
            }
        }

        if (Application.isPlaying)
        {
            RecastGraph.DestroyWalkableAreaObjects();     // we don't need the instances of AStarPathfindingWalkableArea in the game after this point
            RecastGraph.DestroyRecastMeshObjComponents(); // RecastMeshObj's are only used for nav mesh generation, they are not needed after this point
            AStarPathfindingRecastCut.DestroyRecastCutObjects();
            AStarPathfindingGenerationTimeGeo.DestroyGenerationTimeGeoObjects();
        }
    }
Beispiel #22
0
 public static void load()
 {
     LevelNavigation._models                 = new GameObject().transform;
     LevelNavigation.models.name             = "Navigation";
     LevelNavigation.models.parent           = Level.level;
     LevelNavigation.models.tag              = "Logic";
     LevelNavigation.models.gameObject.layer = LayerMasks.LOGIC;
     LevelNavigation._bounds                 = new List <Bounds>();
     LevelNavigation.flagData                = new List <FlagData>();
     if (ReadWrite.fileExists(Level.info.path + "/Environment/Bounds.dat", false, false))
     {
         River river = new River(Level.info.path + "/Environment/Bounds.dat", false);
         byte  b     = river.readByte();
         if (b > 0)
         {
             byte b2 = river.readByte();
             for (byte b3 = 0; b3 < b2; b3 += 1)
             {
                 Vector3 vector  = river.readSingleVector3();
                 Vector3 vector2 = river.readSingleVector3();
                 LevelNavigation.bounds.Add(new Bounds(vector, vector2));
             }
         }
         river.closeRiver();
     }
     if (ReadWrite.fileExists(Level.info.path + "/Environment/Flags_Data.dat", false, false))
     {
         River river2 = new River(Level.info.path + "/Environment/Flags_Data.dat", false);
         byte  b4     = river2.readByte();
         if (b4 > 0)
         {
             byte b5 = river2.readByte();
             for (byte b6 = 0; b6 < b5; b6 += 1)
             {
                 string newDifficultyGUID = river2.readString();
                 byte   newMaxZombies     = 64;
                 if (b4 > 1)
                 {
                     newMaxZombies = river2.readByte();
                 }
                 bool newSpawnZombies = true;
                 if (b4 > 2)
                 {
                     newSpawnZombies = river2.readBoolean();
                 }
                 LevelNavigation.flagData.Add(new FlagData(newDifficultyGUID, newMaxZombies, newSpawnZombies));
             }
         }
         river2.closeRiver();
     }
     if (LevelNavigation.flagData.Count < LevelNavigation.bounds.Count)
     {
         for (int i = LevelNavigation.flagData.Count; i < LevelNavigation.bounds.Count; i++)
         {
             LevelNavigation.flagData.Add(new FlagData(string.Empty, 64, true));
         }
     }
     if (Level.isEditor)
     {
         LevelNavigation.flags = new List <Flag>();
         Object.Destroy(AstarPath.active.GetComponent <TileHandlerHelpers>());
         if (ReadWrite.fileExists(Level.info.path + "/Environment/Flags.dat", false, false))
         {
             River river3 = new River(Level.info.path + "/Environment/Flags.dat", false);
             byte  b7     = river3.readByte();
             if (b7 > 2)
             {
                 byte b8 = river3.readByte();
                 for (byte b9 = 0; b9 < b8; b9 += 1)
                 {
                     Vector3 newPoint = river3.readSingleVector3();
                     float   num      = river3.readSingle();
                     float   num2     = river3.readSingle();
                     if (b7 < 4)
                     {
                         num  *= 0.5f;
                         num2 *= 0.5f;
                     }
                     RecastGraph recastGraph = null;
                     if (ReadWrite.fileExists(string.Concat(new object[]
                     {
                         Level.info.path,
                         "/Environment/Navigation_",
                         b9,
                         ".dat"
                     }), false, false))
                     {
                         River river4 = new River(string.Concat(new object[]
                         {
                             Level.info.path,
                             "/Environment/Navigation_",
                             b9,
                             ".dat"
                         }), false);
                         byte b10 = river4.readByte();
                         if (b10 > 0)
                         {
                             recastGraph = LevelNavigation.buildGraph(river4);
                         }
                         river4.closeRiver();
                     }
                     if (recastGraph == null)
                     {
                         recastGraph = LevelNavigation.addGraph();
                     }
                     LevelNavigation.flags.Add(new Flag(newPoint, num, num2, recastGraph, LevelNavigation.flagData[(int)b9]));
                 }
             }
             river3.closeRiver();
         }
     }
     else if (Provider.isServer)
     {
         byte b11 = 0;
         while (ReadWrite.fileExists(string.Concat(new object[]
         {
             Level.info.path,
             "/Environment/Navigation_",
             b11,
             ".dat"
         }), false, false))
         {
             River river5 = new River(string.Concat(new object[]
             {
                 Level.info.path,
                 "/Environment/Navigation_",
                 b11,
                 ".dat"
             }), false);
             byte b12 = river5.readByte();
             if (b12 > 0)
             {
                 LevelNavigation.buildGraph(river5);
             }
             river5.closeRiver();
             b11 += 1;
         }
     }
 }
Beispiel #23
0
    public override void OnInspectorGUI(NavGraph target)
    {
        RecastGraph graph = target as RecastGraph;

        bool preEnabled = GUI.enabled;

        //if (graph.forceBounds) {

        graph.useCRecast = GUILayout.Toolbar(graph.useCRecast ?1:0, new GUIContent[2] {
            new GUIContent("C# Recast", "I have translated a portion of Recast to C#, this can be used in a webplayer but is more limited than the C++ version"),
            new GUIContent("C++ Recast", "Use the original C++ version of Recast, faster scanning times and has more features than the C# version, but it can only be used in the editor or on standalone applications (note that you can still scan the graph in the editor and then cache the startup if you want to build for a webplayer)"
                           + "\nTake a look in the docs on RecastGraph.useCRecast for more information on the special considerations when using this mode")
        }) == 1;

        if (graph.useCRecast)
        {
            BuildTarget bt = EditorUserBuildSettings.activeBuildTarget;
            if (bt != BuildTarget.StandaloneOSXIntel)
            {
                if (GUILayout.Button("Note that the C++ version of Recast does not work in your selected build target (" + bt + ")\n" +
                                     "Change build target to standalone (osx) if you want to be able to use C++\n" +
                                     "Click here for more info", AstarPathEditor.helpBox))
                {
                    Application.OpenURL(AstarPathEditor.GetURL("cRecastHelp"));
                }
            }
            else
            {
                if (GUILayout.Button("Note the special considerations when using C++ Recast\nClick here for more info", AstarPathEditor.helpBox))
                {
                    Application.OpenURL(AstarPathEditor.GetURL("cRecastHelp"));
                }
            }

            if (Application.platform == RuntimePlatform.WindowsEditor)
            {
                GUILayout.Label("C++ Recast can currently not be used on Windows", AstarPathEditor.helpBox);
            }
        }

        System.Int64 estWidth = Mathf.RoundToInt(Mathf.Ceil(graph.forcedBoundsSize.x / graph.cellSize));
        System.Int64 estDepth = Mathf.RoundToInt(Mathf.Ceil(graph.forcedBoundsSize.z / graph.cellSize));

        if (estWidth * estDepth >= 1024 * 1024 || estDepth >= 1024 * 1024 || estWidth >= 1024 * 1024)
        {
            GUIStyle helpBox = GUI.skin.FindStyle("HelpBox");
            if (helpBox == null)
            {
                helpBox = GUI.skin.FindStyle("Box");
            }

            Color preColor = GUI.color;
            if (estWidth * estDepth >= 2048 * 2048 || estDepth >= 2048 * 2048 || estWidth >= 2048 * 2048)
            {
                GUI.color = Color.red;
            }
            else
            {
                GUI.color = Color.yellow;
            }

            GUILayout.Label("Warning : Might take some time to calculate", helpBox);
            GUI.color = preColor;
        }

        GUI.enabled = false;
        EditorGUILayout.LabelField("Width (samples)", estWidth.ToString());

        EditorGUILayout.LabelField("Depth (samples)", estDepth.ToString());

        /*} else {
         *      GUI.enabled = false;
         *      EditorGUILayout.LabelField ("Width (samples)","undetermined");
         *      EditorGUILayout.LabelField ("Depth (samples)","undetermined");
         * }*/
        GUI.enabled = preEnabled;

        graph.cellSize = EditorGUILayout.FloatField(new GUIContent("Cell Size", "Size of one voxel in world units"), graph.cellSize);
        if (graph.cellSize < 0.001F)
        {
            graph.cellSize = 0.001F;
        }

        graph.cellHeight = EditorGUILayout.FloatField(new GUIContent("Cell Height", "Height of one voxel in world units"), graph.cellHeight);
        if (graph.cellHeight < 0.001F)
        {
            graph.cellHeight = 0.001F;
        }

        graph.walkableHeight  = EditorGUILayout.FloatField(new GUIContent("Walkable Height", "Minimum distance to the roof for an area to be walkable"), graph.walkableHeight);
        graph.walkableClimb   = EditorGUILayout.FloatField(new GUIContent("Walkable Climb", "How high can the character climb"), graph.walkableClimb);
        graph.characterRadius = EditorGUILayout.FloatField(new GUIContent("Character Radius", "Radius of the character, it's good to add some margin though"), graph.characterRadius);

        if (graph.useCRecast)
        {
            graph.regionMinSize = EditorGUILayout.IntField(new GUIContent("Min Region Size", "The lowest number of voxles in one area for it not to be deleted"), graph.regionMinSize);
        }

        graph.maxSlope      = EditorGUILayout.Slider(new GUIContent("Max Slope", "Approximate maximum slope"), graph.maxSlope, 0F, 90F);
        graph.maxEdgeLength = EditorGUILayout.FloatField(new GUIContent("Max Edge Length", "Maximum length of one edge in the completed navmesh before it is split. A lower value can often yield better quality graphs"), graph.maxEdgeLength);
        graph.maxEdgeLength = graph.maxEdgeLength < graph.cellSize ? graph.cellSize : graph.maxEdgeLength;

        /*if (!graph.useCRecast) {
         *      graph.erosionRadius = EditorGUILayout.IntSlider ("Erosion radius",graph.erosionRadius,0,256);
         * }*/

        graph.contourMaxError = EditorGUILayout.FloatField(new GUIContent("Max edge error", "Amount of simplification to apply to edges"), graph.contourMaxError);

        graph.rasterizeTerrain = EditorGUILayout.Toggle(new GUIContent("Rasterize Terrain", "Should a rasterized terrain be included"), graph.rasterizeTerrain);
        if (graph.rasterizeTerrain)
        {
            EditorGUI.indentLevel++;
            graph.rasterizeTrees = EditorGUILayout.Toggle(new GUIContent("Rasterize Trees", "Rasterize tree colliders on terrains. " +
                                                                         "If the tree prefab has a collider, that collider will be rasterized. " +
                                                                         "Otherwise a simple box collider will be used and the script will " +
                                                                         "try to adjust it to the tree's scale, it might not do a very good job though so " +
                                                                         "an attached collider is preferable."), graph.rasterizeTrees);
            if (graph.rasterizeTrees)
            {
                EditorGUI.indentLevel++;
                graph.colliderRasterizeDetail = EditorGUILayout.FloatField(new GUIContent("Collider Detail", "Controls the detail of the generated collider meshes. Increasing does not necessarily yield better navmeshes, but lowering will speed up scan"), graph.colliderRasterizeDetail);
                EditorGUI.indentLevel--;
            }

            graph.terrainSampleSize = EditorGUILayout.IntField(new GUIContent("Terrain Sample Size", "Size of terrain samples. A lower value is better, but slower"), graph.terrainSampleSize);
            graph.terrainSampleSize = graph.terrainSampleSize < 1 ? 1 : graph.terrainSampleSize;            //Clamp to at least 1
            EditorGUI.indentLevel--;
        }

        graph.rasterizeMeshes    = EditorGUILayout.Toggle(new GUIContent("Rasterize Meshes", "Should meshes be rasterized and used for building the navmesh"), graph.rasterizeMeshes);
        graph.rasterizeColliders = EditorGUILayout.Toggle(new GUIContent("Rasterize Colliders", "Should colliders be rasterized and used for building the navmesh"), graph.rasterizeColliders);
        if (graph.rasterizeColliders)
        {
            EditorGUI.indentLevel++;
            graph.colliderRasterizeDetail = EditorGUILayout.FloatField(new GUIContent("Collider Detail", "Controls the detail of the generated collider meshes. Increasing does not necessarily yield better navmeshes, but lowering will speed up scan"), graph.colliderRasterizeDetail);
            EditorGUI.indentLevel--;
        }

        graph.mask = EditorGUILayoutx.LayerMaskField("Layer Mask", graph.mask);

        graph.includeOutOfBounds = EditorGUILayout.Toggle(new GUIContent("Include out of bounds", "Should voxels out of bounds, on the Y axis below the graph, be included or not"), graph.includeOutOfBounds);
        Separator();

        graph.forcedBoundsCenter = EditorGUILayout.Vector3Field("Center", graph.forcedBoundsCenter);
        graph.forcedBoundsSize   = EditorGUILayout.Vector3Field("Size", graph.forcedBoundsSize);

        if (GUILayout.Button(new GUIContent("Snap bounds to scene", "Will snap the bounds of the graph to exactly contain all active meshes in the scene")))
        {
            graph.SnapForceBoundsToScene();
            GUI.changed = true;
        }

        Separator();

        tagMaskFoldout = EditorGUILayoutx.UnityTagMaskList(new GUIContent("Tag Mask"), tagMaskFoldout, graph.tagMask);

        Separator();

        graph.showMeshOutline = EditorGUILayout.Toggle(new GUIContent("Show mesh outline", "Toggles gizmos for drawing an outline of the mesh"), graph.showMeshOutline);

        graph.accurateNearestNode = EditorGUILayout.Toggle(new GUIContent("Accurate Nearest Node Queries", "More accurate nearest node queries. See docs for more info"), graph.accurateNearestNode);

        if (GUILayout.Button("Export to file"))
        {
            ExportToFile(graph);
        }

        /*graph.replaceMesh = (Mesh)ObjectField (new GUIContent ("Replacement Mesh","If you make edits to the mesh manually, you can drop the new mesh file here to import it"), graph.replaceMesh,typeof(Mesh),false);
         *
         * if (graph.replaceMesh != null) {
         *      HelpBox ("Note: Graph will be replaced by the mesh");
         * }*/
        //graph.mask = 1 << EditorGUILayout.LayerField ("Mask",(int)Mathf.Log (graph.mask,2));
    }
Beispiel #24
0
    // A star pathfinding pro (APP)
    static public bool CreateAPPNavMesh(bool multiTile, Transform singleZone, Transform zonesRootTransform, bool doActivateAndDeactivateGeoForGeneration, float navBoundsOffset, bool doScan)
    {
        if (AstarPath.active == null)
        {
            EB.Debug.LogError("LevelHelperEditor::ExportLevel AStar object not found!");
            return(false);
        }

        AstarPath.active.graphs = new NavGraph[0]; // clear graphs

        GameObject zonesRoot = zonesRootTransform.gameObject;

        if (zonesRoot == null)
        {
            EB.Debug.LogError("LevelHelperEditor::Zones gameObject not found!");
            return(false);
        }

        // re-init valid graph types in underlying AstarData object
        AstarPath.active.astarData.FindGraphTypes();

        const float kBoundingBoxHeight = 100.0f; // this is an arbitrary amount, if there is ever a tall level, this can be increased
        RecastGraph recastGraph        = null;
        float       gridSizeX          = EditorVars.GridSize;
        float       gridSizeY          = EditorVars.GridSize;
        float       gridSizeZ          = EditorVars.GridSize;

        if (null != singleZone)
        {
            recastGraph = (RecastGraph)AstarPath.active.astarData.AddGraph(typeof(RecastGraph));

            GlobalNavHelper nav_helper = singleZone.GetComponent <GlobalNavHelper>();
            if (nav_helper != null)
            {
                gridSizeX = nav_helper.m_Range.x;
                gridSizeY = nav_helper.m_Range.y;
                gridSizeZ = nav_helper.m_Range.z;
            }

            Vector3 center      = new Vector3(singleZone.position.x + gridSizeX / 2.0f, 0.0f, singleZone.position.z + gridSizeZ / 2.0f);
            Vector3 boundingBox = Vector3.zero;
            if (multiTile)
            { // if it's multi tile, we create a bounding box which is three times the size of our zone, so that our zone will be placed in the center
                boundingBox = new Vector3(gridSizeX * 3f, gridSizeY * 3f, gridSizeZ * 3f);
                SetNavMeshDefaults(recastGraph, center, boundingBox, multiTile);
                recastGraph.tileSizeX         = recastGraph.tileSizeZ = (int)(EditorVars.GridSize / recastGraph.cellSize); // this line sets the tile size so that each tile will hold the size of a zone
                recastGraph.useCenterTileOnly = true;
            }
            else
            {
                boundingBox = new Vector3(gridSizeX, gridSizeY, gridSizeZ);
                SetNavMeshDefaults(recastGraph, center, boundingBox, multiTile);
            }
        }
        else
        {
            // or geo can be tested to get the y extents
            Vector3 NavMeshBoundingBoxMin = new Vector3(float.MaxValue, -(kBoundingBoxHeight * 0.5f), float.MaxValue);
            Vector3 NavMeshBoundingBoxMax = new Vector3(-float.MaxValue, kBoundingBoxHeight * 0.5f, -float.MaxValue);

            // walk zones to generate the bounding box encompassing the entire level (all zones)
            foreach (Transform zone in zonesRoot.transform)
            {
                gridSizeX = EditorVars.GridSize;
                gridSizeY = EditorVars.GridSize;
                gridSizeZ = EditorVars.GridSize;
                GlobalNavHelper nav_helper = zone.GetComponent <GlobalNavHelper>();
                if (nav_helper != null)
                {
                    gridSizeX = nav_helper.m_Range.x;
                    gridSizeY = nav_helper.m_Range.y;
                    gridSizeZ = nav_helper.m_Range.z;
                }

                float zoneXMin = zone.position.x + navBoundsOffset;
                float zoneXMax = zone.position.x + gridSizeX + navBoundsOffset;

                float zoneZMin = zone.position.z + navBoundsOffset;
                float zoneZMax = zone.position.z + gridSizeZ + navBoundsOffset;

                NavMeshBoundingBoxMin.x = zoneXMin < NavMeshBoundingBoxMin.x ? zoneXMin : NavMeshBoundingBoxMin.x;
                NavMeshBoundingBoxMax.x = zoneXMax > NavMeshBoundingBoxMax.x ? zoneXMax : NavMeshBoundingBoxMax.x;

                NavMeshBoundingBoxMin.z = zoneZMin < NavMeshBoundingBoxMin.z ? zoneZMin : NavMeshBoundingBoxMin.z;
                NavMeshBoundingBoxMax.z = zoneZMax > NavMeshBoundingBoxMax.z ? zoneZMax : NavMeshBoundingBoxMax.z;
            }

            Vector3 NavMeshBoundingBoxCenter = Vector3.Lerp(NavMeshBoundingBoxMin, NavMeshBoundingBoxMax, 0.5f);
            Vector3 NavMeshBoundingBox       = NavMeshBoundingBoxMax - NavMeshBoundingBoxMin;

            // one monolithic nav mesh to encompass all zones
            recastGraph = (RecastGraph)AstarPath.active.astarData.AddGraph(typeof(RecastGraph));
            SetNavMeshDefaults(recastGraph, NavMeshBoundingBoxCenter, NavMeshBoundingBox, multiTile);
            recastGraph.useCenterTileOnly = false;
        }

        AstarPath.active.astarData.data_cachedStartup = null;
        AstarPath.active.astarData.cacheStartup       = false;
        recastGraph.generateFromInputMesh             = false;
        AstarPath.active.showNavGraphs = true;

        if (doScan)
        {
            LevelHelper.FusionMenuScan(doActivateAndDeactivateGeoForGeneration); // build navmeshes from recast graph
        }

        return(true);
    }
Beispiel #25
0
        public static void save()
        {
            River river = new River(Level.info.path + "/Environment/Bounds.dat", false);

            river.writeByte(LevelNavigation.SAVEDATA_BOUNDS_VERSION);
            river.writeByte((byte)LevelNavigation.bounds.Count);
            byte b = 0;

            while ((int)b < LevelNavigation.bounds.Count)
            {
                river.writeSingleVector3(LevelNavigation.bounds[(int)b].center);
                river.writeSingleVector3(LevelNavigation.bounds[(int)b].size);
                b += 1;
            }
            river.closeRiver();
            River river2 = new River(Level.info.path + "/Environment/Flags_Data.dat", false);

            river2.writeByte(LevelNavigation.SAVEDATA_FLAG_DATA_VERSION);
            river2.writeByte((byte)LevelNavigation.flagData.Count);
            byte b2 = 0;

            while ((int)b2 < LevelNavigation.flagData.Count)
            {
                river2.writeString(LevelNavigation.flagData[(int)b2].difficultyGUID);
                river2.writeByte(LevelNavigation.flagData[(int)b2].maxZombies);
                river2.writeBoolean(LevelNavigation.flagData[(int)b2].spawnZombies);
                b2 += 1;
            }
            river2.closeRiver();
            River river3 = new River(Level.info.path + "/Environment/Flags.dat", false);

            river3.writeByte(LevelNavigation.SAVEDATA_FLAGS_VERSION);
            int num = LevelNavigation.flags.Count;

            while (ReadWrite.fileExists(string.Concat(new object[]
            {
                Level.info.path,
                "/Environment/Navigation_",
                num,
                ".dat"
            }), false, false))
            {
                ReadWrite.deleteFile(string.Concat(new object[]
                {
                    Level.info.path,
                    "/Environment/Navigation_",
                    num,
                    ".dat"
                }), false, false);
                num++;
            }
            river3.writeByte((byte)LevelNavigation.flags.Count);
            byte b3 = 0;

            while ((int)b3 < LevelNavigation.flags.Count)
            {
                Flag flag = LevelNavigation.flags[(int)b3];
                river3.writeSingleVector3(flag.point);
                river3.writeSingle(flag.width);
                river3.writeSingle(flag.height);
                if (flag.needsNavigationSave)
                {
                    River river4 = new River(string.Concat(new object[]
                    {
                        Level.info.path,
                        "/Environment/Navigation_",
                        b3,
                        ".dat"
                    }), false);
                    river4.writeByte(LevelNavigation.SAVEDATA_NAVIGATION_VERSION);
                    RecastGraph graph = flag.graph;
                    river4.writeSingleVector3(graph.forcedBoundsCenter);
                    river4.writeSingleVector3(graph.forcedBoundsSize);
                    river4.writeByte((byte)graph.tileXCount);
                    river4.writeByte((byte)graph.tileZCount);
                    RecastGraph.NavmeshTile[] tiles = graph.GetTiles();
                    for (int i = 0; i < graph.tileZCount; i++)
                    {
                        for (int j = 0; j < graph.tileXCount; j++)
                        {
                            RecastGraph.NavmeshTile navmeshTile = tiles[j + i * graph.tileXCount];
                            river4.writeUInt16((ushort)navmeshTile.tris.Length);
                            for (int k = 0; k < navmeshTile.tris.Length; k++)
                            {
                                river4.writeUInt16((ushort)navmeshTile.tris[k]);
                            }
                            river4.writeUInt16((ushort)navmeshTile.verts.Length);
                            for (int l = 0; l < navmeshTile.verts.Length; l++)
                            {
                                Int3 @int = navmeshTile.verts[l];
                                river4.writeInt32(@int.x);
                                river4.writeInt32(@int.y);
                                river4.writeInt32(@int.z);
                            }
                        }
                    }
                    river4.closeRiver();
                    flag.needsNavigationSave = false;
                }
                b3 += 1;
            }
            river3.closeRiver();
        }
Beispiel #26
0
	public static Bounds CollectMeshes (MeshFilter[] filters, RecastGraph.ExtraMesh[] extraMeshes, Bounds bounds, out Vector3[] verts, out int[] tris) {
		List<Vector3> verticeList = new List<Vector3>();
		List<int> triangleList = new List<int>();
		
		for (int i=0;i<filters.Length;i++) {
			
			MeshFilter filter = filters[i];
			
			if (filter.renderer == null || filter.sharedMesh == null) {
				continue;
			}
			
			if (!filter.renderer.bounds.Intersects (bounds)) {
				continue;
			}
			
			Vector3[] vs = filter.sharedMesh.vertices;
			int[] ts = filter.sharedMesh.triangles;
			
			//Vector3 trOffset = filters.transform.position;
			
			Matrix4x4 offsetMatrix = filter.transform.localToWorldMatrix;
			
			for (int q=0;q<vs.Length;q++) {
				vs[q] = offsetMatrix.MultiplyPoint3x4 (vs[q]);
			}
			
			for (int q=0;q<ts.Length;q++) {
				ts[q] += verticeList.Count;
			}
			verticeList.AddRange (vs);
			triangleList.AddRange (ts);
			
			/*if (!forceBounds) {
				bounds.Encapsulate (filter.renderer.bounds);
			}*/
		}
		
		if (extraMeshes != null) {
			for (int i=0;i< extraMeshes.Length;i++) {
				RecastGraph.ExtraMesh extraMesh = extraMeshes[i];
				
				
				if (!extraMesh.bounds.Intersects (bounds)) {
					continue;
				}
				
				Vector3[] vs = extraMesh.vertices;
				int[] ts = extraMesh.triangles;
				
				if (triangleList.Capacity < triangleList.Count + ts.Length) {
					triangleList.Capacity = Mathf.Max (2*triangleList.Capacity, triangleList.Count + ts.Length);
				}
				
				int tOffset = verticeList.Count;
				
				for (int q=0;q<ts.Length;q++) {
					triangleList.Add (ts[q] + tOffset);
				}
				
				if (extraMesh.matrix.isIdentity) {
					//An identity matrix will change nothing, so skip applying it
					verticeList.AddRange (vs);
				} else {
					Matrix4x4 m = extraMesh.matrix;
					for (int q=0;q<vs.Length;q++) {
						verticeList.Add (m.MultiplyPoint3x4(vs[q]));
					}
				}
			}
		}
		
		verts = verticeList.ToArray ();
		tris = triangleList.ToArray ();
		return bounds;
	}
Beispiel #27
0
	public VoxelArea VoxelizeMesh (MeshFilter[] filters, RecastGraph.ExtraMesh[] extraMeshes = null) {
		Vector3[] verts;
		int[] tris;
		Bounds bounds = CollectMeshes (filters,extraMeshes, forcedBounds,out verts, out tris);
		
		
		AstarProfiler.StartProfile ("Build Navigation Mesh");
		
		AstarProfiler.StartProfile ("Voxelizing - Step 1");
		
		CellScale = new Vector3 (cellSize,cellHeight,cellSize);
		CellScaleDivision = new Vector3 (1F/cellSize,1F/cellHeight,1F/cellSize);
		
		float ics = 1F/cellSize;
		float ich = 1F/cellHeight;
		
		voxelWalkableHeight = (uint)(walkableHeight/cellHeight);
		voxelWalkableClimb = Mathf.RoundToInt (walkableClimb/cellHeight);
		
		/*Mesh mesh1 = g1.GetComponent<MeshFilter>().sharedMesh;
		Matrix4x4 matrix1 = g1.transform.localToWorldMatrix;
		
		Mesh mesh2 = g2.GetComponent<MeshFilter>().sharedMesh;
		Matrix4x4 matrix2 = g2.transform.localToWorldMatrix;
		
		Vector3 pos = g1.transform.position;
		Vector3 pos2 = g2.transform.position;
		
		int[] tris1 = mesh1.triangles;
		int[] tris2 = mesh2.triangles;
		
		Vector3[] verts1 = mesh1.vertices;
		int v1L = verts1.Length;
		Vector3[] verts2 = mesh2.vertices;
		
		int[] tris = new int[tris1.Length+tris2.Length];
		
		for (int i=0;i<tris1.Length;i++) {
			tris[i] = tris1[i];
		}
		
		
		int sV = tris1.Length;
		for (int i=0;i<tris2.Length;i++) {
			tris[i+sV] = tris2[i]+v1L;
		}
		
		Vector3[] verts = new Vector3[tris1.Length+tris2.Length];
		
		for (int i=0;i<verts1.Length;i++) {
			verts[i] = matrix1.MultiplyPoint3x4 (verts1[i]);//+pos;
		}
		
		for (int i=0;i<verts2.Length;i++) {
			verts[i+v1L] = matrix2.MultiplyPoint3x4 (verts2[i]);//verts2[i]+pos2;
		}*/
		
		//MeshFilter[] filters = FindObjectsOfType(typeof(MeshFilter)) as MeshFilter[];
		
		//Start Voxel
		
		//Bounds
		//Bounds bounds = g1.renderer.bounds;
		//bounds.Encapsulate (g2.renderer.bounds.min);
		//bounds.Encapsulate (g2.renderer.bounds.max);
		
		//Debug.DrawLine (bounds.min,bounds.max,Color.white);
		
		//Vector3 center = bounds.center;
		Vector3 min = bounds.min;
		voxelOffset = min;
		//End Bounds
		
		for (int i=0;i<verts.Length;i++) {
			verts[i] -= bounds.min;
			verts[i].x *= ics;
			verts[i].y *= ich;
			verts[i].z *= ics;
		}
		
		bounds.size = Vector3.Scale (bounds.size,CellScaleDivision);
		
		//Initialize the voxel area
		voxelArea = new VoxelArea (bounds);
		
		AstarProfiler.EndProfile ("Voxelizing - Step 1");
		
		AstarProfiler.StartProfile ("Voxelizing - Step 2");
		
		/*Vector3 p1;
		Vector3 p2;
		Vector3 p3;
		
		int minX;
		int minZ;
		int maxX;
		int maxZ;*/
		
		//Vector3 normal;
		
		float slopeLimit = Mathf.Cos (maxSlope*Mathf.Deg2Rad);
		
		//Utility.StartTimerAdditive (true);
		
		float[] vTris = new float[3*3];
		float[] vOut = new float[7*3];
		float[] vRow = new float[7*3];
		float[] vCellOut = new float[7*3];
		float[] vCell = new float[7*3];
	
		for (int i=0;i<tris.Length;i += 3) {
			//Debug.Log (i);
			//if (Random.value < 0.97F) {
			//	continue;
			//}
			
			Vector3 p1;
			Vector3 p2;
			Vector3 p3;
			
			int minX;
			int minZ;
			int maxX;
			int maxZ;
			
			Vector3 normal;
			
			int area = 8;
			
			p1 = verts[tris[i]];
			p2 = verts[tris[i+1]];
			p3 = verts[tris[i+2]];
			
			minX = Mathf.FloorToInt (Utility.Min (p1.x,p2.x,p3.x));
			// (Mathf.Min (Mathf.Min (p1.x,p2.x),p3.x));
			minZ = Mathf.FloorToInt (Utility.Min (p1.z,p2.z,p3.z));
			
			maxX = Mathf.CeilToInt (Utility.Max (p1.x,p2.x,p3.x));
			maxZ = Mathf.CeilToInt (Utility.Max (p1.z,p2.z,p3.z));
			
			minX = Mathf.Clamp (minX , 0 , voxelArea.width-1);
			maxX = Mathf.Clamp (maxX , 0 , voxelArea.width-1);
			minZ = Mathf.Clamp (minZ , 0 , voxelArea.depth-1);
			maxZ = Mathf.Clamp (maxZ , 0 , voxelArea.depth-1);
			
			normal = Vector3.Cross (p2-p1,p3-p1);
			
			float dot = Vector3.Dot (normal.normalized,Vector3.up);
			
			//if (dot <= 0) {
				//(area = 0;
				//continue;
			if (dot < slopeLimit) {
				area = UnwalkableArea;
				//continue;
			} else {
				area = 1;
			}
			
			//Debug.DrawLine (p1*cellSize+min+Vector3.up*0.2F,p2*cellSize+min+Vector3.up*0.1F,Color.red);
			//Debug.DrawLine (p2*cellSize+min+Vector3.up*0.1F,p3*cellSize+min,Color.red);
			//Debug.DrawRay (((p1+p2+p3)/3.0F)*cellSize-bounds.center,normal,Color.cyan);
			
			Utility.CopyVector (vTris,0,p1);
			Utility.CopyVector (vTris,3,p2);
			Utility.CopyVector (vTris,6,p3);
			
			//Utility.StartTimerAdditive (false);
			for (int x=minX;x<=maxX;x++) {
				
				int nrow = Utility.ClipPolygon (vTris , 3 , vOut , 1F , -x+0.5F,0);
				
				if (nrow < 3) {
					continue;
				}
				
				
				nrow = Utility.ClipPolygon (vOut,nrow,vRow,-1F,x+0.5F,0);
				
				if (nrow < 3) {
					continue;
				}
				
				float clampZ1 = vRow[2];
				float clampZ2 = vRow[2];
				for (int q=1; q < nrow;q++) {
					float val = vRow[q*3+2];
					clampZ1 = Mathf.Min (clampZ1,val);
					clampZ2 = Mathf.Max (clampZ2,val);
				}
				
				int clampZ1I = Mathfx.Clamp (Mathf.RoundToInt (clampZ1),0, voxelArea.depth-1);
				int clampZ2I = Mathfx.Clamp (Mathf.RoundToInt (clampZ2),0, voxelArea.depth-1);
				
				for (int z=clampZ1I;z<=clampZ2I;z++) {
					
					int ncell = Utility.ClipPolygon (vRow , nrow , vCellOut , 1F , -z+0.5F,2);
					
					if (ncell < 3) {
						continue;
					}
					
					ncell = Utility.ClipPolygonY (vCellOut , ncell , vCell , -1F , z+0.5F,2);
					
					if (ncell < 3) {
						continue;
					}
					
					/*if((Mathf.Round (z/2) == (z/2.0F))) {
						continue;
					}
					for (int q=0, j = ncell-1; q < ncell; j=q, q++) {
						Debug.DrawLine (vCell[q]*cellSize+min,vCell[j]*cellSize+min,Color.cyan);
					}*/
					
					float sMin = vCell[1];
					float sMax = vCell[1];
					for (int q=1; q < ncell;q++) {
						float val = vCell[q*3+1];
						sMin = Mathf.Min (sMin,val);
						sMax = Mathf.Max (sMax,val);
					}
					
					//Debug.DrawLine (new Vector3(x,sMin,z)*cellSize+min,new Vector3(x,sMax,z)*cellSize+min,Color.cyan);
					//if (z < 0 || x < 0 || z >= voxelArea.depth || x >= voxelArea.width) {
						//Debug.DrawRay (new Vector3(x,sMin,z)*cellSize+min, Vector3.up, Color.red);
						//continue;
					//}
					int maxi = Mathf.CeilToInt(sMax);
					if (includeOutOfBounds || maxi >= 0) {
						maxi = maxi < 0 ? 0 : maxi;
						int mini = Mathf.FloorToInt(sMin+1);
						voxelArea.cells[z*voxelArea.width+x].AddSpan ((mini >= 0 ? (uint)mini : 0),(uint)maxi,area, voxelWalkableClimb);
					}
				}
			}
			
			//Utility.EndTimerAdditive ("",false);
		}
		AstarProfiler.EndProfile ("Voxelizing - Step 2");
		
		/*int wd = voxelArea.width*voxelArea.depth;
		for (int x=0;x<wd;x++) {
			VoxelCell c = voxelArea.cells[x];
			float cPos = (float)x/(float)voxelArea.width;
			float  cPos2 = Mathf.Floor (cPos);
			
			Vector3 p = new Vector3((cPos-cPos2)*voxelArea.width,0,cPos2);
			p *= cellSize;
			p += min;
			VoxelSpan span = c.firstSpan;
			
			int count =0;
			while (span != null) {
				Color col = count < Utility.colors.Length ? Utility.colors[count] : Color.white;
				//p.y = span.bottom*cellSize+min.y;
				Debug.DrawLine (p+new Vector3(0,span.bottom*cellSize,0),p+new Vector3(0,span.top*cellSize,0),col);
				span = span.next;
				count++;
			}
			
		}*/
		
		//return;
		//Step 2 - Navigable Space
		
		AstarProfiler.StartProfile ("Filter Ledges");
		
		FilterLedges (voxelWalkableHeight, voxelWalkableClimb, cellSize, cellHeight, min);
		
		AstarProfiler.EndProfile ("Filter Ledges");
		
		AstarProfiler.StartProfile ("Filter Low Height Spans");
		FilterLowHeightSpans (voxelWalkableHeight, cellSize, cellHeight, min);
		AstarProfiler.EndProfile ("Filter Low Height Spans");
		/*if (firstStep && false) {
			int sCount = voxelArea.GetSpanCountAll ();
			Vector3[] debugPointsTop = new Vector3[sCount];
			Vector3[] debugPointsBottom = new Vector3[sCount];
			Color[] debugColors = new Color[sCount];
			
			int debugPointsCount = 0;
			
			for (int z=0, pz = 0;z < wd;z += voxelArea.width, pz++) {
				for (int x=0;x < voxelArea.width;x++) {
					
					Vector3 p = new Vector3(x,0,pz)*cellSize+min;
					
					//CompactVoxelCell c = voxelArea.compactCells[x+z];
					VoxelCell c = voxelArea.cells[x+z];
					//if (c.count == 0) {
					//	Debug.DrawRay (p,Vector3.up,Color.red);
					//}
					
					//for (int i=(int)c.index, ni = (int)(c.index+c.count);i<ni;i++) 
					
					for (VoxelSpan s = c.firstSpan; s != null; s = s.next) {
						//CompactVoxelSpan s = voxelArea.compactSpans[i];
						
						p.y = ((float)(s.top))*cellHeight+min.y;
						
						debugPointsTop[debugPointsCount] = p;
						
						p.y = ((float)s.bottom)*cellHeight+min.y;
						debugPointsBottom[debugPointsCount] = p;
						
						debugColors[debugPointsCount] = s.area == 1 ? Color.green : (s.area == 2 ? Color.yellow : Color.red);
						debugPointsCount++;
						
						//Debug.DrawRay (p,Vector3.up*0.5F,Color.green);
					}
				}
			}

			DebugUtility.DrawCubes (debugPointsTop,debugPointsBottom,debugColors, cellSize);
		}*/
		
		BuildCompactField ();
		
		/*
		int sCount = spanCount;//voxelArea.GetSpanCount ();
		Vector3[] debugPointsTop = new Vector3[sCount];
		Vector3[] debugPointsBottom = new Vector3[sCount];
		Color[] debugColors = new Color[sCount];
		
		int debugPointsCount = 0;
		
		for (int z=0, pz = 0;z < wd;z += voxelArea.width, pz++) {
			for (int x=0;x < voxelArea.width;x++) {
				
				Vector3 p = new Vector3(x,0,pz)*cellSize+min;
				
				//CompactVoxelCell c = voxelArea.compactCells[x+z];
				CompactVoxelCell c = voxelArea.compactCells[x+z];
				//if (c.count == 0) {
				//	Debug.DrawRay (p,Vector3.up,Color.red);
				//}
				
				//for (int i=(int)c.index, ni = (int)(c.index+c.count);i<ni;i++) 
				
				for (int i = (int)c.index; i < c.index+c.count; i++) {
					CompactVoxelSpan s = voxelArea.compactSpans[i];
					//CompactVoxelSpan s = voxelArea.compactSpans[i];
					
					p.y = ((float)(s.y+0.1F))*cellHeight+min.y;
					
					debugPointsTop[debugPointsCount] = p;
					
					p.y = ((float)s.y)*cellHeight+min.y;
					debugPointsBottom[debugPointsCount] = p;
					
					debugColors[debugPointsCount] = s.area == 1 ? Color.green : (s.area == 2 ? Color.yellow : Color.red);
					debugPointsCount++;
					
					//Debug.DrawRay (p,Vector3.up*0.5F,Color.green);
				}
			}
		}
		
		if (firstStep) {
			DebugUtility.DrawCubes (debugPointsTop,debugPointsBottom,debugColors, cellSize);
		}*/
		/*for (int z=0, pz = 0;z < wd;z += voxelArea.width, pz++) {
			for (int x=0;x < voxelArea.width;x++) {
				
				Vector3 p = new Vector3(x,0,pz)*cellSize+min;
				Vector3 ph = new Vector3(x,0,pz)*cellSize+min;
				
				CompactVoxelCell c = voxelArea.compactCells[x+z];
				
				if (c.count == 0) {
					Debug.DrawRay (p,Vector3.up,Color.red);
				}
				
				for (int i=(int)c.index, ni = (int)(c.index+c.count);i<ni;i++) {
					
					CompactVoxelSpan s = voxelArea.compactSpans[i];
					p.y = ((float)s.y)*cellSize+min.y;
					ph.y = ((float)s.y+Mathf.Clamp ((float)s.h,0,2))*cellSize+min.y;
					
					Debug.DrawLine (p,ph,Color.green);
					/*for (int d = 0; d<4;d++) {
						int conn = s.GetConnection (d);
						
						
						if (conn == NotConnected) {
							Debug.DrawRay (p,Vector3.up*0.2F,Color.red);
							Debug.DrawRay (p,voxelArea.VectorDirection[d]*cellSize*0.5F,Color.red);
						}
					}*
				}
			}
		}*/
		
		BuildVoxelConnections ();
		
		//ErodeWalkableArea (2);
		AstarProfiler.PrintResults ();
		return voxelArea;
		/*
		
		voxelOffset = min;
		
		AstarProfiler.StartProfile ("Build Distance Field");
		
		BuildDistanceField (min);
		
		AstarProfiler.EndProfile ("Build Distance Field");
		AstarProfiler.StartProfile ("Build Regions");
		
		BuildRegions (min);
		
		AstarProfiler.EndProfile ("Build Regions");
		
		AstarProfiler.StartProfile ("Build Contours");
		
		BuildContours ();
		
		AstarProfiler.EndProfile ("Build Contours");
		
		AstarProfiler.EndProfile ("Build Navigation Mesh");
		AstarProfiler.StartProfile ("Build Debug Mesh");
		
		int sCount = voxelArea.compactSpans.Length;
		Vector3[] debugPointsTop = new Vector3[sCount];
		Vector3[] debugPointsBottom = new Vector3[sCount];
		Color[] debugColors = new Color[sCount];
		
		int debugPointsCount = 0;
		
		//int wd = voxelArea.width*voxelArea.depth;
		
		for (int z=0, pz = 0;z < wd;z += voxelArea.width, pz++) {
			for (int x=0;x < voxelArea.width;x++) {
				
				Vector3 p = new Vector3(x,0,pz)*cellSize+min;
				
				//CompactVoxelCell c = voxelArea.compactCells[x+z];
				CompactVoxelCell c = voxelArea.compactCells[x+z];
				//if (c.count == 0) {
				//	Debug.DrawRay (p,Vector3.up,Color.red);
				//}
				
				for (int i=(int)c.index, ni = (int)(c.index+c.count);i<ni;i++) {
					CompactVoxelSpan s = voxelArea.compactSpans[i];
					
					p.y = ((float)(s.y+0.1F))*cellHeight+min.y;
					
					debugPointsTop[debugPointsCount] = p;
					
					p.y = ((float)s.y)*cellHeight+min.y;
					debugPointsBottom[debugPointsCount] = p;
					
					debugColors[debugPointsCount] = //Color.Lerp (Color.black, Color.white , (float)voxelArea.dist[i] / (float)voxelArea.maxDistance);
					//Utility.GetColor ((int)s.area);
					Utility.IntToColor ((int)s.reg,0.8F);
					//Color.Lerp (Color.black, Color.white , (float)s.area / 10F);
					//(float)(Mathf.Abs(dst[i]-src[i])) / (float)5);//s.area == 1 ? Color.green : (s.area == 2 ? Color.yellow : Color.red);
					debugPointsCount++;
					
					//Debug.DrawRay (p,Vector3.up*0.5F,Color.green);
				}
			}
		}

		DebugUtility.DrawCubes (debugPointsTop,debugPointsBottom,debugColors, cellSize);
		
		AstarProfiler.EndProfile ("Build Debug Mesh");
		
		/*for (int z=0, pz = 0;z < wd;z += voxelArea.width, pz++) {
			for (int x=0;x < voxelArea.width;x++) {
				
				Vector3 p = new Vector3(x,0,pz)*cellSize+min;
				
				CompactVoxelCell c = voxelArea.compactCells[x+z];
				
				if (c.count == 0) {
					//Debug.DrawRay (p,Vector3.up,Color.red);
				}
				
				for (int i=(int)c.index, ni = (int)(c.index+c.count);i<ni;i++) {
					
					CompactVoxelSpan s = voxelArea.compactSpans[i];
					p.y = ((float)s.y)*cellHeight+min.y;
					
					
					for (int d = 0; d<4;d++) {
						int conn = s.GetConnection (d);
						
						
						if (conn == NotConnected) {
							//Debug.DrawRay (p,Vector3.up*0.2F,Color.red);
							Debug.DrawRay (p,voxelArea.VectorDirection[d]*cellSize*0.5F,Color.red);
						} else {
							Debug.DrawRay (p,voxelArea.VectorDirection[d]*cellSize*0.5F,Color.green);
						}
					}
				}
			}
		}*/
		
		
		/*int sCount = voxelArea.compactSpans.Length;
		Vector3[] debugPointsTop = new Vector3[sCount];
		Vector3[] debugPointsBottom = new Vector3[sCount];
		Color[] debugColors = new Color[sCount];
		
		int debugPointsCount = 0;
		
		//int wd = voxelArea.width*voxelArea.depth;
		
		for (int z=0, pz = 0;z < wd;z += voxelArea.width, pz++) {
			for (int x=0;x < voxelArea.width;x++) {
				
				Vector3 p = new Vector3(x,0,pz)*cellSize+min;
				
				//CompactVoxelCell c = voxelArea.compactCells[x+z];
				CompactVoxelCell c = voxelArea.compactCells[x+z];
				//if (c.count == 0) {
				//	Debug.DrawRay (p,Vector3.up,Color.red);
				//}
				
				for (int i=(int)c.index, ni = (int)(c.index+c.count);i<ni;i++) {
					CompactVoxelSpan s = voxelArea.compactSpans[i];
					
					p.y = ((float)(s.y+0.1F))*cellHeight+min.y;
					
					debugPointsTop[debugPointsCount] = p;
					
					p.y = ((float)s.y)*cellHeight+min.y;
					debugPointsBottom[debugPointsCount] = p;
					
					Color col = Color.black;
					
					switch (s.area) {
						case 0:
							col = Color.red;
							break;
						case 1:
							col = Color.green;
							break;
						case 2:
							col = Color.yellow;
							break;
						case 3:
							col = Color.magenta;
							break;
					}
					
					debugColors[debugPointsCount] = col;//Color.Lerp (Color.black, Color.white , (float)dst[i] / (float)voxelArea.maxDistance);//(float)(Mathf.Abs(dst[i]-src[i])) / (float)5);//s.area == 1 ? Color.green : (s.area == 2 ? Color.yellow : Color.red);
					debugPointsCount++;
					
					//Debug.DrawRay (p,Vector3.up*0.5F,Color.green);
				}
			}
		}

		DebugUtility.DrawCubes (debugPointsTop,debugPointsBottom,debugColors, cellSize);*/
		
		//AstarProfiler.PrintResults ();
		
		//firstStep = false;
		
	}
Beispiel #28
0
        private static RecastGraph buildGraph(River river)
        {
            RecastGraph recastGraph = LevelNavigation.addGraph();
            int         graphIndex  = AstarPath.active.astarData.GetGraphIndex(recastGraph);

            TriangleMeshNode.SetNavmeshHolder(graphIndex, recastGraph);
            recastGraph.forcedBoundsCenter = river.readSingleVector3();
            recastGraph.forcedBoundsSize   = river.readSingleVector3();
            recastGraph.tileXCount         = (int)river.readByte();
            recastGraph.tileZCount         = (int)river.readByte();
            RecastGraph.NavmeshTile[] array = new RecastGraph.NavmeshTile[recastGraph.tileXCount * recastGraph.tileZCount];
            recastGraph.SetTiles(array);
            for (int i = 0; i < recastGraph.tileZCount; i++)
            {
                for (int j = 0; j < recastGraph.tileXCount; j++)
                {
                    RecastGraph.NavmeshTile navmeshTile = new RecastGraph.NavmeshTile();
                    navmeshTile.x      = j;
                    navmeshTile.z      = i;
                    navmeshTile.w      = 1;
                    navmeshTile.d      = 1;
                    navmeshTile.bbTree = new BBTree(navmeshTile);
                    int num = j + i * recastGraph.tileXCount;
                    array[num]       = navmeshTile;
                    navmeshTile.tris = new int[(int)river.readUInt16()];
                    for (int k = 0; k < navmeshTile.tris.Length; k++)
                    {
                        navmeshTile.tris[k] = (int)river.readUInt16();
                    }
                    navmeshTile.verts = new Int3[(int)river.readUInt16()];
                    for (int l = 0; l < navmeshTile.verts.Length; l++)
                    {
                        navmeshTile.verts[l] = new Int3(river.readInt32(), river.readInt32(), river.readInt32());
                    }
                    navmeshTile.nodes = new TriangleMeshNode[navmeshTile.tris.Length / 3];
                    num <<= 12;
                    for (int m = 0; m < navmeshTile.nodes.Length; m++)
                    {
                        navmeshTile.nodes[m] = new TriangleMeshNode(AstarPath.active);
                        TriangleMeshNode triangleMeshNode = navmeshTile.nodes[m];
                        triangleMeshNode.GraphIndex = (uint)graphIndex;
                        triangleMeshNode.Penalty    = 0u;
                        triangleMeshNode.Walkable   = true;
                        triangleMeshNode.v0         = (navmeshTile.tris[m * 3] | num);
                        triangleMeshNode.v1         = (navmeshTile.tris[m * 3 + 1] | num);
                        triangleMeshNode.v2         = (navmeshTile.tris[m * 3 + 2] | num);
                        triangleMeshNode.UpdatePositionFromVertices();
                        navmeshTile.bbTree.Insert(triangleMeshNode);
                    }
                    recastGraph.CreateNodeConnections(navmeshTile.nodes);
                }
            }
            for (int n = 0; n < recastGraph.tileZCount; n++)
            {
                for (int num2 = 0; num2 < recastGraph.tileXCount; num2++)
                {
                    RecastGraph.NavmeshTile tile = array[num2 + n * recastGraph.tileXCount];
                    recastGraph.ConnectTileWithNeighbours(tile);
                }
            }
            return(recastGraph);
        }
    private void calculateMainNavAreaEditor(GameObject m)
    {
        m.SetActive(true);
        navAreaSetup[] componentsInChildren = m.GetComponent <mutantController>().navRef.GetComponentsInChildren <navAreaSetup>();
        int            num = 0;

        if (!m.GetComponent <mutantController>().navRef.gameObject.activeInHierarchy)
        {
            return;
        }
        foreach (navAreaSetup navAreaSetup in componentsInChildren)
        {
            if (navAreaSetup.areaNum > num)
            {
                num = navAreaSetup.areaNum;
            }
        }
        this.mostCommonArea.Clear();
        if (AstarPath.active == null)
        {
            AstarPath.active = (UnityEngine.Object.FindObjectOfType(typeof(AstarPath)) as AstarPath);
        }
        RecastGraph recastGraph = AstarPath.active.astarData.recastGraph;

        for (int j = 0; j <= num; j++)
        {
            List <uint> list = new List <uint>();
            foreach (navAreaSetup navAreaSetup2 in componentsInChildren)
            {
                if (navAreaSetup2.areaNum == j)
                {
                    GraphNode node = recastGraph.GetNearest(navAreaSetup2.gameObject.transform.position, NNConstraint.Default).node;
                    if (node != null)
                    {
                        list.Add(node.Area);
                    }
                }
            }
            Dictionary <uint, int> dictionary = new Dictionary <uint, int>();
            this.mostCommonArea.Add(list[0]);
            dictionary.Add(list[0], 1);
            for (int l = 1; l < list.Count; l++)
            {
                if (dictionary.ContainsKey(list[l]))
                {
                    Dictionary <uint, int> dictionary2;
                    uint key;
                    (dictionary2 = dictionary)[key = list[l]] = dictionary2[key] + 1;
                    if (dictionary[list[l]] > dictionary[this.mostCommonArea[j]])
                    {
                        this.mostCommonArea[j] = list[l];
                    }
                }
                else
                {
                    dictionary.Add(list[l], 1);
                }
            }
        }
        m.SetActive(false);
    }
Beispiel #30
0
    void SerializeUnityNavMesh(NavMeshTriangulation unityNavMesh, ref RecastGraph recast)
    {
        if (active == null || active.data == null)
        {
            return;
        }

        var vertMap = ObjectPoolSimple <Dictionary <int, int> > .Claim();

        var totalVoxelWidth = (int)(recast.forcedBoundsSize.x / recast.cellSize + 0.5f);
        var totalVoxelDepth = (int)(recast.forcedBoundsSize.z / recast.cellSize + 0.5f);
        var tileSizeX       = recast.editorTileSize;
        var tileSizeZ       = recast.editorTileSize;
        var tileXCount      = (totalVoxelWidth + tileSizeX - 1) / tileSizeX;
        var tileZCount      = (totalVoxelDepth + tileSizeZ - 1) / tileSizeZ;
        var tileWorldSize   = recast.TileWorldSizeX;
        var bucket          = ArrayPool <List <int> > .Claim((tileXCount + 1) *(tileZCount + 1));

        for (int i = 0; i < unityNavMesh.vertices.Length; i++)
        {
            var v         = unityNavMesh.vertices[i];
            var tileIndex = vertexOnTile(
                v, recast.forcedBoundsCenter, recast.forcedBoundsSize, tileWorldSize, tileXCount, tileZCount);
            tileIndex = 0;
            if (bucket[tileIndex] == null)
            {
                bucket[tileIndex] = ListPool <int> .Claim();
            }
            bucket[tileIndex].Add(i);
        }
        foreach (var b in bucket)
        {
            if (b == null)
            {
                continue;
            }
            for (int i = 0; i < b.Count; i++)
            {
                for (int j = 0; j < i; j++)
                {
                    if (b[i] >= unityNavMesh.vertices.Length || b[j] >= unityNavMesh.vertices.Length)
                    {
                        continue;
                    }
                    if (Vector3.Distance(unityNavMesh.vertices[b[i]], unityNavMesh.vertices[b[j]]) < 1e-3)
                    {
                        vertMap[b[i]] = b[j];
                        break;
                    }
                }
            }
        }
        ArrayPool <List <int> > .Release(ref bucket, true);

        // only one tile
        recast.transform  = recast.CalculateTransform();
        recast.tileXCount = 1;
        recast.tileZCount = 1;
        recast.tileSizeX  = totalVoxelWidth + 1;
        recast.tileSizeZ  = totalVoxelDepth + 1;
        recast.ResetTiles(recast.tileXCount * recast.tileZCount);
        TriangleMeshNode.SetNavmeshHolder((int)recast.graphIndex, recast);
        var graphUpdateLock = active.PausePathfinding();

        for (int z = 0; z < recast.tileZCount; z++)
        {
            for (int x = 0; x < recast.tileXCount; x++)
            {
                var tileOffset = recast.forcedBoundsCenter - recast.forcedBoundsSize * 0.5f + new Vector3(
                    x * tileWorldSize,
                    0,
                    z * tileWorldSize
                    );
                var trisClaim = ArrayPool <int> .Claim(unityNavMesh.indices.Length);

                var tris = Memory.ShrinkArray(trisClaim, unityNavMesh.indices.Length);
                ArrayPool <int> .Release(ref trisClaim, true);

                for (int i = 0; i < tris.Length; i++)
                {
                    var tri = unityNavMesh.indices[i];
                    if (vertMap.ContainsKey(tri))
                    {
                        tri = vertMap[tri];
                    }
                    tris[i] = tri;
                }
                var vertsClaim = ArrayPool <Int3> .Claim(unityNavMesh.vertices.Length);

                var verts = Memory.ShrinkArray(vertsClaim, unityNavMesh.vertices.Length);
                ArrayPool <Int3> .Release(ref vertsClaim, true);

                for (int i = 0; i < verts.Length; i++)
                {
                    var vertInWorld = unityNavMesh.vertices[i];
                    var vertInTile  = vertInWorld - tileOffset;
                    verts[i] = new Int3(vertInTile);
                }
                recast.ReplaceTile(x, z, 1, 1, verts, tris);
            }
        }
        graphUpdateLock.Release();

        ObjectPoolSimple <Dictionary <int, int> > .Release(ref vertMap);
    }
Beispiel #31
0
    public static Bounds CollectMeshes(MeshFilter[] filters, RecastGraph.ExtraMesh[] extraMeshes, Bounds bounds, out Vector3[] verts, out int[] tris)
    {
        List<Vector3> verticeList = new List<Vector3>();
        List<int> triangleList = new List<int>();

        for (int i=0;i<filters.Length;i++) {

            MeshFilter filter = filters[i];

            if (filter.renderer == null || filter.sharedMesh == null) {
                continue;
            }

            if (!filter.renderer.bounds.Intersects (bounds)) {
                continue;
            }

            Vector3[] vs = filter.sharedMesh.vertices;
            int[] ts = filter.sharedMesh.triangles;

            //Vector3 trOffset = filters.transform.position;

            Matrix4x4 offsetMatrix = filter.transform.localToWorldMatrix;

            for (int q=0;q<vs.Length;q++) {
                vs[q] = offsetMatrix.MultiplyPoint3x4 (vs[q]);
            }

            for (int q=0;q<ts.Length;q++) {
                ts[q] += verticeList.Count;
            }
            verticeList.AddRange (vs);
            triangleList.AddRange (ts);

            /*if (!forceBounds) {
                bounds.Encapsulate (filter.renderer.bounds);
            }*/
        }

        if (extraMeshes != null) {
            for (int i=0;i< extraMeshes.Length;i++) {
                RecastGraph.ExtraMesh extraMesh = extraMeshes[i];

                if (!extraMesh.bounds.Intersects (bounds)) {
                    continue;
                }

                Vector3[] vs = extraMesh.vertices;
                int[] ts = extraMesh.triangles;

                for (int q=0;q<ts.Length;q++) {
                    ts[q] += verticeList.Count;
                }

                verticeList.AddRange (vs);
                triangleList.AddRange (ts);
            }
        }

        verts = verticeList.ToArray ();
        tris = triangleList.ToArray ();
        return bounds;
    }