// Find all nodes that appear within a range public List <Node> QueryRange(AABB range) { // Prepare an array of results List <Node> nodesInRange = new List <Node>(); // Automatically abort if the range does not intersect this quad if (!bounds.IntersectsAABB(range)) { return(nodesInRange); // empty list } // Check objects at this quad level foreach (Node n in nodes) { if (range.ContainsPoint(n.position)) { nodesInRange.Add(n); } } if (northWest == null) { return(nodesInRange); } nodesInRange.AddRange(northWest.QueryRange(range)); nodesInRange.AddRange(northEast.QueryRange(range)); nodesInRange.AddRange(southWest.QueryRange(range)); nodesInRange.AddRange(southEast.QueryRange(range)); return(nodesInRange); }
public List <XY> QueryRange(AABB range) { List <XY> pointsInRange = new List <XY>(); if (!boundary.IntersectsAABB(range)) { return(pointsInRange); } for (int p = 0; p < points.Count; p++) { if (range.ContainsPoint(points[p])) { pointsInRange.Add(points[p]); } } if (northWest == null) { return(pointsInRange); } List <XY> pointsInRangeNorthWest = northWest.QueryRange(range); List <XY> pointsInRangeNorthEast = northEast.QueryRange(range); List <XY> pointsInRangeSouthWest = southWest.QueryRange(range); List <XY> pointsInRangeSouthEast = southEast.QueryRange(range); for (int i = 0; i < pointsInRangeNorthWest.Count; i++) { pointsInRange.Add(pointsInRangeNorthWest[i]); } for (int i = 0; i < pointsInRangeNorthEast.Count; i++) { pointsInRange.Add(pointsInRangeNorthEast[i]); } for (int i = 0; i < pointsInRangeSouthWest.Count; i++) { pointsInRange.Add(pointsInRangeSouthWest[i]); } for (int i = 0; i < pointsInRangeSouthEast.Count; i++) { pointsInRange.Add(pointsInRangeSouthEast[i]); } return(pointsInRange); }
// Insert a node into the quadtree public bool Insert(Node node) { // Ignore objects that do not belong in this quad tree if (!bounds.ContainsPoint(node.position)) { return(false); } // If there is space in this quad tree, add the object here if (nodes.Count < treeCapacity) { nodes.Add(node); return(true); } // Otherwise, subdivide and then add the point to whichever node will accept it if (northWest == null) { Subdivide(); } if (northWest.Insert(node)) { return(true); } if (northEast.Insert(node)) { return(true); } if (southWest.Insert(node)) { return(true); } if (southEast.Insert(node)) { return(true); } // Otherwise, the point cannot be inserted for some unknown reason (this should never happen) return(false); }
public bool Insert(XY point) { if (!boundary.ContainsPoint(point)) { return(false); } if (points.Count < QT_NODE_CAPACITY) { points.Add(point); return(true); } if (northWest == null) { Subdivide(); } if (northWest.Insert(point)) { return(true); } if (northEast.Insert(point)) { return(true); } if (southWest.Insert(point)) { return(true); } if (southEast.Insert(point)) { return(true); } return(false); }
//Determine if a world point exists in the //mesh public bool ContainsWorldPoint(ref Vector3 worldPoint, ref int[] indices, ref Vector3[] vertices) { bool containsWorldPoint = false; //First do a broad phase contains point detection //using AABB contains point method MeshRenderer meshRenderer = GetComponent <MeshRenderer>(); AABB aabb = GetComponent <AABB>(); Vector3 center = Vector3.zero; aabb.SetCenter(ref center); Vector3 extents = meshRenderer.bounds.extents; aabb.SetHalfExtent(ref extents); directionVector = center - worldPoint; if (aabb.ContainsPoint(ref worldPoint)) { startPoint = worldPoint; int numberOfTriangles = indices.Length / 3; int index = 0; int numberOfRayCastHits = 0; bool isWorldPointSameAsMeshVertex = false; for (int i = 0; i < numberOfTriangles; i++) { int a = indices[index]; index++; int b = indices[index]; index++; int c = indices[index]; Vector3 aVector = vertices[a]; Vector3 bVector = vertices[b]; Vector3 cVector = vertices[c]; //Check to see if the world point is same as one of the mesh //vertices //If it is then, exit out and simply return true if (worldPoint == aVector || worldPoint == bVector || worldPoint == cVector) { isWorldPointSameAsMeshVertex = true; break; } bool hit = CustomPhysics.RayCastHit(ref startPoint, ref directionVector, ref aVector, ref bVector, ref cVector); if (hit) { numberOfRayCastHits++; } } //If it hits once or none, then we know the point is inside the mesh //Also if the point is the mesh vertex, we consider that inside the mesh as //well if (numberOfRayCastHits == 0 || numberOfRayCastHits == 1 || isWorldPointSameAsMeshVertex) { containsWorldPoint = true; } //If it hits more than once, then we know the point is outside the mesh else if (numberOfRayCastHits > 1) { containsWorldPoint = false; } } Debug.Log("contains point" + worldPoint + " " + containsWorldPoint); return(containsWorldPoint); }