diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/clientstate.cc | 38 | ||||
-rw-r--r-- | src/core/clientstate.h | 65 | ||||
-rw-r--r-- | src/core/entity.cc | 15 | ||||
-rw-r--r-- | src/core/gameconnection.cc | 6 | ||||
-rw-r--r-- | src/core/gameinterface.cc | 89 |
5 files changed, 206 insertions, 7 deletions
diff --git a/src/core/clientstate.cc b/src/core/clientstate.cc new file mode 100644 index 0000000..b34b16a --- /dev/null +++ b/src/core/clientstate.cc @@ -0,0 +1,38 @@ +/* + core/clientstate.cc + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#include "core/clientstate.h" + +namespace core { + +ClientState::ClientState() +{ + state_visible = false; + state_detailvisible = false; + state_fuzz = math::randomf(); +} + +ClientState::ClientState(Entity *entity) +{ + state_visible = false; + state_detailvisible = false; + state_fuzz = math::randomf(); + assign(entity); +} + +ClientState::~ClientState() +{} + +void ClientState::assign(Entity * entity) +{ + state_location.assign(entity->location()); + state_axis.assign(entity->axis()); + + state_previouslocation.assign(entity->location()); + state_previousaxis.assign(entity->axis()); +} + +} diff --git a/src/core/clientstate.h b/src/core/clientstate.h new file mode 100644 index 0000000..915f96f --- /dev/null +++ b/src/core/clientstate.h @@ -0,0 +1,65 @@ +/* + core/clientstate.h + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#ifndef __INCLUDED_CORE_CLIENTSTATE_H__ +#define __INCLUDED_CORE_CLIENTSTATE_H__ + +#include "math/axis.h" +#include "math/mathlib.h" +#include "math/vector3f.h" + +namespace core +{ + class ClientState; +} + +#include "core/entity.h" + +namespace core +{ + +/// Entity client render state +class ClientState { +public: + ClientState(); + ClientState(Entity *entity); + + ~ClientState(); + + inline math::Vector3f const & location() { return state_location; } + + inline math::Vector3f const & previouslocation() { return state_previouslocation; } + + inline math::Axis const & previousaxis() { return state_previousaxis; } + + inline math::Axis const & axis() { return state_axis; } + + inline bool visible() const { return state_visible; } + + inline bool detailvisible() const { return state_detailvisible; } + + /// client render fuzz factor + inline float fuzz() const { return state_fuzz; }; + + /// assign the content of an entity + void assign(Entity *entity); + + math::Vector3f state_location; + math::Axis state_axis; + + math::Vector3f state_previouslocation; + math::Axis state_previousaxis; + + bool state_visible; + bool state_detailvisible; + + float state_fuzz; +}; + +} + +#endif // __INCLUDED_CORE_CLIENTSTATE_H__ + diff --git a/src/core/entity.cc b/src/core/entity.cc index cc956b0..46231d8 100644 --- a/src/core/entity.cc +++ b/src/core/entity.cc @@ -115,7 +115,11 @@ Entity::Entity(std::istream & is) is >> entity_color; is >> s; // shape is >> entity_radius; - is >> entity_axis; + + is >> entity_axis[0]; + is >> entity_axis[1]; + entity_axis[2] = math::crossproduct(entity_axis.forward(), entity_axis.left()); + entity_shape = (Shape) s ; char c; @@ -135,7 +139,9 @@ Entity::Entity(std::istream & is) entity_destroyed = false; entity_dirty = false; + // this entity is created clientside entity_clientstate = 0; + add(this, entity_id); } @@ -156,7 +162,8 @@ void Entity::serialize(std::ostream & os) const << entity_color << " " << entity_shape << " " << entity_radius << " " - << entity_axis << " " + << entity_axis.forward() << " " + << entity_axis.left() << " " << "\"" << entity_name << "\" " << "\"" << entity_modelname << "\""; } @@ -232,16 +239,16 @@ void EntityDynamic::serialize_server_update(std::ostream & os) const os << entity_location << " "; os << entity_axis.forward() << " "; os << entity_axis.left() << " "; - os << entity_axis.up() << " "; os << entity_speed; } void EntityDynamic::recieve_server_update(std::istream &is) { is >> entity_location; + // axis up vector is the crossproduct of forward and left is >> entity_axis[0]; is >> entity_axis[1]; - is >> entity_axis[2]; + entity_axis[2] = math::crossproduct(entity_axis.forward(), entity_axis.left()); is >> entity_speed; } diff --git a/src/core/gameconnection.cc b/src/core/gameconnection.cc index b5ac27d..c86a0ae 100644 --- a/src/core/gameconnection.cc +++ b/src/core/gameconnection.cc @@ -102,9 +102,7 @@ void GameConnection::frame(float seconds) if (connection_frametime < f) { return; } - } - - connection_frametime = 0; + } if (localcontrol() && localcontrol()->dirty()) { std::ostringstream netmsg; @@ -129,6 +127,8 @@ void GameConnection::frame(float seconds) } connection_network->transmit(); + + connection_frametime = 0; } } diff --git a/src/core/gameinterface.cc b/src/core/gameinterface.cc index d1bc1c3..99f884d 100644 --- a/src/core/gameinterface.cc +++ b/src/core/gameinterface.cc @@ -120,6 +120,95 @@ void GameInterface::update_clientstate(float seconds) 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; + + // update client state + if (!entity->state()) { + entity->entity_clientstate = new core::ClientState(entity); + } + + 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 side; + float u; + + // clientstate axis: direction + + side = entity->state()->axis().left().x * entity->axis().forward().x + + entity->state()->axis().left().y * entity->axis().forward().y + + entity->state()->axis().left().z * entity->axis().forward().z; + + if (fabs(side) < 0.9999) { + // project entity->axis().forward() into the plane with entity->state()->axis().up() normal + math::Vector3f const & n = entity->state()->axis().up(); + math::Vector3f 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; + + float cosangle = math::dotproduct(p, entity->state()->axis().forward()); + float angle = acos(cosangle) * 180.0f / M_PI; + angle = math::sgnf(side) * angle * seconds / + (core::game()->serverframetime() - core::game()->clientframetime()); + + if (angle > 0.001) + entity->state()->state_axis.change_direction(angle); + } + + // clientstate axis: pitch + side = entity->state()->axis().forward().x * entity->axis().up().x + + entity->state()->axis().forward().y * entity->axis().up().y + + entity->state()->axis().forward().z * entity->axis().up().z; + + if (fabs(side) < 0.9999) { + // project entity->axis().up() into the plane with entity->state()->axis()->left() normal + math::Vector3f const & n = entity->state()->axis().left(); + math::Vector3f 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; + + float cosangle = math::dotproduct(p, entity->state()->axis().up()); + float angle = acos(cosangle) * 180.0f / M_PI; + angle = math::sgnf(side) * angle * seconds / + (core::game()->serverframetime() - core::game()->clientframetime()); + + if (angle > 0.001) + entity->state()->state_axis.change_pitch(-angle); + } + + + /* + // clientstate axis: roll + side = entity->state()->axis().left().x * entity->axis().up().x + + entity->state()->axis().left().y * entity->axis().up().y + + entity->state()->axis().left().z * entity->axis().up().z; + + if (fabs(side) < 0.9999) { + float cosangle = math::dotproduct(entity->axis().up(), entity->state()->axis().up()); + float angle = acos(cosangle) * 180.0f / M_PI; + angle = math::sgnf(side) * angle * seconds / + (core::game()->serverframetime() - core::game()->clientframetime()); + + if (angle > 0.001) + entity->state()->state_axis.change_roll(-angle); + } + */ + + } + + } + + } } float GameInterface::timeoffset() { |