public override void ScanInternal (OnScanStatus status) {
			
			scans++;
			
			if (nodeSize <= 0) {
				return;
			}
			
			GenerateMatrix ();
			
			if (width > 1024 || depth > 1024) {
				Debug.LogError ("One of the grid's sides is longer than 1024 nodes");
				return;
			}
			
			//GenerateBounds ();
			
			/*neighbourOffsets = new int[8] {
				-width-1,-width,-width+1,
				-1,1,
				width-1,width,width+1
			}*/
			
			SetUpOffsetsAndCosts ();
			
			//GridNode.RemoveGridGraph (this);
			
			LevelGridNode.SetGridGraph (active.astarData.GetGraphIndex(this), this);
			
			//graphNodes = new LevelGridNode[width*depth];
			
			//nodes = CreateNodes (width*depth);
			//graphNodes = nodes as LevelGridNode[];
			
			maxClimb = Mathf.Clamp (maxClimb,0,characterHeight);
			
			LinkedLevelCell[] linkedCells = new LinkedLevelCell[width*depth];
			
			if (collision == null) {
				collision = new GraphCollision ();
			}
			collision.Initialize (matrix,nodeSize);
			
			for (int z = 0; z < depth; z ++) {
				for (int x = 0; x < width; x++) {
					
					linkedCells[z*width+x] = new LinkedLevelCell ();
					
					LinkedLevelCell llc = linkedCells[z*width+x];
					//GridNode node = graphNodes[z*width+x];//new LevelGridNode ();
					
					//node.SetIndex (z*width+x);
					
					Vector3 pos = matrix.MultiplyPoint3x4 (new Vector3 (x+0.5F,0,z+0.5F));
					
					
					RaycastHit[] hits = collision.CheckHeightAll (pos);
					
					//Sort the hits based on distance with bubble sort (fast enough)
					//Furthest away first (i.e lowest nodes in the graph)
					/*bool changed = true;
					while (changed) {
						changed = false;
						for (int i=0;i<hits.Length-1;i++) {
							if (hits[i].distance < hits[i+1].distance) {
								RaycastHit tmp = hits[i];
								hits[i] = hits[i+1];
								hits[i+1] = tmp;
								changed = true;
							}
						}
					}*/
					
					for (int i=0;i<hits.Length/2;i++) {
						RaycastHit tmp = hits[i];
						
						hits[i] = hits[hits.Length-1-i];
						hits[hits.Length-1-i] = tmp;
					}
					
					if (hits.Length > 0) {
						
						//lln.position = hits[0].point;
						//lln.walkable = collision.Check (lln.position);
						
						
						/*LinkedLevelNode lln = new LinkedLevelNode ();
						lln.position = hits[0].point;
						lln.walkable = collision.Check (lln.position);
						llc.first = lln;*/
						
						LinkedLevelNode lln = null;
						
						for (int i=0;i<hits.Length;i++) {
							
							LinkedLevelNode tmp = new LinkedLevelNode ();
							tmp.position = hits[i].point;
							
							if (lln != null) {
								/** \todo Use hit.distance instead */
								if (tmp.position.y - lln.position.y <= mergeSpanRange) {
									//if (tmp.position.y > lln.position.y) {
										lln.position = tmp.position;
										lln.hit = hits[i];
										lln.walkable = collision.Check (tmp.position);
									//}
									continue;
								}
							}
							
							tmp.walkable = collision.Check (tmp.position);
							tmp.hit = hits[i];
							tmp.height = float.PositiveInfinity;
							
							if (llc.first == null) {
								llc.first = tmp;
								lln = tmp;
							} else {
								lln.next = tmp;
								
								lln.height = tmp.position.y - lln.position.y;
								lln = lln.next;
							}
						
						}
					} else {
						LinkedLevelNode lln = new LinkedLevelNode ();
						lln.position = pos;
						lln.height = float.PositiveInfinity;
						lln.walkable = !collision.unwalkableWhenNoGround;
						llc.first = lln;
					}
					
					//node.penalty = 0;//Mathf.RoundToInt (Random.value*100);
					
					//node.walkable = collision.Check (node.position);
					
					//node.SetGridIndex (gridIndex);
				}
			}
			
			
			int spanCount = 0;
			layerCount = 0;
			//Count the total number of nodes in the graph
			for (int z = 0; z < depth; z ++) {
				for (int x = 0; x < width; x++) {
					
					LinkedLevelCell llc = linkedCells[z*width+x];
					
					LinkedLevelNode lln = llc.first;
					int cellCount = 0;
					//Loop through all nodes in this cell
					do {
						cellCount++;
						spanCount++;
						lln = lln.next;
					} while (lln != null);
					
					layerCount = cellCount > layerCount ? cellCount : layerCount;
				}
			}
			
			if (layerCount > LevelGridNode.MaxLayerCount) {
				Debug.LogError ("Too many layers, a maximum of LevelGridNode.MaxLayerCount are allowed (found "+layerCount+")");
				return;
			}
			
			//Create all nodes
			nodes = new LevelGridNode[width*depth*layerCount];
			for (int i=0;i<nodes.Length;i++) {
				nodes[i] = new LevelGridNode (active);
				nodes[i].Penalty = initialPenalty;
			}
			
			int nodeIndex = 0;
			
			//Max slope in cosinus
			float cosAngle = Mathf.Cos (maxSlope*Mathf.Deg2Rad);
			
			for (int z = 0; z < depth; z++) {
				for (int x = 0; x < width; x++) {
					
					LinkedLevelCell llc = linkedCells[z*width+x];
					LinkedLevelNode lln = llc.first;
					
					llc.index = nodeIndex;
					
					int count = 0;
					int layerIndex = 0;
					do {
						LevelGridNode node = nodes[z*width+x + width*depth*layerIndex] as LevelGridNode;
#if ASTAR_SET_LEVELGRIDNODE_HEIGHT
						node.height = lln.height;
#endif
						node.SetPosition ((Int3)lln.position);
						node.Walkable = lln.walkable;
						
						//Adjust penalty based on the surface slope
						if (lln.hit.normal != Vector3.zero && (penaltyAngle || cosAngle < 1.0f)) {
							//Take the dot product to find out the cosinus of the angle it has (faster than Vector3.Angle)
							float angle = Vector3.Dot (lln.hit.normal.normalized,collision.up);
							
							//Add penalty based on normal
							if (penaltyAngle) {
								node.Penalty += (uint)Mathf.RoundToInt ((1F-angle)*penaltyAngleFactor);
							}
							
							//Check if the slope is flat enough to stand on
							if (angle < cosAngle) {
								node.Walkable = false;
							}
						}
						
						node.NodeInGridIndex = z*width+x;
						//node.nodeOffset = count;
						if (lln.height < characterHeight) {
							node.Walkable = false;
						}
						
						node.WalkableErosion = node.Walkable;
						
						nodeIndex++;
						count++;
						lln = lln.next;
						layerIndex++;
					} while (lln != null);
					
					for (;layerIndex<layerCount;layerIndex++) {
						nodes[z*width+x + width*depth*layerIndex] = null;
					}
					
					llc.count = count;
				}
			}
			
			nodeIndex = 0;
			
			nodeCellIndices = new int[linkedCells.Length];
			
			for (int z = 0; z < depth; z ++) {
				for (int x = 0; x < width; x++) {
					
					/*LinkedLevelCell llc = linkedCells[z*width+x];
					LinkedLevelNode lln = llc.first;
					
					nodeCellIndices[z*width+x] = llc.index;
					
					do {
						LevelGridNode node = (LevelGridNode)nodes[nodeIndex];
						
						CalculateConnections (nodes,linkedCells,node,x,z,n);
						nodeIndex++;
						lln = lln.next;
					} while (lln != null);*/
					
					for (int i=0;i<layerCount;i++) {
						GraphNode node = nodes[z*width+x + width*depth*i];
						CalculateConnections (nodes,node,x,z,i);
					}
				}
			}
			
			uint graphIndex = (uint)active.astarData.GetGraphIndex(this);
			
			for (int i=0;i<nodes.Length;i++) {
				LevelGridNode lgn = nodes[i] as LevelGridNode;
				if (lgn == null) continue;
				
				UpdatePenalty (lgn);
				
				lgn.GraphIndex = graphIndex;
				
				//Set the node to be unwalkable if it hasn't got any connections
				if (!lgn.HasAnyGridConnections ()) {
					lgn.Walkable = false;
					lgn.WalkableErosion = lgn.Walkable;
				}
			}
					/*GridNode node = graphNodes[z*width+x];
				
					CalculateConnections (graphNodes,x,z,node);
					
					if (z == 5 && x == 5) {
						int index = z*width+x;
						Debug.DrawRay (node.position,(nodes[index+neighbourOffsets[0]].position-node.position)*0.5F,Color.red);
						Debug.DrawRay (node.position,(nodes[index+neighbourOffsets[0]].position-node.position)*0.5F,Color.green);
						Debug.DrawRay (node.position,(nodes[index+neighbourOffsets[0]].position-node.position)*0.5F,Color.blue);
						Debug.DrawRay (node.position,(nodes[index+neighbourOffsets[0]].position-node.position)*0.5F,Color.yellow);
						Debug.DrawRay (node.position,(nodes[index+neighbourOffsets[0]].position-node.position)*0.5F,Color.cyan);
						Debug.DrawRay (node.position,(nodes[index+neighbourOffsets[0]].position-node.position)*0.5F,Color.magenta);
						Debug.DrawRay (node.position,(nodes[index+neighbourOffsets[0]].position-node.position)*0.5F,Color.black);
						Debug.DrawRay (node.position,(nodes[index+neighbourOffsets[0]].position-node.position)*0.5F,Color.white);
					}*/
				//}
			//}
			
			ErodeWalkableArea (0,0,width,depth);
		}
		public override void DeserializeExtraInfo (GraphSerializationContext ctx)
		{

			int count = ctx.reader.ReadInt32();
			if (count == -1) {
				nodes = null;
				return;
			}

			nodes = new LevelGridNode[count];
			for (int i=0;i<nodes.Length;i++) {
				if (ctx.reader.ReadInt32() != -1 ){
					nodes[i] = new LevelGridNode (active);
					nodes[i].DeserializeNode(ctx);
				} else {
					nodes[i] = null;
				}
			}
		}
