Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/input.cc1
-rw-r--r--src/core/entity.cc24
-rw-r--r--src/core/entity.h8
-rw-r--r--src/core/net.h2
-rw-r--r--src/game/game.cc1
-rw-r--r--src/game/ship.cc122
-rw-r--r--src/game/shipmodel.cc6
7 files changed, 123 insertions, 41 deletions
diff --git a/src/client/input.cc b/src/client/input.cc
index aaf83fa..044ebc2 100644
--- a/src/client/input.cc
+++ b/src/client/input.cc
@@ -618,6 +618,7 @@ void frame(float seconds)
if (core::application()->connected() && core::localcontrol()) {
mouse_control = !console()->visible() && ((input_mousecontrol->value() > 0) || mouse_control_override);
+ core::localcontrol()->set_autolevel(!mouse_control);
if (mouse_control) {
// the mouse will not react if it is in the deadzone
diff --git a/src/core/entity.cc b/src/core/entity.cc
index 20e34ee..d23959f 100644
--- a/src/core/entity.cc
+++ b/src/core/entity.cc
@@ -322,6 +322,7 @@ EntityControlable::EntityControlable(Player *owner, unsigned int flags) :
EntityDynamic(flags)
{
entity_thrust = 0;
+ entity_autolevel = false;
target_direction = 0.0f;
target_thrust = 0.0f;
@@ -338,6 +339,14 @@ EntityControlable::EntityControlable(std::istream & is) :
{
unsigned int o;
+ entity_thrust = 0;
+ entity_autolevel = false;
+
+ target_direction = 0.0f;
+ target_thrust = 0.0f;
+ target_pitch = 0.0f;
+ target_roll = 0.0f;
+
is >> entity_thrust;
is >> o;
@@ -366,6 +375,7 @@ void EntityControlable::serialize_client_update(std::ostream & os) const
os << " " << target_pitch;
os << " " << target_thrust;
os << " " << target_roll;
+ os << " " << (autolevel() ? 1 : 0);
}
@@ -376,6 +386,13 @@ void EntityControlable::receive_client_update(std::istream &is)
is >> target_pitch;
is >> target_thrust;
is >> target_roll;
+
+ unsigned int b = 0;
+ is >> b;
+ if (b)
+ entity_autolevel = true;
+ else
+ entity_autolevel = true;
}
void EntityControlable::serialize_server_update(std::ostream & os) const
@@ -409,6 +426,13 @@ void EntityControlable::set_thrust(float thrust)
}
}
+void EntityControlable::set_autolevel(bool autolevel)
+{
+ if (entity_autolevel != autolevel) {
+ entity_autolevel = autolevel;
+ entity_dirty = true;
+ }
+}
void EntityControlable::set_direction(float direction)
{
if ((flags() & Static) == Static)
diff --git a/src/core/entity.h b/src/core/entity.h
index ca2d029..2515796 100644
--- a/src/core/entity.h
+++ b/src/core/entity.h
@@ -286,6 +286,9 @@ public:
/// serialize a server-to-client update on a stream
virtual void serialize_server_update(std::ostream & os) const;
+ /// autolevel mode
+ bool autolevel() const { return entity_autolevel; }
+
/*----- mutators -------------------------------------------------- */
@@ -300,6 +303,9 @@ public:
/// set the target direction
void set_direction(float direction);
+
+ /// set autolevel request
+ void set_autolevel(bool autolevel);
/// set the target pitch
void set_pitch(float pitch);
@@ -336,7 +342,7 @@ public:
private:
// owner of the entity
Player *entity_owner;
-
+ bool entity_autolevel;
};
/// a Globe entity
diff --git a/src/core/net.h b/src/core/net.h
index c80b979..04c77a5 100644
--- a/src/core/net.h
+++ b/src/core/net.h
@@ -11,7 +11,7 @@ namespace core
{
/// network protocol version
-const unsigned int PROTOCOLVERSION = 3;
+const unsigned int PROTOCOLVERSION = 4;
/// maximum lenght of a (compressed) network message block
const unsigned int FRAMESIZE = 1152;
diff --git a/src/game/game.cc b/src/game/game.cc
index b6c0366..e481c9f 100644
--- a/src/game/game.cc
+++ b/src/game/game.cc
@@ -498,6 +498,7 @@ bool Game::load_ships()
} else if (shipsini.got_key_float("maxspeed", shipmodel->shipmodel_maxspeed)) {
continue;
} else if (shipsini.got_key_float("turnspeed", shipmodel->shipmodel_turnspeed)) {
+ math::clamp(shipmodel->shipmodel_turnspeed, 0.0f, 90.0f);
continue;
} else {
con_warn << shipsini.name() << " unknown key '" << shipsini.key() << "' at line " << shipsini.line() << std::endl;
diff --git a/src/game/ship.cc b/src/game/ship.cc
index f61c9bd..d8f7bb3 100644
--- a/src/game/ship.cc
+++ b/src/game/ship.cc
@@ -17,6 +17,8 @@ using math::degrees180f;
namespace game {
+const float MIN_DELTA = 10e-10;
+
Ship::Ship(core::Player *owner, ShipModel *shipmodel) :
core::EntityControlable(owner, ship_enttype)
{
@@ -45,31 +47,68 @@ Ship::~Ship()
void Ship::frame(float seconds)
{
const float direction_change_speed = 2;
+ float cosangle; // cosine of an angle
+ float angle; // angle in radians
+ math::Vector3f n; // normal of a plane
- // update thrust
+ // target axis
+ math::Axis target_axis(entity_axis);
+
+ // clamp input values
math::clamp(target_thrust, 0.0f, 1.0f);
- entity_thrust = target_thrust;
-
- // update pitch
math::clamp(target_pitch, -1.0f, 1.0f);
- if (current_target_pitch < target_pitch) {
- current_target_pitch += direction_change_speed * seconds;
- if (current_target_pitch > target_pitch)
- current_target_pitch = target_pitch;
- } else if (current_target_pitch > target_pitch) {
- current_target_pitch -= direction_change_speed * seconds;
- if (current_target_pitch < target_pitch)
- current_target_pitch = target_pitch;
+ math::clamp(target_roll, -1.0f, 1.0f);
+ math::clamp(target_direction, -1.0f, 1.0f);
+
+ // update thrust
+ entity_thrust = target_thrust;
+
+
+ if (autolevel()) {
+ n.assign(math::crossproduct(entity_axis.up(), math::Vector3f(0, 0, 1.0f)));
+ if (!(n.length() < MIN_DELTA)) {
+ cosangle = math::dotproduct(entity_axis.up(), math::Vector3f(0, 0, 1.0f));
+ target_roll = acos(cosangle);
+ math::clamp(target_roll, 0.0f, 1.0f);
+ target_roll *= M_1_PI;
+ target_roll *= math::sgnf(math::dotproduct(entity_axis.left(), math::Vector3f(0.0, 0.0f, 1.0f)));
+ } else {
+ target_roll = 0;
+ }
}
-
- if (fabs(seconds*current_target_pitch) > 0.0f) {
- math::clamp(current_target_pitch, -1.0f, 1.0f);
- float pitch_offset = seconds * current_target_pitch;
- entity_axis.change_pitch(360.0f * ship_shipmodel->turnspeed() * pitch_offset);
+
+ if (current_target_roll < target_roll) {
+ current_target_roll += direction_change_speed * seconds;
+ if (current_target_roll > target_roll)
+ current_target_roll = target_roll;
+ } else if (current_target_roll > target_roll) {
+ current_target_roll -= direction_change_speed * seconds;
+ if (current_target_roll < target_roll)
+ current_target_roll = target_roll;
}
+ math::clamp(current_target_roll, -1.0f, 1.0f);
- // update direction
- math::clamp(target_direction, -1.0f, 1.0f);
+ if (fabs(current_target_roll) > MIN_DELTA) {
+ float roll_offset = seconds * current_target_roll;
+ entity_axis.change_roll(ship_shipmodel->turnspeed() * roll_offset);
+ } else {
+ current_target_roll = 0.0f;
+ }
+
+ // auto-leveling
+ if (autolevel()) {
+ n.assign(math::crossproduct(entity_axis.up(), math::Vector3f(0.0f, 0.0f, 1.0f)));
+ if (!(n.length() < MIN_DELTA)) {
+ cosangle = math::dotproduct(entity_axis.up(), math::Vector3f(0.0f, 0.0f, 1.0f));
+ target_pitch = acos(cosangle);
+ math::clamp(target_roll, 0.0f, 1.0f);
+ target_pitch *= -math::sgnf(math::dotproduct(entity_axis.forward(), math::Vector3f(0.0, 0.0f, 1.0f)));
+ } else {
+ target_pitch = 0;
+ }
+ }
+
+ // update target_axis direction
if (current_target_direction < target_direction) {
current_target_direction += direction_change_speed * seconds;
if (current_target_direction > target_direction) {
@@ -81,27 +120,38 @@ void Ship::frame(float seconds)
current_target_direction = target_direction;
}
}
- if (fabs(seconds*current_target_direction) > 0.0f ) {
+
+ if (fabs(current_target_direction) > MIN_DELTA ) {
math::clamp(current_target_direction, -1.0f, 1.0f);
- float direction_offset = seconds * current_target_direction;
- entity_axis.change_direction(360.0f * ship_shipmodel->turnspeed() * direction_offset);
+ target_axis.change_direction(ship_shipmodel->turnspeed() * current_target_direction);
+ } else {
+ //current_target_direction = 0.0f;
}
- // update roll
- math::clamp(target_roll, -1.0f, 1.0f);
- if (current_target_roll < target_roll) {
- current_target_roll += direction_change_speed * seconds;
- if (current_target_roll > target_roll)
- current_target_roll = target_roll;
- } else if (current_target_roll > target_roll) {
- current_target_roll -= direction_change_speed * seconds;
- if (current_target_roll < target_roll)
- current_target_roll = target_roll;
+ if (current_target_pitch < target_pitch) {
+ current_target_pitch += direction_change_speed * seconds;
+ if (current_target_pitch > target_pitch)
+ current_target_pitch = target_pitch;
+ } else if (current_target_pitch > target_pitch) {
+ current_target_pitch -= direction_change_speed * seconds;
+ if (current_target_pitch < target_pitch)
+ current_target_pitch = target_pitch;
}
- if (fabs(current_target_roll) > 0.0f) {
- math::clamp(current_target_roll, -1.0f, 1.0f);
- float roll_offset = seconds * current_target_roll;
- entity_axis.change_roll(360.0f * ship_shipmodel->turnspeed() * roll_offset);
+
+ if (fabs(current_target_pitch) > MIN_DELTA) {
+ math::clamp(current_target_pitch, -1.0f, 1.0f);
+ target_axis.change_pitch(ship_shipmodel->turnspeed() * current_target_pitch);
+ } else {
+ //current_target_pitch = 0.0f;
+ }
+
+ n.assign(math::crossproduct(entity_axis.forward(), target_axis.forward()));
+ if (!(n.length() < MIN_DELTA)) {
+ n.normalize();
+ cosangle = math::dotproduct(entity_axis.forward(), target_axis.forward());
+ angle = acos(cosangle) * seconds; // * 180.0f / M_PI;
+ if (angle > MIN_DELTA)
+ entity_axis.rotate(n, -angle);
}
// update speed
diff --git a/src/game/shipmodel.cc b/src/game/shipmodel.cc
index 6a226f4..8ff182f 100644
--- a/src/game/shipmodel.cc
+++ b/src/game/shipmodel.cc
@@ -15,9 +15,9 @@ std::map<std::string, ShipModel *> ShipModel::registry;
ShipModel::ShipModel()
{
//default specifications
- shipmodel_acceleration = 1.0f;
- shipmodel_maxspeed = 3.0f;
- shipmodel_turnspeed = 0.1f;
+ shipmodel_acceleration = 1.0f; // thruster acceleration in game untits/second^2
+ shipmodel_maxspeed = 3.0f; // maximum thruster speed in game units/second
+ shipmodel_turnspeed = 45.0f; // 45 degrees per second
shipmodel_jumpdrive = false;
}