void DrawSelectedObject() { if (_lineMaterial == null) { return; } NewBoxCollider box = _selectedObject.GetComponent <NewBoxCollider> (); if (box != null) { DrawCube(box.origin.dots, 1f); DrawCube(box.origin.dots, 1.0005f); DrawCube(box.origin.dots, 1.0006f); DrawCube(box.origin.dots, 1.0007f); DrawCube(box.origin.dots, 1.0008f); return; } NewSphereCollider sphere = _selectedObject.GetComponent <NewSphereCollider> (); if (sphere != null) { DrawSphere(sphere.radius, sphere.transform.position); return; } }
public bool SphereToSphere(NewSphereCollider sphereA, NewSphereCollider sphereB) { // reference https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_collision_detection float distance = Mathf.Sqrt( (sphereA.transform.position.x - sphereB.transform.position.x) * (sphereA.transform.position.x - sphereB.transform.position.x) + (sphereA.transform.position.y - sphereB.transform.position.y) * (sphereA.transform.position.y - sphereB.transform.position.y) + (sphereA.transform.position.z - sphereB.transform.position.z) * (sphereA.transform.position.z - sphereB.transform.position.z)); return(distance < (sphereA.radius + sphereB.radius)); }
public CollisionData SphereToSphereManifold(NewSphereCollider sphereA, NewSphereCollider sphereB) { // reference: https://gamedevelopment.tutsplus.com/tutorials/how-to-create-a-custom-2d-physics-engine-the-basics-and-impulse-resolution--gamedev-6331 // Manifold Initialisation CollisionData manifold = new CollisionData(); manifold.bodyA = sphereA.transform.gameObject.GetComponent <NewRigidBody>(); manifold.bodyB = sphereB.transform.gameObject.GetComponent <NewRigidBody>(); manifold.bodyAobj = sphereA.transform.gameObject; manifold.bodyBobj = sphereB.transform.gameObject; manifold.normal = Vector3.zero; manifold.penetration = 0.0f; // Exit if no collision manifold.wasCollision = SphereToSphere(sphereA, sphereB); if (manifold.wasCollision == false) { return(manifold); } Vector3 relativePosition = sphereB.transform.position - sphereA.transform.position; float distance = Mathf.Sqrt( (sphereA.transform.position.x - sphereB.transform.position.x) * (sphereA.transform.position.x - sphereB.transform.position.x) + (sphereA.transform.position.y - sphereB.transform.position.y) * (sphereA.transform.position.y - sphereB.transform.position.y) + (sphereA.transform.position.z - sphereB.transform.position.z) * (sphereA.transform.position.z - sphereB.transform.position.z)); // Ensure there is a distance to avoid / 0 error manifold.contacts = new List <Vector3>(); if (distance != 0.0f) { manifold.penetration = (sphereA.radius + sphereB.radius) - distance; manifold.normal = relativePosition / distance; manifold.contacts.Add(sphereA.transform.position); } // Avoid / 0 error else { manifold.penetration = sphereA.radius; manifold.normal = new Vector3(0.0f, 1.0f, 0.0f); // Consistent value (randomly chosen) manifold.contacts.Add(manifold.normal * sphereA.radius + sphereA.transform.position); } return(manifold); }
public bool SphereToBox(NewSphereCollider sphere, NewBoxCollider box) { // reference https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_collision_detection // find the closest point on the box to the center of the sphere Vector3 closestPoint = Vector3.zero; closestPoint.x = Mathf.Max(box.minBounds.x, Mathf.Min(sphere.transform.position.x, box.maxBounds.x)); closestPoint.y = Mathf.Max(box.minBounds.y, Mathf.Min(sphere.transform.position.y, box.maxBounds.y)); closestPoint.z = Mathf.Max(box.minBounds.z, Mathf.Min(sphere.transform.position.z, box.maxBounds.z)); // distance between closest point and center of the sphere float distance = Mathf.Sqrt( (closestPoint.x - sphere.transform.position.x) * (closestPoint.x - sphere.transform.position.x) + (closestPoint.y - sphere.transform.position.y) * (closestPoint.y - sphere.transform.position.y) + (closestPoint.z - sphere.transform.position.z) * (closestPoint.z - sphere.transform.position.z)); return(distance < sphere.radius); }
public CollisionData BoxToSphereManifold(NewBoxCollider box, NewSphereCollider sphere) { // reference: https://gamedevelopment.tutsplus.com/tutorials/how-to-create-a-custom-2d-physics-engine-the-basics-and-impulse-resolution--gamedev-6331 // (NOTE reference is in 2d, had to add 3D as well as my own manifold stuff) // Initialise manifold CollisionData manifold = new CollisionData(); manifold.bodyA = box.transform.gameObject.GetComponent <NewRigidBody> (); manifold.bodyB = sphere.transform.gameObject.GetComponent <NewRigidBody> (); manifold.bodyAobj = box.transform.gameObject; manifold.bodyBobj = sphere.transform.gameObject; manifold.normal = Vector3.zero; manifold.penetration = 0.0f; manifold.wasCollision = false; Vector3 relativePosition = sphere.transform.position - box.transform.position; // Closest point on A to center of B Vector3 closestPoint = Vector3.zero; closestPoint.x = Mathf.Max(box.minBounds.x, Mathf.Min(sphere.transform.position.x, box.maxBounds.x)); closestPoint.y = Mathf.Max(box.minBounds.y, Mathf.Min(sphere.transform.position.y, box.maxBounds.y)); closestPoint.z = Mathf.Max(box.minBounds.z, Mathf.Min(sphere.transform.position.z, box.maxBounds.z)); // If Circle is inside Box bool inside = false; if (relativePosition == closestPoint) { inside = true; // Find closest axis if (Mathf.Abs(relativePosition.x) > Mathf.Abs(relativePosition.y) && Mathf.Abs(relativePosition.x) > Mathf.Abs(relativePosition.z)) { // Clamp to closest extent if (closestPoint.x > 0.0f) { closestPoint.x = box.extents.x; } else { closestPoint.x = -box.extents.x; } } // y-axis is shorter else if (Mathf.Abs(relativePosition.y) > Mathf.Abs(relativePosition.z)) { // Clamp to closest extent if (closestPoint.y > 0.0f) { closestPoint.y = box.extents.y; } else { closestPoint.y = -box.extents.y; } } // z-axis is shorter else { // Clamp to closest extent if (closestPoint.z > 0.0f) { closestPoint.z = box.extents.z; } else { closestPoint.z = -box.extents.z; } } } Vector3 normal = sphere.transform.position - closestPoint; float distance = (closestPoint.x - sphere.transform.position.x) * (closestPoint.x - sphere.transform.position.x) + (closestPoint.y - sphere.transform.position.y) * (closestPoint.y - sphere.transform.position.y) + (closestPoint.z - sphere.transform.position.z) * (closestPoint.z - sphere.transform.position.z); // If no collision then return manifold.wasCollision = (Mathf.Sqrt(distance) < sphere.radius); if (manifold.wasCollision == false) { return(manifold); } distance = Mathf.Sqrt(distance); // Flip collision normal if inside if (inside == true) { manifold.normal = Vector3.Normalize(-normal); } else { manifold.normal = Vector3.Normalize(normal); } manifold.penetration = sphere.radius - distance; // Contact point manifold.contacts = new List <Vector3> (); manifold.contacts.Add(closestPoint); return(manifold); }