Beispiel #3
0
        public override NNInfo GetNearestForce(Vector3 position, NNConstraint constraint)
        {
            if (this.nodes == null || this.depth * this.width * this.layerCount != this.nodes.Length || this.layerCount == 0)
            {
                return(default(NNInfo));
            }
            Vector3 vector = position;

            position = this.inverseMatrix.MultiplyPoint3x4(position);
            int           num           = Mathf.Clamp(Mathf.RoundToInt(position.x - 0.5f), 0, this.width - 1);
            int           num2          = Mathf.Clamp(Mathf.RoundToInt(position.z - 0.5f), 0, this.depth - 1);
            float         num3          = float.PositiveInfinity;
            int           num4          = 2;
            LevelGridNode levelGridNode = this.GetNearestNode(vector, num, num2, constraint);

            if (levelGridNode != null)
            {
                num3 = ((Vector3)levelGridNode.position - vector).sqrMagnitude;
            }
            if (levelGridNode != null)
            {
                if (num4 == 0)
                {
                    return(new NNInfo(levelGridNode));
                }
                num4--;
            }
            float num5 = (!constraint.constrainDistance) ? float.PositiveInfinity : AstarPath.active.maxNearestNodeDistance;
            float num6 = num5 * num5;
            int   num7 = 1;

            while (true)
            {
                int i = num2 + num7;
                if (this.nodeSize * (float)num7 > num5)
                {
                    break;
                }
                int j;
                for (j = num - num7; j <= num + num7; j++)
                {
                    if (j >= 0 && i >= 0 && j < this.width && i < this.depth)
                    {
                        LevelGridNode nearestNode = this.GetNearestNode(vector, j, i, constraint);
                        if (nearestNode != null)
                        {
                            float sqrMagnitude = ((Vector3)nearestNode.position - vector).sqrMagnitude;
                            if (sqrMagnitude < num3 && sqrMagnitude < num6)
                            {
                                num3          = sqrMagnitude;
                                levelGridNode = nearestNode;
                            }
                        }
                    }
                }
                i = num2 - num7;
                for (j = num - num7; j <= num + num7; j++)
                {
                    if (j >= 0 && i >= 0 && j < this.width && i < this.depth)
                    {
                        LevelGridNode nearestNode2 = this.GetNearestNode(vector, j, i, constraint);
                        if (nearestNode2 != null)
                        {
                            float sqrMagnitude2 = ((Vector3)nearestNode2.position - vector).sqrMagnitude;
                            if (sqrMagnitude2 < num3 && sqrMagnitude2 < num6)
                            {
                                num3          = sqrMagnitude2;
                                levelGridNode = nearestNode2;
                            }
                        }
                    }
                }
                j = num - num7;
                for (i = num2 - num7 + 1; i <= num2 + num7 - 1; i++)
                {
                    if (j >= 0 && i >= 0 && j < this.width && i < this.depth)
                    {
                        LevelGridNode nearestNode3 = this.GetNearestNode(vector, j, i, constraint);
                        if (nearestNode3 != null)
                        {
                            float sqrMagnitude3 = ((Vector3)nearestNode3.position - vector).sqrMagnitude;
                            if (sqrMagnitude3 < num3 && sqrMagnitude3 < num6)
                            {
                                num3          = sqrMagnitude3;
                                levelGridNode = nearestNode3;
                            }
                        }
                    }
                }
                j = num + num7;
                for (i = num2 - num7 + 1; i <= num2 + num7 - 1; i++)
                {
                    if (j >= 0 && i >= 0 && j < this.width && i < this.depth)
                    {
                        LevelGridNode nearestNode4 = this.GetNearestNode(vector, j, i, constraint);
                        if (nearestNode4 != null)
                        {
                            float sqrMagnitude4 = ((Vector3)nearestNode4.position - vector).sqrMagnitude;
                            if (sqrMagnitude4 < num3 && sqrMagnitude4 < num6)
                            {
                                num3          = sqrMagnitude4;
                                levelGridNode = nearestNode4;
                            }
                        }
                    }
                }
                if (levelGridNode != null)
                {
                    if (num4 == 0)
                    {
                        goto Block_37;
                    }
                    num4--;
                }
                num7++;
            }
            return(new NNInfo(levelGridNode));

Block_37:
            return(new NNInfo(levelGridNode));
        }
