/// <summary> /// check if input body has collided with plane /// </summary> /// <param name="body"></param> /// <param name="plane"></param> /// <returns></returns> private MyCollision CollidedWithPlane(MyRigidBody body, MyPlaneCollider plane) { // default to no collision MyCollision collision = null; // get the mesh filter for the plane MeshFilter filter = plane.gameObject.GetComponent<MeshFilter>(); // make sure it has a mesh filter if (filter && filter.mesh.normals.Length > 0) { // get one of the vertext normals --- first one should do as the are all the same var normal = filter.transform.TransformDirection(filter.mesh.normals[0]); // distance of sphere centre from plane float distanceFromSphereCentre = Mathf.Abs(Vector3.Dot(normal, transform.position)) + (plane as MyPlaneCollider).distance; // distance of sphere from plane float distanceFromSphere = distanceFromSphereCentre - distanceToSurface; // check for intersection if (distanceFromSphere < 0) { // create a new collision object, containing the vector of the normal and the distance from the plane collision = new MyCollision(this, plane, new Vector3(transform.position.x, transform.position.y - ((MySphereCollider)body).radius, transform.position.z), normal, distanceFromSphere); } } return collision; }
/// <summary> /// Check the Segment Collision and Remove colliding Cells with there later Generations /// </summary> /// <param name="_cellsToCheck">The List of Cells to Check the Collision with</param> /// <returns></returns> public HashSet <int> CheckCollision(List <Cell> _cellsToCheck) { List <Cell> PolyPolyCheckList = new List <Cell>(); HashSet <int> StreetIDsToRecreate = new HashSet <int>(); //Sphere Sphere Collsion | fast but not precies | Save the Cells that can possible collide for a more precies check for (int i = 0; i < _cellsToCheck.Count; i++) { if (!_cellsToCheck[i].IsBlocked && MyCollision.SphereSphere(m_Center, m_CollisionRadius, _cellsToCheck[i].m_PosCenter, _cellsToCheck[i].m_Radius)) { PolyPolyCheckList.Add(_cellsToCheck[i]); } } //Poly Poly Collision | slow but more precies for (int i = 0; i < PolyPolyCheckList.Count; i++) { if (!PolyPolyCheckList[i].IsBlocked && MyCollision.PolyPoly(PolyPolyCheckList[i].m_Corner, m_CornerPos)) { PolyPolyCheckList[i].Delete(); //Delete the Colliding Cell and the later Generations int id = PolyPolyCheckList[i].m_Street.ID; StreetIDsToRecreate.Add(id); //Saves the Street ID to recreate the Grid Mesh } } return(StreetIDsToRecreate); }
/// <summary> /// Check if the input body has corrected with a sphere /// </summary> /// <param name="body"></param> /// <param name="sphere"></param> /// <returns></returns> private MyCollision CollidedWithSphere(MyRigidBody body, MySphereCollider sphere) { // default to no collision MyCollision collision = null; // combined radius of both spheres float combinedRadius = this.distanceToSurface + ((MySphereCollider)sphere).radius; // the vector between the centres of the spheres Vector3 direction = sphere.transform.position - transform.position; // distance between centres float centreDistance = direction.magnitude; // normalise the direction direction /= centreDistance; // check interection if (centreDistance < combinedRadius) { // create a new collision object, containing the vector of the normal and the distance from the sphere collision = new MyCollision(this, sphere, new Vector3(transform.position.x, transform.position.y - ((MySphereCollider)body).radius, transform.position.z), direction, centreDistance); } return collision; }
private void ChooseNextDirection() { bool col = true; while (col == true) { _direction = GetRandomDirection(_direction); List <int> moveGroupIndicesAfterTurn = _direction.FrontMoveGroup(); int collisionCount = 0; for (int i = 0; i < moveGroupIndicesAfterTurn.Count; i++) { CollisionType obstacle = MyCollision.Check(Cubes[moveGroupIndicesAfterTurn[i]], _direction, MyGameManager.MyGrid); if (obstacle == CollisionType.GridEdge || obstacle == CollisionType.Stone) { Debug.Log("Collided with " + obstacle); collisionCount++; } } if (collisionCount == 0) { col = false; } } }
/// <summary> /// Check if the HitPos is over an Building/Area /// </summary> /// <param name="b"></param> /// <returns></returns> protected bool CheckAreaCollision(out ABuilding b) { List <Area> SphereSphere = new List <Area>(); b = null; foreach (Area area in BuildingManager.m_AllAreas) { if (MyCollision.SphereSphere(new Vector2(m_hitPos.x, m_hitPos.z), 0.8f, new Vector2(area.m_OP.Position.x, area.m_OP.Position.z), area.m_Radius)) { SphereSphere.Add(area); } } if (SphereSphere.Count == 0) { return(false); } else { int index = -1; float closestDistance = float.MaxValue; for (int i = 0; i < SphereSphere.Count; i++) { float distance = Vector3.SqrMagnitude(SphereSphere[i].m_OP.Position - m_hitPos); if (distance < closestDistance) { closestDistance = distance; index = i; } } b = SphereSphere[index].m_Building; return(true); } }
/// <summary> /// Check to see if a collision has occured with any other rigid bodies /// </summary> /// <param name="body"></param> /// <returns></returns> public override MyCollision CheckCollision(MyRigidBody other) { // declare null MyCollision for return MyCollision collision = null; // check for collision with other spheres if(other is MySphereRigidBody && other.name != name) { // combined radius of both spheres float combinedRadius = this.radius + ((MySphereRigidBody)other).radius; // the vector between the centres of the spheres Vector3 direction = other.transform.position - transform.position; // distance between centres float centreDistance = direction.magnitude; // normalise the direction direction /= centreDistance; // check interection if(centreDistance < combinedRadius) { // create a new collision object, containing the vector of the normal and the distance from the sphere collision = new MyCollision(this, other, direction, centreDistance); } } else if(other is MyPlaneRigidBody) //check for collision with a plane { // get the mesh filter for the plane MeshFilter filter = other.gameObject.GetComponent<MeshFilter>(); // make sure it has a mesh filter if (filter && filter.mesh.normals.Length > 0) { // get one of the vertext normals --- first one should do as the are all the same var normal = filter.transform.TransformDirection(filter.mesh.normals[0]); // distance of sphere centre from plane float distanceFromSphereCentre = Mathf.Abs(Vector3.Dot(normal, transform.position)) + (other as MyPlaneRigidBody).distance; // distance of sphere from plane float distanceFromSphere = distanceFromSphereCentre - radius; // check for intersection if (distanceFromSphere < 0) { // create a new collision object, containing the vector of the normal and the distance from the plane collision = new MyCollision(this, other, normal, distanceFromSphere); } } } // return the collision return collision; }
private IEnumerator MineStone() { List <int> moveGroupIndices = _direction.FrontMoveGroup(); List <Direction> minePatternDirection; for (int i = 0; i < moveGroupIndices.Count; i++) { CollisionType obstacle = MyCollision.Check(Cubes[moveGroupIndices[i]], _direction, MyGameManager.MyGrid); if (obstacle == CollisionType.Stone) { int nextX = (int)_direction.DirectionToVector().x + (int)GridTools.GridPosition(Cubes[moveGroupIndices[i]].transform.position).x; int nextY = (int)_direction.DirectionToVector().y + (int)GridTools.GridPosition(Cubes[moveGroupIndices[i]].transform.position).y; if (i == 0) { minePatternDirection = new List <Direction> { _direction.TurnLeft(), _direction.TurnLeft().TurnRight(), _direction.TurnLeft().TurnRight().TurnLeft() }; } else { minePatternDirection = new List <Direction> { _direction.TurnRight(), _direction.TurnRight().TurnLeft(), _direction.TurnRight().TurnLeft().TurnRight() }; } _direction = minePatternDirection[0]; yield return(StartCoroutine(MoveParts(_direction.FrontMoveGroup(), timeToMove))); _direction = minePatternDirection[1]; yield return(StartCoroutine(MoveParts(_direction.FrontMoveGroup(), timeToMove))); yield return(StartCoroutine(MoveParts(_direction.Opposite().FrontMoveGroup(), timeToMove))); yield return(StartCoroutine(MoveParts(_direction.FrontMoveGroup(), timeToMove))); yield return(new WaitForSeconds(2f)); Destroy(MyGameManager.StoneInstances[new Vector2(nextX, nextY)]); MyGameManager.MyGrid.Cells[nextX, nextY] = 0; yield return(StartCoroutine(MoveParts(_direction.Opposite().FrontMoveGroup(), timeToMove))); _direction = minePatternDirection[2]; yield return(StartCoroutine(MoveParts(_direction.Opposite().FrontMoveGroup(), timeToMove))); } } yield return(null); }
/// <summary> /// Deal with floating point errors in the positional calculations /// </summary> /// <param name="collision"></param> public void PositionalCorrection(MyCollision collision) { float percent = 0.2f; // usually 20% to 80% float slop = 0.01f; // usually 0.01 to 0.1 if (collision.bodyA is MyBoxRigidBody || collision.bodyB is MyBoxRigidBody) percent = 0.01f; Vector3 correction = (Mathf.Max(Mathf.Abs(collision.penetration - slop), 0.0f) / (collision.bodyA.inverseMass + collision.bodyB.inverseMass)) * percent * collision.collisionNormal; collision.bodyA.transform.position += collision.bodyA.inverseMass * correction; collision.bodyB.transform.position -= collision.bodyB.inverseMass * correction; }
private static void ResolveInelastic(MyCollision collision) { var A = collision.colliderA; var B = collision.colliderB; var velocity = A.mass / (A.mass + B.mass) * A.velocity + B.mass / (A.mass + B.mass) * B.velocity; A.velocity = velocity; B.velocity = velocity; }
/// <summary> /// Checks whether the current BoundingFrustum intersects the specified Ray. /// </summary> /// <param name="ray">The Ray to check for intersection with.</param> /// <param name="inDistance">The distance at which the ray enters the frustum if there is an intersection and the ray starts outside the frustum.</param> /// <param name="outDistance">The distance at which the ray exits the frustum if there is an intersection.</param> /// <returns><c>true</c> if the current BoundingFrustum intersects the specified Ray.</returns> public bool Intersects(ref MyRay ray, out float?inDistance, out float?outDistance) { if (Contains(ray.Position) != MyContainmentType.Disjoint) { float nearstPlaneDistance = float.MaxValue; for (int i = 0; i < 6; i++) { var plane = GetPlane(i); float distance; if (MyCollision.RayIntersectsPlane(ref ray, ref plane, out distance) && distance < nearstPlaneDistance) { nearstPlaneDistance = distance; } } inDistance = nearstPlaneDistance; outDistance = null; return(true); } else { //We will find the two points at which the ray enters and exists the frustum //These two points make a line which center inside the frustum if the ray intersects it //Or outside the frustum if the ray intersects frustum planes outside it. float minDist = float.MaxValue; float maxDist = float.MinValue; for (int i = 0; i < 6; i++) { var plane = GetPlane(i); float distance; if (MyCollision.RayIntersectsPlane(ref ray, ref plane, out distance)) { minDist = Math.Min(minDist, distance); maxDist = Math.Max(maxDist, distance); } } MyVector3 minPoint = ray.Position + ray.Direction * minDist; MyVector3 maxPoint = ray.Position + ray.Direction * maxDist; MyVector3 center = (minPoint + maxPoint) / 2f; if (Contains(ref center) != MyContainmentType.Disjoint) { inDistance = minDist; outDistance = maxDist; return(true); } else { inDistance = null; outDistance = null; return(false); } } }
/// <summary> /// deal with floating point errors in the positional calculations /// </summary> /// <param name="collision"></param> public void PositionalCorrection(MyCollision collision) { float percent = 0.2f; // usually 20% to 80% float slop = 0.01f; // usually 0.01 to 0.1 if (collision.bodyA is MyBoxCollider || collision.bodyB is MyBoxCollider) percent = 0.01f; Vector3 correction = (Mathf.Max(Mathf.Abs(collision.penetration - slop), 0.0f) / (collision.bodyA.inverseMass + collision.bodyB.inverseMass)) * percent * collision.collisionNormal; collision.bodyA.transform.position += collision.bodyA.inverseMass * correction; //collision.bodyB.transform.position -= collision.bodyB.inverseMass * correction; }
/// <summary> /// Check für Collider with a OverlapSphere /// </summary> /// <returns>return true if another Cell from a diffrent Street ID collid</returns> public bool CheckForCollision() { List<Cell> cellToCheck = new List<Cell>(); List<StreetSegment> segToCheck = new List<StreetSegment>(); List<Cross> crossToCheck = new List<Cross>(); //Sphere Sphere //Cell Cell foreach (Cell c in GridManager.m_AllCells) if (c.ID != this.ID && MyCollision.SphereSphere(this.m_PosCenter, this.m_Radius, c.m_PosCenter, c.m_Radius)) cellToCheck.Add(c); List<StreetComponent> allComponetns = StreetComponentManager.GetAllStreetComponents(); //Cell Segment for (int i = 0; i < allComponetns.Count; i++) { StreetComponent comp = allComponetns[i]; if (comp.ID == this.ID) continue; if (comp is Street) { Street s = (Street)comp; foreach (StreetSegment seg in s.m_Segments) if (MyCollision.SphereSphere(this.m_PosCenter, this.m_Radius, seg.m_Center, seg.m_CollisionRadius)) segToCheck.Add(seg); } else if (comp is Cross) { Cross c = (Cross)comp; if (MyCollision.SphereSphere(this.m_PosCenter, this.m_Radius, c.m_center, 1.7f)) crossToCheck.Add(c); } } //Poly Poly //Cell Cross foreach (Cross c in crossToCheck) if (MyCollision.PolyPoly(this.m_Corner, c.m_corners)) return true; //Cell Segment foreach (StreetSegment seg in segToCheck) if (MyCollision.PolyPoly(this.m_Corner, seg.m_CornerPos)) return true; //Cell Cell foreach (Cell c in cellToCheck) if (MyCollision.PolyPoly(this.m_Corner, c.m_Corner)) return true; return false; }
private MyPlaneIntersectionType PlaneIntersectsPoints(ref MyPlane plane, MyVector3[] points) { var result = MyCollision.PlaneIntersectsPoint(ref plane, ref points[0]); for (int i = 1; i < points.Length; i++) { if (MyCollision.PlaneIntersectsPoint(ref plane, ref points[i]) != result) { return(MyPlaneIntersectionType.Intersecting); } } return(result); }
private void ResolveElastic(MyCollision collision) { var A = collision.colliderA; var B = collision.colliderB; var av = A.velocity - (2 * B.mass) / (A.mass + B.mass) * Vector3.Project(A.velocity - B.velocity, A.transform.position - B.transform.position); var bv = B.velocity - (2 * A.mass) / (A.mass + B.mass) * Vector3.Project(B.velocity - A.velocity, B.transform.position - A.transform.position); A.velocity = av; B.velocity = bv; }
public override void MyOnCollisionEnter(MyCollision c) { // Adjust the velocity of the cannon ball if (c.gameObject.GetComponent <CannonBall>()) { if (gameObject.GetComponent <Renderer>().material.color.a > 0) { CannonBall cb = c.gameObject.GetComponent <CannonBall>(); cb.vx -= vx * 30; cb.vy += vy * 30; cb.GhostDestroy(); } } }
/// <summary> /// Checks for collisions with other bodies /// </summary> /// <param name="other"></param> /// <returns></returns> public MyCollision CheckCollision(MyRigidBody other) { // no collision by default MyCollision collision = null; // only check for collisions on bodies that we are interested in switch (this.RigidBodyType) { case global::RigidBodyType.SOLID_SPHERE: case global::RigidBodyType.HOLLOW_SPHERE: case global::RigidBodyType.SOLID_BOX: collision = Collided(this, other); break; default: break; } return collision; }
/// <summary> /// Determines whether there is an intersection between a <see cref="MyRay"/> and a <see cref="MyOrientedBoundingBox"/>. /// </summary> /// <param name="ray">The ray to test.</param> /// <param name="point">When the method completes, contains the point of intersection, /// or <see cref="MyVector3.Zero"/> if there was no intersection.</param> /// <returns>Whether the two objects intersected.</returns> public bool Intersects(ref MyRay ray, out MyVector3 point) { // Put ray in box space MyMatrix invTrans; MyMatrix.Invert(ref Transformation, out invTrans); MyRay bRay; MyVector3.TransformNormal(ref ray.Direction, ref invTrans, out bRay.Direction); MyVector3.TransformCoordinate(ref ray.Position, ref invTrans, out bRay.Position); //Perform a regular ray to BoundingBox check var bb = new MyBoundingBox(-Extents, Extents); var intersects = MyCollision.RayIntersectsBox(ref bRay, ref bb, out point); //Put the result intersection back to world if (intersects) MyVector3.TransformCoordinate(ref point, ref Transformation, out point); return intersects; }
private MyCollision Collided(MyRigidBody object1, MyRigidBody object2) { MyCollision collision = null; switch(object2.RigidBodyType) { case global::RigidBodyType.PLANE: collision = CollidedWithPlane(object1, object2 as MyPlaneCollider); break; case global::RigidBodyType.SOLID_SPHERE: case global::RigidBodyType.HOLLOW_SPHERE: collision = CollidedWithSphere(object1, object2 as MySphereCollider); break; case global::RigidBodyType.SOLID_BOX: collision = CollidedWithBox(object1, object2 as MyBoxCollider); break; default: break; } return collision; }
public void CheckGridCollision() { m_center = new Vector2(transform.position.x, transform.position.z); m_corners[0] = m_center + new Vector2(1.2f, 1.2f); m_corners[1] = m_center + new Vector2(-1.2f, 1.2f); m_corners[2] = m_center + new Vector2(-1.2f, -1.2f); m_corners[3] = m_center + new Vector2(1.2f, -1.2f); HashSet <int> StreetsToRecreate = new HashSet <int>(); List <Cell> PolyPolyCheckList = new List <Cell>(); List <Cell> CellsToCheck = GridManager.m_AllCells; //Sphere Sphere Coll for (int i = 0; i < CellsToCheck.Count; i++) { if (MyCollision.SphereSphere(m_center, 1.7f, CellsToCheck[i].m_PosCenter, CellsToCheck[i].m_Radius)) { PolyPolyCheckList.Add(CellsToCheck[i]); } } //Poly Poly Coll for (int i = 0; i < PolyPolyCheckList.Count; i++) { if (MyCollision.PolyPoly(PolyPolyCheckList[i].m_Corner, m_corners)) { PolyPolyCheckList[i].Delete(); int id = PolyPolyCheckList[i].m_Street.ID; StreetsToRecreate.Add(id); } } //Recreate Grid foreach (int i in StreetsToRecreate) { Street s = StreetComponentManager.GetStreetByID(i); GridManager.RemoveGridMesh(s); MeshGenerator.CreateGridMesh(s, s.m_GridObj.GetComponent <MeshFilter>(), s.m_GridRenderer); } }
/// <summary> /// Determines the intersection relationship between the frustum and a bounding box. /// </summary> /// <param name="box">The box.</param> /// <returns>Type of the containment</returns> public MyContainmentType Contains(ref MyBoundingBox box) { MyVector3 p, n; MyPlane plane; var result = MyContainmentType.Contains; for (int i = 0; i < 6; i++) { plane = GetPlane(i); GetBoxToPlanePVertexNVertex(ref box, ref plane.Normal, out p, out n); if (MyCollision.PlaneIntersectsPoint(ref plane, ref p) == MyPlaneIntersectionType.Back) { return(MyContainmentType.Disjoint); } if (MyCollision.PlaneIntersectsPoint(ref plane, ref n) == MyPlaneIntersectionType.Back) { result = MyContainmentType.Intersects; } } return(result); }
public override void MyOnCollisionEnter(MyCollision c) { if (c.gameObject.GetComponent <Ground>()) { Debug.Log("I hit the ground"); DestroySelf(); } if (c.gameObject.GetComponent <Stonehenge>()) { Stonehenge stonehenge = c.gameObject.GetComponent <Stonehenge>(); if (transform.position.y > c.gameObject.transform.position.y + 0.2f) // Top collision { Debug.Log("Top collision"); vy = Mathf.Abs(vy - (gravity * elapsedTime)) * restitution; elapsedTime = 0; } else // Side collision { vx = -vx * restitution; } } }
/// <summary> /// Get the distance which when added to camera position along the lookat direction will do the effect of zoom to extents (zoom to fit) operation, /// so all the passed points will fit in the current view. /// if the returned value is positive, the camera will move toward the lookat direction (ZoomIn). /// if the returned value is negative, the camera will move in the reverse direction of the lookat direction (ZoomOut). /// </summary> /// <param name="points">The points.</param> /// <returns>The zoom to fit distance</returns> public float GetZoomToExtentsShiftDistance(MyVector3[] points) { float vAngle = (float)((Math.PI / 2.0 - Math.Acos(MyVector3.Dot(pNear.Normal, pTop.Normal)))); float vSin = (float)Math.Sin(vAngle); float hAngle = (float)((Math.PI / 2.0 - Math.Acos(MyVector3.Dot(pNear.Normal, pLeft.Normal)))); float hSin = (float)Math.Sin(hAngle); float horizontalToVerticalMapping = vSin / hSin; var ioFrustrum = GetInsideOutClone(); float maxPointDist = float.MinValue; for (int i = 0; i < points.Length; i++) { float pointDist = MyCollision.DistancePlanePoint(ref ioFrustrum.pTop, ref points[i]); pointDist = Math.Max(pointDist, MyCollision.DistancePlanePoint(ref ioFrustrum.pBottom, ref points[i])); pointDist = Math.Max(pointDist, MyCollision.DistancePlanePoint(ref ioFrustrum.pLeft, ref points[i]) * horizontalToVerticalMapping); pointDist = Math.Max(pointDist, MyCollision.DistancePlanePoint(ref ioFrustrum.pRight, ref points[i]) * horizontalToVerticalMapping); maxPointDist = Math.Max(maxPointDist, pointDist); } return(-maxPointDist / vSin); }
/// <summary> /// Determines if there is an intersection between the current object and a triangle. /// </summary> /// <param name="vertex1">The first vertex of the triangle to test.</param> /// <param name="vertex2">The second vertex of the triangle to test.</param> /// <param name="vertex3">The third vertex of the triangle to test.</param> /// <returns>Whether the two objects intersected.</returns> public bool Intersects(ref MyVector3 vertex1, ref MyVector3 vertex2, ref MyVector3 vertex3) { return(MyCollision.SphereIntersectsTriangle(ref this, ref vertex1, ref vertex2, ref vertex3)); }
/// <summary> /// Determines if there is an intersection between the current object and a <see cref="MyRay"/>. /// </summary> /// <param name="ray">The ray to test.</param> /// <returns>Whether the two objects intersected.</returns> public bool Intersects(ref MyRay ray) { float distance; return(MyCollision.RayIntersectsSphere(ref ray, ref this, out distance)); }
/// <summary> /// Determines whether the current objects contains a <see cref="MyBoundingSphere"/>. /// </summary> /// <param name="sphere">The sphere to test.</param> /// <returns>The type of containment the two objects have.</returns> public MyContainmentType Contains(ref MyBoundingSphere sphere) { return(MyCollision.SphereContainsSphere(ref this, ref sphere)); }
/// <summary> /// Determines whether the current objects contains a <see cref="MyBoundingBox"/>. /// </summary> /// <param name="box">The box to test.</param> /// <returns>The type of containment the two objects have.</returns> public MyContainmentType Contains(ref MyBoundingBox box) { return(MyCollision.SphereContainsBox(ref this, ref box)); }
/// <summary> /// Determines whether the current objects contains a triangle. /// </summary> /// <param name="vertex1">The first vertex of the triangle to test.</param> /// <param name="vertex2">The second vertex of the triangle to test.</param> /// <param name="vertex3">The third vertex of the triangle to test.</param> /// <returns>The type of containment the two objects have.</returns> public MyContainmentType Contains(ref MyVector3 vertex1, ref MyVector3 vertex2, ref MyVector3 vertex3) { return(MyCollision.SphereContainsTriangle(ref this, ref vertex1, ref vertex2, ref vertex3)); }
/// <summary> /// Determines whether the current objects contains a point. /// </summary> /// <param name="point">The point to test.</param> /// <returns>The type of containment the two objects have.</returns> public MyContainmentType Contains(ref MyVector3 point) { return(MyCollision.SphereContainsPoint(ref this, ref point)); }
/// <summary> /// Determines if there is an intersection between the current object and a <see cref="MyBoundingSphere"/>. /// </summary> /// <param name="sphere">The sphere to test.</param> /// <returns>Whether the two objects intersected.</returns> public bool Intersects(ref MyBoundingSphere sphere) { return(MyCollision.SphereIntersectsSphere(ref this, ref sphere)); }
/// <summary> /// Determines if there is an intersection between the current object and a <see cref="MyBoundingBox"/>. /// </summary> /// <param name="box">The box to test.</param> /// <returns>Whether the two objects intersected.</returns> public bool Intersects(ref MyBoundingBox box) { return(MyCollision.BoxIntersectsSphere(ref box, ref this)); }
/// <summary> /// Resolves a collision between this and another rigid body /// </summary> /// <param name="body"></param> public void ResolveCollision(MyCollision collision) { if ((collision.bodyA is MyPlaneRigidBody && (collision.bodyB is MySphereRigidBody || collision.bodyB is MyBoxRigidBody)) || ((collision.bodyA is MySphereRigidBody || collision.bodyA is MyBoxRigidBody) && collision.bodyB is MyPlaneRigidBody)) { // Calculate relative velocity Vector3 relativeVelocity = collision.bodyA.velocity - collision.bodyB.velocity; // Calculate relative velocity in terms of the normal direction float velocityAlongNormal = Vector3.Dot(relativeVelocity, collision.collisionNormal); // Do not resolve if velocities are separating if (velocityAlongNormal > 0) return; // Calculate restitution float e = Mathf.Min(collision.bodyA.restitution, collision.bodyB.restitution); // Calculate impulse scalar float j = -(1 + e) * velocityAlongNormal; j /= collision.bodyA.inverseMass + collision.bodyB.inverseMass; // Apply impulse Vector3 impulse = j * collision.collisionNormal; collision.bodyA.velocity += collision.bodyA.inverseMass * impulse; collision.bodyB.velocity -= collision.bodyB.inverseMass * impulse; // recalcuate the relative velocity relativeVelocity = collision.bodyA.velocity - collision.bodyB.velocity; // get the tangent vector Vector3 tangent = Vector3.Dot(relativeVelocity, collision.collisionNormal) * collision.collisionNormal; tangent.Normalize(); // get the magnitude of the force along the friction vactor float jt = -Vector3.Dot(relativeVelocity, tangent); jt /= collision.bodyA.inverseMass + collision.bodyB.inverseMass; // get average coefficioent of friciotn in collision float mu = (collision.bodyA.staticFriction + collision.bodyB.staticFriction) / 2; // Clamp magnitude of friction and create impulse vector Vector3 frictionImpulse; if(Mathf.Abs( jt ) < j * mu) frictionImpulse = jt * tangent; else { dynamicFriction = (collision.bodyA.dynamicFriction + collision.bodyB.dynamicFriction) / 2; frictionImpulse = -j * tangent * dynamicFriction;; } // Apply collision.bodyA.velocity += collision.bodyA.inverseMass * frictionImpulse; collision.bodyB.velocity -= collision.bodyB.inverseMass * frictionImpulse; // correct the position PositionalCorrection(collision); } if (collision.bodyA is MySphereRigidBody && collision.bodyB is MySphereRigidBody) { // Calculate relative velocity Vector3 relativeVelocity = collision.bodyB.velocity - collision.bodyA.velocity; // Calculate relative velocity in terms of the normal direction float velocityAlongNormal = Vector3.Dot(relativeVelocity, collision.collisionNormal); // Do not resolve if velocities are separating if (velocityAlongNormal > 0) return; // Calculate restitution float e = Mathf.Min(collision.bodyA.restitution, collision.bodyB.restitution); // Calculate impulse scalar float j = -(1 + e) * velocityAlongNormal; j /= collision.bodyA.inverseMass + collision.bodyB.inverseMass; // Apply impulse Vector3 impulse = j * collision.collisionNormal; collision.bodyA.velocity -= collision.bodyA.inverseMass * impulse; collision.bodyB.velocity += collision.bodyB.inverseMass * impulse; // recalcuate the relative velocity relativeVelocity = collision.bodyA.velocity - collision.bodyB.velocity; // get the tangent vector Vector3 tangent = Vector3.Dot(relativeVelocity, collision.collisionNormal) * collision.collisionNormal; tangent.Normalize(); // get the magnitude of the force along the friction vactor float jt = -Vector3.Dot(relativeVelocity, tangent); jt /= collision.bodyA.inverseMass + collision.bodyB.inverseMass; // get average coefficioent of friciotn in collision float mu = (collision.bodyA.staticFriction + collision.bodyB.staticFriction) / 2; // Clamp magnitude of friction and create impulse vector Vector3 frictionImpulse; if (Mathf.Abs(jt) < j * mu) frictionImpulse = jt * tangent; else { dynamicFriction = (collision.bodyA.dynamicFriction + collision.bodyB.dynamicFriction) / 2; frictionImpulse = -j * tangent * dynamicFriction; ; } // Apply collision.bodyA.velocity -= collision.bodyA.inverseMass * frictionImpulse; collision.bodyB.velocity += collision.bodyB.inverseMass * frictionImpulse; } }
/// <summary> /// Determines if there is an intersection between the current object and a <see cref="MyPlane"/>. /// </summary> /// <param name="plane">The plane to test.</param> /// <returns>Whether the two objects intersected.</returns> public MyPlaneIntersectionType Intersects(ref MyPlane plane) { return(MyCollision.PlaneIntersectsSphere(ref plane, ref this)); }
/// <summary> /// Determines if there is an intersection between the current object and a <see cref="MyRay"/>. /// </summary> /// <param name="ray">The ray to test.</param> /// <param name="point">When the method completes, contains the point of intersection, /// or <see cref="MyVector3.Zero"/> if there was no intersection.</param> /// <returns>Whether the two objects intersected.</returns> public bool Intersects(ref MyRay ray, out MyVector3 point) { return(MyCollision.RayIntersectsSphere(ref ray, ref this, out point)); }