Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 3
0
        // 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);
        }
Ejemplo n.º 4
0
 public void FindObstaclesInBox(AxisAlignedBox box,
                                CollisionTileManager.AddTreeObstaclesCallback callback)
 {
     if (box.Intersects(location))
     {
         callback(speedTree);
     }
 }
Ejemplo n.º 5
0
 /** 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);
     }
 }
Ejemplo n.º 6
0
        /* 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);
        }
Ejemplo n.º 7
0
        // --- 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);
                        }
                    }
                }
            }
        }