Beispiel #4
0
 public static bool CheckConnection(LevelGridNode node, int dir)
 {
     return(node.GetConnection(dir));
 }
        /** Recalculates single cell.
         *
         * \param x X coordinate of the cell
         * \param z Z coordinate of the cell
         * \param preserveExistingNodes If true, nodes will be reused, this can be used to preserve e.g penalty when recalculating
         *
         * \returns If new layers or nodes were added. If so, you need to call
         * AstarPath.active.DataUpdate() after this function to make sure pathfinding works correctly for them
         * (when doing a scan, that function does not need to be called however).
         *
         * \note Connections are not recalculated for the nodes.
         */
        public bool RecalculateCell(int x, int z, bool preserveExistingNodes)
        {
            LinkedLevelCell llc = new LinkedLevelCell ();
            //GridNode node = graphNodes[z*width+x];//new LevelGridNode ();

            //node.SetIndex (z*width+x);

            Vector3 pos = matrix.MultiplyPoint3x4 (new Vector3 (x+0.5F,0,z+0.5F));

            RaycastHit[] hits = collision.CheckHeightAll (pos);

            //Sort the hits based on distance with bubble sort (fast enough)
            //Furthest away first (i.e lowest nodes in the graph)
            /*bool changed = true;
            while (changed) {
                changed = false;
                for (int i=0;i<hits.Length-1;i++) {
                    if (hits[i].distance < hits[i+1].distance) {
                        RaycastHit tmp = hits[i];
                        hits[i] = hits[i+1];
                        hits[i+1] = tmp;
                        changed = true;
                    }
                }
            }*/

            for (int i=0;i<hits.Length/2;i++) {
                RaycastHit tmp = hits[i];

                hits[i] = hits[hits.Length-1-i];
                hits[hits.Length-1-i] = tmp;
            }

            bool addedNodes = false;

            if (hits.Length > 0) {

                //lln.position = hits[0].point;
                //lln.walkable = collision.Check (lln.position);

                /*LinkedLevelNode lln = new LinkedLevelNode ();
                lln.position = hits[0].point;
                lln.walkable = collision.Check (lln.position);
                llc.first = lln;*/

                LinkedLevelNode lln = null;

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

                    LinkedLevelNode tmp = new LinkedLevelNode ();
                    tmp.position = hits[i].point;

                    if (lln != null) {
                        /** \todo Use hit.distance instead */
                        if (tmp.position.y - lln.position.y <= mergeSpanRange) {
                            //if (tmp.position.y > lln.position.y) {
                                lln.position = tmp.position;
                                lln.hit = hits[i];
                                lln.walkable = collision.Check (tmp.position);
                            //}
                            continue;
                        }
                    }

                    tmp.walkable = collision.Check (tmp.position);
                    tmp.hit = hits[i];
                    tmp.height = float.PositiveInfinity;

                    if (llc.first == null) {
                        llc.first = tmp;
                        lln = tmp;
                    } else {
                        lln.next = tmp;

                        lln.height = tmp.position.y - lln.position.y;
                        lln = lln.next;
                    }

                }
            } else {
                LinkedLevelNode lln = new LinkedLevelNode ();
                lln.position = pos;
                lln.height = float.PositiveInfinity;
                lln.walkable = !collision.unwalkableWhenNoGround;
                llc.first = lln;
            }

            //=========

            {
                //llc
                LinkedLevelNode lln = llc.first;

                int count = 0;
                int layerIndex = 0;
                do {

                    if (layerIndex >= layerCount) {
                        if (layerIndex+1 > LevelGridNode.MaxLayerCount) {
                            Debug.LogError ("Too many layers, a maximum of LevelGridNode.MaxLayerCount are allowed (required "+(layerIndex+1)+")");
                            return addedNodes;
                        }

                        AddLayers (1);
                        addedNodes = true;
                    }

                    LevelGridNode node = nodes[z*width+x + width*depth*layerIndex] as LevelGridNode;

                    if (node == null || !preserveExistingNodes) {
                        //Create a new node
                        nodes[z*width+x + width*depth*layerIndex] = new LevelGridNode();
                        node = nodes[z*width+x + width*depth*layerIndex] as LevelGridNode;
                        node.penalty = initialPenalty;
                        node.SetGridIndex (LevelGridNode.SetGridGraph(this));
                        addedNodes = true;
                    }

                    node.connections = null;
            #if ASTAR_SET_LEVELGRIDNODE_HEIGHT
                    node.height = lln.height;
            #endif
                    node.position = (Int3)lln.position;
                    node.walkable = lln.walkable;
                    node.Bit15 = node.walkable;

                    //Adjust penalty based on the surface slope
                    if (lln.hit.normal != Vector3.zero) {
                        //Take the dot product to find out the cosinus of the angle it has (faster than Vector3.Angle)
                        float angle = Vector3.Dot (lln.hit.normal.normalized,collision.up);

                        //Add penalty based on normal
                        if (penaltyAngle) {
                            node.penalty += (uint)Mathf.RoundToInt ((1F-angle)*penaltyAngleFactor);
                        }

                        //Max slope in cosinus
                        float cosAngle = Mathf.Cos (maxSlope*Mathf.Deg2Rad);

                        //Check if the slope is flat enough to stand on
                        if (angle < cosAngle) {
                            node.walkable = false;
                        }
                    }

                    node.SetIndex (z*width+x);
                    //node.nodeOffset = count;
                    if (lln.height < characterHeight) {
                        node.walkable = false;
                    }
                    count++;
                    lln = lln.next;
                    layerIndex++;
                } while (lln != null);

                for (;layerIndex<layerCount;layerIndex++) {
                    nodes[z*width+x + width*depth*layerIndex] = null;
                }

                llc.count = count;
            }

            return addedNodes;
        }
        // Token: 0x060024E5 RID: 9445 RVA: 0x0019BBB0 File Offset: 0x00199DB0
        protected override IEnumerable <Progress> ScanInternal()
        {
            if (this.nodeSize <= 0f)
            {
                yield break;
            }
            base.UpdateTransform();
            if (this.width > 1024 || this.depth > 1024)
            {
                Debug.LogError("One of the grid's sides is longer than 1024 nodes");
                yield break;
            }
            this.lastScannedWidth = this.width;
            this.lastScannedDepth = this.depth;
            this.SetUpOffsetsAndCosts();
            LevelGridNode.SetGridGraph((int)this.graphIndex, this);
            this.maxClimb = Mathf.Clamp(this.maxClimb, 0f, this.characterHeight);
            LinkedLevelNode[] linkedCells = new LinkedLevelNode[this.width * this.depth];
            this.collision = (this.collision ?? new GraphCollision());
            this.collision.Initialize(base.transform, this.nodeSize);
            int progressCounter = 0;
            int num;

            for (int z = 0; z < this.depth; z = num + 1)
            {
                if (progressCounter >= 1000)
                {
                    progressCounter = 0;
                    yield return(new Progress(Mathf.Lerp(0.1f, 0.5f, (float)z / (float)this.depth), "Calculating positions"));
                }
                progressCounter += this.width;
                for (int i = 0; i < this.width; i++)
                {
                    linkedCells[z * this.width + i] = this.SampleCell(i, z);
                }
                num = z;
            }
            this.layerCount = 0;
            for (int j = 0; j < linkedCells.Length; j++)
            {
                int num2 = 0;
                for (LinkedLevelNode linkedLevelNode = linkedCells[j]; linkedLevelNode != null; linkedLevelNode = linkedLevelNode.next)
                {
                    num2++;
                }
                this.layerCount = Math.Max(this.layerCount, num2);
            }
            if (this.layerCount > 255)
            {
                Debug.LogError(string.Concat(new object[]
                {
                    "Too many layers, a maximum of ",
                    255,
                    " (LevelGridNode.MaxLayerCount) layers are allowed (found ",
                    this.layerCount,
                    ")"
                }));
                yield break;
            }
            this.nodes = new LevelGridNode[this.width * this.depth * this.layerCount];
            for (int z = 0; z < this.depth; z = num + 1)
            {
                if (progressCounter >= 1000)
                {
                    progressCounter = 0;
                    yield return(new Progress(Mathf.Lerp(0.5f, 0.8f, (float)z / (float)this.depth), "Creating nodes"));
                }
                progressCounter += this.width;
                for (int k = 0; k < this.width; k++)
                {
                    this.RecalculateCell(k, z, true, true);
                }
                num = z;
            }
            for (int z = 0; z < this.depth; z = num + 1)
            {
                if (progressCounter >= 1000)
                {
                    progressCounter = 0;
                    yield return(new Progress(Mathf.Lerp(0.8f, 0.9f, (float)z / (float)this.depth), "Calculating connections"));
                }
                progressCounter += this.width;
                for (int l = 0; l < this.width; l++)
                {
                    this.CalculateConnections(l, z);
                }
                num = z;
            }
            yield return(new Progress(0.95f, "Calculating Erosion"));

            for (int m = 0; m < this.nodes.Length; m++)
            {
                LevelGridNode levelGridNode = this.nodes[m];
                if (levelGridNode != null && !levelGridNode.HasAnyGridConnections())
                {
                    levelGridNode.Walkable        = false;
                    levelGridNode.WalkableErosion = levelGridNode.Walkable;
                }
            }
            this.ErodeWalkableArea();
            yield break;
        }
