Пример #1
0
		public void Insert ( Agent agent ) {
			int i = 0;
			Rect r = bounds;
			Vector2 p = new Vector2(agent.position.x, agent.position.z);

			agent.next = null;

			maxRadius = System.Math.Max (agent.radius, maxRadius);

			int depth = 0;

			while (true) {
				depth++;

				if ( nodes[i].child00 == i ) {
					// Leaf node. Break at depth 10 in case lots of agents ( > LeafSize ) are in the same spot
					if ( nodes[i].count < LeafSize || depth > 10 ) {
						nodes[i].Add (agent);
						nodes[i].count++;
						break;
					} else {
						// Split
						Node node = nodes[i];
						node.child00 = GetNodeIndex();
						node.child01 = GetNodeIndex();
						node.child10 = GetNodeIndex();
						node.child11 = GetNodeIndex();
						nodes[i] = node;

						nodes[i].Distribute ( nodes, r );
					}
				}
				// Note, no else
				if ( nodes[i].child00 != i ) {
					// Not a leaf node
					Vector2 c = r.center;
					if (p.x > c.x) {
						if (p.y > c.y) {
							i = nodes[i].child11;
							r = Rect.MinMaxRect ( c.x, c.y, r.xMax, r.yMax );
						} else {
							i = nodes[i].child10;
							r = Rect.MinMaxRect ( c.x, r.yMin, r.xMax, c.y );
						}
					} else {
						if (p.y > c.y) {
							i = nodes[i].child01;
							r = Rect.MinMaxRect ( r.xMin, c.y, c.x, r.yMax );
						} else {
							i = nodes[i].child00;
							r = Rect.MinMaxRect ( r.xMin, r.yMin, c.x, c.y );
						}
					}
				}
			}
		}
Пример #2
0
			public void Distribute ( Node[] nodes, Rect r ) {
				Vector2 c = r.center;
				while (linkedList != null) {
					Agent nx = linkedList.next;
					if (linkedList.position.x > c.x) {
						if (linkedList.position.z > c.y) {
							nodes[child11].Add (linkedList);
						} else {
							nodes[child10].Add (linkedList);
						}
					} else {
						if (linkedList.position.z > c.y) {
							nodes[child01].Add (linkedList);
						} else {
							nodes[child00].Add (linkedList);
						}
					}
					linkedList = nx;
				}
				count = 0;
			}
Пример #3
0
		public float InsertAgentNeighbour (Agent agent, float rangeSq) {
			if (this == agent) return rangeSq;

			if ( (agent.layer & collidesWith) == 0 ) return rangeSq;

			//2D Dist
			float dist = Sqr(agent.position.x-position.x) + Sqr(agent.position.z - position.z);
			
			if (dist < rangeSq) {
				if (neighbours.Count < maxNeighbours) {
					neighbours.Add (agent);
					neighbourDists.Add (dist);
				}

				int i = neighbours.Count-1;
				if ( dist < neighbourDists[i] ) {
					while ( i != 0 && dist < neighbourDists[i-1]) {
						neighbours[i] = neighbours[i-1];
						neighbourDists[i] = neighbourDists[i-1];
						i--;
					}
					neighbours[i] = agent;
					neighbourDists[i] = dist;
				}

				if (neighbours.Count == maxNeighbours) {
					rangeSq = neighbourDists[neighbourDists.Count-1];
				}
			}
			return rangeSq;
		}
Пример #4
0
			public void Add ( Agent agent ) {
				agent.next = linkedList;
				linkedList = agent;
			}
Пример #5
0
		float QueryRec ( int i, Vector2 p, float radius, Agent agent, Rect r ) {

			if ( nodes[i].child00 == i ) {
				// Leaf node
				Agent a = nodes[i].linkedList;
				while (a != null) {
					float v = agent.InsertAgentNeighbour ( a, radius*radius );
					if ( v < radius*radius ) {
						radius = Mathf.Sqrt(v);
					}

					//Debug.DrawLine (a.position, new Vector3(p.x,0,p.y),Color.black);
					/*float dist = (new Vector2(a.position.x, a.position.z) - p).sqrMagnitude;
					if ( dist < radius*radius && a != agent ) {

					}*/
					a = a.next;
				}
			} else {

				// Not a leaf node
				Vector2 c = r.center;
				if (p.x-radius < c.x) {
					if (p.y-radius < c.y) {
						radius = QueryRec ( nodes[i].child00, p, radius, agent, Rect.MinMaxRect ( r.xMin, r.yMin, c.x, c.y ) );
					}
					if (p.y+radius > c.y) {
						radius = QueryRec ( nodes[i].child01, p, radius, agent, Rect.MinMaxRect ( r.xMin, c.y, c.x, r.yMax ) );
					}
				}

				if (p.x+radius > c.x) {
					if (p.y-radius < c.y) {
						radius = QueryRec ( nodes[i].child10, p, radius, agent, Rect.MinMaxRect ( c.x, r.yMin, r.xMax, c.y ) );
					}
					if (p.y+radius > c.y) {
						radius = QueryRec ( nodes[i].child11, p, radius, agent, Rect.MinMaxRect ( c.x, c.y, r.xMax, r.yMax ) );
					}
				}
			}

			return radius;
		}
Пример #6
0
		public void Query ( Vector2 p, float radius, Agent agent ) {
			QueryRec ( 0, p, radius, agent, bounds );
		}
Пример #7
0
		/** Enqueue an agent at the specified position.
		 * You can use the returned interface to read several parameters such as position and velocity
		 * and set for example radius and desired velocity.
		 * 
		 * \see RemoveAgent
		 */
		public IAgent AddAgent (Vector3 position) {
			
			Agent agent = new Agent (position);
			
			//Don't interfere with ongoing calculations
			if (Multithreading && doubleBuffering) for (int j=0;j<workers.Length;j++) workers[j].WaitOne();
			
			agents.Add (agent);
			agent.simulator = this;
			
			return agent;
		}