Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2008-05-10 10:19:16 +0000
committerStijn Buys <ingar@osirion.org>2008-05-10 10:19:16 +0000
commit930db4020b9af2ccd999cb3a8c980cc9d527f8cf (patch)
tree1767c67dbe94615c02d529f3ed04e614cb948921 /src/core
parent421fc71813f08bfe359f9ac7596933a7e4cea6e0 (diff)
client-side axis interpolation
Diffstat (limited to 'src/core')
-rw-r--r--src/core/clientstate.cc38
-rw-r--r--src/core/clientstate.h65
-rw-r--r--src/core/entity.cc15
-rw-r--r--src/core/gameconnection.cc6
-rw-r--r--src/core/gameinterface.cc89
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() {