Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2008-07-29 19:36:51 +0000
committerStijn Buys <ingar@osirion.org>2008-07-29 19:36:51 +0000
commitceedc716cb0fe1e0360d2dd9e37a67ff726c4f0b (patch)
treec09228a09ea78a735c13d371659420fb3e51e754 /src/game/ship.cc
parent8b356bcd3cab06db7a47f464bffef7a1b62f2d30 (diff)
first attempt at auto-leveling
Diffstat (limited to 'src/game/ship.cc')
-rw-r--r--src/game/ship.cc122
1 files changed, 86 insertions, 36 deletions
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