Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/gameinterface.cc')
-rw-r--r--src/core/gameinterface.cc207
1 files changed, 108 insertions, 99 deletions
diff --git a/src/core/gameinterface.cc b/src/core/gameinterface.cc
index 1f4a5cd..f50c1cc 100644
--- a/src/core/gameinterface.cc
+++ b/src/core/gameinterface.cc
@@ -18,6 +18,8 @@
namespace core
{
+const float MIN_DELTA = 10e-10;
+
void func_list_model(std::string const &args)
{
model::Model::list();
@@ -97,12 +99,10 @@ void GameInterface::clear()
game_clientframetime = 0;
}
-void GameInterface::reset_clientstate(float servertime)
+void GameInterface::reset_clientstate(float timestamp, float prevtimestamp)
{
- game_previousframetime = game_serverframetime;
- game_clientframetime = game_serverframetime;
-
- game_serverframetime = servertime;
+ game_previousframetime = prevtimestamp;
+ game_serverframetime = timestamp;
std::map<unsigned int, core::Entity *>::iterator it;
for (it=core::Entity::registry.begin(); it != core::Entity::registry.end(); it++) {
@@ -112,121 +112,130 @@ void GameInterface::reset_clientstate(float servertime)
if (entity->state() && !(entity->flags() & core::Entity::Static))
entity->state()->assign(entity);
}
-}
-
-void GameInterface::update_clientstate(float seconds)
-{
- game_clientframetime += seconds;
- if (game_clientframetime > game_serverframetime)
+ if ( game_clientframetime < game_previousframetime)
+ game_clientframetime = game_previousframetime;
+ else if ( game_clientframetime > game_serverframetime)
game_clientframetime = game_serverframetime;
- std::map<unsigned int, Entity *>::iterator it;
- for (it=Entity::registry.begin(); it != Entity::registry.end(); it++) {
+}
+
- Entity *entity = (*it).second;
+void GameInterface::update_entity_clientstate(Entity *entity)
+{
+ if (!entity->state()) {
+ entity->entity_clientstate = new core::ClientState(entity);
+ entity->entity_clientstate->assign(entity);
+ }
- // update client state
- if (!entity->state()) {
- entity->entity_clientstate = new core::ClientState(entity);
- }
+ if (!(entity->flags() & core::Entity::Static))
+ return;
+
+ if (game_clientframetime < game_serverframetime) {
if (!(entity->flags() & core::Entity::Static)) {
-
+
// clientstate location
entity->state()->state_location = entity->state()->previouslocation() +
- (entity->location() - entity->state()->previouslocation()) * core::game()->timeoffset();
-
- if (core::game()->clientframetime() < core::game()->serverframetime()) {
-
- // http://local.wasp.uwa.edu.au/~pbourke/geometry/planeline/
- float cosangle;
- float angle;
- float side;
- float u;
-
- math::Vector3f n;
- math::Vector3f p;
-
- // 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;
-
- if (fabs(side) > 0.00005f) {
- cosangle = math::dotproduct(p, entity->state()->axis().up());
-
- if (fabs(cosangle) < 0.99995f) {
- angle = acos(cosangle) * 180.0f / M_PI;
- angle = math::sgnf(side) * angle * seconds /
- (core::game()->serverframetime() - core::game()->clientframetime());
-
- entity->state()->state_axis.change_pitch(-angle);
- }
+ (entity->location() - entity->state()->previouslocation()) * timeoffset();
+
+ // 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;
-
- if (fabs(side) > 0.00005f) {
- cosangle = math::dotproduct(p, entity->state()->axis().forward());
- if (fabs(cosangle) < 0.99995f) {
- angle = acos(cosangle) * 180.0f / M_PI;
- angle = math::sgnf(side) * angle * seconds /
- (core::game()->serverframetime() - core::game()->clientframetime());
-
- entity->state()->state_axis.change_direction(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);
}
-
- // 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;
-
- if (fabs(side) > 0.00005f) {
- cosangle = math::dotproduct(p, entity->state()->axis().up());
+ }
+
+ // 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;
- if (fabs(cosangle) < 0.99995f) {
- angle = math::sgnf(side) * angle * seconds /
- (core::game()->serverframetime() - core::game()->clientframetime());
-
- entity->state()->state_axis.change_roll(angle);
- }
+ angle = math::sgnf(side) * angle * timeoffset();
+ entity->state()->state_axis.change_roll(angle);
}
-
}
- }
+ }
+
+ } else {
+ entity->state()->assign(entity);
+ }
+}
+void GameInterface::update_clientstate(float seconds)
+{
+ std::map<unsigned int, core::Entity *>::iterator it;
+ for (it=core::Entity::registry.begin(); it != core::Entity::registry.end(); it++) {
+ update_entity_clientstate((*it).second);
}
}
float GameInterface::timeoffset() {
+ if (game_clientframetime > game_serverframetime)
+ return 1;
+
float d = game_serverframetime - game_previousframetime;
if (d <= 0)
return 0;