private void Query(AxisAlignedBox bounds, QuadNode node, List <T> results) { //lock (syncLock) { if (node == null) { return; } if (bounds.Intersects(node.Bounds)) { foreach (T quadObject in node.Objects) { if (bounds.Intersects(quadObject.Bounds)) { results.Add(quadObject); } } foreach (QuadNode childNode in node.Nodes) { Query(bounds, childNode, results); } } } }
public bool PointIn(Vector3 p3) { Debug.Assert(closed, "Boundary not closed"); int crossings = 0; Vector2 point = new Vector2(p3.x, p3.z); p3.y = 0; // see if the point falls within the bounding box if (bounds.Intersects(p3)) // XXX { Vector2 topPoint = new Vector2(point.x, bounds.Maximum.z); for (int i = 0; i < (points.Count - 1); i++) { if (IntersectSegments(points[i], points[i + 1], point, topPoint)) { crossings++; } } // check final segment if (IntersectSegments(points[points.Count - 1], points[0], point, topPoint)) { crossings++; } // odd number of crossings means the point is inside return((crossings & 1) == 1); } return(false); }
// Check if a portal intersects an AABB // NOTE: This check is not exact. public bool intersects(AxisAlignedBox aab) { // Only check if portal is open if (this.mOpen) { switch (this.mType) { case PORTAL_TYPE.PORTAL_TYPE_QUAD: // since ogre doesn't have built in support for a quad, just check // if the box intersects both the sphere of the portal and the plane // this can result in false positives, but they will be minimal if (!aab.Intersects(this.mDerivedSphere)) { return(false); } if (aab.Intersects(this.mDerivedPlane)) { return(true); } break; case PORTAL_TYPE.PORTAL_TYPE_AABB: { // aab to aab check var aabb = new AxisAlignedBox(this.mDerivedCorners[0], this.mDerivedCorners[1]); return(aab.Intersects(aabb)); } case PORTAL_TYPE.PORTAL_TYPE_SPHERE: // aab to sphere check return(aab.Intersects(this.mDerivedSphere)); } } return(false); }
public void FindObstaclesInBox(AxisAlignedBox box, CollisionTileManager.AddTreeObstaclesCallback callback) { if (box.Intersects(location)) { callback(speedTree); } }
/** Returns if the camera is over this landscape page. */ public CameraPageState IsCameraIn(Vector3 pos) { if (boundsExt.Intersects(pos) == true) { if (boundsInt.Intersects(pos) == true) { // Full into this page return(CameraPageState.Inside); } else { // Over the change zone return(CameraPageState.Change); } } else { // Not in this page return(CameraPageState.Outside); } }
/* Test if a scene node intersected a portal during the last time delta * (from last frame time to current frame time). This function checks * if the node "crossed over" the portal also. */ public PortalIntersectResult intersects(PCZSceneNode pczsn) { // Only check if portal is open if (this.mOpen) { if (pczsn == this.mNode) { // ignore the scene node if it is the node the portal is associated with return(PortalIntersectResult.NO_INTERSECT); } // most complicated case - if the portal is a quad: if (this.mType == PORTAL_TYPE.PORTAL_TYPE_QUAD) { // the node is modeled as a line segment (prevPostion to currentPosition) // intersection test is then between the capsule and the line segment. var nodeSegment = new Segment(); nodeSegment.Set(pczsn.PreviousPosition, pczsn.DerivedPosition); // we model the portal as a line swept sphere (mPrevDerivedCP to mDerivedCP). var portalCapsule = new Capsule(); portalCapsule.Set(this.mPrevDerivedCP, this.mDerivedCP, this.mRadius); if (portalCapsule.Intersects(nodeSegment)) { // the portal intersected the node at some time from last frame to this frame. // Now check if node "crossed" the portal // a crossing occurs if the "side" of the final position of the node compared // to the final position of the portal is negative AND the initial position // of the node compared to the initial position of the portal is non-negative if (this.mDerivedPlane.GetSide(pczsn.DerivedPosition) == PlaneSide.Negative && this.mPrevDerivedPlane.GetSide(pczsn.DerivedPosition) != PlaneSide.Negative) { // safety check - make sure the node has at least one dimension which is // small enough to fit through the portal! (avoid the "elephant fitting // through a mouse hole" case) Vector3 nodeHalfVector = pczsn.WorldAABB.HalfSize; var portalBox = new Vector3(this.mRadius, this.mRadius, this.mRadius); portalBox.Floor(nodeHalfVector); if (portalBox.x < this.mRadius) { // crossing occurred! return(PortalIntersectResult.INTERSECT_CROSS); } } } // there was no crossing of the portal by the node, but it might be touching // the portal. We check for this by checking the bounding box of the node vs. // the sphere of the portal if (this.mDerivedSphere.Intersects(pczsn.WorldAABB) && this.mDerivedPlane.GetSide(pczsn.WorldAABB) == PlaneSide.Both) { // intersection but no crossing // note this means that the node is CURRENTLY touching the portal. if (this.mDerivedPlane.GetSide(pczsn.DerivedPosition) != PlaneSide.Negative) { // the node is on the positive (front) or exactly on the CP of the portal return(PortalIntersectResult.INTERSECT_NO_CROSS); } else { // the node is on the negative (back) side of the portal - it might be in the wrong zone! return(PortalIntersectResult.INTERSECT_BACK_NO_CROSS); } } // no intersection CURRENTLY. (there might have been an intersection // during the time between last frame and this frame, but it wasn't a portal // crossing, and it isn't touching anymore, so it doesn't matter. return(PortalIntersectResult.NO_INTERSECT); } else if (this.mType == PORTAL_TYPE.PORTAL_TYPE_AABB) { // for aabb's we check if the center point went from being inside to being outside // the aabb (or vice versa) for crossing. var aabb = new AxisAlignedBox(this.mDerivedCorners[0], this.mDerivedCorners[1]); //bool previousInside = aabb.contains(pczsn->getPrevPosition()); bool currentInside = aabb.Contains(pczsn.DerivedPosition); if (this.mDirection == Vector3.UnitZ) { // portal norm is "outward" pointing, look for going from outside to inside //if (previousInside == false && if (currentInside == true) { return(PortalIntersectResult.INTERSECT_CROSS); } } else { // portal norm is "inward" pointing, look for going from inside to outside //if (previousInside == true && if (currentInside == false) { return(PortalIntersectResult.INTERSECT_CROSS); } } // doesn't cross, but might be touching. This is a little tricky because we only // care if the node aab is NOT fully contained in the portal aabb because we consider // the surface of the portal aabb the actual 'portal'. First, check to see if the // aab of the node intersects the aabb portal if (aabb.Intersects(pczsn.WorldAABB)) { // now check if the intersection between the two is not the same as the // full node aabb, if so, then this means that the node is not fully "contained" // which is what we are looking for. AxisAlignedBox overlap = aabb.Intersection(pczsn.WorldAABB); if (overlap != pczsn.WorldAABB) { return(PortalIntersectResult.INTERSECT_NO_CROSS); } } return(PortalIntersectResult.NO_INTERSECT); } else { // for spheres we check if the center point went from being inside to being outside // the sphere surface (or vice versa) for crossing. //Real previousDistance2 = mPrevDerivedCP.squaredDistance(pczsn->getPrevPosition()); Real currentDistance2 = this.mDerivedCP.DistanceSquared(pczsn.DerivedPosition); Real mRadius2 = this.mRadius * this.mRadius; if (this.mDirection == Vector3.UnitZ) { // portal norm is "outward" pointing, look for going from outside to inside //if (previousDistance2 >= mRadius2 && if (currentDistance2 < mRadius2) { return(PortalIntersectResult.INTERSECT_CROSS); } } else { // portal norm is "inward" pointing, look for going from inside to outside //if (previousDistance2 < mRadius2 && if (currentDistance2 >= mRadius2) { return(PortalIntersectResult.INTERSECT_CROSS); } } // no crossing, but might be touching - check distance if (System.Math.Sqrt(System.Math.Abs(mRadius2 - currentDistance2)) <= this.mRadius) { return(PortalIntersectResult.INTERSECT_NO_CROSS); } return(PortalIntersectResult.NO_INTERSECT); } } return(PortalIntersectResult.NO_INTERSECT); }
// --- find nodes which intersect various types of BV's --- public override void FindNodes(AxisAlignedBox t, ref List <PCZSceneNode> list, List <Portal> visitedPortals, bool includeVisitors, bool recurseThruPortals, PCZSceneNode exclude) { // if this zone has an enclosure, check against the enclosure AABB first if (null != mEnclosureNode) { if (!mEnclosureNode.WorldAABB.Intersects(t)) { // AABB of zone does not intersect t, just return. return; } } foreach (PCZSceneNode pczsn in mHomeNodeList) { if (pczsn != exclude) { // make sure node is not already in the list (might have been added in another // zone it was visiting) if (!list.Contains(pczsn)) { bool nsect = t.Intersects(pczsn.WorldAABB); if (nsect) { list.Add(pczsn); } } } } if (includeVisitors) { // check visitor nodes foreach (PCZSceneNode pczsn in mVisitorNodeList) { if (pczsn != exclude) { // make sure node is not already in the list (might have been added in another // zone it was visiting) if (!list.Contains(pczsn)) { bool nsect = t.Intersects(pczsn.WorldAABB); if (nsect) { list.Add(pczsn); } } } } } // if asked to, recurse through portals if (recurseThruPortals) { foreach (Portal portal in mPortals) { // check portal versus bounding box if (portal.intersects(t)) { // make sure portal hasn't already been recursed through if (!visitedPortals.Contains(portal)) { // save portal to the visitedPortals list visitedPortals.Add(portal); // recurse into the connected zone portal.getTargetZone().FindNodes(t, ref list, visitedPortals, includeVisitors, recurseThruPortals, exclude); } } } } }