/* 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);
}