Browse Source

Added ray-sphere collision detection

victorfisac 9 years ago
parent
commit
fcd30c5649
2 changed files with 38 additions and 1 deletions
  1. 36 1
      src/models.c
  2. 2 0
      src/raylib.h

+ 36 - 1
src/models.c

@@ -1341,7 +1341,42 @@ bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius
 {
     bool collision = false;
     
-    // TODO: implement collision...
+    Vector3 raySpherePos = VectorSubtract(spherePosition, ray.position);
+    float distance = VectorLength(raySpherePos);
+    float vector = VectorDotProduct(raySpherePos, ray.direction);
+    float d = sphereRadius*sphereRadius - (distance*distance - vector*vector);
+    
+    if(d >= 0.0f) collision = true;
+    
+    return collision;
+}
+
+// Detect collision between ray and sphere with extended parameters and collision point detection
+bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius, Vector3 *collisionPoint)
+{
+    bool collision = false;
+    
+    Vector3 raySpherePos = VectorSubtract(spherePosition, ray.position);
+    float distance = VectorLength(raySpherePos);
+    float vector = VectorDotProduct(raySpherePos, ray.direction);
+    float d = sphereRadius*sphereRadius - (distance*distance - vector*vector);
+    
+    if(d >= 0.0f) collision = true;
+    
+    // Calculate collision point
+    Vector3 offset = ray.direction;
+    float collisionDistance = 0;
+    
+    // Check if ray origin is inside the sphere to calculate the correct collision point
+    if(distance < sphereRadius) collisionDistance = vector + sqrt(d);
+    else collisionDistance = vector - sqrt(d);
+    
+    VectorScale(&offset, collisionDistance);
+    Vector3 cPoint = VectorAdd(ray.position, offset);
+    
+    collisionPoint->x = cPoint.x;
+    collisionPoint->y = cPoint.y;
+    collisionPoint->z = cPoint.z;
     
     return collision;
 }

+ 2 - 0
src/raylib.h

@@ -770,6 +770,8 @@ void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vec
 bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB);                     // Detect collision between two spheres
 bool CheckCollisionBoxes(Vector3 minBBox1, Vector3 maxBBox1, Vector3 minBBox2, Vector3 maxBBox2);               // Detect collision between two boxes
 bool CheckCollisionBoxSphere(Vector3 minBBox, Vector3 maxBBox, Vector3 centerSphere, float radiusSphere);       // Detect collision between box and sphere
+bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius);                              // Detect collision between ray and sphere
+bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius, Vector3 *collisionPoint);   // Detect collision between ray and sphere with extended parameters and collision point detection
 bool CheckCollisionRayBox(Ray ray, Vector3 minBBox, Vector3 maxBBox);                                           // Detect collision between ray and box
 Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *playerPosition, float radius);   // Detect collision of player radius with cubicmap
                                                                                                                 // NOTE: Return the normal vector of the impacted surface