Beispiel #7
0
        public override void ScanInternal(OnScanStatus statusCallback)
        {
            if (this.nodeSize <= 0f)
            {
                return;
            }
            base.GenerateMatrix();
            if (this.width > 1024 || this.depth > 1024)
            {
                Debug.LogError("One of the grid's sides is longer than 1024 nodes");
                return;
            }
            this.lastScannedWidth = this.width;
            this.lastScannedDepth = this.depth;
            this.SetUpOffsetsAndCosts();
            LevelGridNode.SetGridGraph(this.active.astarData.GetGraphIndex(this), this);
            this.maxClimb = Mathf.Clamp(this.maxClimb, 0f, this.characterHeight);
            LinkedLevelCell[] array = new LinkedLevelCell[this.width * this.depth];
            this.collision = (this.collision ?? new GraphCollision());
            this.collision.Initialize(this.matrix, this.nodeSize);
            for (int i = 0; i < this.depth; i++)
            {
                for (int j = 0; j < this.width; j++)
                {
                    array[i * this.width + j] = new LinkedLevelCell();
                    LinkedLevelCell linkedLevelCell = array[i * this.width + j];
                    Vector3         position        = this.matrix.MultiplyPoint3x4(new Vector3((float)j + 0.5f, 0f, (float)i + 0.5f));
                    RaycastHit[]    array2          = this.collision.CheckHeightAll(position);
                    for (int k = 0; k < array2.Length / 2; k++)
                    {
                        RaycastHit raycastHit = array2[k];
                        array2[k] = array2[array2.Length - 1 - k];
                        array2[array2.Length - 1 - k] = raycastHit;
                    }
                    if (array2.Length > 0)
                    {
                        LinkedLevelNode linkedLevelNode = null;
                        for (int l = 0; l < array2.Length; l++)
                        {
                            LinkedLevelNode linkedLevelNode2 = new LinkedLevelNode();
                            linkedLevelNode2.position = array2[l].point;
                            if (linkedLevelNode != null && linkedLevelNode2.position.y - linkedLevelNode.position.y <= this.mergeSpanRange)
                            {
                                linkedLevelNode.position = linkedLevelNode2.position;
                                linkedLevelNode.hit      = array2[l];
                                linkedLevelNode.walkable = this.collision.Check(linkedLevelNode2.position);
                            }
                            else
                            {
                                linkedLevelNode2.walkable = this.collision.Check(linkedLevelNode2.position);
                                linkedLevelNode2.hit      = array2[l];
                                linkedLevelNode2.height   = float.PositiveInfinity;
                                if (linkedLevelCell.first == null)
                                {
                                    linkedLevelCell.first = linkedLevelNode2;
                                    linkedLevelNode       = linkedLevelNode2;
                                }
                                else
                                {
                                    linkedLevelNode.next   = linkedLevelNode2;
                                    linkedLevelNode.height = linkedLevelNode2.position.y - linkedLevelNode.position.y;
                                    linkedLevelNode        = linkedLevelNode.next;
                                }
                            }
                        }
                    }
                    else
                    {
                        linkedLevelCell.first = new LinkedLevelNode
                        {
                            position = position,
                            height   = float.PositiveInfinity,
                            walkable = !this.collision.unwalkableWhenNoGround
                        };
                    }
                }
            }
            int num = 0;

            this.layerCount = 0;
            for (int m = 0; m < this.depth; m++)
            {
                for (int n = 0; n < this.width; n++)
                {
                    LinkedLevelCell linkedLevelCell2 = array[m * this.width + n];
                    LinkedLevelNode linkedLevelNode3 = linkedLevelCell2.first;
                    int             num2             = 0;
                    do
                    {
                        num2++;
                        num++;
                        linkedLevelNode3 = linkedLevelNode3.next;
                    }while (linkedLevelNode3 != null);
                    this.layerCount = ((num2 <= this.layerCount) ? this.layerCount : num2);
                }
            }
            if (this.layerCount > 255)
            {
                Debug.LogError("Too many layers, a maximum of LevelGridNode.MaxLayerCount are allowed (found " + this.layerCount + ")");
                return;
            }
            this.nodes = new LevelGridNode[this.width * this.depth * this.layerCount];
            for (int num3 = 0; num3 < this.nodes.Length; num3++)
            {
                this.nodes[num3]         = new LevelGridNode(this.active);
                this.nodes[num3].Penalty = this.initialPenalty;
            }
            int   num4 = 0;
            float num5 = Mathf.Cos(this.maxSlope * 0.0174532924f);

            for (int num6 = 0; num6 < this.depth; num6++)
            {
                for (int num7 = 0; num7 < this.width; num7++)
                {
                    LinkedLevelCell linkedLevelCell3 = array[num6 * this.width + num7];
                    LinkedLevelNode linkedLevelNode4 = linkedLevelCell3.first;
                    linkedLevelCell3.index = num4;
                    int num8 = 0;
                    int num9 = 0;
                    do
                    {
                        LevelGridNode levelGridNode = this.nodes[num6 * this.width + num7 + this.width * this.depth * num9];
                        levelGridNode.SetPosition((Int3)linkedLevelNode4.position);
                        levelGridNode.Walkable = linkedLevelNode4.walkable;
                        if (linkedLevelNode4.hit.normal != Vector3.zero && (this.penaltyAngle || num5 < 1f))
                        {
                            float num10 = Vector3.Dot(linkedLevelNode4.hit.normal.normalized, this.collision.up);
                            if (this.penaltyAngle)
                            {
                                levelGridNode.Penalty += (uint)Mathf.RoundToInt((1f - num10) * this.penaltyAngleFactor);
                            }
                            if (num10 < num5)
                            {
                                levelGridNode.Walkable = false;
                            }
                        }
                        levelGridNode.NodeInGridIndex = num6 * this.width + num7;
                        if (linkedLevelNode4.height < this.characterHeight)
                        {
                            levelGridNode.Walkable = false;
                        }
                        levelGridNode.WalkableErosion = levelGridNode.Walkable;
                        num4++;
                        num8++;
                        linkedLevelNode4 = linkedLevelNode4.next;
                        num9++;
                    }while (linkedLevelNode4 != null);
                    while (num9 < this.layerCount)
                    {
                        this.nodes[num6 * this.width + num7 + this.width * this.depth * num9] = null;
                        num9++;
                    }
                    linkedLevelCell3.count = num8;
                }
            }
            this.nodeCellIndices = new int[array.Length];
            for (int num11 = 0; num11 < this.depth; num11++)
            {
                for (int num12 = 0; num12 < this.width; num12++)
                {
                    for (int num13 = 0; num13 < this.layerCount; num13++)
                    {
                        GraphNode node = this.nodes[num11 * this.width + num12 + this.width * this.depth * num13];
                        this.CalculateConnections(this.nodes, node, num12, num11, num13);
                    }
                }
            }
            uint graphIndex = (uint)this.active.astarData.GetGraphIndex(this);

            for (int num14 = 0; num14 < this.nodes.Length; num14++)
            {
                LevelGridNode levelGridNode2 = this.nodes[num14];
                if (levelGridNode2 != null)
                {
                    this.UpdatePenalty(levelGridNode2);
                    levelGridNode2.GraphIndex = graphIndex;
                    if (!levelGridNode2.HasAnyGridConnections())
                    {
                        levelGridNode2.Walkable        = false;
                        levelGridNode2.WalkableErosion = levelGridNode2.Walkable;
                    }
                }
            }
            this.ErodeWalkableArea();
        }
 /** Returns if \a node is connected to it's neighbour in the specified direction */
 public bool CheckConnection(LevelGridNode node, int dir)
 {
     return node.GetConnection (dir);
 }
        // Token: 0x060024F1 RID: 9457 RVA: 0x0019C554 File Offset: 0x0019A754
        public override NNInfoInternal GetNearestForce(Vector3 position, NNConstraint constraint)
        {
            if (this.nodes == null || this.depth * this.width * this.layerCount != this.nodes.Length || this.layerCount == 0)
            {
                return(default(NNInfoInternal));
            }
            Vector3 vector = position;

            position = base.transform.InverseTransform(position);
            float         x             = position.x;
            float         z             = position.z;
            int           num           = Mathf.Clamp((int)x, 0, this.width - 1);
            int           num2          = Mathf.Clamp((int)z, 0, this.depth - 1);
            float         num3          = float.PositiveInfinity;
            int           num4          = 2;
            LevelGridNode levelGridNode = this.GetNearestNode(vector, num, num2, constraint);

            if (levelGridNode != null)
            {
                num3 = ((Vector3)levelGridNode.position - vector).sqrMagnitude;
            }
            if (levelGridNode != null && num4 > 0)
            {
                num4--;
            }
            float num5 = constraint.constrainDistance ? AstarPath.active.maxNearestNodeDistance : float.PositiveInfinity;
            float num6 = num5 * num5;
            int   num7 = 1;

            for (;;)
            {
                int i = num2 + num7;
                if (this.nodeSize * (float)num7 > num5)
                {
                    break;
                }
                int j;
                for (j = num - num7; j <= num + num7; j++)
                {
                    if (j >= 0 && i >= 0 && j < this.width && i < this.depth)
                    {
                        LevelGridNode nearestNode = this.GetNearestNode(vector, j, i, constraint);
                        if (nearestNode != null)
                        {
                            float sqrMagnitude = ((Vector3)nearestNode.position - vector).sqrMagnitude;
                            if (sqrMagnitude < num3 && sqrMagnitude < num6)
                            {
                                num3          = sqrMagnitude;
                                levelGridNode = nearestNode;
                            }
                        }
                    }
                }
                i = num2 - num7;
                for (j = num - num7; j <= num + num7; j++)
                {
                    if (j >= 0 && i >= 0 && j < this.width && i < this.depth)
                    {
                        LevelGridNode nearestNode2 = this.GetNearestNode(vector, j, i, constraint);
                        if (nearestNode2 != null)
                        {
                            float sqrMagnitude2 = ((Vector3)nearestNode2.position - vector).sqrMagnitude;
                            if (sqrMagnitude2 < num3 && sqrMagnitude2 < num6)
                            {
                                num3          = sqrMagnitude2;
                                levelGridNode = nearestNode2;
                            }
                        }
                    }
                }
                j = num - num7;
                for (i = num2 - num7 + 1; i <= num2 + num7 - 1; i++)
                {
                    if (j >= 0 && i >= 0 && j < this.width && i < this.depth)
                    {
                        LevelGridNode nearestNode3 = this.GetNearestNode(vector, j, i, constraint);
                        if (nearestNode3 != null)
                        {
                            float sqrMagnitude3 = ((Vector3)nearestNode3.position - vector).sqrMagnitude;
                            if (sqrMagnitude3 < num3 && sqrMagnitude3 < num6)
                            {
                                num3          = sqrMagnitude3;
                                levelGridNode = nearestNode3;
                            }
                        }
                    }
                }
                j = num + num7;
                for (i = num2 - num7 + 1; i <= num2 + num7 - 1; i++)
                {
                    if (j >= 0 && i >= 0 && j < this.width && i < this.depth)
                    {
                        LevelGridNode nearestNode4 = this.GetNearestNode(vector, j, i, constraint);
                        if (nearestNode4 != null)
                        {
                            float sqrMagnitude4 = ((Vector3)nearestNode4.position - vector).sqrMagnitude;
                            if (sqrMagnitude4 < num3 && sqrMagnitude4 < num6)
                            {
                                num3          = sqrMagnitude4;
                                levelGridNode = nearestNode4;
                            }
                        }
                    }
                }
                if (levelGridNode != null)
                {
                    if (num4 == 0)
                    {
                        break;
                    }
                    num4--;
                }
                num7++;
            }
            NNInfoInternal result = new NNInfoInternal(levelGridNode);

            if (levelGridNode != null)
            {
                int xcoordinateInGrid = levelGridNode.XCoordinateInGrid;
                int zcoordinateInGrid = levelGridNode.ZCoordinateInGrid;
                result.clampedPosition = base.transform.Transform(new Vector3(Mathf.Clamp(x, (float)xcoordinateInGrid, (float)xcoordinateInGrid + 1f), base.transform.InverseTransform((Vector3)levelGridNode.position).y, Mathf.Clamp(z, (float)zcoordinateInGrid, (float)zcoordinateInGrid + 1f)));
            }
            return(result);
        }
