Example #1
0
		//----------------------------------------------------------------------------
		public bool Intersects( Capsule capsule )
		{
			float fDist = Distance( capsule.Segment );
			return fDist <= capsule.Radius;
		}
Example #2
0
		//----------------------------------------------------------------------------
		public bool Intersects( Capsule otherCapsule )
		{
			Real fDistance = mSegment.Distance( otherCapsule.mSegment );
			Real fRSum = mRadius + otherCapsule.mRadius;
			return fDistance <= fRSum;
		}
Example #3
0
        //----------------------------------------------------------------------------
        public bool Intersects(Capsule capsule)
        {
            float fDist = Distance(capsule.Segment);

            return(fDist <= capsule.Radius);
        }
Example #4
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);
        }
Example #5
0
        /* This function check if *this* portal "crossed over" the other portal.
         */

        public bool crossedPortal(Portal otherPortal)
        {
            // Only check if portal is open
            if (otherPortal.mOpen)
            {
                // we model both portals as line swept spheres (mPrevDerivedCP to mDerivedCP).
                // intersection test is then between the capsules.
                // BUGBUG! This routine needs to check for case where one or both objects
                //         don't move - resulting in simple sphere tests
                // BUGBUG! If one (or both) portals are aabb's this is REALLY not accurate.
                Capsule portalCapsule, otherPortalCapsule;

                portalCapsule = new Capsule();
                portalCapsule.Set(getPrevDerivedCP(), getDerivedCP(), getRadius());

                otherPortalCapsule = new Capsule();
                otherPortalCapsule.Set(otherPortal.mPrevDerivedCP, otherPortal.mDerivedCP, otherPortal.mRadius);

                if (portalCapsule.Intersects(otherPortalCapsule))
                {
                    // the portal intersected the other portal at some time from last frame to this frame.
                    // Now check if this portal "crossed" the other portal
                    switch (otherPortal.Type)
                    {
                    case PORTAL_TYPE.PORTAL_TYPE_QUAD:
                        // a crossing occurs if the "side" of the final position of this portal compared
                        // to the final position of the other portal is negative AND the initial position
                        // of this portal compared to the initial position of the other portal is non-negative
                        // NOTE: This function assumes that this portal is the smaller portal potentially crossing
                        //       over the otherPortal which is larger.
                        if (otherPortal.getDerivedPlane().GetSide(this.mDerivedCP) == PlaneSide.Negative &&
                            otherPortal.getPrevDerivedPlane().GetSide(this.mPrevDerivedCP) != PlaneSide.Negative)
                        {
                            // crossing occurred!
                            return(true);
                        }
                        break;

                    case 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(otherPortal.getDerivedCorner(0), otherPortal.getDerivedCorner(1));
                        //bool previousInside = aabb.contains(mPrevDerivedCP);
                        bool currentInside = aabb.Contains(this.mDerivedCP);
                        if (otherPortal.getDerivedDirection() == Vector3.UnitZ)
                        {
                            // portal norm is "outward" pointing, look for going from outside to inside
                            //if (previousInside == false &&
                            if (currentInside == true)
                            {
                                return(true);
                            }
                        }
                        else
                        {
                            // portal norm is "inward" pointing, look for going from inside to outside
                            //if (previousInside == true &&
                            if (currentInside == false)
                            {
                                return(true);
                            }
                        }
                    }
                    break;

                    case PORTAL_TYPE.PORTAL_TYPE_SPHERE:
                    {
                        // 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(otherPortal->getPrevDerivedCP());
                        Real currentDistance2 = this.mDerivedCP.DistanceSquared(otherPortal.getDerivedCP());
                        Real mRadius2         = System.Math.Sqrt(otherPortal.getRadius());
                        if (otherPortal.getDerivedDirection() == Vector3.UnitZ)
                        {
                            // portal norm is "outward" pointing, look for going from outside to inside
                            //if (previousDistance2 >= mRadius2 &&
                            if (currentDistance2 < mRadius2)
                            {
                                return(true);
                            }
                        }
                        else
                        {
                            // portal norm is "inward" pointing, look for going from inside to outside
                            //if (previousDistance2 < mRadius2 &&
                            if (currentDistance2 >= mRadius2)
                            {
                                return(true);
                            }
                        }
                    }
                    break;
                    }
                }
            }
            // there was no crossing of the portal by this portal. It might be touching
            // the other portal (but we don't care currently)
            return(false);
        }
