/// <summary> /// Adds the bounds to the pathfinder. /// </summary> /// <param name='t'> /// T. /// </param> public static void AddBounds(Transform t) { //Debug.Log (t.name); Bounds b = t.collider.bounds; GraphUpdateObject guo = new GraphUpdateObject(b); AstarPath.active.UpdateGraphs (guo); }
public void SetState (bool open) { this.open = open; if (updateGraphsWithGUO) { // Update the graph below the door // Set the tag of the nodes below the door // To something indicating that the door is open or closed GraphUpdateObject guo = new GraphUpdateObject(bounds); int tag = open ? opentag : closedtag; // There are only 32 tags if (tag > 31) { Debug.LogError("tag > 31"); return; } guo.modifyTag = true; guo.setTag = tag; guo.updatePhysics = false; AstarPath.active.UpdateGraphs(guo); } // Play door animations if (open) { GetComponent<Animation>().Play("Open"); } else { GetComponent<Animation>().Play("Close"); } }
/** Updates graphs and checks if all nodes are still reachable from each other. * Graphs are updated, then a check is made to see if the nodes are still reachable from each other. * If they are not, the graphs are reverted to before the update and \a false is returned. * This is slower than a normal graph update. * All queued graph updates and thread safe callbacks will be flushed during this function. * * \note This might return true for small areas even if there is no possible path if AstarPath.minAreaSize is greater than zero (0). * So when using this, it is recommended to set AstarPath.minAreaSize to 0. (A* Inspector -> Settings -> Pathfinding) * * \param guo The GraphUpdateObject to update the graphs with * \param nodes Nodes which should have valid paths between them. All nodes should be walkable or \a false will be returned. * \param alwaysRevert If true, reverts the graphs to the old state even if no blocking ocurred * * \returns True if the given nodes are still reachable from each other after the \a guo has been applied. False otherwise. */ public static bool UpdateGraphsNoBlock (GraphUpdateObject guo, List<GraphNode> nodes, bool alwaysRevert = false) { //Make sure all nodes are walkable for (int i = 0; i < nodes.Count; i++) if (!nodes[i].Walkable) return false; //Track changed nodes to enable reversion of the guo guo.trackChangedNodes = true; bool worked = true; AstarPath.RegisterSafeUpdate(delegate() { AstarPath.active.UpdateGraphs(guo); //Call thread safe callbacks, includes graph updates AstarPath.active.FlushGraphUpdates(); //Check if all nodes are in the same area and that they are walkable, i.e that there are paths between all of them worked = worked && PathUtilities.IsPathPossible(nodes); //If it did not work, revert the GUO if (!worked || alwaysRevert) { guo.RevertFromBackup(); //The revert operation does not revert ALL nodes' area values, so we must flood fill again AstarPath.active.FloodFill(); } }); //Force the thread safe callback to be called AstarPath.active.FlushThreadSafeCallbacks(); //Disable tracking nodes, not strictly necessary, but will slightly reduce the cance that some user causes errors guo.trackChangedNodes = false; return worked; }
public GameObject obstacle; // Cube #endregion Fields #region Methods public void PlaceObject(GameObject go) { Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition); RaycastHit hit; if ( Physics.Raycast (ray, out hit, Mathf.Infinity)) { string hitName = hit.collider.name; Debug.Log ("Voici la hauteur du GO : " + go.transform.lossyScale.y); if (hitName == "Ground") { Vector3 posGO = hit.collider.gameObject.transform.position; //Vector3 p = new Vector3(hit.point.x, posGO.y + go.transform.lossyScale.y / 2, hit.point.z); Vector3 p = new Vector3(hit.point.x, 1, hit.point.z); Debug.Log ("Avec la position : " + p); GameObject obj = (GameObject)GameObject.Instantiate (go,p,Quaternion.identity); Bounds b = obj.collider.bounds; //Pathfinding.Console.Write ("// Placing Object\n"); GraphUpdateObject guo = new GraphUpdateObject(b); AstarPath.active.UpdateGraphs (guo); if (direct) { //Pathfinding.Console.Write ("// Flushing\n"); AstarPath.active.FlushGraphUpdates(); } } } }
/** Updates graphs with a created GUO. * Creates a Pathfinding::GraphUpdateObject with a Pathfinding::GraphUpdateShape * representing the polygon of this object and update all graphs using AstarPath::UpdateGraphs. * This will not update graphs directly. See AstarPath::UpdateGraph for more info. */ public void Apply() { if (AstarPath.active == null) { Debug.LogError ("There is no AstarPath object in the scene"); return; } firstApplied = true; Pathfinding.GraphUpdateShape shape = new Pathfinding.GraphUpdateShape (); shape.convex = convex; shape.points = points; GraphUpdateObject guo = new GraphUpdateObject (shape.GetBounds ()); guo.shape = shape; guo.modifyWalkability = modifyWalkability; guo.setWalkability = setWalkability; guo.addPenalty = penalty; #if ConfigureTagsAsMultiple guo.tags = tags; #else guo.modifyTag = modifyTag; guo.setTag = setTag; #endif AstarPath.active.UpdateGraphs (guo); }
public void SetState (bool open) { this.open = open; if (updateGraphsWithGUO) { GraphUpdateObject guo = new GraphUpdateObject(bounds); #if ConfigureTagsAsMultiple guo.tags = new TagMask (); guo.tags.tagsChange = 1 << bitToChange; guo.tags.tagsSet = open ? 1 << bitToChange : 0; #else int tag = open ? opentag : closedtag; if (tag > 31) { Debug.LogError ("tag > 31"); return; } guo.modifyTag = true; guo.setTag = tag; guo.updatePhysics = false; #endif AstarPath.active.UpdateGraphs (guo); } if (open) { animation.Play ("Open"); } else { animation.Play ("Close"); } }
public void DoStuff() { guo = new GraphUpdateObject(Fsm.GetOwnerDefaultTarget(target).collider.bounds); startNode = AstarPath.active.GetNearest (Start.Value).node; endNode = AstarPath.active.GetNearest (End.Value).node; PathIsPossible.Value = GraphUpdateUtilities.UpdateGraphsNoBlock(guo, startNode, endNode, true); }
// private float castle_offset = 10.0f; // Use this for initialization void Start() { // float ter_Width = Terrain.activeTerrain.terrainData.size.x; // float ter_Height = Terrain.activeTerrain.terrainData.size.z; for(int i = 0; i < 25; ++i) { for(int j = 0; j < 50; ++j) { if(ground_tiles[i,j] == 0) { } else if(ground_tiles[i,j] == 1) { //Vector3 pos = new Vector3((-12 * j) + 5, 0.1f, (ter_Height - (250 * i) - 30f) / 4.0f); Vector3 pos = new Vector3(10 * j + 5, 0.1f, 250 - (10 * i)-5f); GameObject obj = (GameObject)Instantiate(water, pos, Quaternion.identity); Bounds b = obj.collider.bounds; GraphUpdateObject guo = new GraphUpdateObject(b); AstarPath.active.UpdateGraphs(guo); } else if(ground_tiles[i,j] == 2) { Vector3 pos = new Vector3(10 * j + 5, 0.1f, 250 - (10 * i)-5f); GameObject obj = (GameObject)Instantiate(tree, pos, Quaternion.Euler(-90,0,0)); Bounds b = obj.collider.bounds; GraphUpdateObject guo = new GraphUpdateObject(b); AstarPath.active.UpdateGraphs(guo); } //else if(ground_tiles[i,j] == 3) //{ // Vector3 pos = new Vector3(10 * j + 5, 0.1f, ter_Height - (10 * i)-5f); // Instantiate(goldmine, pos, Quaternion.identity); //} //else if(ground_tiles[i,j] == 4) //{ // Vector3 pos = new Vector3(10 * j + 5, 0.1f, ter_Height - (10 * i)-5f); // Instantiate(farm, pos, Quaternion.identity); //} //else if(ground_tiles[i,j] == 5) //{ // Vector3 pos = new Vector3(10 * j + 5, 0.1f, ter_Height - (10 * i)-5f); // Instantiate(barracks, pos, Quaternion.identity); //} else if(ground_tiles[i,j] == 6) { /*//Vector3 pos = new Vector3(10 * j + 5, 0.1f, (ter_Height - (250 * i) - 30f) / 4.0f); Vector3 pos = new Vector3(10 * j + 5, 0.1f, ter_Height - (10 * i)-5f); Instantiate(Ore_Fields, pos, Quaternion.identity); */ } else { Debug.Log ("Invalid tile index"); } } } }
/** Updates graphs and checks if all nodes are still reachable from each other. * Graphs are updated, then a check is made to see if the nodes are still reachable from each other. * If they are not, the graphs are reverted to before the update and \a false is returned.\n * This is slower than a normal graph update. * All queued graph updates and thread safe callbacks will be flushed during this function. * * \note This might return true for small areas even if there is no possible path if AstarPath.minAreaSize is greater than zero (0). * So when using this, it is recommended to set AstarPath.minAreaSize to 0 (A* Inspector -> Settings -> Pathfinding) * * \param guo The GraphUpdateObject to update the graphs with * \param node1 Node which should have a valid path to \a node2. All nodes should be walkable or \a false will be returned. * \param node2 Node which should have a valid path to \a node1. All nodes should be walkable or \a false will be returned. * \param alwaysRevert If true, reverts the graphs to the old state even if no blocking ocurred * * \returns True if the given nodes are still reachable from each other after the \a guo has been applied. False otherwise. * \code var guo = new GraphUpdateObject (tower.GetComponent<Collider>.bounds); var spawnPointNode = AstarPath.active.GetNearest (spawnPoint.position).node; var goalNode = AstarPath.active.GetNearest (goalNode.position).node; if (GraphUpdateUtilities.UpdateGraphsNoBlock (guo, spawnPointNode, goalNode, false)) { // Valid tower position // Since the last parameter (which is called "alwaysRevert") in the method call was false // The graph is now updated and the game can just continue } else { // Invalid tower position. It blocks the path between the spawn point and the goal // The effect on the graph has been reverted Destroy (tower); } \endcode */ public static bool UpdateGraphsNoBlock (GraphUpdateObject guo, GraphNode node1, GraphNode node2, bool alwaysRevert = false) { List<GraphNode> buffer = ListPool<GraphNode>.Claim (); buffer.Add (node1); buffer.Add (node2); bool worked = UpdateGraphsNoBlock (guo, buffer, alwaysRevert); ListPool<GraphNode>.Release (buffer); return worked; }
private bool NoPathBlockage(GameObject placedObject) { var updateObject = new GraphUpdateObject(placedObject.GetComponent<Collider2D>().bounds); Vector3 start = GameManager.instance.spawnPoint.transform.position; Vector3 end = GameManager.instance.exitPoint.transform.position; var startNode = AstarPath.active.GetNearest(start).node; var endNode = AstarPath.active.GetNearest(end).node; return GraphUpdateUtilities.UpdateGraphsNoBlock(updateObject, startNode, endNode); }
public void updateGraph(GameObject obj, bool addTower) { GraphUpdateObject graphObj = new GraphUpdateObject (obj.GetComponent<Collider> ().bounds); if (!addTower) { graphObj.modifyWalkability = true; graphObj.setWalkability = true; } AstarPath.active.UpdateGraphs (graphObj); updateMonstersPath (); }
private void instatiateObject(string asset, Vector3 coords) { GameObject resource = (GameObject)Instantiate (Resources.Load ("Prefabs/" + asset, typeof(GameObject)), coords, Quaternion.identity); //Crear l'arbre if (GameObject.Find ("Map")) { resource.transform.parent = GameObject.Find ("Map").transform; } var guo = new GraphUpdateObject (resource.GetComponent<Collider> ().bounds); guo.updatePhysics = true; AstarPath.active.UpdateGraphs (guo); }
/** Updates graphs and checks if all nodes are still reachable from each other. * Graphs are updated, then a check is made to see if the nodes are still reachable from each other. * If they are not, the graphs are reverted to before the update and \a false is returned.\n * This is slower than a normal graph update. * All queued graph updates and thread safe callbacks will be flushed during this function. * * \note This might return true for small areas even if there is no possible path if AstarPath.minAreaSize is greater than zero (0). * So when using this, it is recommended to set AstarPath.minAreaSize to 0 (A* Inspector -> Settings -> Pathfinding) * * \param guo The GraphUpdateObject to update the graphs with * \param node1 Node which should have a valid path to \a node2. All nodes should be walkable or \a false will be returned. * \param node2 Node which should have a valid path to \a node1. All nodes should be walkable or \a false will be returned. * \param alwaysRevert If true, revert the graphs even though no blocking ocurred */ public static bool UpdateGraphsNoBlock(GraphUpdateObject guo, Node node1, Node node2, bool alwaysRevert = false) { List<Node> buffer = ClaimNodeBuffer (); buffer.Add (node1); buffer.Add (node2); bool worked = UpdateGraphsNoBlock (guo,buffer, alwaysRevert); ReleaseNodeBuffer (buffer); return worked; }
void addToPathFinder() { //AstarPath.active.UpdateGraphs(gameObject.collider.bounds); //Bounds b = gameObject.collider.bounds; //guo = new GraphUpdateObject(b); //addToPathFinder();*/ //print ("add"); AstarPath.active.UpdateGraphs (guo,0.0f); Bounds b = gameObject.collider.bounds; guo = new GraphUpdateObject(b); AstarPath.active.UpdateGraphs (guo); }
public void UpdateGraph(GameObject go) { if(go.layer == LAYER_MASK ) AstarPath.active.UpdateGraphs (go.collider.bounds); guo = new GraphUpdateObject(go.collider.bounds); AstarPath.active.UpdateGraphs(guo); graphUpdate.Apply(); AstarPath.active.FloodFill(); AstarPath.active.Scan(); }
private void doNavCut() { if (this.blockNav) { return; } if (AstarPath.active && !this.coolDown) { this.go = base.gameObject; if (this.oneTimeOnly) { this.blockNav = true; } Collider component = this.go.GetComponent<Collider>(); if (!component) { return; } Bounds bounds = component.bounds; this.diff = bounds.center.y - bounds.extents.y; float num = Terrain.activeTerrain.SampleHeight(bounds.center) + Terrain.activeTerrain.transform.position.y; this.diff -= num; if (this.diff > 7f) { return; } getStructureStrength component2 = this.go.GetComponent<getStructureStrength>(); bool flag = false; if (this.go.layer == 21 && component2) { if (component2._type == getStructureStrength.structureType.floor) { this.go.layer = 26; flag = true; } else if (component2._type == getStructureStrength.structureType.wall) { this.go.layer = 20; flag = true; } } GraphUpdateObject ob = new GraphUpdateObject(bounds); AstarPath.active.UpdateGraphs(ob); this.coolDown = true; base.Invoke("resetCoolDown", 1f); if (flag) { base.Invoke("resetLayer", 0.2f); } } }
public void PlaceObject(GameObject go, Vector3 pos) { GameObject obj = (GameObject)GameObject.Instantiate (go,pos,Quaternion.identity); obj.SetActive (true); if (obj.collider != null) { Bounds b = obj.collider.bounds; GraphUpdateObject guo = new GraphUpdateObject(b); AstarPath.active.UpdateGraphs (guo); } if (direct) AstarPath.active.FlushGraphUpdates(); }
void Update() { if(isBuildingPlaced){ Bounds bou; BoxCollider b = GetComponent<BoxCollider>(); if(b != null){ bou = b.bounds; var guo = new GraphUpdateObject(bou); guo.updatePhysics = true; AstarPath.active.UpdateGraphs(guo); isBuildingPlaced = false; } } }
private void doStumpRemove() { if (!AstarPath.active) { return; } Terrain activeTerrain = Terrain.activeTerrain; if (activeTerrain) { Collider component = base.transform.GetComponent<Collider>(); GraphUpdateObject ob = new GraphUpdateObject(component.bounds); AstarPath.active.UpdateGraphs(ob, 0f); UnityEngine.Object.Destroy(base.gameObject); } }
public void SetState (bool open) { this.open = open; GraphUpdateObject guo = new GraphUpdateObject(bounds); guo.tagsChange = 1 << bitToChange; guo.tagsValue = open ? 1 << bitToChange : 0; AstarPath.active.UpdateGraphs (guo); if (open) { animation.Play ("Open"); } else { animation.Play ("Close"); } }
public void SetState (bool open) { this.open = open; GraphUpdateObject guo = new GraphUpdateObject(bounds); int tag = open ? opentag : closedtag; if (tag > 31) { Debug.LogError ("tag > 31"); return; } guo.modifyTag = true; guo.setTag = tag; AstarPath.active.UpdateGraphs (guo); if (open) { animation.Play ("Open"); } else { animation.Play ("Close"); } }
public GameObject go; /** GameObject to place. Make sure the layer it is in is included in the collision mask on the GridGraph settings (assuming a GridGraph) */ #endregion Fields #region Methods public void PlaceObject() { Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition); RaycastHit hit; if ( Physics.Raycast (ray, out hit, Mathf.Infinity)) { Vector3 p = hit.point; GameObject obj = (GameObject)GameObject.Instantiate (go,p,Quaternion.identity); Bounds b = obj.GetComponent<Collider>().bounds; //Pathfinding.Console.Write ("// Placing Object\n"); GraphUpdateObject guo = new GraphUpdateObject(b); AstarPath.active.UpdateGraphs (guo); if (direct) { //Pathfinding.Console.Write ("// Flushing\n"); AstarPath.active.FlushGraphUpdates(); } } }
public void RemoveObject () { Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition); RaycastHit hit; if ( Physics.Raycast (ray, out hit, Mathf.Infinity)) { if (hit.collider.isTrigger || hit.transform.gameObject.name == "Ground") return; Bounds b = hit.collider.bounds; Destroy (hit.collider); Destroy (hit.collider.gameObject); //Pathfinding.Console.Write ("// Placing Object\n"); GraphUpdateObject guo = new GraphUpdateObject(b); AstarPath.active.UpdateGraphs (guo,0.0f); if (direct) { //Pathfinding.Console.Write ("// Flushing\n"); AstarPath.active.FlushGraphUpdates(); } } }
public GameObject go; /** GameObject to place. Make sure the layer it is in is included in the collision mask on the GridGraph settings (assuming a GridGraph) */ #endregion Fields #region Methods public void PlaceObject() { Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition); RaycastHit hit; if ( Physics.Raycast (ray, out hit, Mathf.Infinity)) { Vector3 p = hit.point; GameObject obj = (GameObject)GameObject.Instantiate (go,p,Quaternion.identity); Bounds b = obj.collider.bounds; GraphUpdateObject ob = new GraphUpdateObject(b); AstarPath.active.UpdateGraphs (ob); if (direct) { AstarPath.active.FlushGraphUpdates(); } } }
public void SetState (bool open) { this.open = open; if (updateGraphsWithGUO) { GraphUpdateObject guo = new GraphUpdateObject(bounds); int tag = open ? opentag : closedtag; if (tag > 31) { Debug.LogError ("tag > 31"); return; } guo.modifyTag = true; guo.setTag = tag; guo.updatePhysics = false; AstarPath.active.UpdateGraphs (guo); } if (open) { GetComponent<Animation>().Play ("Open"); } else { GetComponent<Animation>().Play ("Close"); } }
public void CreateBuildingIA(GameObject building, Vector3 coords) { creationBuilding = (GameObject)Instantiate (building, coords, Quaternion.identity); creationBuildingConstruction = (GameObject)Instantiate (building, coords, Quaternion.identity); creationBuildingConstruction.SetActive (false); float wood = owner.GetResourceAmount (RTSObject.ResourceType.Wood); if (wood >= creationBuildingConstruction.GetComponent<Building> ().cost) { Debug.Log ("Tenemos suficiente madera"); creationBuildingConstruction.SetActive (true); currentProject = creationBuildingConstruction.GetComponent<Building> (); currentProject.hitPoints = 0; currentProject.needsBuilding = true; currentProject.owner = owner; var guo = new GraphUpdateObject (currentProject.GetComponent<BoxCollider> ().bounds); guo.updatePhysics = true; AstarPath.active.UpdateGraphs (guo); owner.resourceAmounts [RTSObject.ResourceType.Wood] -= currentProject.cost; SetNewPath (coords, false); } }
public void PlaceObject() { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit raycastHit; if (Physics.Raycast(ray, out raycastHit, float.PositiveInfinity)) { Vector3 point = raycastHit.point; GameObject gameObject = (GameObject)UnityEngine.Object.Instantiate(this.go, point, Quaternion.identity); if (this.issueGUOs) { Bounds bounds = gameObject.GetComponent<Collider>().bounds; GraphUpdateObject ob = new GraphUpdateObject(bounds); AstarPath.active.UpdateGraphs(ob); if (this.direct) { AstarPath.active.FlushGraphUpdates(); } } } }
public bool isTowerPutable(GameObject obj, Player_Board.e_player playerPlaying) { Transform spawn; Transform nexus; if (playerPlaying == Player_Board.e_player.PLAYER1) { spawn = GameObject.Find ("PLAYER1-MOBSPAWN").transform; nexus = GameObject.Find ("PLAYER1-NEXUS").transform; } else { spawn = GameObject.Find ("PLAYER2-MOBSPAWN").transform; nexus = GameObject.Find ("PLAYER2-NEXUS").transform; } GraphUpdateObject guo = new GraphUpdateObject (obj.GetComponent<Collider> ().bounds); GraphNode spawnNode = AstarPath.active.GetNearest (spawn.position).node; GraphNode nexusNode = AstarPath.active.GetNearest (nexus.position).node; if (GraphUpdateUtilities.UpdateGraphsNoBlock (guo, spawnNode, nexusNode, false)) { Debug.Log ("Tower is putable"); return true; } else { Debug.Log ("Tower is NOT putable !!"); return false; } }
public void RemoveObject() { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit raycastHit; if (Physics.Raycast(ray, out raycastHit, float.PositiveInfinity)) { if (raycastHit.collider.isTrigger || raycastHit.transform.gameObject.name == "Ground") { return; } Bounds bounds = raycastHit.collider.bounds; UnityEngine.Object.Destroy(raycastHit.collider); UnityEngine.Object.Destroy(raycastHit.collider.gameObject); if (this.issueGUOs) { GraphUpdateObject ob = new GraphUpdateObject(bounds); AstarPath.active.UpdateGraphs(ob, 0f); if (this.direct) { AstarPath.active.FlushGraphUpdates(); } } } }
public void changeModel(string estat) { if (estat == "finished") { ReplaceChildWithChildFromGameObjectTemplate (finishedModel); AudioClip normal = Resources.Load ("Sounds/Building/Ta_Da") as AudioClip; audio.PlayOneShot (normal); } else if (estat == "demolished") { //var exp = demolishedModel.GetComponent<ParticleSystem>(); ReplaceChildWithChildFromGameObjectTemplate (demolishedModel); AudioClip semi = Resources.Load ("Sounds/Building/Pickaxe" ) as AudioClip; audio.PlayOneShot (semi); //exp.Play(); //Destroy(gameObject, exp.duration); } else if (estat == "construction") { ReplaceChildWithChildFromGameObjectTemplate (constructionModel); AudioClip onconst = Resources.Load ("Sounds/Building/Fire_Burning") as AudioClip; audio.PlayOneShot (onconst); } var guo = new GraphUpdateObject (this.GetComponent<BoxCollider> ().bounds); guo.updatePhysics = true; AstarPath.active.UpdateGraphs (guo); }
public new void UpdateArea(GraphUpdateObject o) { if (this.nodes == null || this.nodes.Length != this.width * this.depth * this.layerCount) { Debug.LogWarning("The Grid Graph is not scanned, cannot update area "); return; } IntRect a; IntRect a2; IntRect intRect; bool flag; int num; base.CalculateAffectedRegions(o, out a, out a2, out intRect, out flag, out num); bool flag2 = o is LayerGridGraphUpdate && ((LayerGridGraphUpdate)o).recalculateNodes; bool flag3 = (o is LayerGridGraphUpdate) ? ((LayerGridGraphUpdate)o).preserveExistingNodes : (!o.resetPenaltyOnPhysics); if (o.trackChangedNodes && flag2) { Debug.LogError("Cannot track changed nodes when creating or deleting nodes.\nWill not update LayerGridGraph"); return; } IntRect b = new IntRect(0, 0, this.width - 1, this.depth - 1); IntRect intRect2 = IntRect.Intersection(a2, b); if (!flag2) { for (int i = intRect2.xmin; i <= intRect2.xmax; i++) { for (int j = intRect2.ymin; j <= intRect2.ymax; j++) { for (int k = 0; k < this.layerCount; k++) { o.WillUpdateNode(this.nodes[k * this.width * this.depth + j * this.width + i]); } } } } if (o.updatePhysics && !o.modifyWalkability) { this.collision.Initialize(base.transform, this.nodeSize); intRect2 = IntRect.Intersection(intRect, b); for (int l = intRect2.xmin; l <= intRect2.xmax; l++) { for (int m = intRect2.ymin; m <= intRect2.ymax; m++) { this.RecalculateCell(l, m, !flag3, false); } } for (int n = intRect2.xmin; n <= intRect2.xmax; n++) { for (int num2 = intRect2.ymin; num2 <= intRect2.ymax; num2++) { this.CalculateConnections(n, num2); } } } intRect2 = IntRect.Intersection(a, b); for (int num3 = intRect2.xmin; num3 <= intRect2.xmax; num3++) { for (int num4 = intRect2.ymin; num4 <= intRect2.ymax; num4++) { for (int num5 = 0; num5 < this.layerCount; num5++) { int num6 = num5 * this.width * this.depth + num4 * this.width + num3; LevelGridNode levelGridNode = this.nodes[num6]; if (levelGridNode != null) { if (flag) { levelGridNode.Walkable = levelGridNode.WalkableErosion; if (o.bounds.Contains((Vector3)levelGridNode.position)) { o.Apply(levelGridNode); } levelGridNode.WalkableErosion = levelGridNode.Walkable; } else if (o.bounds.Contains((Vector3)levelGridNode.position)) { o.Apply(levelGridNode); } } } } } if (flag && num == 0) { intRect2 = IntRect.Intersection(a2, b); for (int num7 = intRect2.xmin; num7 <= intRect2.xmax; num7++) { for (int num8 = intRect2.ymin; num8 <= intRect2.ymax; num8++) { this.CalculateConnections(num7, num8); } } return; } if (flag && num > 0) { IntRect a3 = IntRect.Union(a, intRect).Expand(num); IntRect intRect3 = a3.Expand(num); a3 = IntRect.Intersection(a3, b); intRect3 = IntRect.Intersection(intRect3, b); for (int num9 = intRect3.xmin; num9 <= intRect3.xmax; num9++) { for (int num10 = intRect3.ymin; num10 <= intRect3.ymax; num10++) { for (int num11 = 0; num11 < this.layerCount; num11++) { int num12 = num11 * this.width * this.depth + num10 * this.width + num9; LevelGridNode levelGridNode2 = this.nodes[num12]; if (levelGridNode2 != null) { bool walkable = levelGridNode2.Walkable; levelGridNode2.Walkable = levelGridNode2.WalkableErosion; if (!a3.Contains(num9, num10)) { levelGridNode2.TmpWalkable = walkable; } } } } } for (int num13 = intRect3.xmin; num13 <= intRect3.xmax; num13++) { for (int num14 = intRect3.ymin; num14 <= intRect3.ymax; num14++) { this.CalculateConnections(num13, num14); } } base.ErodeWalkableArea(intRect3.xmin, intRect3.ymin, intRect3.xmax + 1, intRect3.ymax + 1); for (int num15 = intRect3.xmin; num15 <= intRect3.xmax; num15++) { for (int num16 = intRect3.ymin; num16 <= intRect3.ymax; num16++) { if (!a3.Contains(num15, num16)) { for (int num17 = 0; num17 < this.layerCount; num17++) { int num18 = num17 * this.width * this.depth + num16 * this.width + num15; LevelGridNode levelGridNode3 = this.nodes[num18]; if (levelGridNode3 != null) { levelGridNode3.Walkable = levelGridNode3.TmpWalkable; } } } } } for (int num19 = intRect3.xmin; num19 <= intRect3.xmax; num19++) { for (int num20 = intRect3.ymin; num20 <= intRect3.ymax; num20++) { this.CalculateConnections(num19, num20); } } } }
/** Updates an area in the list graph. * Recalculates possibly affected connections, i.e all connectionlines passing trough the bounds of the \a guo will be recalculated * \astarpro */ public void UpdateArea(GraphUpdateObject guo) { if (nodes == null) { return; } for (int i = 0; i < nodeCount; i++) { if (guo.bounds.Contains((Vector3)nodes[i].position)) { guo.WillUpdateNode(nodes[i]); guo.Apply(nodes[i]); } } if (guo.updatePhysics) { //Use a copy of the bounding box, we should not change the GUO's bounding box since it might be used for other graph updates Bounds bounds = guo.bounds; if (thickRaycast) { //Expand the bounding box to account for the thick raycast bounds.Expand(thickRaycastRadius * 2); } //Create two temporary arrays used for holding new connections and costs List <GraphNode> tmp_arr = Pathfinding.Util.ListPool <GraphNode> .Claim(); List <uint> tmp_arr2 = Pathfinding.Util.ListPool <uint> .Claim(); for (int i = 0; i < nodeCount; i++) { PointNode node = nodes[i]; var a = (Vector3)node.position; List <GraphNode> conn = null; List <uint> costs = null; for (int j = 0; j < nodeCount; j++) { if (j == i) { continue; } var b = (Vector3)nodes[j].position; if (VectorMath.SegmentIntersectsBounds(bounds, a, b)) { float dist; PointNode other = nodes[j]; bool contains = node.ContainsConnection(other); bool validConnection = IsValidConnection(node, other, out dist); if (!contains && validConnection) { // A new connection should be added if (conn == null) { tmp_arr.Clear(); tmp_arr2.Clear(); conn = tmp_arr; costs = tmp_arr2; conn.AddRange(node.connections); costs.AddRange(node.connectionCosts); } uint cost = (uint)Mathf.RoundToInt(dist * Int3.FloatPrecision); conn.Add(other); costs.Add(cost); } else if (contains && !validConnection) { // A connection should be removed if (conn == null) { tmp_arr.Clear(); tmp_arr2.Clear(); conn = tmp_arr; costs = tmp_arr2; conn.AddRange(node.connections); costs.AddRange(node.connectionCosts); } int p = conn.IndexOf(other); //Shouldn't have to check for it, but who knows what might go wrong if (p != -1) { conn.RemoveAt(p); costs.RemoveAt(p); } } } } // Save the new connections if any were changed if (conn != null) { node.connections = conn.ToArray(); node.connectionCosts = costs.ToArray(); } } // Release buffers back to the pool Pathfinding.Util.ListPool <GraphNode> .Release(tmp_arr); Pathfinding.Util.ListPool <uint> .Release(tmp_arr2); } }
public GraphUpdateThreading CanUpdateAsync(GraphUpdateObject o) { return(GraphUpdateThreading.UnityThread); }
GraphUpdateThreading IUpdatableGraph.CanUpdateAsync(GraphUpdateObject o) { return(o.updatePhysics ? GraphUpdateThreading.UnityInit | GraphUpdateThreading.SeparateThread | GraphUpdateThreading.UnityPost : GraphUpdateThreading.SeparateThread); }
public static void UpdateArea(GraphUpdateObject o, INavmesh graph) { Bounds bounds = o.bounds; // Bounding rectangle with floating point coordinates Rect r = Rect.MinMaxRect(bounds.min.x, bounds.min.z, bounds.max.x, bounds.max.z); // Bounding rectangle with int coordinates var r2 = new IntRect( Mathf.FloorToInt(bounds.min.x * Int3.Precision), Mathf.FloorToInt(bounds.min.z * Int3.Precision), Mathf.FloorToInt(bounds.max.x * Int3.Precision), Mathf.FloorToInt(bounds.max.z * Int3.Precision) ); // Corners of the bounding rectangle var a = new Int3(r2.xmin, 0, r2.ymin); var b = new Int3(r2.xmin, 0, r2.ymax); var c = new Int3(r2.xmax, 0, r2.ymin); var d = new Int3(r2.xmax, 0, r2.ymax); var ymin = ((Int3)bounds.min).y; var ymax = ((Int3)bounds.max).y; // Loop through all nodes graph.GetNodes(_node => { var node = _node as TriangleMeshNode; bool inside = false; int allLeft = 0; int allRight = 0; int allTop = 0; int allBottom = 0; // Check bounding box rect in XZ plane for (int v = 0; v < 3; v++) { Int3 p = node.GetVertex(v); var vert = (Vector3)p; if (r2.Contains(p.x, p.z)) { inside = true; break; } if (vert.x < r.xMin) { allLeft++; } if (vert.x > r.xMax) { allRight++; } if (vert.z < r.yMin) { allTop++; } if (vert.z > r.yMax) { allBottom++; } } if (!inside) { if (allLeft == 3 || allRight == 3 || allTop == 3 || allBottom == 3) { return(true); } } // Check if the polygon edges intersect the bounding rect for (int v = 0; v < 3; v++) { int v2 = v > 1 ? 0 : v + 1; Int3 vert1 = node.GetVertex(v); Int3 vert2 = node.GetVertex(v2); if (VectorMath.SegmentsIntersectXZ(a, b, vert1, vert2)) { inside = true; break; } if (VectorMath.SegmentsIntersectXZ(a, c, vert1, vert2)) { inside = true; break; } if (VectorMath.SegmentsIntersectXZ(c, d, vert1, vert2)) { inside = true; break; } if (VectorMath.SegmentsIntersectXZ(d, b, vert1, vert2)) { inside = true; break; } } // Check if the node contains any corner of the bounding rect if (inside || node.ContainsPoint(a) || node.ContainsPoint(b) || node.ContainsPoint(c) || node.ContainsPoint(d)) { inside = true; } if (!inside) { return(true); } int allAbove = 0; int allBelow = 0; // Check y coordinate for (int v = 0; v < 3; v++) { Int3 p = node.GetVertex(v); if (p.y < ymin) { allBelow++; } if (p.y > ymax) { allAbove++; } } // Polygon is either completely above the bounding box or completely below it if (allBelow == 3 || allAbove == 3) { return(true); } // Triangle is inside the bounding box! // Update it! o.WillUpdateNode(node); o.Apply(node); return(true); }); }
public void UpdateAreaInit(GraphUpdateObject o) { }
public void Apply() { if (AstarPath.active == null) { Debug.LogError("There is no AstarPath object in the scene", this); return; } GraphUpdateObject graphUpdateObject; if (this.points == null || this.points.Length == 0) { PolygonCollider2D component = base.GetComponent <PolygonCollider2D>(); if (component != null) { Vector2[] array = component.points; Vector3[] array2 = new Vector3[array.Length]; for (int i = 0; i < array2.Length; i++) { Vector2 vector = array[i] + component.offset; array2[i] = new Vector3(vector.x, 0f, vector.y); } Matrix4x4 matrix = base.transform.localToWorldMatrix * Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(-90f, 0f, 0f), Vector3.one); GraphUpdateShape shape = new GraphUpdateShape(this.points, this.convex, matrix, this.minBoundsHeight); graphUpdateObject = new GraphUpdateObject(this.GetBounds()); graphUpdateObject.shape = shape; } else { Bounds bounds = this.GetBounds(); if (bounds.center == Vector3.zero && bounds.size == Vector3.zero) { Debug.LogError("Cannot apply GraphUpdateScene, no points defined and no renderer or collider attached", this); return; } graphUpdateObject = new GraphUpdateObject(bounds); } } else { GraphUpdateShape graphUpdateShape; if (this.legacyMode && !this.legacyUseWorldSpace) { Vector3[] array3 = new Vector3[this.points.Length]; for (int j = 0; j < this.points.Length; j++) { array3[j] = base.transform.TransformPoint(this.points[j]); } graphUpdateShape = new GraphUpdateShape(array3, this.convex, Matrix4x4.identity, this.minBoundsHeight); } else { graphUpdateShape = new GraphUpdateShape(this.points, this.convex, (!this.legacyMode || !this.legacyUseWorldSpace) ? base.transform.localToWorldMatrix : Matrix4x4.identity, this.minBoundsHeight); } Bounds bounds2 = graphUpdateShape.GetBounds(); graphUpdateObject = new GraphUpdateObject(bounds2); graphUpdateObject.shape = graphUpdateShape; } this.firstApplied = true; graphUpdateObject.modifyWalkability = this.modifyWalkability; graphUpdateObject.setWalkability = this.setWalkability; graphUpdateObject.addPenalty = this.penaltyDelta; graphUpdateObject.updatePhysics = this.updatePhysics; graphUpdateObject.updateErosion = this.updateErosion; graphUpdateObject.resetPenaltyOnPhysics = this.resetPenaltyOnPhysics; graphUpdateObject.modifyTag = this.modifyTag; graphUpdateObject.setTag = this.setTag; AstarPath.active.UpdateGraphs(graphUpdateObject); }
public static void UpdateArea(GraphUpdateObject o, INavmeshHolder graph) { Bounds bounds = graph.transform.InverseTransform(o.bounds); // Bounding rectangle with integer coordinates var irect = new IntRect( Mathf.FloorToInt(bounds.min.x * Int3.Precision), Mathf.FloorToInt(bounds.min.z * Int3.Precision), Mathf.CeilToInt(bounds.max.x * Int3.Precision), Mathf.CeilToInt(bounds.max.z * Int3.Precision) ); // Corners of the bounding rectangle var a = new Int3(irect.xmin, 0, irect.ymin); var b = new Int3(irect.xmin, 0, irect.ymax); var c = new Int3(irect.xmax, 0, irect.ymin); var d = new Int3(irect.xmax, 0, irect.ymax); var ymin = ((Int3)bounds.min).y; var ymax = ((Int3)bounds.max).y; // Loop through all nodes and check if they intersect the bounding box graph.GetNodes(_node => { var node = _node as TriangleMeshNode; bool inside = false; int allLeft = 0; int allRight = 0; int allTop = 0; int allBottom = 0; // Check bounding box rect in XZ plane for (int v = 0; v < 3; v++) { Int3 p = node.GetVertexInGraphSpace(v); if (irect.Contains(p.x, p.z)) { inside = true; break; } if (p.x < irect.xmin) { allLeft++; } if (p.x > irect.xmax) { allRight++; } if (p.z < irect.ymin) { allTop++; } if (p.z > irect.ymax) { allBottom++; } } if (!inside && (allLeft == 3 || allRight == 3 || allTop == 3 || allBottom == 3)) { return; } // Check if the polygon edges intersect the bounding rect for (int v = 0; v < 3; v++) { int v2 = v > 1 ? 0 : v + 1; Int3 vert1 = node.GetVertexInGraphSpace(v); Int3 vert2 = node.GetVertexInGraphSpace(v2); if (VectorMath.SegmentsIntersectXZ(a, b, vert1, vert2)) { inside = true; break; } if (VectorMath.SegmentsIntersectXZ(a, c, vert1, vert2)) { inside = true; break; } if (VectorMath.SegmentsIntersectXZ(c, d, vert1, vert2)) { inside = true; break; } if (VectorMath.SegmentsIntersectXZ(d, b, vert1, vert2)) { inside = true; break; } } // Check if the node contains any corner of the bounding rect if (inside || node.ContainsPointInGraphSpace(a) || node.ContainsPointInGraphSpace(b) || node.ContainsPointInGraphSpace(c) || node.ContainsPointInGraphSpace(d)) { inside = true; } if (!inside) { return; } int allAbove = 0; int allBelow = 0; // Check y coordinate for (int v = 0; v < 3; v++) { Int3 p = node.GetVertexInGraphSpace(v); if (p.y < ymin) { allBelow++; } if (p.y > ymax) { allAbove++; } } // Polygon is either completely above the bounding box or completely below it if (allBelow == 3 || allAbove == 3) { return; } // Triangle is inside the bounding box! // Update it! o.WillUpdateNode(node); o.Apply(node); }); }
void IUpdatableGraph.UpdateArea(GraphUpdateObject o) { UpdateArea(o, this); }
public void Apply() { if (AstarPath.active == null) { Debug.LogError("There is no AstarPath object in the scene"); } else { GraphUpdateObject obj2; if ((this.points == null) || (this.points.Length == 0)) { Bounds bounds; Collider component = base.GetComponent <Collider>(); Renderer renderer = base.GetComponent <Renderer>(); if (component != null) { bounds = component.bounds; } else if (renderer != null) { bounds = renderer.bounds; } else { Debug.LogWarning("Cannot apply GraphUpdateScene, no points defined and no renderer or collider attached"); return; } if (bounds.size.y < this.minBoundsHeight) { bounds.size = new Vector3(bounds.size.x, this.minBoundsHeight, bounds.size.z); } obj2 = new GraphUpdateObject(bounds); } else { GraphUpdateShape shape = new GraphUpdateShape { convex = this.convex }; Vector3[] points = this.points; if (!this.useWorldSpace) { points = new Vector3[this.points.Length]; Matrix4x4 localToWorldMatrix = base.transform.localToWorldMatrix; for (int i = 0; i < points.Length; i++) { points[i] = localToWorldMatrix.MultiplyPoint3x4(this.points[i]); } } shape.points = points; Bounds b = shape.GetBounds(); if (b.size.y < this.minBoundsHeight) { b.size = new Vector3(b.size.x, this.minBoundsHeight, b.size.z); } obj2 = new GraphUpdateObject(b) { shape = shape }; } this.firstApplied = true; obj2.modifyWalkability = this.modifyWalkability; obj2.setWalkability = this.setWalkability; obj2.addPenalty = this.penaltyDelta; obj2.updatePhysics = this.updatePhysics; obj2.updateErosion = this.updateErosion; obj2.resetPenaltyOnPhysics = this.resetPenaltyOnPhysics; obj2.modifyTag = this.modifyTag; obj2.setTag = this.setTag; AstarPath.active.UpdateGraphs(obj2); } }
/** Updates graphs with a created GUO. * Creates a Pathfinding.GraphUpdateObject with a Pathfinding.GraphUpdateShape * representing the polygon of this object and update all graphs using AstarPath.UpdateGraphs. * This will not update graphs directly. See AstarPath.UpdateGraph for more info. */ public void Apply() { if (AstarPath.active == null) { Debug.LogError("There is no AstarPath object in the scene"); return; } GraphUpdateObject guo; if (points == null || points.Length == 0) { var coll = GetComponent <Collider>(); var rend = GetComponent <Renderer>(); Bounds b; if (coll != null) { b = coll.bounds; } else if (rend != null) { b = rend.bounds; } else { Debug.LogWarning("Cannot apply GraphUpdateScene, no points defined and no renderer or collider attached"); return; } if (b.size.y < minBoundsHeight) { b.size = new Vector3(b.size.x, minBoundsHeight, b.size.z); } guo = new GraphUpdateObject(b); } else { var shape = new GraphUpdateShape(); shape.convex = convex; Vector3[] worldPoints = points; if (!useWorldSpace) { worldPoints = new Vector3[points.Length]; Matrix4x4 matrix = transform.localToWorldMatrix; for (int i = 0; i < worldPoints.Length; i++) { worldPoints[i] = matrix.MultiplyPoint3x4(points[i]); } } shape.points = worldPoints; Bounds b = shape.GetBounds(); if (b.size.y < minBoundsHeight) { b.size = new Vector3(b.size.x, minBoundsHeight, b.size.z); } guo = new GraphUpdateObject(b); guo.shape = shape; } firstApplied = true; guo.modifyWalkability = modifyWalkability; guo.setWalkability = setWalkability; guo.addPenalty = penaltyDelta; guo.updatePhysics = updatePhysics; guo.updateErosion = updateErosion; guo.resetPenaltyOnPhysics = resetPenaltyOnPhysics; guo.modifyTag = modifyTag; guo.setTag = setTag; AstarPath.active.UpdateGraphs(guo); }
// Token: 0x0600052A RID: 1322 RVA: 0x0002D6B8 File Offset: 0x0002BAB8 public void UpdateArea(GraphUpdateObject guo) { if (this.nodes == null) { return; } for (int i = 0; i < this.nodeCount; i++) { if (guo.bounds.Contains((Vector3)this.nodes[i].position)) { guo.WillUpdateNode(this.nodes[i]); guo.Apply(this.nodes[i]); } } if (guo.updatePhysics) { Bounds bounds = guo.bounds; if (this.thickRaycast) { bounds.Expand(this.thickRaycastRadius * 2f); } List <GraphNode> list = ListPool <GraphNode> .Claim(); List <uint> list2 = ListPool <uint> .Claim(); for (int j = 0; j < this.nodeCount; j++) { PointNode pointNode = this.nodes[j]; Vector3 a = (Vector3)pointNode.position; List <GraphNode> list3 = null; List <uint> list4 = null; for (int k = 0; k < this.nodeCount; k++) { if (k != j) { Vector3 b = (Vector3)this.nodes[k].position; if (Polygon.LineIntersectsBounds(bounds, a, b)) { PointNode pointNode2 = this.nodes[k]; bool flag = pointNode.ContainsConnection(pointNode2); float num; if (!flag && this.IsValidConnection(pointNode, pointNode2, out num)) { if (list3 == null) { list.Clear(); list2.Clear(); list3 = list; list4 = list2; list3.AddRange(pointNode.connections); list4.AddRange(pointNode.connectionCosts); } uint item = (uint)Mathf.RoundToInt(num * 1000f); list3.Add(pointNode2); list4.Add(item); } else if (flag && !this.IsValidConnection(pointNode, pointNode2, out num)) { if (list3 == null) { list.Clear(); list2.Clear(); list3 = list; list4 = list2; list3.AddRange(pointNode.connections); list4.AddRange(pointNode.connectionCosts); } int num2 = list3.IndexOf(pointNode2); if (num2 != -1) { list3.RemoveAt(num2); list4.RemoveAt(num2); } } } } } if (list3 != null) { pointNode.connections = list3.ToArray(); pointNode.connectionCosts = list4.ToArray(); } } ListPool <GraphNode> .Release(list); ListPool <uint> .Release(list2); } }
/// <summary> /// Updates graphs with a created GUO. /// Creates a Pathfinding.GraphUpdateObject with a Pathfinding.GraphUpdateShape /// representing the polygon of this object and update all graphs using AstarPath.UpdateGraphs. /// This will not update graphs immediately. See AstarPath.UpdateGraph for more info. /// </summary> public void Apply() { if (AstarPath.active == null) { Debug.LogError("There is no AstarPath object in the scene", this); return; } GraphUpdateObject guo; if (points == null || points.Length == 0) { var polygonCollider = GetComponent <PolygonCollider2D>(); if (polygonCollider != null) { var points2D = polygonCollider.points; Vector3[] pts = new Vector3[points2D.Length]; for (int i = 0; i < pts.Length; i++) { var p = points2D[i] + polygonCollider.offset; pts[i] = new Vector3(p.x, 0, p.y); } var mat = transform.localToWorldMatrix * Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(-90, 0, 0), Vector3.one); var shape = new GraphUpdateShape(pts, convex, mat, minBoundsHeight); guo = new GraphUpdateObject(GetBounds()); guo.shape = shape; } else { var bounds = GetBounds(); if (bounds.center == Vector3.zero && bounds.size == Vector3.zero) { Debug.LogError("Cannot apply GraphUpdateScene, no points defined and no renderer or collider attached", this); return; } guo = new GraphUpdateObject(bounds); } } else { GraphUpdateShape shape; if (legacyMode && !legacyUseWorldSpace) { // Used for compatibility with older versions var worldPoints = new Vector3[points.Length]; for (int i = 0; i < points.Length; i++) { worldPoints[i] = transform.TransformPoint(points[i]); } shape = new GraphUpdateShape(worldPoints, convex, Matrix4x4.identity, minBoundsHeight); } else { shape = new GraphUpdateShape(points, convex, legacyMode && legacyUseWorldSpace ? Matrix4x4.identity : transform.localToWorldMatrix, minBoundsHeight); } var bounds = shape.GetBounds(); guo = new GraphUpdateObject(bounds); guo.shape = shape; } firstApplied = true; guo.modifyWalkability = modifyWalkability; guo.setWalkability = setWalkability; guo.addPenalty = penaltyDelta; guo.updatePhysics = updatePhysics; guo.updateErosion = updateErosion; guo.resetPenaltyOnPhysics = resetPenaltyOnPhysics; guo.modifyTag = modifyTag; guo.setTag = setTag; AstarPath.active.UpdateGraphs(guo); }
public new void UpdateArea(GraphUpdateObject o) { if (this.nodes == null || this.nodes.Length != this.width * this.depth * this.layerCount) { Debug.LogWarning("The Grid Graph is not scanned, cannot update area "); return; } Bounds bounds = o.bounds; Vector3 a; Vector3 a2; GridGraph.GetBoundsMinMax(bounds, this.inverseMatrix, out a, out a2); int xmin = Mathf.RoundToInt(a.x - 0.5f); int xmax = Mathf.RoundToInt(a2.x - 0.5f); int ymin = Mathf.RoundToInt(a.z - 0.5f); int ymax = Mathf.RoundToInt(a2.z - 0.5f); IntRect intRect = new IntRect(xmin, ymin, xmax, ymax); IntRect intRect2 = intRect; IntRect b = new IntRect(0, 0, this.width - 1, this.depth - 1); IntRect intRect3 = intRect; bool flag = o.updatePhysics || o.modifyWalkability; bool flag2 = o is LayerGridGraphUpdate && ((LayerGridGraphUpdate)o).recalculateNodes; bool preserveExistingNodes = !(o is LayerGridGraphUpdate) || ((LayerGridGraphUpdate)o).preserveExistingNodes; int num = (!o.updateErosion) ? 0 : this.erodeIterations; if (o.trackChangedNodes && flag2) { Debug.LogError("Cannot track changed nodes when creating or deleting nodes.\nWill not update LayerGridGraph"); return; } if (o.updatePhysics && !o.modifyWalkability && this.collision.collisionCheck) { Vector3 a3 = new Vector3(this.collision.diameter, 0f, this.collision.diameter) * 0.5f; a -= a3 * 1.02f; a2 += a3 * 1.02f; intRect3 = new IntRect(Mathf.RoundToInt(a.x - 0.5f), Mathf.RoundToInt(a.z - 0.5f), Mathf.RoundToInt(a2.x - 0.5f), Mathf.RoundToInt(a2.z - 0.5f)); intRect2 = IntRect.Union(intRect3, intRect2); } if (flag || num > 0) { intRect2 = intRect2.Expand(num + 1); } IntRect intRect4 = IntRect.Intersection(intRect2, b); if (!flag2) { for (int i = intRect4.xmin; i <= intRect4.xmax; i++) { for (int j = intRect4.ymin; j <= intRect4.ymax; j++) { for (int k = 0; k < this.layerCount; k++) { o.WillUpdateNode(this.nodes[k * this.width * this.depth + j * this.width + i]); } } } } if (o.updatePhysics && !o.modifyWalkability) { this.collision.Initialize(this.matrix, this.nodeSize); intRect4 = IntRect.Intersection(intRect3, b); bool flag3 = false; for (int l = intRect4.xmin; l <= intRect4.xmax; l++) { for (int m = intRect4.ymin; m <= intRect4.ymax; m++) { flag3 |= this.RecalculateCell(l, m, preserveExistingNodes); } } for (int n = intRect4.xmin; n <= intRect4.xmax; n++) { for (int num2 = intRect4.ymin; num2 <= intRect4.ymax; num2++) { for (int num3 = 0; num3 < this.layerCount; num3++) { int num4 = num3 * this.width * this.depth + num2 * this.width + n; LevelGridNode levelGridNode = this.nodes[num4]; if (levelGridNode != null) { this.CalculateConnections(this.nodes, levelGridNode, n, num2, num3); } } } } } intRect4 = IntRect.Intersection(intRect, b); for (int num5 = intRect4.xmin; num5 <= intRect4.xmax; num5++) { for (int num6 = intRect4.ymin; num6 <= intRect4.ymax; num6++) { for (int num7 = 0; num7 < this.layerCount; num7++) { int num8 = num7 * this.width * this.depth + num6 * this.width + num5; LevelGridNode levelGridNode2 = this.nodes[num8]; if (levelGridNode2 != null) { if (flag) { levelGridNode2.Walkable = levelGridNode2.WalkableErosion; if (o.bounds.Contains((Vector3)levelGridNode2.position)) { o.Apply(levelGridNode2); } levelGridNode2.WalkableErosion = levelGridNode2.Walkable; } else if (o.bounds.Contains((Vector3)levelGridNode2.position)) { o.Apply(levelGridNode2); } } } } } if (flag && num == 0) { intRect4 = IntRect.Intersection(intRect2, b); for (int num9 = intRect4.xmin; num9 <= intRect4.xmax; num9++) { for (int num10 = intRect4.ymin; num10 <= intRect4.ymax; num10++) { for (int num11 = 0; num11 < this.layerCount; num11++) { int num12 = num11 * this.width * this.depth + num10 * this.width + num9; LevelGridNode levelGridNode3 = this.nodes[num12]; if (levelGridNode3 != null) { this.CalculateConnections(this.nodes, levelGridNode3, num9, num10, num11); } } } } } else if (flag && num > 0) { IntRect a4 = IntRect.Union(intRect, intRect3).Expand(num); IntRect a5 = a4.Expand(num); a4 = IntRect.Intersection(a4, b); a5 = IntRect.Intersection(a5, b); for (int num13 = a5.xmin; num13 <= a5.xmax; num13++) { for (int num14 = a5.ymin; num14 <= a5.ymax; num14++) { for (int num15 = 0; num15 < this.layerCount; num15++) { int num16 = num15 * this.width * this.depth + num14 * this.width + num13; LevelGridNode levelGridNode4 = this.nodes[num16]; if (levelGridNode4 != null) { bool walkable = levelGridNode4.Walkable; levelGridNode4.Walkable = levelGridNode4.WalkableErosion; if (!a4.Contains(num13, num14)) { levelGridNode4.TmpWalkable = walkable; } } } } } for (int num17 = a5.xmin; num17 <= a5.xmax; num17++) { for (int num18 = a5.ymin; num18 <= a5.ymax; num18++) { for (int num19 = 0; num19 < this.layerCount; num19++) { int num20 = num19 * this.width * this.depth + num18 * this.width + num17; LevelGridNode levelGridNode5 = this.nodes[num20]; if (levelGridNode5 != null) { this.CalculateConnections(this.nodes, levelGridNode5, num17, num18, num19); } } } } this.ErodeWalkableArea(a5.xmin, a5.ymin, a5.xmax + 1, a5.ymax + 1); for (int num21 = a5.xmin; num21 <= a5.xmax; num21++) { for (int num22 = a5.ymin; num22 <= a5.ymax; num22++) { if (!a4.Contains(num21, num22)) { for (int num23 = 0; num23 < this.layerCount; num23++) { int num24 = num23 * this.width * this.depth + num22 * this.width + num21; LevelGridNode levelGridNode6 = this.nodes[num24]; if (levelGridNode6 != null) { levelGridNode6.Walkable = levelGridNode6.TmpWalkable; } } } } } for (int num25 = a5.xmin; num25 <= a5.xmax; num25++) { for (int num26 = a5.ymin; num26 <= a5.ymax; num26++) { for (int num27 = 0; num27 < this.layerCount; num27++) { int num28 = num27 * this.width * this.depth + num26 * this.width + num25; LevelGridNode levelGridNode7 = this.nodes[num28]; if (levelGridNode7 != null) { this.CalculateConnections(this.nodes, levelGridNode7, num25, num26, num27); } } } } } }
// Token: 0x060004C2 RID: 1218 RVA: 0x000293EC File Offset: 0x000277EC public static void UpdateArea(GraphUpdateObject o, INavmesh graph) { Bounds bounds = o.bounds; Rect r = Rect.MinMaxRect(bounds.min.x, bounds.min.z, bounds.max.x, bounds.max.z); IntRect r2 = new IntRect(Mathf.FloorToInt(bounds.min.x * 1000f), Mathf.FloorToInt(bounds.min.z * 1000f), Mathf.FloorToInt(bounds.max.x * 1000f), Mathf.FloorToInt(bounds.max.z * 1000f)); Int3 a = new Int3(r2.xmin, 0, r2.ymin); Int3 b = new Int3(r2.xmin, 0, r2.ymax); Int3 c = new Int3(r2.xmax, 0, r2.ymin); Int3 d = new Int3(r2.xmax, 0, r2.ymax); Int3 ia = a; Int3 ib = b; Int3 ic = c; Int3 id = d; graph.GetNodes(delegate(GraphNode _node) { TriangleMeshNode triangleMeshNode = _node as TriangleMeshNode; bool flag = false; int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; for (int i = 0; i < 3; i++) { Int3 vertex = triangleMeshNode.GetVertex(i); Vector3 vector = (Vector3)vertex; if (r2.Contains(vertex.x, vertex.z)) { flag = true; break; } if (vector.x < r.xMin) { num++; } if (vector.x > r.xMax) { num2++; } if (vector.z < r.yMin) { num3++; } if (vector.z > r.yMax) { num4++; } } if (!flag && (num == 3 || num2 == 3 || num3 == 3 || num4 == 3)) { return(true); } for (int j = 0; j < 3; j++) { int i2 = (j <= 1) ? (j + 1) : 0; Int3 vertex2 = triangleMeshNode.GetVertex(j); Int3 vertex3 = triangleMeshNode.GetVertex(i2); if (Polygon.Intersects(a, b, vertex2, vertex3)) { flag = true; break; } if (Polygon.Intersects(a, c, vertex2, vertex3)) { flag = true; break; } if (Polygon.Intersects(c, d, vertex2, vertex3)) { flag = true; break; } if (Polygon.Intersects(d, b, vertex2, vertex3)) { flag = true; break; } } if (triangleMeshNode.ContainsPoint(ia) || triangleMeshNode.ContainsPoint(ib) || triangleMeshNode.ContainsPoint(ic) || triangleMeshNode.ContainsPoint(id)) { flag = true; } if (!flag) { return(true); } o.WillUpdateNode(triangleMeshNode); o.Apply(triangleMeshNode); return(true); }); }
/// <summary> /// Update all graphs using the GraphUpdateObject. /// This can be used to, e.g make all nodes in an area unwalkable, or set them to a higher penalty. /// The graphs will be updated as soon as possible (with respect to AstarPath.batchGraphUpdates) /// /// See: FlushGraphUpdates /// </summary> public void AddToQueue(GraphUpdateObject ob) { // Put the GUO in the queue graphUpdateQueue.Enqueue(ob); }
GraphUpdateThreading IUpdatableGraph.CanUpdateAsync(GraphUpdateObject o) { return((!o.updatePhysics) ? GraphUpdateThreading.SeparateThread : ((GraphUpdateThreading)7)); }
public void UpdateArea(GraphUpdateObject o) { if (nodes == null || nodes.Length == 0) { Debug.LogError("NavGraph hasn't been generated yet or does not contain any nodes"); return; // new NNInfo (); } //System.DateTime startTime = System.DateTime.Now; Bounds bounds = o.bounds; Rect r = Rect.MinMaxRect(bounds.min.x, bounds.min.z, bounds.max.x, bounds.max.z); Vector3 a = new Vector3(r.xMin, 0, r.yMin); // -1 -1 Vector3 b = new Vector3(r.xMin, 0, r.yMax); // -1 1 Vector3 c = new Vector3(r.xMax, 0, r.yMin); // 1 -1 Vector3 d = new Vector3(r.xMax, 0, r.yMax); // 1 1 for (int i = 0; i < nodes.Length; i++) { MeshNode node = nodes[i] as MeshNode; bool inside = false; int allLeft = 0; int allRight = 0; int allTop = 0; int allBottom = 0; for (int v = 0; v < 3; v++) { Vector3 vert = (Vector3)vertices[node[v]]; Vector2 vert2D = new Vector2(vert.x, vert.z); if (r.Contains(vert2D)) { //Debug.DrawRay (vert,Vector3.up,Color.yellow); inside = true; break; } if (vert.x < r.xMin) { allLeft++; } if (vert.x > r.xMax) { allRight++; } if (vert.z < r.yMin) { allTop++; } if (vert.z > r.yMax) { allBottom++; } //if (!bounds.Contains (node[v]) { // inside = false; // break; //} } if (!inside) { if (allLeft == 3 || allRight == 3 || allTop == 3 || allBottom == 3) { continue; } } for (int v = 0; v < 3; v++) { int v2 = v > 1 ? 0 : v + 1; Vector3 vert1 = (Vector3)vertices[node[v]]; Vector3 vert2 = (Vector3)vertices[node[v2]]; if (Polygon.Intersects(a, b, vert1, vert2)) { inside = true; break; } if (Polygon.Intersects(a, c, vert1, vert2)) { inside = true; break; } if (Polygon.Intersects(c, d, vert1, vert2)) { inside = true; break; } if (Polygon.Intersects(d, b, vert1, vert2)) { inside = true; break; } } if (!inside && ContainsPoint(node, a)) { inside = true; } //Debug.DrawRay (a+Vector3.right*0.01F*i,Vector3.up,Color.red); } if (!inside && ContainsPoint(node, b)) { inside = true; } //Debug.DrawRay (b+Vector3.right*0.01F*i,Vector3.up,Color.red); } if (!inside && ContainsPoint(node, c)) { inside = true; } //Debug.DrawRay (c+Vector3.right*0.01F*i,Vector3.up,Color.red); } if (!inside && ContainsPoint(node, d)) { inside = true; } //Debug.DrawRay (d+Vector3.right*0.01F*i,Vector3.up,Color.red); } if (!inside) { continue; } o.Apply(node); //Debug.DrawLine (vertices[node.v1],vertices[node.v2],Color.blue); //Debug.DrawLine (vertices[node.v2],vertices[node.v3],Color.blue); //Debug.DrawLine (vertices[node.v3],vertices[node.v1],Color.blue); //Debug.Break (); } //System.DateTime endTime = System.DateTime.Now; //float theTime = (endTime-startTime).Ticks*0.0001F; //Debug.Log ("Intersecting bounds with navmesh took "+theTime.ToString ("0.000")+" ms"); }
public void UpdateArea(GraphUpdateObject o) { UpdateArea(o, this); }
GraphUpdateThreading IUpdatableGraph.CanUpdateAsync(GraphUpdateObject o) { return(GraphUpdateThreading.UnityThread); }
public static void UpdateArea(GraphUpdateObject o, INavmesh graph) { Bounds bounds = o.bounds; Rect rect = Rect.MinMaxRect(bounds.min.x, bounds.min.z, bounds.max.x, bounds.max.z); IntRect irect = new IntRect(Mathf.FloorToInt(bounds.min.x * 1000f), Mathf.FloorToInt(bounds.min.z * 1000f), Mathf.FloorToInt(bounds.max.x * 1000f), Mathf.FloorToInt(bounds.max.z * 1000f)); Int3 a = new Int3(irect.xmin, 0, irect.ymin); Int3 b = new Int3(irect.xmin, 0, irect.ymax); Int3 c = new Int3(irect.xmax, 0, irect.ymin); Int3 d = new Int3(irect.xmax, 0, irect.ymax); int ymin = ((Int3)bounds.min).y; int ymax = ((Int3)bounds.max).y; graph.GetNodes(delegate(GraphNode _node) { TriangleMeshNode triangleMeshNode = _node as TriangleMeshNode; bool flag = false; int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; for (int i = 0; i < 3; i++) { Int3 vertex = triangleMeshNode.GetVertex(i); Vector3 vector = (Vector3)vertex; if (irect.Contains(vertex.x, vertex.z)) { flag = true; break; } if (vector.x < rect.xMin) { num++; } if (vector.x > rect.xMax) { num2++; } if (vector.z < rect.yMin) { num3++; } if (vector.z > rect.yMax) { num4++; } } if (!flag && (num == 3 || num2 == 3 || num3 == 3 || num4 == 3)) { return; } for (int j = 0; j < 3; j++) { int i2 = (j > 1) ? 0 : (j + 1); Int3 vertex2 = triangleMeshNode.GetVertex(j); Int3 vertex3 = triangleMeshNode.GetVertex(i2); if (VectorMath.SegmentsIntersectXZ(a, b, vertex2, vertex3)) { flag = true; break; } if (VectorMath.SegmentsIntersectXZ(a, c, vertex2, vertex3)) { flag = true; break; } if (VectorMath.SegmentsIntersectXZ(c, d, vertex2, vertex3)) { flag = true; break; } if (VectorMath.SegmentsIntersectXZ(d, b, vertex2, vertex3)) { flag = true; break; } } if (flag || triangleMeshNode.ContainsPoint(a) || triangleMeshNode.ContainsPoint(b) || triangleMeshNode.ContainsPoint(c) || triangleMeshNode.ContainsPoint(d)) { flag = true; } if (!flag) { return; } int num5 = 0; int num6 = 0; for (int k = 0; k < 3; k++) { Int3 vertex4 = triangleMeshNode.GetVertex(k); if (vertex4.y < ymin) { num6++; } if (vertex4.y > ymax) { num5++; } } if (num6 == 3 || num5 == 3) { return; } o.WillUpdateNode(triangleMeshNode); o.Apply(triangleMeshNode); }); }
void IUpdatableGraph.UpdateAreaInit(GraphUpdateObject o) { }
public void UpdateAreaPost(GraphUpdateObject o) { }
void IUpdatableGraph.UpdateAreaPost(GraphUpdateObject o) { }
public void Apply() { if (AstarPath.active == null) { Debug.LogError("There is no AstarPath object in the scene"); return; } GraphUpdateObject graphUpdateObject; if (this.points == null || this.points.Length == 0) { Collider component = base.GetComponent <Collider>(); Renderer component2 = base.GetComponent <Renderer>(); Bounds bounds; if (component != null) { bounds = component.bounds; } else { if (!(component2 != null)) { Debug.LogWarning("Cannot apply GraphUpdateScene, no points defined and no renderer or collider attached"); return; } bounds = component2.bounds; } if (bounds.size.y < this.minBoundsHeight) { bounds.size = new Vector3(bounds.size.x, this.minBoundsHeight, bounds.size.z); } graphUpdateObject = new GraphUpdateObject(bounds); } else { GraphUpdateShape graphUpdateShape = new GraphUpdateShape(); graphUpdateShape.convex = this.convex; Vector3[] array = this.points; if (!this.useWorldSpace) { array = new Vector3[this.points.Length]; Matrix4x4 localToWorldMatrix = base.transform.localToWorldMatrix; for (int i = 0; i < array.Length; i++) { array[i] = localToWorldMatrix.MultiplyPoint3x4(this.points[i]); } } graphUpdateShape.points = array; Bounds bounds2 = graphUpdateShape.GetBounds(); if (bounds2.size.y < this.minBoundsHeight) { bounds2.size = new Vector3(bounds2.size.x, this.minBoundsHeight, bounds2.size.z); } graphUpdateObject = new GraphUpdateObject(bounds2); graphUpdateObject.shape = graphUpdateShape; } this.firstApplied = true; graphUpdateObject.modifyWalkability = this.modifyWalkability; graphUpdateObject.setWalkability = this.setWalkability; graphUpdateObject.addPenalty = this.penaltyDelta; graphUpdateObject.updatePhysics = this.updatePhysics; graphUpdateObject.updateErosion = this.updateErosion; graphUpdateObject.resetPenaltyOnPhysics = this.resetPenaltyOnPhysics; graphUpdateObject.modifyTag = this.modifyTag; graphUpdateObject.setTag = this.setTag; AstarPath.active.UpdateGraphs(graphUpdateObject); }
/// <summary> /// Updates an area in the list graph. /// Recalculates possibly affected connections, i.e all connectionlines passing trough the bounds of the guo will be recalculated /// </summary> void IUpdatableGraph.UpdateArea(GraphUpdateObject guo) { if (nodes == null) { return; } for (int i = 0; i < nodeCount; i++) { var node = nodes[i]; if (guo.bounds.Contains((Vector3)node.position)) { guo.WillUpdateNode(node); guo.Apply(node); } } if (guo.updatePhysics) { // Use a copy of the bounding box, we should not change the GUO's bounding box since it might be used for other graph updates Bounds bounds = guo.bounds; if (thickRaycast) { // Expand the bounding box to account for the thick raycast bounds.Expand(thickRaycastRadius * 2); } // Create a temporary list used for holding connection data List <Connection> tmpList = Pathfinding.Util.ListPool <Connection> .Claim(); for (int i = 0; i < nodeCount; i++) { PointNode node = nodes[i]; var nodePos = (Vector3)node.position; List <Connection> conn = null; for (int j = 0; j < nodeCount; j++) { if (j == i) { continue; } var otherNodePos = (Vector3)nodes[j].position; // Check if this connection intersects the bounding box. // If it does we need to recalculate that connection. if (VectorMath.SegmentIntersectsBounds(bounds, nodePos, otherNodePos)) { float dist; PointNode other = nodes[j]; bool contains = node.ContainsConnection(other); bool validConnection = IsValidConnection(node, other, out dist); // Fill the 'conn' list when we need to change a connection if (conn == null && (contains != validConnection)) { tmpList.Clear(); conn = tmpList; conn.AddRange(node.connections); } if (!contains && validConnection) { // A new connection should be added uint cost = (uint)Mathf.RoundToInt(dist * Int3.FloatPrecision); conn.Add(new Connection(other, cost)); RegisterConnectionLength((other.position - node.position).sqrMagnitudeLong); } else if (contains && !validConnection) { // A connection should be removed for (int q = 0; q < conn.Count; q++) { if (conn[q].node == other) { conn.RemoveAt(q); break; } } } } } // Save the new connections if any were changed if (conn != null) { node.connections = conn.ToArray(); node.SetConnectivityDirty(); } } // Release buffers back to the pool Pathfinding.Util.ListPool <Connection> .Release(ref tmpList); } }
/** Updates an area in the list graph. * Recalculates possibly affected connections, i.e all connectionlines passing trough the bounds of the \a guo will be recalculated * \astarpro */ public void UpdateArea(GraphUpdateObject guo) { if (nodes == null) { return; } for (int i = 0; i < nodeCount; i++) { if (guo.bounds.Contains((Vector3)nodes[i].position)) { guo.WillUpdateNode(nodes[i]); guo.Apply(nodes[i]); } } if (guo.updatePhysics) { //Use a copy of the bounding box, we should not change the GUO's bounding box since it might be used for other graph updates Bounds bounds = guo.bounds; if (thickRaycast) { //Expand the bounding box to account for the thick raycast bounds.Expand(thickRaycastRadius * 2); } //Create two temporary arrays used for holding new connections and costs List <GraphNode> tmp_arr = Pathfinding.Util.ListPool <GraphNode> .Claim(); List <uint> tmp_arr2 = Pathfinding.Util.ListPool <uint> .Claim(); for (int i = 0; i < nodeCount; i++) { PointNode node = nodes[i] as PointNode; Vector3 a = (Vector3)node.position; List <GraphNode> conn = null; List <uint> costs = null; for (int j = 0; j < nodeCount; j++) { if (j == i) { continue; } Vector3 b = (Vector3)nodes[j].position; if (Polygon.LineIntersectsBounds(bounds, a, b)) { float dist; PointNode other = nodes[j] as PointNode; bool contains = node.ContainsConnection(other); //Note, the IsValidConnection test will actually only be done once //no matter what,so there is no performance penalty there if (!contains && IsValidConnection(node, other, out dist)) { //Debug.DrawLine (a+Vector3.up*0.1F,b+Vector3.up*0.1F,Color.green); if (conn == null) { tmp_arr.Clear(); tmp_arr2.Clear(); conn = tmp_arr; costs = tmp_arr2; conn.AddRange(node.connections); costs.AddRange(node.connectionCosts); } uint cost = (uint)Mathf.RoundToInt(dist * Int3.FloatPrecision); conn.Add(other); costs.Add(cost); } else if (contains && !IsValidConnection(node, other, out dist)) { //Debug.DrawLine (a+Vector3.up*0.5F*Random.value,b+Vector3.up*0.5F*Random.value,Color.red); if (conn == null) { tmp_arr.Clear(); tmp_arr2.Clear(); conn = tmp_arr; costs = tmp_arr2; conn.AddRange(node.connections); costs.AddRange(node.connectionCosts); } int p = conn.IndexOf(other); //Shouldn't have to check for it, but who knows what might go wrong if (p != -1) { conn.RemoveAt(p); costs.RemoveAt(p); } } } } if (conn != null) { node.connections = conn.ToArray(); node.connectionCosts = costs.ToArray(); } } Pathfinding.Util.ListPool <GraphNode> .Release(tmp_arr); Pathfinding.Util.ListPool <uint> .Release(tmp_arr2); } }
// Token: 0x060004C1 RID: 1217 RVA: 0x000293E2 File Offset: 0x000277E2 public void UpdateArea(GraphUpdateObject o) { NavMeshGraph.UpdateArea(o, this); }
public static void UpdateArea(GraphUpdateObject o, INavmesh graph) { //System.DateTime startTime = System.DateTime.UtcNow; var bounds = o.bounds; var r = Rect.MinMaxRect(bounds.min.x, bounds.min.z, bounds.max.x, bounds.max.z); var r2 = new IntRect( Mathf.FloorToInt(bounds.min.x * Int3.Precision), Mathf.FloorToInt(bounds.min.z * Int3.Precision), Mathf.FloorToInt(bounds.max.x * Int3.Precision), Mathf.FloorToInt(bounds.max.z * Int3.Precision) ); var a = new Int3(r2.xmin, 0, r2.ymin); var b = new Int3(r2.xmin, 0, r2.ymax); var c = new Int3(r2.xmax, 0, r2.ymin); var d = new Int3(r2.xmax, 0, r2.ymax); var ia = (Int3)a; var ib = (Int3)b; var ic = (Int3)c; var id = (Int3)d; //for (int i=0;i<nodes.Length;i++) { graph.GetNodes(delegate(GraphNode _node) { var node = _node as TriangleMeshNode; var inside = false; var allLeft = 0; var allRight = 0; var allTop = 0; var allBottom = 0; for (var v = 0; v < 3; v++) { var p = node.GetVertex(v); var vert = (Vector3)p; //Vector2 vert2D = new Vector2 (vert.x,vert.z); if (r2.Contains(p.x, p.z)) { //Debug.DrawRay (vert,Vector3.up*10,Color.yellow); inside = true; break; } if (vert.x < r.xMin) { allLeft++; } if (vert.x > r.xMax) { allRight++; } if (vert.z < r.yMin) { allTop++; } if (vert.z > r.yMax) { allBottom++; } } if (!inside) { if (allLeft == 3 || allRight == 3 || allTop == 3 || allBottom == 3) { return(true); } } //Debug.DrawLine ((Vector3)node.GetVertex(0),(Vector3)node.GetVertex(1),Color.yellow); //Debug.DrawLine ((Vector3)node.GetVertex(1),(Vector3)node.GetVertex(2),Color.yellow); //Debug.DrawLine ((Vector3)node.GetVertex(2),(Vector3)node.GetVertex(0),Color.yellow); for (var v = 0; v < 3; v++) { var v2 = v > 1 ? 0 : v + 1; var vert1 = node.GetVertex(v); var vert2 = node.GetVertex(v2); if (Polygon.Intersects(a, b, vert1, vert2)) { inside = true; break; } if (Polygon.Intersects(a, c, vert1, vert2)) { inside = true; break; } if (Polygon.Intersects(c, d, vert1, vert2)) { inside = true; break; } if (Polygon.Intersects(d, b, vert1, vert2)) { inside = true; break; } } if (node.ContainsPoint(ia) || node.ContainsPoint(ib) || node.ContainsPoint(ic) || node.ContainsPoint(id)) { inside = true; } if (!inside) { return(true); } o.WillUpdateNode(node); o.Apply(node); /*Debug.DrawLine ((Vector3)node.GetVertex(0),(Vector3)node.GetVertex(1),Color.blue); * Debug.DrawLine ((Vector3)node.GetVertex(1),(Vector3)node.GetVertex(2),Color.blue); * Debug.DrawLine ((Vector3)node.GetVertex(2),(Vector3)node.GetVertex(0),Color.blue); * Debug.Break ();*/ return(true); }); //System.DateTime endTime = System.DateTime.UtcNow; //float theTime = (endTime-startTime).Ticks*0.0001F; //Debug.Log ("Intersecting bounds with navmesh took "+theTime.ToString ("0.000")+" ms"); }
public static void UpdateArea(GraphUpdateObject o, INavmesh graph) { //System.DateTime startTime = System.DateTime.UtcNow; Bounds bounds = o.bounds; Rect r = Rect.MinMaxRect(bounds.min.x, bounds.min.z, bounds.max.x, bounds.max.z); var r2 = new IntRect( Mathf.FloorToInt(bounds.min.x * Int3.Precision), Mathf.FloorToInt(bounds.min.z * Int3.Precision), Mathf.FloorToInt(bounds.max.x * Int3.Precision), Mathf.FloorToInt(bounds.max.z * Int3.Precision) ); var a = new Int3(r2.xmin, 0, r2.ymin); var b = new Int3(r2.xmin, 0, r2.ymax); var c = new Int3(r2.xmax, 0, r2.ymin); var d = new Int3(r2.xmax, 0, r2.ymax); graph.GetNodes(_node => { var node = _node as TriangleMeshNode; bool inside = false; int allLeft = 0; int allRight = 0; int allTop = 0; int allBottom = 0; for (int v = 0; v < 3; v++) { Int3 p = node.GetVertex(v); var vert = (Vector3)p; if (r2.Contains(p.x, p.z)) { inside = true; break; } if (vert.x < r.xMin) { allLeft++; } if (vert.x > r.xMax) { allRight++; } if (vert.z < r.yMin) { allTop++; } if (vert.z > r.yMax) { allBottom++; } } if (!inside) { if (allLeft == 3 || allRight == 3 || allTop == 3 || allBottom == 3) { return(true); } } for (int v = 0; v < 3; v++) { int v2 = v > 1 ? 0 : v + 1; Int3 vert1 = node.GetVertex(v); Int3 vert2 = node.GetVertex(v2); if (Polygon.Intersects(a, b, vert1, vert2)) { inside = true; break; } if (Polygon.Intersects(a, c, vert1, vert2)) { inside = true; break; } if (Polygon.Intersects(c, d, vert1, vert2)) { inside = true; break; } if (Polygon.Intersects(d, b, vert1, vert2)) { inside = true; break; } } if (node.ContainsPoint(a) || node.ContainsPoint(b) || node.ContainsPoint(c) || node.ContainsPoint(d)) { inside = true; } if (!inside) { return(true); } o.WillUpdateNode(node); o.Apply(node); return(true); }); }