private static Intersection TestIntersectionSphereSphere(Hitbox caller, Hitbox collider, Vector3 offsetCaller) { Intersection i = null; Vector3 diff = collider.GetCenter() - (caller.GetCenter() + offsetCaller); float diffLength = diff.LengthFast; float radiusCaller = caller.Owner.Scale.X / 2; float radiusCollider = collider.Owner.Scale.X / 2; float diffCollision = diffLength - (radiusCollider + radiusCaller); if (diffCollision < 0) { // collision detected! diff.NormalizeFast(); Vector3 mtv = diff * diffCollision; Vector3 mtvUp = new Vector3(0, (caller.GetCenter() + offsetCaller).Y >= collider.GetCenter().Y ? -diffCollision : diffCollision, 0); // approximated! Vector3 collisionSurfaceNormal = Vector3.NormalizeFast((caller.GetCenter() + offsetCaller) - collider.GetCenter()); i = new Intersection(collider.Owner, caller, collider, mtv, mtvUp, "KWSphere", collisionSurfaceNormal); return(i); } return(i); }
/// <summary> /// Berechnet das Volumen der Kollision (wie viel von Objekt B schneidet sich mit Objekt A?) /// </summary> /// <returns>IntersectionVolume-Instanz mit genaueren Angaben zum Volumen</returns> public IntersectionVolume CalculateVolume() { if (mHitboxCaller.Owner.IsSpherePerfect()) { mHitboxCaller.UpdateSphereForClipping(); } if (mHitboxCollider.Owner.IsSpherePerfect()) { mHitboxCollider.UpdateSphereForClipping(); } List <Vector3> volumeVertices = Hitbox.ClipFaces(mHitboxCaller, mHitboxCollider); volumeVertices.AddRange(Hitbox.ClipFaces(mHitboxCollider, mHitboxCaller)); if (volumeVertices.Count > 0) { IntersectionVolume volume = new IntersectionVolume(volumeVertices, mHitboxCaller.GetCenter()); return(volume); } else { IntersectionVolume volume = new IntersectionVolume(); return(volume); } }
private static Intersection TestIntersectionConvexHullSphere(Hitbox caller, Hitbox collider, Vector3 offsetCaller) { float mtvDistance = float.MaxValue; float mtvDirection = 1; float mtvDistanceUp = float.MaxValue; float mtvDirectionUp = 1; MTVTemp = Vector3.Zero; MTVTempUp = Vector3.Zero; bool useSphereNormal = false; float sphereRadius = collider.Owner.Scale.X / 2; Vector3 collisionSurfaceNormal = new Vector3(0, 0, 0); float shape1Min, shape1Max, shape2Min, shape2Max; for (int i = 0; i < caller.mNormals.Length; i++) { SatTest(ref caller.mNormals[i], ref caller.mVertices, out shape1Min, out shape1Max, ref ZeroVector); shape2Min = Vector3.Dot(collider.GetCenter() - caller.mNormals[i] * sphereRadius, caller.mNormals[i]); shape2Max = Vector3.Dot(collider.GetCenter() + caller.mNormals[i] * sphereRadius, caller.mNormals[i]); if (!Overlaps(shape1Min, shape1Max, shape2Min, shape2Max)) { return(null); } else { bool m = CalculateOverlap(ref caller.mNormals[i], ref shape1Min, ref shape1Max, ref shape2Min, ref shape2Max, ref mtvDistance, ref mtvDistanceUp, ref MTVTemp, ref MTVTempUp, ref mtvDirection, ref mtvDirectionUp, ref caller.mCenter, ref collider.mCenter, ref offsetCaller); if (m) { collisionSurfaceNormal = Vector3.NormalizeFast((caller.mCenter + offsetCaller) - collider.mCenter); } } } //collider is sphere: Vector3 sphereToHullDirectionVector = Vector3.NormalizeFast((caller.GetCenter() + offsetCaller) - collider.GetCenter()); SatTest(ref sphereToHullDirectionVector, ref caller.mVertices, out shape1Min, out shape1Max, ref offsetCaller); shape2Min = Vector3.Dot(collider.GetCenter() - sphereToHullDirectionVector * sphereRadius, sphereToHullDirectionVector); shape2Max = Vector3.Dot(collider.GetCenter() + sphereToHullDirectionVector * sphereRadius, sphereToHullDirectionVector); if (!Overlaps(shape1Min, shape1Max, shape2Min, shape2Max)) { return(null); } else { bool m = CalculateOverlap(ref sphereToHullDirectionVector, ref shape1Min, ref shape1Max, ref shape2Min, ref shape2Max, ref mtvDistance, ref mtvDistanceUp, ref MTVTemp, ref MTVTempUp, ref mtvDirection, ref mtvDirectionUp, ref caller.mCenter, ref collider.mCenter, ref offsetCaller); if (m) { useSphereNormal = true; } } if (MTVTemp == Vector3.Zero) { return(null); } Intersection o = new Intersection(collider.Owner, caller, collider, MTVTemp, MTVTempUp, collider.mMesh.Name, useSphereNormal ? sphereToHullDirectionVector : collisionSurfaceNormal); return(o); }
private static Intersection TestIntersectionSphereConvexHull(Hitbox caller, Hitbox collider, Vector3 offsetCaller) { float mtvDistance = float.MaxValue; float mtvDirection = 1; float mtvDistanceUp = float.MaxValue; float mtvDirectionUp = 1; MTVTemp = Vector3.Zero; MTVTempUp = Vector3.Zero; float sphereRadius = caller.Owner.Scale.X / 2; int bestCollisionIndex = 0; float shape1Min, shape1Max, shape2Min, shape2Max; for (int i = 0; i < collider.mNormals.Length; i++) { shape1Min = Vector3.Dot((caller.GetCenter() + offsetCaller) - collider.mNormals[i] * sphereRadius, collider.mNormals[i]); shape1Max = Vector3.Dot((caller.GetCenter() + offsetCaller) + collider.mNormals[i] * sphereRadius, collider.mNormals[i]); SatTest(ref collider.mNormals[i], ref collider.mVertices, out shape2Min, out shape2Max, ref ZeroVector); if (!Overlaps(shape1Min, shape1Max, shape2Min, shape2Max)) { return(null); } else { bool m = CalculateOverlap(ref collider.mNormals[i], ref shape1Min, ref shape1Max, ref shape2Min, ref shape2Max, ref mtvDistance, ref mtvDistanceUp, ref MTVTemp, ref MTVTempUp, ref mtvDirection, ref mtvDirectionUp, ref caller.mCenter, ref collider.mCenter, ref offsetCaller); if (m) { bestCollisionIndex = i; } } } Vector3 hullToSphereDirectionVector = Vector3.NormalizeFast((caller.GetCenter() + offsetCaller) - collider.GetCenter()); shape1Min = Vector3.Dot((caller.GetCenter() + offsetCaller) - hullToSphereDirectionVector * sphereRadius, hullToSphereDirectionVector); shape1Max = Vector3.Dot((caller.GetCenter() + offsetCaller) + hullToSphereDirectionVector * sphereRadius, hullToSphereDirectionVector); SatTest(ref hullToSphereDirectionVector, ref collider.mVertices, out shape2Min, out shape2Max, ref ZeroVector); if (!Overlaps(shape1Min, shape1Max, shape2Min, shape2Max)) { return(null); } else { bool m = CalculateOverlap(ref hullToSphereDirectionVector, ref shape1Min, ref shape1Max, ref shape2Min, ref shape2Max, ref mtvDistance, ref mtvDistanceUp, ref MTVTemp, ref MTVTempUp, ref mtvDirection, ref mtvDirectionUp, ref caller.mCenter, ref collider.mCenter, ref offsetCaller); if (m) { bestCollisionIndex = -100; } } if (MTVTemp == Vector3.Zero) { return(null); } Intersection o = new Intersection(collider.Owner, caller, collider, MTVTemp, MTVTempUp, collider.mMesh.Name, bestCollisionIndex == -100 ? hullToSphereDirectionVector : collider.mNormals[bestCollisionIndex]); return(o); }