Example #6
0
		/* This function check if *this* portal "crossed over" the other portal.
		*/
		public bool crossedPortal( Portal otherPortal )
		{
			// Only check if portal is open
			if ( otherPortal.mOpen )
			{
				// we model both portals as line swept spheres (mPrevDerivedCP to mDerivedCP).
				// intersection test is then between the capsules.
				// BUGBUG! This routine needs to check for case where one or both objects
				//         don't move - resulting in simple sphere tests
				// BUGBUG! If one (or both) portals are aabb's this is REALLY not accurate.
				Capsule portalCapsule, otherPortalCapsule;

				portalCapsule = new Capsule();
				portalCapsule.Set( this.getPrevDerivedCP(), this.getDerivedCP(), this.getRadius() );

				otherPortalCapsule = new Capsule();
				otherPortalCapsule.Set( otherPortal.mPrevDerivedCP,
									   otherPortal.mDerivedCP,
									   otherPortal.mRadius );

				if ( portalCapsule.Intersects( otherPortalCapsule ) )
				{
					// the portal intersected the other portal at some time from last frame to this frame.
					// Now check if this portal "crossed" the other portal
					switch ( otherPortal.Type )
					{
						case PORTAL_TYPE.PORTAL_TYPE_QUAD:
							// a crossing occurs if the "side" of the final position of this portal compared
							// to the final position of the other portal is negative AND the initial position
							// of this portal compared to the initial position of the other portal is non-negative
							// NOTE: This function assumes that this portal is the smaller portal potentially crossing
							//       over the otherPortal which is larger.
							if ( otherPortal.getDerivedPlane().GetSide( mDerivedCP ) == PlaneSide.Negative &&
								otherPortal.getPrevDerivedPlane().GetSide( mPrevDerivedCP ) != PlaneSide.Negative )
							{
								// crossing occurred!
								return true;
							}
							break;
						case 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.
								AxisAlignedBox aabb = new AxisAlignedBox( otherPortal.getDerivedCorner( 0 ), otherPortal.getDerivedCorner( 1 ) );
								//bool previousInside = aabb.contains(mPrevDerivedCP);
								bool currentInside = aabb.Contains( mDerivedCP );
								if ( otherPortal.getDerivedDirection() == Vector3.UnitZ )
								{
									// portal norm is "outward" pointing, look for going from outside to inside
									//if (previousInside == false &&
									if ( currentInside == true )
									{
										return true;
									}
								}
								else
								{
									// portal norm is "inward" pointing, look for going from inside to outside
									//if (previousInside == true &&
									if ( currentInside == false )
									{
										return true;
									}
								}
							}
							break;
						case PORTAL_TYPE.PORTAL_TYPE_SPHERE:
							{
								// 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(otherPortal->getPrevDerivedCP());
								Real currentDistance2 = mDerivedCP.DistanceSquared( otherPortal.getDerivedCP() );
								Real mRadius2 = System.Math.Sqrt( otherPortal.getRadius() );
								if ( otherPortal.getDerivedDirection() == Vector3.UnitZ )
								{
									// portal norm is "outward" pointing, look for going from outside to inside
									//if (previousDistance2 >= mRadius2 &&
									if ( currentDistance2 < mRadius2 )
									{
										return true;
									}
								}
								else
								{
									// portal norm is "inward" pointing, look for going from inside to outside
									//if (previousDistance2 < mRadius2 &&
									if ( currentDistance2 >= mRadius2 )
									{
										return true;
									}
								}
							}
							break;
					}
				}
			}
			// there was no crossing of the portal by this portal. It might be touching
			// the other portal (but we don't care currently)
			return false;
		}
Example #7
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 ( mOpen )
			{
				if ( pczsn == 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 ( 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.
					Segment nodeSegment = new Segment();
					nodeSegment.Set( pczsn.PreviousPosition, pczsn.DerivedPosition );

					// we model the portal as a line swept sphere (mPrevDerivedCP to mDerivedCP).
					Capsule portalCapsule = new Capsule();
					portalCapsule.Set( mPrevDerivedCP, mDerivedCP, 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 ( mDerivedPlane.GetSide( pczsn.DerivedPosition ) == PlaneSide.Negative &&
							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;
							Vector3 portalBox = new Vector3( mRadius, mRadius, mRadius );
							portalBox.Floor( nodeHalfVector );
							if ( portalBox.x < 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 ( mDerivedSphere.Intersects( pczsn.WorldAABB ) &&
						mDerivedPlane.GetSide( pczsn.WorldAABB ) == PlaneSide.Both )
					{
						// intersection but no crossing
						// note this means that the node is CURRENTLY touching the portal.
						if ( 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 ( 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.
					AxisAlignedBox aabb = new AxisAlignedBox( mDerivedCorners[ 0 ], mDerivedCorners[ 1 ] );
					//bool previousInside = aabb.contains(pczsn->getPrevPosition());
					bool currentInside = aabb.Contains( pczsn.DerivedPosition );
					if ( 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 = mDerivedCP.DistanceSquared( pczsn.DerivedPosition );
					Real mRadius2 = mRadius * mRadius;
					if ( 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 ) ) <= mRadius )
					{
						return PortalIntersectResult.INTERSECT_NO_CROSS;
					}
					return PortalIntersectResult.NO_INTERSECT;
				}
			}
			return PortalIntersectResult.NO_INTERSECT;

		}