From 17408276791033e8122819185abf3bcb01740105 Mon Sep 17 00:00:00 2001
From: Stijn Buys <ingar@osirion.org>
Date: Sun, 27 Jul 2008 12:23:33 +0000
Subject: a nicer cl_prediction

---
 src/core/gameinterface.cc | 108 +++++++++++++---------------------------------
 1 file changed, 31 insertions(+), 77 deletions(-)

diff --git a/src/core/gameinterface.cc b/src/core/gameinterface.cc
index 23b27bc..be4d288 100644
--- a/src/core/gameinterface.cc
+++ b/src/core/gameinterface.cc
@@ -140,87 +140,41 @@ void GameInterface::update_entity_clientstate(Entity *entity)
 		entity->state()->state_location = entity->state()->previouslocation() + 
 		(entity->location() - entity->state()->previouslocation()) * timeoffset();
 
-		if (game_clientframetime < game_serverframetime) {
+		if (game_clientframetime <= game_serverframetime) {
 		
-			//FIXME this is hopelessly broken
-
-			// http://local.wasp.uwa.edu.au/~pbourke/geometry/planeline/
-			float cosangle;
-			float angle;
-			float side;
-			float u;
-			float l;
-	
-			math::Vector3f n;
-			math::Vector3f p;
-	
 			entity->state()->state_axis.assign(entity->state()->previousaxis());
-			// clientstate axis: pitch
-	
-			// project entity->axis().up() into the plane with entity->state()->axis()->left() normal
-			n = entity->state()->axis().left();
-			p = entity->axis().up();
-			u = p[0]*n[0] + p[1]*n[1] + p[2]*n[2] / (-n[0]*n[0] - n[1]*n[1] - n[2] * n[2]);
-			p = entity->axis().up() + u * n;
-	
-			side = entity->state()->axis().forward().x * p.x + 
-				entity->state()->axis().forward().y * p.y +
-				entity->state()->axis().forward().z * p.z;
-	
-			l = p.length();
-			if ((fabs(side) - MIN_DELTA > 0)) {
-                                                            				cosangle = math::dotproduct(p, entity->state()->axis().up());		
-				if (fabs(cosangle) + MIN_DELTA < 1 ) {
-					angle = acos(cosangle) * 180.0f / M_PI;
-					angle = math::sgnf(side) * angle *  timeoffset();
-					entity->state()->state_axis.change_pitch(-angle);
-				}
-			}
-	
-			// clientstate axis: direction
-	
-			// project entity->axis().forward() into the plane with entity->state()->axis().up() normal
-			n = entity->state()->axis().up();
-			p = entity->axis().forward();
-			u = p[0]*n[0] + p[1]*n[1] + p[2]*n[2] / (-n[0]*n[0] - n[1]*n[1] - n[2] * n[2]);
-			p = entity->axis().forward() + u * n;
-	
-			side = entity->state()->axis().left().x * p.x + 
-				entity->state()->axis().left().y * p.y +
-				entity->state()->axis().left().z * p.z;
-	
-			l = p.length();
-			if ((fabs(side) - MIN_DELTA > 0)) {
-				cosangle = math::dotproduct(p, entity->state()->axis().forward());
-				if (fabs(cosangle) + MIN_DELTA < 1 ) {
-					angle = acos(cosangle) * 180.0f / M_PI;
-					angle = math::sgnf(side) * angle *  timeoffset();
-					entity->state()->state_axis.change_direction(angle);
-				}
+
+			float cosangle;		// cosine of an angle
+			float angle;		// angle in radians	
+			math::Vector3f n;	// normal of a plane
+
+			n.assign(math::crossproduct( entity->state()->axis().forward(), entity->axis().forward()));
+			if (!(n.length() < MIN_DELTA)) {
+				n.normalize();
+				cosangle = math::dotproduct( entity->state()->axis().forward(),  entity->axis().forward());
+				angle = acos(cosangle) * timeoffset(); // * 180.0f / M_PI;
+				if (angle > MIN_DELTA)
+					entity->state()->state_axis.rotate(n, -angle);
 			}
-	
-			// clientstate axis: roll
-	
-			// project entity->axis().up() into the plane with entity->state()->axis().forward() normal
-			n = entity->state()->axis().forward();
-			p = entity->axis().up();
-			u = p[0]*n[0] + p[1]*n[1] + p[2]*n[2] / (-n[0]*n[0] - n[1]*n[1] - n[2] * n[2]);
-			p = entity->axis().up() + u * n;
-	
-			side = entity->state()->axis().left().x * p.x + 
-				entity->state()->axis().left().y * p.y +
-				entity->state()->axis().left().z * p.z;
-	
-			l = p.length();
-			if ((fabs(side) - MIN_DELTA > 0)) {
-				cosangle = math::dotproduct(p, entity->state()->axis().up());
-				if (fabs(cosangle) + MIN_DELTA < 1 ) {
-					angle = acos(cosangle) * 180.0f / M_PI;
-					angle = math::sgnf(side) * angle *  timeoffset();
-					entity->state()->state_axis.change_roll(angle);
-				}
+
+			n.assign(math::crossproduct( entity->state()->axis().left(), entity->axis().left()));
+			if (!(n.length() < MIN_DELTA)) {
+				n.normalize();
+				cosangle = math::dotproduct( entity->state()->axis().left(), entity->axis().left());
+				angle = acos(cosangle) * timeoffset(); // * 180.0f / M_PI;
+				if (angle > MIN_DELTA)
+					entity->state()->state_axis.rotate(n, -angle);
 			}
-			
+
+			n.assign(math::crossproduct( entity->state()->axis().up(), entity->axis().up()));
+			if (!(n.length() < MIN_DELTA)) {
+				n.normalize();
+				cosangle = math::dotproduct( entity->state()->axis().up(), entity->axis().up());
+				angle = acos(cosangle) * timeoffset(); // * 180.0f / M_PI;
+				if (angle > MIN_DELTA)
+					entity->state()->state_axis.rotate(n, -angle);
+			} 
+
 		} else {
 			entity->state()->state_axis.assign(entity->axis());
 		}
-- 
cgit v1.2.3