Beispiel #10
0
        public new bool SnappedLinecast(Vector3 _a, Vector3 _b, GraphNode hint, out GraphHitInfo hit)
        {
            hit = default(GraphHitInfo);
            LevelGridNode levelGridNode  = base.GetNearest(_a, NNConstraint.None).node as LevelGridNode;
            LevelGridNode levelGridNode2 = base.GetNearest(_b, NNConstraint.None).node as LevelGridNode;

            if (levelGridNode == null || levelGridNode2 == null)
            {
                hit.node  = null;
                hit.point = _a;
                return(true);
            }
            _a    = this.inverseMatrix.MultiplyPoint3x4((Vector3)levelGridNode.position);
            _a.x -= 0.5f;
            _a.z -= 0.5f;
            _b    = this.inverseMatrix.MultiplyPoint3x4((Vector3)levelGridNode2.position);
            _b.x -= 0.5f;
            _b.z -= 0.5f;
            Int3 ob   = new Int3(Mathf.RoundToInt(_a.x), Mathf.RoundToInt(_a.y), Mathf.RoundToInt(_a.z));
            Int3 @int = new Int3(Mathf.RoundToInt(_b.x), Mathf.RoundToInt(_b.y), Mathf.RoundToInt(_b.z));

            hit.origin = (Vector3)ob;
            if (!levelGridNode.Walkable)
            {
                hit.node    = levelGridNode;
                hit.point   = this.matrix.MultiplyPoint3x4(new Vector3((float)ob.x + 0.5f, 0f, (float)ob.z + 0.5f));
                hit.point.y = ((Vector3)hit.node.position).y;
                return(true);
            }
            int           num  = Mathf.Abs(ob.x - @int.x);
            int           num2 = Mathf.Abs(ob.z - @int.z);
            LevelGridNode levelGridNode4;

            for (LevelGridNode levelGridNode3 = levelGridNode; levelGridNode3 != levelGridNode2; levelGridNode3 = levelGridNode4)
            {
                if (levelGridNode3.NodeInGridIndex == levelGridNode2.NodeInGridIndex)
                {
                    hit.node  = levelGridNode3;
                    hit.point = (Vector3)levelGridNode3.position;
                    return(true);
                }
                num  = Math.Abs(ob.x - @int.x);
                num2 = Math.Abs(ob.z - @int.z);
                int num3 = 0;
                if (num >= num2)
                {
                    num3 = ((@int.x <= ob.x) ? 3 : 1);
                }
                else if (num2 > num)
                {
                    num3 = ((@int.z <= ob.z) ? 0 : 2);
                }
                if (!this.CheckConnection(levelGridNode3, num3))
                {
                    hit.node  = levelGridNode3;
                    hit.point = (Vector3)levelGridNode3.position;
                    return(true);
                }
                levelGridNode4 = this.nodes[levelGridNode3.NodeInGridIndex + this.neighbourOffsets[num3] + this.width * this.depth * levelGridNode3.GetConnectionValue(num3)];
                if (!levelGridNode4.Walkable)
                {
                    hit.node  = levelGridNode4;
                    hit.point = (Vector3)levelGridNode4.position;
                    return(true);
                }
                ob = (Int3)this.inverseMatrix.MultiplyPoint3x4((Vector3)levelGridNode4.position);
            }
            return(false);
        }
 public void CalculateConnections(int x, int z, int layerIndex, LevelGridNode node)
 {
     this.CalculateConnections(x, z, layerIndex);
 }
        // Token: 0x060024EB RID: 9451 RVA: 0x0019C13C File Offset: 0x0019A33C
        public override void CalculateConnections(GridNodeBase baseNode)
        {
            LevelGridNode levelGridNode = baseNode as LevelGridNode;

            this.CalculateConnections(levelGridNode.XCoordinateInGrid, levelGridNode.ZCoordinateInGrid, levelGridNode.LayerCoordinateInGrid);
        }
        // Token: 0x060024E7 RID: 9447 RVA: 0x0019BD9C File Offset: 0x00199F9C
        public override void RecalculateCell(int x, int z, bool resetPenalties = true, bool resetTags = true)
        {
            float           num             = Mathf.Cos(this.maxSlope * 0.017453292f);
            int             i               = 0;
            LinkedLevelNode linkedLevelNode = this.SampleCell(x, z);

            while (linkedLevelNode != null)
            {
                if (i >= this.layerCount)
                {
                    if (i + 1 > 255)
                    {
                        Debug.LogError(string.Concat(new object[]
                        {
                            "Too many layers, a maximum of ",
                            255,
                            " are allowed (required ",
                            i + 1,
                            ")"
                        }));
                        return;
                    }
                    this.AddLayers(1);
                }
                int           num2          = z * this.width + x + this.width * this.depth * i;
                LevelGridNode levelGridNode = this.nodes[num2];
                bool          flag          = levelGridNode == null;
                if (flag)
                {
                    if (this.nodes[num2] != null)
                    {
                        this.nodes[num2].Destroy();
                    }
                    levelGridNode = (this.nodes[num2] = new LevelGridNode(this.active));
                    levelGridNode.NodeInGridIndex       = z * this.width + x;
                    levelGridNode.LayerCoordinateInGrid = i;
                    levelGridNode.GraphIndex            = this.graphIndex;
                }
                levelGridNode.position        = (Int3)linkedLevelNode.position;
                levelGridNode.Walkable        = linkedLevelNode.walkable;
                levelGridNode.WalkableErosion = levelGridNode.Walkable;
                if (flag || resetPenalties)
                {
                    levelGridNode.Penalty = this.initialPenalty;
                    if (this.penaltyPosition)
                    {
                        levelGridNode.Penalty += (uint)Mathf.RoundToInt(((float)levelGridNode.position.y - this.penaltyPositionOffset) * this.penaltyPositionFactor);
                    }
                }
                if (flag || resetTags)
                {
                    levelGridNode.Tag = 0u;
                }
                if (linkedLevelNode.hit.normal != Vector3.zero && (this.penaltyAngle || num > 0.0001f))
                {
                    float num3 = Vector3.Dot(linkedLevelNode.hit.normal.normalized, this.collision.up);
                    if (resetTags && this.penaltyAngle)
                    {
                        levelGridNode.Penalty += (uint)Mathf.RoundToInt((1f - num3) * this.penaltyAngleFactor);
                    }
                    if (num3 < num)
                    {
                        levelGridNode.Walkable = false;
                    }
                }
                if (linkedLevelNode.height < this.characterHeight)
                {
                    levelGridNode.Walkable = false;
                }
                levelGridNode.WalkableErosion = levelGridNode.Walkable;
                linkedLevelNode = linkedLevelNode.next;
                i++;
            }
            while (i < this.layerCount)
            {
                int num4 = z * this.width + x + this.width * this.depth * i;
                if (this.nodes[num4] != null)
                {
                    this.nodes[num4].Destroy();
                }
                this.nodes[num4] = null;
                i++;
            }
        }
		public override void ScanInternal (OnScanStatus statusCallback) {

			if (nodeSize <= 0) {
				return;
			}

			GenerateMatrix ();

			if (width > 1024 || depth > 1024) {
				Debug.LogError ("One of the grid's sides is longer than 1024 nodes");
				return;
			}

			lastScannedWidth = width;
			lastScannedDepth = depth;

			SetUpOffsetsAndCosts ();

			LevelGridNode.SetGridGraph (active.astarData.GetGraphIndex(this), this);

			maxClimb = Mathf.Clamp (maxClimb,0,characterHeight);

			var linkedCells = new LinkedLevelCell[width*depth];

			collision = collision ?? new GraphCollision ();
			collision.Initialize (matrix,nodeSize);

			for (int z = 0; z < depth; z ++) {
				for (int x = 0; x < width; x++) {

					linkedCells[z*width+x] = new LinkedLevelCell ();

					LinkedLevelCell llc = linkedCells[z*width+x];

					Vector3 pos = matrix.MultiplyPoint3x4 (new Vector3 (x+0.5F,0,z+0.5F));


					RaycastHit[] hits = collision.CheckHeightAll (pos);

					for (int i=0;i<hits.Length/2;i++) {
						RaycastHit tmp = hits[i];

						hits[i] = hits[hits.Length-1-i];
						hits[hits.Length-1-i] = tmp;
					}

					if (hits.Length > 0) {

						LinkedLevelNode lln = null;

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

							var tmp = new LinkedLevelNode ();
							tmp.position = hits[i].point;

							if (lln != null) {
								/** \todo Use hit.distance instead */
								if (tmp.position.y - lln.position.y <= mergeSpanRange) {
										lln.position = tmp.position;
										lln.hit = hits[i];
										lln.walkable = collision.Check (tmp.position);
									continue;
								}
							}

							tmp.walkable = collision.Check (tmp.position);
							tmp.hit = hits[i];
							tmp.height = float.PositiveInfinity;

							if (llc.first == null) {
								llc.first = tmp;
								lln = tmp;
							} else {
								lln.next = tmp;

								lln.height = tmp.position.y - lln.position.y;
								lln = lln.next;
							}

						}
					} else {
						var lln = new LinkedLevelNode ();
						lln.position = pos;
						lln.height = float.PositiveInfinity;
						lln.walkable = !collision.unwalkableWhenNoGround;
						llc.first = lln;
					}
				}
			}


			int spanCount = 0;
			layerCount = 0;
			// Count the total number of nodes in the graph
			for (int z = 0; z < depth; z ++) {
				for (int x = 0; x < width; x++) {

					LinkedLevelCell llc = linkedCells[z*width+x];

					LinkedLevelNode lln = llc.first;
					int cellCount = 0;
					// Loop through all nodes in this cell
					do {
						cellCount++;
						spanCount++;
						lln = lln.next;
					} while (lln != null);

					layerCount = cellCount > layerCount ? cellCount : layerCount;
				}
			}

			if (layerCount > LevelGridNode.MaxLayerCount) {
				Debug.LogError ("Too many layers, a maximum of LevelGridNode.MaxLayerCount are allowed (found "+layerCount+")");
				return;
			}

			// Create all nodes
			nodes = new LevelGridNode[width*depth*layerCount];
			for (int i=0;i<nodes.Length;i++) {
				nodes[i] = new LevelGridNode (active);
				nodes[i].Penalty = initialPenalty;
			}

			int nodeIndex = 0;

			// Max slope in cosinus
			float cosAngle = Mathf.Cos (maxSlope*Mathf.Deg2Rad);

			for (int z = 0; z < depth; z++) {
				for (int x = 0; x < width; x++) {

					LinkedLevelCell llc = linkedCells[z*width+x];
					LinkedLevelNode lln = llc.first;

					llc.index = nodeIndex;

					int count = 0;
					int layerIndex = 0;
					do {
						var node = nodes[z*width+x + width*depth*layerIndex];
#if ASTAR_SET_LEVELGRIDNODE_HEIGHT
						node.height = lln.height;
#endif
						node.SetPosition ((Int3)lln.position);
						node.Walkable = lln.walkable;

						// Adjust penalty based on the surface slope
						if (lln.hit.normal != Vector3.zero && (penaltyAngle || cosAngle < 1.0f)) {
							//Take the dot product to find out the cosinus of the angle it has (faster than Vector3.Angle)
							float angle = Vector3.Dot (lln.hit.normal.normalized,collision.up);

							// Add penalty based on normal
							if (penaltyAngle) {
								node.Penalty += (uint)Mathf.RoundToInt ((1F-angle)*penaltyAngleFactor);
							}

							// Check if the slope is flat enough to stand on
							if (angle < cosAngle) {
								node.Walkable = false;
							}
						}

						node.NodeInGridIndex = z*width+x;

						if (lln.height < characterHeight) {
							node.Walkable = false;
						}

						node.WalkableErosion = node.Walkable;

						nodeIndex++;
						count++;
						lln = lln.next;
						layerIndex++;
					} while (lln != null);

					for (;layerIndex<layerCount;layerIndex++) {
						nodes[z*width+x + width*depth*layerIndex] = null;
					}

					llc.count = count;
				}
			}

			nodeIndex = 0;

			nodeCellIndices = new int[linkedCells.Length];

			for (int z = 0; z < depth; z ++) {
				for (int x = 0; x < width; x++) {
					for (int i=0;i<layerCount;i++) {
						GraphNode node = nodes[z*width+x + width*depth*i];
						CalculateConnections (nodes,node,x,z,i);
					}
				}
			}

			uint graphIndex = (uint)active.astarData.GetGraphIndex(this);

			for (int i=0;i<nodes.Length;i++) {
				var lgn = nodes[i];
				if (lgn == null) continue;

				UpdatePenalty (lgn);

				lgn.GraphIndex = graphIndex;

				// Set the node to be unwalkable if it hasn't got any connections
				if (!lgn.HasAnyGridConnections ()) {
					lgn.Walkable = false;
					lgn.WalkableErosion = lgn.Walkable;
				}
			}

			ErodeWalkableArea ();
		}
