// check if portal is close to another portal. // Note, both portals are assumed to be stationary // and DerivedCP is the current position. // this function is INTENTIONALLY NOT EXACT because // it is used by PCZSM::connectPortalsToTargetZonesByLocation // which is a utility function to link up nearby portals // public bool closeTo(Portal otherPortal) { // only portals of the same type can be "close to" each other. if (this.mType != otherPortal.Type) { return(false); } bool close = false; switch (this.mType) { default: case PORTAL_TYPE.PORTAL_TYPE_QUAD: { // quad portals must be within 1/4 sphere of each other Sphere quarterSphere1 = this.mDerivedSphere; quarterSphere1.Radius = quarterSphere1.Radius * 0.25f; Sphere quarterSphere2 = otherPortal.getDerivedSphere(); quarterSphere2.Radius = quarterSphere2.Radius * 0.25f; close = quarterSphere1.Intersects(quarterSphere2); } break; case PORTAL_TYPE.PORTAL_TYPE_AABB: // NOTE: AABB's must match perfectly if (this.mDerivedCP == otherPortal.getDerivedCP() && this.mCorners[0] == otherPortal.getCorner(0) && this.mCorners[1] == otherPortal.getCorner(1)) { close = true; } break; case PORTAL_TYPE.PORTAL_TYPE_SPHERE: // NOTE: Spheres must match perfectly if (this.mDerivedCP == otherPortal.getDerivedCP() && this.mRadius == otherPortal.getRadius()) { close = true; } break; } return(close); }
/* 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; }
/* 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); }
// check if portal is close to another portal. // Note, both portals are assumed to be stationary // and DerivedCP is the current position. // this function is INTENTIONALLY NOT EXACT because // it is used by PCZSM::connectPortalsToTargetZonesByLocation // which is a utility function to link up nearby portals // public bool closeTo( Portal otherPortal ) { // only portals of the same type can be "close to" each other. if ( mType != otherPortal.Type ) { return false; } bool close = false; switch ( mType ) { default: case PORTAL_TYPE.PORTAL_TYPE_QUAD: { // quad portals must be within 1/4 sphere of each other Sphere quarterSphere1 = mDerivedSphere; quarterSphere1.Radius = quarterSphere1.Radius * 0.25f; Sphere quarterSphere2 = otherPortal.getDerivedSphere(); quarterSphere2.Radius = quarterSphere2.Radius * 0.25f; close = quarterSphere1.Intersects( quarterSphere2 ); } break; case PORTAL_TYPE.PORTAL_TYPE_AABB: // NOTE: AABB's must match perfectly if ( mDerivedCP == otherPortal.getDerivedCP() && mCorners[ 0 ] == otherPortal.getCorner( 0 ) && mCorners[ 1 ] == otherPortal.getCorner( 1 ) ) { close = true; } break; case PORTAL_TYPE.PORTAL_TYPE_SPHERE: // NOTE: Spheres must match perfectly if ( mDerivedCP == otherPortal.getDerivedCP() && mRadius == otherPortal.getRadius() ) { close = true; } break; } return close; }