public float distanceBetween(PathFindingNode p) { /*Finds the distance between this node and the one passed in*/ return (float)(Math.Sqrt(Math.Pow(this.x - p.x, 2) + Math.Pow(this.z - p.z, 2))); }
public bool addToLL(PathFindingNode p) { //Don't allow node to point to itself if (string.Compare(p.id, this.id) == 0) return false; //We'll want to manually check containment based upon id. PathFindingNode[] pAry = this.adjacent.ToArray<PathFindingNode>(); for (int i = 0; i < pAry.Length; i++) { if (string.Compare(pAry[i].id, p.id) == 0) return false; //We also want to avoid nodes that pretty much overlap... //if (Math.Abs(p.x - pAry[i].x) <= 5 && Math.Abs(p.z - pAry[i].z) <= 5) // return false; } //Else, add to adjacency list adjacent.AddLast(p); return true; }
PathFindingNode checkContains_andAdd_jwf(PathFindingNode p) { /*In order to avoid nodes positioned almost directly on top of one-another, * this function will be a helper to quad-tree. If the node already exists in the * dictionary, or a node close enough to that node, then this function will return * a reference to that node, else, it returns passed in value */ //Check for close by nodes, including the percise node for (int i = -25; i <= 25; i++) for (int j = -25; j <= 25; j++) { if (this.pathNodeCollection.ContainsKey(string.Format("{0}::{1}", p.x + i, p.z + j))) { return this.pathNodeCollection[string.Format("{0}::{1}", p.x + i, p.z + j)]; } } //Else, we need to add this node to the dictionary this.pathNodeCollection.Add(p.id, p); return p; }
bool jwf_existsCollidable(PathFindingNode node, Int32 dist) { //return false; //Does a collidable object exist within the quadrent //depicted by 'node' and 'dist'? foreach (Object3D model in stage.Collidable) { if (model.Translation.X > (node.x - dist - model.ObjectBoundingSphereRadius - 164) && model.Translation.X < (node.x + dist + model.ObjectBoundingSphereRadius + 164) && model.Translation.Z > (node.z - dist - model.ObjectBoundingSphereRadius - 164) && model.Translation.Z < (node.z + dist + model.ObjectBoundingSphereRadius + 164)) { return true; } } return false; }
public bool jwf_QuadTree(PathFindingNode node, Int32 dist) { //Given that 'node' is located in the middle of the quad //Determine if we should split it into 4 smaller quads based upon //1. If the distance is greater than the maximum allowed distance //2. There is a colidable object within the quad if ((dist > MAX_NODE_SEPARATION) || jwf_existsCollidable(node, dist)) { //Are the nodes already at the minimum distance? if (dist <= MIN_NODE_SEPARATION) { //We are done. return true; } //Else, recursively call this funciton with 4 new quads //Upper left quad jwf_QuadTree(new PathFindingNode(this.stage, node.x - (Int32)(dist / 2), node.z - (Int32)(dist / 2)), dist / 2); //Upper right quad jwf_QuadTree(new PathFindingNode(this.stage, node.x + (Int32)(dist / 2), node.z - (Int32)(dist / 2)), dist / 2); //Lower left quad jwf_QuadTree(new PathFindingNode(this.stage, node.x - (Int32)(dist / 2), node.z + (Int32)(dist / 2)), dist / 2); //Lower right quad jwf_QuadTree(new PathFindingNode(this.stage, node.x + (Int32)(dist / 2), node.z + (Int32)(dist / 2)), dist / 2); } else { //Set up 9 nodes PathFindingNode[] ary = new PathFindingNode[]{ new PathFindingNode(this.stage, node.x - dist, node.z - dist), new PathFindingNode(this.stage, node.x, node.z - dist), new PathFindingNode(this.stage, node.x + dist, node.z - dist), new PathFindingNode(this.stage, node.x - dist, node.z), node, new PathFindingNode(this.stage, node.x + dist, node.z), new PathFindingNode(this.stage, node.x - dist, node.z + dist), new PathFindingNode(this.stage, node.x, node.z + dist), new PathFindingNode(this.stage, node.x + dist, node.z + dist), }; //Add nodes to dictionary for (int i = 0; i < ary.Length; i++) { ary[i] = checkContains_andAdd_jwf(ary[i]); } //Add links for (int i = 0; i < ary.Length; i++) { //Every node (except for center node) gets linked to center node. this.pathNodeCollection[ary[i].id].addToLL(this.pathNodeCollection[ary[4].id]); switch (i) { case 0: //upper left this.pathNodeCollection[ary[i].id].addToLL(this.pathNodeCollection[ary[1].id]); this.pathNodeCollection[ary[i].id].addToLL(this.pathNodeCollection[ary[3].id]); break; case 1: //upper middle this.pathNodeCollection[ary[i].id].addToLL(this.pathNodeCollection[ary[0].id]); this.pathNodeCollection[ary[i].id].addToLL(this.pathNodeCollection[ary[2].id]); break; case 2: //upper right this.pathNodeCollection[ary[i].id].addToLL(this.pathNodeCollection[ary[1].id]); this.pathNodeCollection[ary[i].id].addToLL(this.pathNodeCollection[ary[5].id]); break; case 3: //middle left this.pathNodeCollection[ary[i].id].addToLL(this.pathNodeCollection[ary[0].id]); this.pathNodeCollection[ary[i].id].addToLL(this.pathNodeCollection[ary[6].id]); break; case 4: //middle middle for (int j = 0; j < ary.Length; j++) this.pathNodeCollection[node.id].addToLL(this.pathNodeCollection[ary[j].id]); break; case 5: //middle right this.pathNodeCollection[ary[i].id].addToLL(this.pathNodeCollection[ary[2].id]); this.pathNodeCollection[ary[i].id].addToLL(this.pathNodeCollection[ary[8].id]); break; case 6: //lower left this.pathNodeCollection[ary[i].id].addToLL(this.pathNodeCollection[ary[3].id]); this.pathNodeCollection[ary[i].id].addToLL(this.pathNodeCollection[ary[7].id]); break; case 7: //lower middle this.pathNodeCollection[ary[i].id].addToLL(this.pathNodeCollection[ary[6].id]); this.pathNodeCollection[ary[i].id].addToLL(this.pathNodeCollection[ary[8].id]); break; case 8: //lower right this.pathNodeCollection[ary[i].id].addToLL(this.pathNodeCollection[ary[7].id]); this.pathNodeCollection[ary[i].id].addToLL(this.pathNodeCollection[ary[5].id]); break; default: Console.Write("\nIllegal Node Link Error...\n"); break; } } } return true; }