Beispiel #15
0
 private void RemoveGridGraphFromStatic()
 {
     LevelGridNode.SetGridGraph(this.active.astarData.GetGraphIndex(this), null);
 }
        /** Updates penalty for the node.
         * This function sets penalty to zero (0) and then adjusts it if #penaltyPosition is set to true.
         */
        public virtual void UpdatePenalty(LevelGridNode node)
        {
            node.penalty = 0;//Mathf.RoundToInt (Random.value*100);

            if (penaltyPosition) {
                node.penalty = (uint)Mathf.RoundToInt ((node.position.y-penaltyPositionOffset)*penaltyPositionFactor);
            }
        }
Beispiel #17
0
        public bool RecalculateCell(int x, int z, bool preserveExistingNodes)
        {
            LinkedLevelCell linkedLevelCell = new LinkedLevelCell();
            Vector3         position        = this.matrix.MultiplyPoint3x4(new Vector3((float)x + 0.5f, 0f, (float)z + 0.5f));

            RaycastHit[] array = this.collision.CheckHeightAll(position);
            for (int i = 0; i < array.Length / 2; i++)
            {
                RaycastHit raycastHit = array[i];
                array[i] = array[array.Length - 1 - i];
                array[array.Length - 1 - i] = raycastHit;
            }
            bool result = false;

            if (array.Length > 0)
            {
                LinkedLevelNode linkedLevelNode = null;
                for (int j = 0; j < array.Length; j++)
                {
                    LinkedLevelNode linkedLevelNode2 = new LinkedLevelNode();
                    linkedLevelNode2.position = array[j].point;
                    if (linkedLevelNode != null && linkedLevelNode2.position.y - linkedLevelNode.position.y <= this.mergeSpanRange)
                    {
                        linkedLevelNode.position = linkedLevelNode2.position;
                        linkedLevelNode.hit      = array[j];
                        linkedLevelNode.walkable = this.collision.Check(linkedLevelNode2.position);
                    }
                    else
                    {
                        linkedLevelNode2.walkable = this.collision.Check(linkedLevelNode2.position);
                        linkedLevelNode2.hit      = array[j];
                        linkedLevelNode2.height   = float.PositiveInfinity;
                        if (linkedLevelCell.first == null)
                        {
                            linkedLevelCell.first = linkedLevelNode2;
                            linkedLevelNode       = linkedLevelNode2;
                        }
                        else
                        {
                            linkedLevelNode.next   = linkedLevelNode2;
                            linkedLevelNode.height = linkedLevelNode2.position.y - linkedLevelNode.position.y;
                            linkedLevelNode        = linkedLevelNode.next;
                        }
                    }
                }
            }
            else
            {
                linkedLevelCell.first = new LinkedLevelNode
                {
                    position = position,
                    height   = float.PositiveInfinity,
                    walkable = !this.collision.unwalkableWhenNoGround
                };
            }
            uint            graphIndex       = (uint)this.active.astarData.GetGraphIndex(this);
            LinkedLevelNode linkedLevelNode3 = linkedLevelCell.first;
            int             num = 0;
            int             k   = 0;

            while (true)
            {
                if (k >= this.layerCount)
                {
                    if (k + 1 > 255)
                    {
                        break;
                    }
                    this.AddLayers(1);
                    result = true;
                }
                LevelGridNode levelGridNode = this.nodes[z * this.width + x + this.width * this.depth * k];
                if (levelGridNode == null || !preserveExistingNodes)
                {
                    this.nodes[z * this.width + x + this.width * this.depth * k] = new LevelGridNode(this.active);
                    levelGridNode            = this.nodes[z * this.width + x + this.width * this.depth * k];
                    levelGridNode.Penalty    = this.initialPenalty;
                    levelGridNode.GraphIndex = graphIndex;
                    result = true;
                }
                levelGridNode.SetPosition((Int3)linkedLevelNode3.position);
                levelGridNode.Walkable        = linkedLevelNode3.walkable;
                levelGridNode.WalkableErosion = levelGridNode.Walkable;
                if (linkedLevelNode3.hit.normal != Vector3.zero)
                {
                    float num2 = Vector3.Dot(linkedLevelNode3.hit.normal.normalized, this.collision.up);
                    if (this.penaltyAngle)
                    {
                        levelGridNode.Penalty += (uint)Mathf.RoundToInt((1f - num2) * this.penaltyAngleFactor);
                    }
                    float num3 = Mathf.Cos(this.maxSlope * 0.0174532924f);
                    if (num2 < num3)
                    {
                        levelGridNode.Walkable = false;
                    }
                }
                levelGridNode.NodeInGridIndex = z * this.width + x;
                if (linkedLevelNode3.height < this.characterHeight)
                {
                    levelGridNode.Walkable = false;
                }
                num++;
                linkedLevelNode3 = linkedLevelNode3.next;
                k++;
                if (linkedLevelNode3 == null)
                {
                    goto Block_14;
                }
            }
            Debug.LogError("Too many layers, a maximum of LevelGridNode.MaxLayerCount are allowed (required " + (k + 1) + ")");
            return(result);

Block_14:
            while (k < this.layerCount)
            {
                this.nodes[z * this.width + x + this.width * this.depth * k] = null;
                k++;
            }
            linkedLevelCell.count = num;
            return(result);
        }
 public override Node[] CreateNodes(int number)
 {
     LevelGridNode[] tmp = new LevelGridNode[number];
     for (int i=0;i<number;i++) {
         tmp[i] = new LevelGridNode ();
         tmp[i].penalty = initialPenalty;
     }
     return tmp as Node[];
 }
