Inheritance: IAgent
示例#1
0
		public float InsertAgentNeighbour (Agent agent, float rangeSq) {
			return 0;
		}
示例#2
0
		private void QueryAgentTreeRecursive (Agent agent, ref float rangeSq, int node) {
		}
示例#3
0
		private void QueryObstacleTreeRecursive (Agent agent, float rangeSq, ObstacleTreeNode node) {
		}
示例#4
0
		public void GetAgentNeighbours (Agent agent, float rangeSq) {
			QueryAgentTreeRecursive (agent, ref rangeSq, 0);
		}
示例#5
0
		public void GetObstacleNeighbours (Agent agent, float rangeSq) {
			QueryObstacleTreeRecursive (agent, rangeSq, obstacleRoot);
		}
示例#6
0
		private void QueryAgentTreeRecursive (Agent agent, ref float rangeSq, int node) {
			if (agentTree[node].end - agentTree[node].start <= MAX_LEAF_SIZE) {
				for (int i = agentTree[node].start; i < agentTree[node].end; i++) {
					rangeSq = agent.InsertAgentNeighbour (agents[i], rangeSq);
				}
			} else {
				//Calculate squared distance to the closest point inside the bounding boxes of the child nodes
				float distSqLeft = Sqr (Math.Max (0.0f, agentTree[agentTree[node].left].xmin - agent.position.x))
								 + Sqr (Math.Max (0.0f, agent.position.x - agentTree[agentTree[node].left].xmax))
								 + Sqr (Math.Max (0.0f, agentTree[agentTree[node].left].ymin - agent.position.z))
								 + Sqr (Math.Max (0.0f, agent.position.z - agentTree[agentTree[node].left].ymax));
				
				float distSqRight =Sqr (Math.Max (0.0f, agentTree[agentTree[node].right].xmin - agent.position.x))
								 + Sqr (Math.Max (0.0f, agent.position.x - agentTree[agentTree[node].right].xmax))
								 + Sqr (Math.Max (0.0f, agentTree[agentTree[node].right].ymin - agent.position.z))
								 + Sqr (Math.Max (0.0f, agent.position.z - agentTree[agentTree[node].right].ymax));
				if (distSqLeft < distSqRight) {
					if (distSqLeft < rangeSq) {
						QueryAgentTreeRecursive (agent, ref rangeSq, agentTree[node].left);
						
						if (distSqRight < rangeSq) {
							QueryAgentTreeRecursive (agent, ref rangeSq, agentTree[node].right);
						}
					}
				} else {
					if (distSqRight < rangeSq) {
						QueryAgentTreeRecursive (agent, ref rangeSq, agentTree[node].right);
						
						if (distSqLeft < rangeSq) {
							QueryAgentTreeRecursive (agent, ref rangeSq, agentTree[node].left);
						}
					}
				}
			}
		}
示例#7
0
		private void QueryObstacleTreeRecursive (Agent agent, float rangeSq, ObstacleTreeNode node) {
			if (node == null) return;
			
			ObstacleVertex ob1 = node.obstacle;
			ObstacleVertex ob2 = ob1.next;
			
			float agentLeftOfLine = Polygon.TriangleArea (ob1.position,ob2.position,agent.position);
			
			QueryObstacleTreeRecursive (agent, rangeSq, agentLeftOfLine >= 0.0f ? node.left : node.right);
			
			Vector3 dir2D = ob1.position-ob2.position;
			dir2D.y = 0;
			
			//Isn't this 4 times too large since TriangleArea is actually 2*triangle area
			float distSqLine = Sqr(agentLeftOfLine) / dir2D.sqrMagnitude;
			
			if (distSqLine < rangeSq) {
				if (agentLeftOfLine < 0.0f) {
					/*
			         * Try obstacle at this node only if agent is on right side of
			         * obstacle (and can see obstacle).
			         */
					agent.InsertObstacleNeighbour (node.obstacle, rangeSq);
				}
				
				QueryObstacleTreeRecursive (agent, rangeSq, (agentLeftOfLine >= 0.0f ? node.right : node.left));
			}
		}
示例#8
0
		public float InsertAgentNeighbour (Agent agent, float rangeSq) {
			if (this == agent) 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);
				}
				/** \bug This starts to compare with a lower agent if neighbours.Count >= maxNeighbours */
				int i = neighbours.Count-1;
				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;
		}
示例#9
0
        /** Add 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);
            kdTree.RebuildAgents ();

            agent.simulator = this;

            return agent;
        }
示例#10
0
 public void Add(Agent agent)
 {
     agent.next = linkedList;
     linkedList = agent;
 }
示例#11
0
 public void Query(Vector2 p, float speed, float timeHorizon, float agentRadius, Agent agent)
 {
     new QuadtreeQuery
     {
         p           = p,
         speed       = speed,
         timeHorizon = timeHorizon,
         maxRadius   = float.PositiveInfinity,
         agentRadius = agentRadius,
         agent       = agent,
         nodes       = nodes
     }.QueryRec(0, bounds);
 }
示例#12
0
        /// <summary>
        /// Add a new agent to the tree.
        /// Warning: Agents must not be added multiple times to the same tree
        /// </summary>
        public void Insert(Agent agent)
        {
            int     i = 0;
            Rect    r = bounds;
            Vector2 p = new Vector2(agent.position.x, agent.position.y);

            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
                        nodes[i].child00 = GetNodeIndex();
                        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].child00 + 3;
                            r = Rect.MinMaxRect(c.x, c.y, r.xMax, r.yMax);
                        }
                        else
                        {
                            i = nodes[i].child00 + 2;
                            r = Rect.MinMaxRect(c.x, r.yMin, r.xMax, c.y);
                        }
                    }
                    else
                    {
                        if (p.y > c.y)
                        {
                            i = nodes[i].child00 + 1;
                            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);
                        }
                    }
                }
            }
        }