From 2a8df8b3bf787228bad3d77bdd8ae90cb35e8c20 Mon Sep 17 00:00:00 2001
From: Rtch90 <ritchie.cunningham@protonmail.com>
Date: Fri, 6 Apr 2018 22:21:53 +0100
Subject: [PATCH] [Add] Always collide with sphere when trimesh inside. [Fix]
 Fixed silly landing bug.

---
 src/collider/geom.cpp | 28 ++++++++++++++++++++--------
 src/ship.cpp          |  2 +-
 2 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/src/collider/geom.cpp b/src/collider/geom.cpp
index a6fb7c6..83c1efd 100644
--- a/src/collider/geom.cpp
+++ b/src/collider/geom.cpp
@@ -37,6 +37,24 @@ vector3d Geom::GetPosition(void) const {
 }
 
 void Geom::CollideSphere(Sphere& sphere, void(*callback)(CollisionContact*)) {
+  /*
+   * If the geom is actually within the sphere, create a contact so
+   * that we can't fall into spheres forever and ever and ever..
+   */
+  vector3d v = GetPosition() - sphere.pos;
+  const double len = v.Length();
+  if(len < sphere.radius) {
+    CollisionContact c;
+    c.pos = GetPosition();
+    c.normal = (1.0/len)*v;
+    c.depth = sphere.radius - len;
+    c.triIdx = 0;
+    c.userData1 = this->m_data;
+    c.userData2 = sphere.userData;
+    c.geomFlag = 0;
+    (*callback)(&c);
+    return;
+  }
   for(int i = 0; i < m_geomtree->m_numVertices; i++) {
     vector3d vtx(&m_geomtree->m_vertices[3*i]);
     vector3d from = m_orient[!m_orientIdx] * vtx;
@@ -45,13 +63,8 @@ void Geom::CollideSphere(Sphere& sphere, void(*callback)(CollisionContact*)) {
     const double len = dir.Length();
     dir *= 1.0f/len;
 
-    vector3d _from(from.x, from.y, from.z);
-    vector3d _dir(dir.x, dir.y, dir.z);
-
-    _dir.Normalize();
-
     /* Collide with lovely sphere! */
-    const vector3d v = _from - sphere.pos;
+    const vector3d v = from - sphere.pos;
     const double b = -vector3d::Dot(v, dir);
     double det = (b*b) - vector3d::Dot(v,v) + (sphere.radius*sphere.radius);
     if(det > 0) {
@@ -62,7 +75,7 @@ void Geom::CollideSphere(Sphere& sphere, void(*callback)(CollisionContact*)) {
         if(i1 > 0) {
           if(i1 < len) {
             CollisionContact c;
-            c.pos = _from + _dir*i1;
+            c.pos = from + dir*i1;
             c.normal = vector3d::Normalize(v);
             c.depth = len - i1;
             c.triIdx = 0;
@@ -95,7 +108,6 @@ void Geom::Collide(Geom* b, void(*callback)(CollisionContact*)) {
     isect_t isect;
     isect.dist = len;
     isect.triIdx = -1;
-    _dir.Normalize();
     b->m_geomtree->TraceRay(_from, _dir, &isect);
     if(isect.triIdx != -1) {
       CollisionContact c;
diff --git a/src/ship.cpp b/src/ship.cpp
index da0ab15..4f7f142 100644
--- a/src/ship.cpp
+++ b/src/ship.cpp
@@ -199,6 +199,7 @@ void Ship::Blastoff(void) {
 }
 
 void Ship::TestLanded(void) {
+  m_testLanded = false;
   if(m_launchLockTimeout != 0) return;
   if(GetFrame()->m_astroBody) {
     const dReal* vel = dBodyGetLinearVel(m_body);
@@ -245,7 +246,6 @@ void Ship::TestLanded(void) {
         dBodyDisable(m_body);
         ClearThrusterState();
         m_flightState = LANDED;
-        m_testLanded = false;
       }
     }
   }