Beispiel #19
0
        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);
                            }
                        }
                    }
                }
            }
        }
        public void AddPortal(LevelGridNode n1, LevelGridNode n2, List<Vector3> left, List<Vector3> right)
        {
            if (n1 == n2) {
                return;
            }

            int i1 = n1.GetIndex ();
            int i2 = n2.GetIndex ();
            int x1 = i1 % width;
            int x2 = i2 % width;
            int z1 = i1 / width;
            int z2 = i2 / width;

            Vector3 n1p = (Vector3)n1.position;
            Vector3 n2p = (Vector3)n2.position;

            int diffx = Mathf.Abs (x1-x2);
            int diffz = Mathf.Abs (z1-z2);

            if (diffx > 1 || diffz > 1) {
                //If the nodes are not adjacent to each other

                left.Add (n1p);
                right.Add (n1p);
                left.Add (n2p);
                right.Add (n2p);
            } else if ((diffx+diffz) <= 1){
                //If it is not a diagonal move

                Vector3 dir = n2p - n1p;
                //dir = dir.normalized * nodeSize * 0.5F;
                dir *= 0.5F;
                Vector3 tangent = Vector3.Cross (dir.normalized, Vector3.up);
                tangent *= /*tangent.normalized * */nodeSize * 0.5F;

                left.Add (n1p + dir - tangent);
                right.Add (n1p + dir + tangent);
            } else {
                //Diagonal move

                Vector3 dir = n2p - n1p;
                Vector3 avg = (n1p + n2p) * 0.5F;
                Vector3 tangent = Vector3.Cross (dir.normalized, Vector3.up);

                tangent *= nodeSize * 0.5F;

                left.Add (avg - tangent);
                right.Add (avg + tangent);

                /*Node t1 = nodes[z1 * width + x2];
                Node t2 = nodes[z2 * width + x1];
                Node target = null;

                if (t1.walkable) {
                    target = t1;
                } else if (t2.walkable) {
                    target = t2;
                }

                if (target == null) {
                    Vector3 avg = (n1p + n2p) * 0.5F;

                    left.Add (avg);
                    right.Add (avg);
                } else {
                    AddPortal (n1,(LevelGridNode)target,left,right);
                    AddPortal ((LevelGridNode)target,n2,left,right);
                }*/
            }
        }
        // Token: 0x060024E4 RID: 9444 RVA: 0x0019B62C File Offset: 0x0019982C
        void IUpdatableGraph.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);
                    }
                }
            }
        }