From a185c11f2397c0296a4b62cc266b4fa00a63c1e2 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Wed, 14 May 2008 21:07:10 +0000 Subject: console, camera & interpolation --- src/core/gameinterface.cc | 207 ++++++++++++++++++++++++---------------------- 1 file changed, 108 insertions(+), 99 deletions(-) (limited to 'src/core/gameinterface.cc') 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::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::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::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; -- cgit v1.2.3