public virtual bool sphere_intersects_solid(Sphere checkPos, bool centerCheck) { if (!Sphere.Intersects(checkPos)) { return(false); } var dist = Vector3.Dot(SplittingPlane.Normal, checkPos.Center) + SplittingPlane.D; var reach = checkPos.Radius - PhysicsGlobals.EPSILON; if (dist >= reach) { return(PosNode.sphere_intersects_solid(checkPos, centerCheck)); } if (dist <= -reach) { return(NegNode.sphere_intersects_solid(checkPos, centerCheck)); } if (dist < 0.0f) { if (PosNode.sphere_intersects_solid(checkPos, false)) { return(true); } return(NegNode.sphere_intersects_solid(checkPos, centerCheck)); } else { if (PosNode.sphere_intersects_solid(checkPos, centerCheck)) { return(true); } return(NegNode.sphere_intersects_solid(checkPos, false)); } }
public TransitionState find_collisions(Transition transition, float scale) { var path = transition.SpherePath; var collisions = transition.CollisionInfo; var center = path.LocalSpaceCurrCenter[0].Center; var localSphere = path.LocalSpaceSphere[0]; var movement = localSphere.Center - center; if (path.InsertType == InsertType.Placement || path.ObstructionEthereal) { var clearCell = true; if (path.BuildingCheck) { clearCell = !path.HitsInteriorCell; } if (RootNode.sphere_intersects_solid(localSphere, clearCell)) { return(TransitionState.Collided); } else { return(TransitionState.OK); } } if (path.CheckWalkable) { return(check_walkable(path, localSphere, scale)); } if (path.StepDown) { return(step_sphere_down(transition, localSphere, scale)); } Polygon hitPoly = null; if (path.Collide) { var changed = false; var validPos = new Sphere(localSphere); RootNode.find_walkable(path, validPos, ref hitPoly, movement, path.LocalSpaceZ, ref changed); if (changed) { var offset = validPos.Center - localSphere.Center; var collisionNormal = path.LocalSpacePos.LocalToGlobalVec(offset) * scale; path.AddOffsetToCheckPos(collisionNormal); var contactPlane = hitPoly.Plane.LocalToGlobal(path.CheckPos, path.LocalSpacePos, hitPoly.Plane); contactPlane.D *= scale; collisions.SetContactPlane(contactPlane, false); collisions.ContactPlaneCellID = path.CheckPos.ObjCellID; path.SetWalkable(validPos, hitPoly, path.LocalSpaceZ, path.LocalSpacePos, scale); return(TransitionState.Adjusted); } else { return(TransitionState.OK); } } var contactPoint = Vector3.Zero; var obj = transition.ObjectInfo; if (obj.State.HasFlag(ObjectInfoState.Contact)) { if (RootNode.sphere_intersects_poly(localSphere, movement, ref hitPoly, ref contactPoint)) { return(step_sphere_up(transition, hitPoly.Plane.Normal)); } if (path.NumSphere > 1) { Polygon hitPoly_ = null; var localSphere_ = path.LocalSpaceSphere[1]; if (RootNode.sphere_intersects_poly(localSphere_, movement, ref hitPoly_, ref contactPoint)) { return(slide_sphere(transition, hitPoly_.Plane.Normal)); } if (hitPoly_ != null) { return(NegPolyHit(path, hitPoly_, false)); } if (hitPoly != null) { return(NegPolyHit(path, hitPoly, true)); } } return(TransitionState.OK); } if (RootNode.sphere_intersects_poly(localSphere, movement, ref hitPoly, ref contactPoint) || hitPoly != null) { if (obj.State.HasFlag(ObjectInfoState.PathClipped)) { return(collide_with_pt(transition, localSphere, center, hitPoly, contactPoint, scale)); } var collisionNormal = path.LocalSpacePos.LocalToGlobalVec(hitPoly.Plane.Normal); path.WalkableAllowance = PhysicsGlobals.LandingZ; path.SetCollide(collisionNormal); return(TransitionState.Adjusted); } else if (path.NumSphere > 1) { var localSphere_ = path.LocalSpaceSphere[1]; if (RootNode.sphere_intersects_poly(localSphere_, movement, ref hitPoly, ref contactPoint) || hitPoly != null) { var collisionNormal = path.LocalSpacePos.LocalToGlobalVec(hitPoly.Plane.Normal); collisions.SetCollisionNormal(collisionNormal); return(TransitionState.Collided); } } return(TransitionState.OK); }