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>2015-02-28 20:46:53 +0000
committerStijn Buys <ingar@osirion.org>2015-02-28 20:46:53 +0000
commitcffe02f49b66a70d40816ffc8dea42f9e52da57f (patch)
tree110471c23944d09899d4cacb3cdd40508f359f72
parent26c8cf4d74062fb12871ae9d5298d8ceaab7a2cf (diff)
Reimplemented camera handling enabling 360-degree freelook.
-rw-r--r--src/client/hud.cc22
-rw-r--r--src/client/hudenginestatus.cc3
-rw-r--r--src/client/input.cc185
-rw-r--r--src/client/savegamemenu.cc4
-rw-r--r--src/client/soundext.cc4
-rw-r--r--src/client/targets.cc30
-rw-r--r--src/client/video.cc2
-rw-r--r--src/render/camera.cc512
-rw-r--r--src/render/camera.h305
-rw-r--r--src/render/draw.cc113
-rw-r--r--src/render/draw.h7
-rw-r--r--src/render/dust.cc17
-rw-r--r--src/render/dust.h5
-rw-r--r--src/render/particleejector.cc33
-rw-r--r--src/render/particleejector.h13
-rw-r--r--src/render/particlesystem.cc4
-rw-r--r--src/render/particlesystem.h3
-rw-r--r--src/render/render.cc4
-rw-r--r--src/render/renderext.cc10
-rw-r--r--src/render/renderext.h2
-rwxr-xr-xsrc/ui/modelview.cc20
-rwxr-xr-xsrc/ui/modelview.h3
22 files changed, 725 insertions, 576 deletions
diff --git a/src/client/hud.cc b/src/client/hud.cc
index 1ae008c..49f9c9d 100644
--- a/src/client/hud.cc
+++ b/src/client/hud.cc
@@ -73,8 +73,8 @@ void HUD::draw_offscreen_target(core::Entity *entity, bool is_active_target)
const core::EntityControlable *controlable = ( (entity->type() == core::Entity::Controlable) ? static_cast<core::EntityControlable *>(entity) : 0 );
- math::Vector3f target(entity->location() - render::Camera::eye());
- target = render::Camera::axis().transpose() * target;
+ math::Vector3f target(entity->location() - render::camera().location());
+ target = render::camera().axis().transpose() * target;
math::Vector2f screen_edge;
@@ -205,8 +205,8 @@ void HUD::draw_target(core::Entity *entity, bool is_active_target)
}
// don't draw target if it is outside the visible cone
- Vector3f target(entity->location() - render::Camera::eye());
- if (math::dotproduct(render::Camera::axis().forward(), Vector3f::normalized(target)) < 0.75) {
+ Vector3f target(entity->location() - render::camera().location());
+ if (math::dotproduct(render::camera().axis().forward(), Vector3f::normalized(target)) < 0.75) {
draw_offscreen_target(entity, is_active_target);
return;
}
@@ -216,7 +216,7 @@ void HUD::draw_target(core::Entity *entity, bool is_active_target)
// calculate target screen position
// transform the target into the camera coordinate system
- target = render::Camera::axis().transpose() * target;
+ target = render::camera().axis().transpose() * target;
// calculate the intersection between the line (0,0,0)-target and the frustum front
float t = (render::FRUSTUMFRONT + 0.001f) / target.x();
@@ -416,10 +416,12 @@ void HUD::draw()
{
using namespace render;
- if (core::localcontrol() && (input::mouse_control || input::joystick_control) &&
- (render::Camera::mode() == render::Camera::Cockpit || render::Camera::mode() == render::Camera::Track)) {
+ if (core::localcontrol() && (input::mouse_control || input::joystick_control) && (render::camera().mode() != render::camera().Overview))
+ {
hud_center->set_visible(true);
- } else {
+ }
+ else
+ {
hud_center->set_visible(false);
}
@@ -468,7 +470,7 @@ void HUD::draw()
if (has_mouse_focus()) {
- if (render::Camera::mode() == render::Camera::Overview) {
+ if (render::camera().mode() == render::camera().Overview) {
ui::root()->set_pointer("pointer", ui::Palette::Highlight);
@@ -484,7 +486,7 @@ void HUD::draw()
ui::root()->set_pointer("control", ui::Palette::Pointer);
- } else if ((input::joystick_lastmoved_time() > input::mouse_lastmoved_time()) && (render::Camera::mode() == render::Camera::Cockpit || render::Camera::mode() == render::Camera::Track)) {
+ } else if ((input::joystick_lastmoved_time() > input::mouse_lastmoved_time()) && (render::camera().mode() == render::camera().Cockpit || render::camera().mode() == render::camera().Track)) {
ui::root()->set_pointer();
diff --git a/src/client/hudenginestatus.cc b/src/client/hudenginestatus.cc
index 1283970..0eeafba 100644
--- a/src/client/hudenginestatus.cc
+++ b/src/client/hudenginestatus.cc
@@ -11,8 +11,9 @@
#include "ui/ui.h"
#include "ui/iconbutton.h"
#include "ui/paint.h"
-#include "render/render.h"
+#include "render/camera.h"
#include "render/gl.h"
+#include "render/render.h"
namespace client
{
diff --git a/src/client/input.cc b/src/client/input.cc
index 72fa5af..dadc027 100644
--- a/src/client/input.cc
+++ b/src/client/input.cc
@@ -139,9 +139,6 @@ void func_ui_control(std::string const &args)
local_direction = 0.0f;
local_pitch = 0.0f;
local_roll = 0.0f;
-
- render::Camera::set_direction(0.0f);
- render::Camera::set_pitch(0.0f);
}
con_print << "mouse control is " << ((input_mousecontrol->value()) ? "on" : "off") << std::endl;
@@ -152,7 +149,7 @@ void func_ui_control(std::string const &args)
void func_view_next(std::string const &args)
{
if (!core::localplayer()->view() && core::application()->connected() && core::localcontrol()) {
- render::Camera::view_next();
+ render::camera().cycle_mode_next();
local_roll = 0;
local_pitch = 0;
local_direction = 0;
@@ -163,7 +160,7 @@ void func_view_next(std::string const &args)
void func_view_prev(std::string const &args)
{
if (!core::localplayer()->view() && core::application()->connected() && core::localcontrol()) {
- render::Camera::view_previous();
+ render::camera().cycle_mode_previous();
local_roll = 0;
local_pitch = 0;
local_direction = 0;
@@ -348,7 +345,8 @@ void shutdown()
void action_press(Key *key)
{
- switch(key->action()->id()) {
+ switch(key->action()->id())
+ {
case Action::None:
case Action::Console:
return;
@@ -411,60 +409,95 @@ void action_press(Key *key)
/* -- camera control ------------------------------ */
+ case Action::FreeLook:
+ if (!freelook_control_override)
+ {
+ freelook_control_override = true;
+ freelook_control_override_time = key->pressed();
+
+ freelook_control_x = mouse_x;
+ freelook_control_y = mouse_y;
+ }
+ break;
case Action::LookLeft:
- if (render::Camera::mode() == render::Camera::Free)
+ if (render::camera().mode() == render::Camera::Free)
{
- render::Camera::set_direction(math::min(key->pressed() - core::application()->time(), 1.0f));
- } else {
- render::Camera::set_direction(-math::min(key->pressed() - core::application()->time(), 1.0f));
+ render::camera().set_movement_direction(-1.0f);
+ }
+ else if ((render::camera().mode() == render::Camera::Track) || (render::camera().mode() == render::Camera::Cockpit))
+ {
+ render::camera().set_freelook_direction(90.0f);
}
break;
case Action::LookRight:
- if (render::Camera::mode() == render::Camera::Free)
+ if (render::camera().mode() == render::Camera::Free)
{
- render::Camera::set_direction(-math::min(key->pressed() - core::application()->time(), 1.0f));
- } else {
- render::Camera::set_direction(math::min(key->pressed() - core::application()->time(), 1.0f));
+ render::camera().set_movement_direction(1.0f);
+ }
+ else if ((render::camera().mode() == render::Camera::Track) || (render::camera().mode() == render::Camera::Cockpit))
+ {
+ render::camera().set_freelook_direction(-90.0f);
}
break;
case Action::LookUp:
- if (render::Camera::mode() == render::Camera::Free)
+ if (render::camera().mode() == render::Camera::Free)
{
- render::Camera::set_pitch(math::min(key->pressed() - core::application()->time(), 1.0f));
- } else {
- render::Camera::set_pitch(-math::min(key->pressed() - core::application()->time(), 1.0f));
+ render::camera().set_movement_pitch(1.0f);
+ }
+ else if ((render::camera().mode() == render::Camera::Track) || (render::camera().mode() == render::Camera::Cockpit))
+ {
+ render::camera().set_freelook_pitch(90.0f);
}
break;
case Action::LookDown:
- if (render::Camera::mode() == render::Camera::Free)
+ if (render::camera().mode() == render::Camera::Free)
{
- render::Camera::set_pitch(-math::min(key->pressed() - core::application()->time(), 1.0f));
- } else {
- render::Camera::set_pitch(math::min(key->pressed() - core::application()->time(), 1.0f));
+ render::camera().set_movement_pitch(-1.0f);
+ }
+ else if ((render::camera().mode() == render::Camera::Track) || (render::camera().mode() == render::Camera::Cockpit))
+ {
+ render::camera().set_freelook_pitch(-90.0f);
}
break;
case Action::ZoomIn:
- render::Camera::set_zoom(-0.1f);
+ if (!core::localplayer()->view())
+ {
+ float m = render::camera().multiplier();
+ if (m > 1.0f)
+ {
+ m -= 0.1f;
+ }
+ else
+ {
+ m = 1.0f;
+ }
+ render::camera().set_multiplier(m);
+ }
break;
case Action::ZoomOut:
- render::Camera::set_zoom(+0.1f);
- break;
- case Action::FreeLook:
- if (!freelook_control_override)
+ if (!core::localplayer()->view())
{
- freelook_control_override = true;
- freelook_control_override_time = key->pressed();
-
- freelook_control_x = mouse_x;
- freelook_control_y = mouse_y;
+ float m = render::camera().multiplier();
+ if (m < 5.0f)
+ {
+ m += 0.1f;
+ }
+ else
+ {
+ m = 5.0f;
+ }
+ render::camera().set_multiplier(m);
}
break;
-
+
/* -- fire control -------------------------------- */
case Action::Fire:
local_controlflags = local_controlflags | core::EntityControlable::ControlFlagFire;
break;
+
+ default:
+ break;
}
}
@@ -531,15 +564,15 @@ void action_release(Key *key)
mouse_control_override_time = 0.0f;
if (!input_mousecontrol->value() || (joystick_control && mouse_control &&
- (render::Camera::mode() == render::Camera::Track || render::Camera::mode() == render::Camera::Cockpit))) {
+ (render::camera().mode() == render::Camera::Track || render::camera().mode() == render::Camera::Cockpit))) {
local_direction = 0.0f;
local_pitch = 0.0f;
local_roll = 0.0f;
local_vstrafe = 0.0f;
local_strafe = 0.0f;
- render::Camera::set_direction(0.0f);
- render::Camera::set_pitch(0.0f);
+ render::camera().set_movement_direction(0.0f);
+ render::camera().set_movement_pitch(0.0f);
}
}
break;
@@ -547,16 +580,26 @@ void action_release(Key *key)
/* -- camera control ------------------------------ */
case Action::LookLeft:
- render::Camera::set_direction(0.0f);
- break;
case Action::LookRight:
- render::Camera::set_direction(0.0f);
+ if (render::camera().mode() == render::Camera::Free)
+ {
+ render::camera().set_movement_direction(0.0f);
+ }
+ else if ((render::camera().mode() == render::Camera::Track) || (render::camera().mode() == render::Camera::Cockpit))
+ {
+ render::camera().set_freelook_direction(0.0f);
+ }
break;
case Action::LookUp:
- render::Camera::set_pitch(0.0f);
- break;
case Action::LookDown:
- render::Camera::set_pitch(0.0f);
+ if (render::camera().mode() == render::Camera::Free)
+ {
+ render::camera().set_movement_pitch(0.0f);
+ }
+ else if ((render::camera().mode() == render::Camera::Track) || (render::camera().mode() == render::Camera::Cockpit))
+ {
+ render::camera().set_freelook_pitch(0.0f);
+ }
break;
case Action::ZoomIn:
break;
@@ -568,8 +611,8 @@ void action_release(Key *key)
freelook_control_override = false;
freelook_control_override_time = 0.0f;
- render::Camera::set_direction(0.0f);
- render::Camera::set_pitch(0.0f);
+ render::camera().set_freelook_direction(0.0f);
+ render::camera().set_freelook_pitch(0.0f);
}
break;
@@ -601,8 +644,8 @@ bool console_key_pressed(const Key *key)
local_pitch = 0.0f;
local_roll = 0.0f;
- render::Camera::set_direction(0.0f);
- render::Camera::set_pitch(0.0f);
+ //render::Camera::set_direction(0.0f);
+ //render::Camera::set_pitch(0.0f);
ui::console()->toggle();
return true;
@@ -737,7 +780,7 @@ void reset()
mouse_direction = 0.0f;
mouse_x = render::State::width() / 2;
mouse_y = render::State::height() / 2;
- render::Camera::reset();
+ render::camera().reset();
render::Dust::reset();
mouse_control_override = false;
mouse_control_override_time = 0.0f;
@@ -951,18 +994,23 @@ void frame()
// if freelook_control is true, the mouse controls freelook
freelook_control = ui::console()->hidden() && freelook_control_override && (freelook_control_override_time + (input_mousedelay->value() / 1000.0f) < core::application()->time());
- // if mouse control is true, the mouse controls the spacecraft
- mouse_control = ui::console()->hidden() && ((input_mousecontrol->value() > 0) || (mouse_control_override && (mouse_control_override_time + (input_mousedelay->value() / 1000.0f) < core::application()->time()) ));
+ if (!freelook_control)
+ {
+ // if mouse control is true, the mouse controls the spacecraft
+ mouse_control = ui::console()->hidden() && ((input_mousecontrol->value() > 0) || (mouse_control_override && (mouse_control_override_time + (input_mousedelay->value() / 1000.0f) < core::application()->time()) ));
- // joystick control takes presedence over mouse control, but not over mouse_control_override
- if (mouse_control && joystick_control && ((render::Camera::mode() == render::Camera::Track) || (render::Camera::mode() == render::Camera::Cockpit))) {
- if (!(mouse_control_override && (mouse_control_override_time + (input_mousedelay->value() / 1000.0f) < core::application()->time()))) {
- mouse_control = false;
+ // joystick control takes presedence over mouse control, but not over mouse_control_override
+ if (mouse_control && joystick_control && ((render::camera().mode() == render::Camera::Track) || (render::camera().mode() == render::Camera::Cockpit)))
+ {
+ if (!(mouse_control_override && (mouse_control_override_time + (input_mousedelay->value() / 1000.0f) < core::application()->time())))
+ {
+ mouse_control = false;
+ }
}
}
if (mouse_control || freelook_control ) {
- const float aim_square_size = 256.0f;
+ const float aim_square_size = math::min(render::State::width(), render::State::height()) * 0.5f;
int l = mouse_x;
int h = mouse_y;
@@ -991,7 +1039,7 @@ void frame()
if (freelook_control)
{
// mouse is controling freelook
- switch (render::Camera::mode())
+ switch (render::camera().mode())
{
case render::Camera::Track:
case render::Camera::Cockpit:
@@ -1007,14 +1055,18 @@ void frame()
// disable autopilot override
local_controlflags = local_controlflags & ~core::EntityControlable::ControlFlagOverride;
}
- render::Camera::set_direction(mouse_direction);
- render::Camera::set_pitch(mouse_pitch);
+
+ render::camera().set_freelook_direction(180.0f * mouse_direction);
+ render::camera().set_freelook_pitch(90.0f * mouse_pitch);
break;
case render::Camera::Free:
- render::Camera::set_direction(-mouse_direction * math::absf(mouse_direction));
- render::Camera::set_pitch(-mouse_pitch * math::absf(mouse_pitch));
+ render::camera().set_movement_direction(0.0f);
+ render::camera().set_movement_pitch(0.0f);
+
+ render::camera().set_freelook_direction(180.0f * mouse_direction);
+ render::camera().set_freelook_pitch(90.0f * mouse_pitch);
// disable autopilot override
local_controlflags = local_controlflags & ~core::EntityControlable::ControlFlagOverride;
@@ -1027,7 +1079,7 @@ void frame()
} else if (mouse_control)
{
// mouse is controling direction
- switch (render::Camera::mode())
+ switch (render::camera().mode())
{
case render::Camera::Track:
case render::Camera::Cockpit:
@@ -1039,8 +1091,8 @@ void frame()
break;
case render::Camera::Free:
- render::Camera::set_direction(-mouse_direction * math::absf(mouse_direction));
- render::Camera::set_pitch(-mouse_pitch * math::absf(mouse_pitch));
+ render::camera().set_movement_direction(mouse_direction);
+ render::camera().set_movement_pitch(mouse_pitch);
// disable autopilot override
local_controlflags = local_controlflags & ~core::EntityControlable::ControlFlagOverride;
@@ -1053,11 +1105,10 @@ void frame()
}
} else {
- //render::Camera::set_direction(0.0f);
- //render::Camera::set_pitch(0.0f);
-
// disable autopilot override
local_controlflags = local_controlflags & ~core::EntityControlable::ControlFlagOverride;
+ render::camera().set_movement_direction(0.0f);
+ render::camera().set_movement_pitch(0.0f);
}
math::clamp(local_direction, -1.0f, 1.0f);
@@ -1089,8 +1140,8 @@ void frame()
local_afterburner = 0.0f;
local_controlflags = core::EntityControlable::ControlFlagNone;
- render::Camera::set_direction(0.0f);
- render::Camera::set_pitch(0.0f);
+ //render::Camera::set_direction(0.0f);
+ //render::Camera::set_pitch(0.0f);
}
}
diff --git a/src/client/savegamemenu.cc b/src/client/savegamemenu.cc
index d002b54..2ba038f 100644
--- a/src/client/savegamemenu.cc
+++ b/src/client/savegamemenu.cc
@@ -567,9 +567,9 @@ void SaveGameMenu::savescreenshot(std::string savename)
gl::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// set camera transformation
- render::Camera::frame(0.0f);
+ render::camera().frame(0.0f);
- render::Camera::frustum();
+ render::camera().draw();
// draw the world
render::draw(0.0f);
diff --git a/src/client/soundext.cc b/src/client/soundext.cc
index dd86a70..9de548b 100644
--- a/src/client/soundext.cc
+++ b/src/client/soundext.cc
@@ -14,7 +14,7 @@
#include "core/entityprojectile.h"
#include "client/soundext.h"
#include "client/client.h"
-#include "render/camera.h"
+#include "render/draw.h"
#include <sstream>
#include <iomanip>
@@ -45,7 +45,7 @@ void render_listener_sound()
(*snd_volume) = master_volume;
}
- audio::update_listener(render::Camera::eye(), render::Camera::axis(), velocity, master_volume);
+ audio::update_listener(render::camera().location(), render::camera().axis(), velocity, master_volume);
}
void render_entity_sound(core::Entity *entity)
diff --git a/src/client/targets.cc b/src/client/targets.cc
index b320b08..ae2afb0 100644
--- a/src/client/targets.cc
+++ b/src/client/targets.cc
@@ -25,7 +25,7 @@
#include "core/range.h"
#include "math/axis.h"
#include "math/vector3f.h"
-#include "render/camera.h"
+#include "render/draw.h"
#include "render/state.h"
namespace client
@@ -395,19 +395,19 @@ void func_target_center(std::string const &args)
// this is essentialy the hover algorithm with the cursor in the center
const core::Entity *new_target = 0;
- math::Vector3f center = render::Camera::eye() + render::Camera::axis().forward() * (render::FRUSTUMFRONT + 0.001);
+ math::Vector3f center = render::camera().location() + render::camera().axis().forward() * (render::FRUSTUMFRONT + 0.001);
float smallest_d = -1;
for (core::Zone::Content::const_iterator it = core::localcontrol()->zone()->content().begin(); it != core::localcontrol()->zone()->content().end(); it++) {
const core::Entity *entity = (*it);
- math::Vector3f v(entity->location() - render::Camera::eye());
+ math::Vector3f v(entity->location() - render::camera().location());
v.normalize();
- if (is_valid_hud_target(entity) && math::dotproduct(render::Camera::axis().forward(), v) > 0.85) {
+ if (is_valid_hud_target(entity) && math::dotproduct(render::camera().axis().forward(), v) > 0.85) {
// calculate the distance from entity location to the line [eye - cursor]
- float d = math::Vector3f::length(math::crossproduct((center - render::Camera::eye()) , (render::Camera::eye() - entity->location()))) / math::Vector3f::length(center - render::Camera::eye());
+ float d = math::Vector3f::length(math::crossproduct((center - render::camera().location()) , (render::camera().location() - entity->location()))) / math::Vector3f::length(center - render::camera().location());
// the entity closer to the center beam
if (smallest_d < 0 || d < smallest_d) {
@@ -495,7 +495,7 @@ void frame()
float x = 0;
float y = 0;
- if ((input::joystick_lastmoved_time() > input::mouse_lastmoved_time()) && (render::Camera::mode() == render::Camera::Cockpit || render::Camera::mode() == render::Camera::Track)) {
+ if ((input::joystick_lastmoved_time() > input::mouse_lastmoved_time()) && (render::camera().mode() == render::Camera::Cockpit || render::camera().mode() == render::Camera::Track)) {
x = 0;
y = 0;
} else {
@@ -503,13 +503,13 @@ void frame()
y = (float)(input::mouse_position_y() - render::State::height() / 2) / (float)render::State::height() / render::State::aspect();
}
- cursor_aim.assign(render::Camera::eye() + render::Camera::axis().forward() * (render::FRUSTUMFRONT + 0.001));
- cursor_aim -= render::Camera::axis().left() * x;
- cursor_aim -= render::Camera::axis().up() * y;
+ cursor_aim.assign(render::camera().location() + render::camera().axis().forward() * (render::FRUSTUMFRONT + 0.001));
+ cursor_aim -= render::camera().axis().left() * x;
+ cursor_aim -= render::camera().axis().up() * y;
float aim_distance = core::range::fxdistance;
- //math::Vector3f center = render::Camera::eye() + (render::Camera::axis().forward() * (render::FRUSTUMFRONT + 0.001f));
+ //math::Vector3f center = render::camera().location() + (render::camera().axis().forward() * (render::FRUSTUMFRONT + 0.001f));
for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it++) {
core::Entity *entity = (*it);
@@ -526,13 +526,13 @@ void frame()
}
// check if the mouse is hovering the entity
- Vector3f v(entity->location() - render::Camera::eye());
+ Vector3f v(entity->location() - render::camera().location());
v.normalize();
- if (math::dotproduct(render::Camera::axis().forward(), v) > 0.75) {
+ if (math::dotproduct(render::camera().axis().forward(), v) > 0.75) {
// calculate the distance from entity location to the line [eye - cursor]
- float d = math::Vector3f::length(math::crossproduct((cursor_aim - render::Camera::eye()) , (render::Camera::eye() - entity->location()))) / math::Vector3f::length(cursor_aim - render::Camera::eye());
+ float d = math::Vector3f::length(math::crossproduct((cursor_aim - render::camera().location()) , (render::camera().location() - entity->location()))) / math::Vector3f::length(cursor_aim - render::camera().location());
float r = entity->radius();
@@ -549,7 +549,7 @@ void frame()
if (z < 0 || myz < z) {
current_hover = entity->id();
// aim slightly behind target to prevent colliding projectiles
- aim_distance = entity->radius() + math::distance(render::Camera::eye(), entity->location());
+ aim_distance = entity->radius() + math::distance(render::camera().location(), entity->location());
z = myz;
}
}
@@ -559,7 +559,7 @@ void frame()
}
}
- cursor_aim = render::Camera::eye() + (cursor_aim - render::Camera::eye()) * aim_distance / math::distance(render::Camera::eye(), cursor_aim);
+ cursor_aim = render::camera().location() + (cursor_aim - render::camera().location()) * aim_distance / math::distance(render::camera().location(), cursor_aim);
if (!current_target) {
current_target_id = 0;
diff --git a/src/client/video.cc b/src/client/video.cc
index b7eb325..5f8c14d 100644
--- a/src/client/video.cc
+++ b/src/client/video.cc
@@ -328,8 +328,6 @@ void frame(float elapsed)
if (core::application()->connected()) {
if (core::game()->time() && core::localplayer()->zone()) {
- render::Camera::frame(elapsed);
- render::Camera::frustum();
render::draw(elapsed); // draw the world
targets::frame(); // validate current target, render sound
diff --git a/src/render/camera.cc b/src/render/camera.cc
index d6cf562..70684d7 100644
--- a/src/render/camera.cc
+++ b/src/render/camera.cc
@@ -6,17 +6,14 @@
#include <cmath>
-#include "core/application.h"
-#include "core/gameinterface.h"
-#include "math/mathlib.h"
-#include "math/matrix4f.h"
#include "render/camera.h"
#include "render/gl.h"
#include "render/state.h"
+#include "core/entity.h"
+#include "core/range.h"
+#include "math/functions.h"
#include "sys/sys.h"
-using math::degrees360f;
-using math::degrees180f;
namespace render
{
@@ -24,134 +21,72 @@ namespace render
const float MIN_DELTA = 10e-10;
const float COS_PI_4 = sqrt(2.0f) * 0.5f;
-const float pitch_free = -30.0f;
-const float pitch_track = -5.0f;
-const float pitch_overview = -5.0f;
-math::Vector3f Camera::camera_eye;
-math::Vector3f Camera::camera_target;
-math::Axis Camera::camera_axis;
-math::Axis Camera::camera_scene_axis;
-Camera::Mode Camera::camera_mode;
-Camera::Mode Camera::camera_previous_mode;
-
-// current and target yaw angle in XZ plane, positive is looking left
-float Camera::direction_current;
-float Camera::direction_target;
-float Camera::target_direction;
-
-// current and target pitch angle in XY, positive is looking up
-float Camera::pitch_current;
-float Camera::pitch_target;
-float Camera::target_pitch;
-
-float Camera::distance;
-float Camera::camera_zoom;
-
-void Camera::init()
+Camera::Camera(const Mode mode)
{
- direction_current = 0;
- direction_target = 0;
-
- pitch_current = pitch_track * 2;
- pitch_target = pitch_track;
-
- target_pitch = 0.0f;
- target_direction = 0.0f;
-
- distance = 0.4f;
- camera_zoom = 2.0f;
-
- camera_mode = Overview;
- camera_previous_mode = Track;
- set_mode(Track);
-
- camera_axis.clear();
- camera_scene_axis.clear();
- camera_eye.clear();
- camera_target.clear();
-
+ _mode = mode;
+ _distance = 1.0f;
+ _multiplier = 1.0f;
+ _target_entity = 0;
+
+ _freelook_direction = 0.0f;
+ _freelook_pitch = 0.0f;
+
+ _movement_direction = 0.0f;
+ _movement_pitch = 0.0f;
}
-void Camera::shutdown()
+Camera::~Camera()
{
}
-void Camera::set_mode(Mode newmode)
+void Camera::set_mode(const Mode mode)
{
+ _mode = mode;
+ reset();
+}
- direction_target = 0;
- direction_current = direction_target;
- pitch_target = pitch_track;
- pitch_current = pitch_target;
-
- target_direction = 0.0f;
- target_pitch = 0.0f;
- distance = 0.4f;
-
- camera_scene_axis.clear();
-
- if (camera_mode != Overview)
- camera_previous_mode = camera_mode;
-
- switch (newmode) {
- case Track:
- // switch camera to Track mode
- camera_mode = Track;
- if (core::localcontrol()) {
- camera_scene_axis.assign(core::localcontrol()->axis());
- }
- break;
-
- case Free:
- // switch camera to Free mode
- camera_mode = Free;
- pitch_target = pitch_free;
- pitch_current = pitch_target;
- break;
-
- case Cockpit:
- camera_mode = Cockpit;
- break;
-
- case Overview:
- // switch camera to Overview mode
- camera_mode = Overview;
+void Camera::set_multiplier(const float multiplier)
+{
+ _multiplier = multiplier;
+}
- default:
- break;
- }
+void Camera::set_freelook_direction(const float angle)
+{
+ _freelook_direction = angle;
+}
+void Camera::set_freelook_pitch(const float angle)
+{
+ _freelook_pitch = angle;
}
-void Camera::view_next()
+void Camera::set_movement_direction(const float speed)
+{
+ _movement_direction = speed;
+ math::clamp(_movement_direction, -1.0f, 1.0f);
+}
+
+void Camera::set_movement_pitch(const float speed)
{
+ _movement_pitch = speed;
+ math::clamp(_movement_pitch, -1.0f, 1.0f);
+}
- if (!core::localcontrol()) {
- set_mode(Overview);
- return;
- }
+void Camera::cycle_mode_next()
+{
- switch (camera_mode) {
+ switch (mode()) {
case Free:
- // switch camera to Track mode
set_mode(Track);
- //con_print << "view: track" << std::endl;
- //core::application()->notify_message(core::Message::Info, std::string("view: track"));
break;
case Track:
- // switch camera to Cockpit mode
set_mode(Cockpit);
- //con_print << "view: cockpit" << std::endl;
- //core::application()->notify_message(core::Message::Info, std::string("view: cockpit"));
break;
case Cockpit:
- // switch camera to Free mode
set_mode(Free);
- //con_print << "view: free" << std::endl;
- //core::application()->notify_message(core::Message::Info, std::string("view: free"));
break;
default:
@@ -159,34 +94,19 @@ void Camera::view_next()
}
}
-void Camera::view_previous()
+void Camera::cycle_mode_previous()
{
-
- if (!core::localcontrol()) {
- set_mode(Overview);
- return;
- }
-
- switch (camera_mode) {
+ switch (mode()) {
case Cockpit:
- // switch camera to Track mode
set_mode(Track);
- //con_print << "view: track" << std::endl;
- //core::application()->notify_message(core::Message::Info, std::string("view: track"));
break;
case Free:
- // switch camera to Cockpit mode
set_mode(Cockpit);
- //con_print << "view: cockpit" << std::endl;
- //core::application()->notify_message(core::Message::Info, std::string("view: cockpit"));
break;
case Track:
- // switch camera to Free mode
set_mode(Free);
- //con_print << "view: free" << std::endl;
- //core::application()->notify_message(core::Message::Info, std::string("view: free"));
break;
default:
@@ -194,180 +114,182 @@ void Camera::view_previous()
}
}
-void Camera::set_zoom(float zoom)
+void Camera::reset()
{
- camera_zoom += zoom;
- math::clamp(camera_zoom, 1.0f, 10.0f);
-}
+ if (target())
+ {
+ _target_location.assign(target()->location());
+ _target_axis.assign(target()->axis());
+ _distance = 0.0f;
+ }
+ else
+ {
+ _location.clear();
+ _target_axis.clear();
+ _distance = 0.0f;
+ }
+ _axis.assign(_target_axis);
+ if (mode() == Free)
+ {
+ _target_axis.clear();
+ }
+
+ _freelook_direction = 0.0f;
+ _freelook_pitch = 0.0f;
-void Camera::frame(float seconds)
+ _movement_direction = 0.0f;
+ _movement_pitch = 0.0f;
+}
+void Camera::set_target(const core::Entity *entity)
{
- math::Axis target_axis;
- float d = 0;
-
- if (core::localplayer()->view()) {
- if (camera_mode != Overview) {
- set_mode(Overview);
- }
- } else if (core::localcontrol()) {
- if (camera_mode == Overview) {
- set_mode(camera_previous_mode);
- }
- } else {
- if (camera_mode != Overview) {
- set_mode(Overview);
- }
- }
+ _target_entity = entity;
+}
- if (mode() == Overview) {
- camera_eye.clear();
-
- if (core::localplayer()->view()) {
- // player view entity
-
- camera_scene_axis.assign(core::localplayer()->view()->axis());
- if (core::localplayer()->view() == core::localcontrol()) {
- camera_scene_axis.change_pitch(pitch_free);
- camera_target.assign(core::localplayer()->view()->location());
- distance = math::max(core::localplayer()->view()->radius(), 1.0f) * 2.0f;
- } else {
- distance = math::max(core::localplayer()->view()->radius(), 1.0f) * 3.0f;
- camera_scene_axis.change_direction(180.0f);
- camera_target.assign(core::localplayer()->view()->location() - core::localplayer()->view()->axis().left()*(math::max(core::localplayer()->view()->radius(), 1.0f)*0.5f));
+void Camera::frame(const float elapsed)
+{
+ const float ROTATESPEED = 25.0f * elapsed;
+ switch(mode())
+ {
+ case Track:
+ {
+ math::Axis desired_axis;
+
+ // 3rd person view
+ if (target())
+ {
+ _target_location.assign(target()->location());
+
+ if (target()->model())
+ {
+ const float modelscale = target()->radius() / target()->model()->radius();
+ _target_location += target()->axis().up() * target()->model()->box().max().z() * modelscale;
+ }
+ else
+ {
+ _target_location += target()->axis().up() * target()->radius();
+ }
+ desired_axis.assign(target()->axis());
+ _distance = target()->radius() * _multiplier * 2.0f;
}
-
- /*
- } else if (core::localplayer()->zone()->default_view()) {
- // default zone view entity
- camera_target.assign(core::localplayer()->zone()->default_view()->location());
- camera_scene_axis.assign(core::localplayer()->zone()->default_view()->axis());
- camera_scene_axis.change_direction(180.0f);
- distance = math::max(core::localplayer()->zone()->default_view()->radius(), 1.0f) * 2.0f;
- */
- } else {
- // default location (0,0,0)
- camera_target.clear();
- camera_scene_axis.clear();
- pitch_current = pitch_overview;
- camera_scene_axis.change_pitch(pitch_current);
- distance = 8.0f;
- }
- } else {
-
- camera_target.assign(core::localcontrol()->location());
- target_axis.assign(core::localcontrol()->axis());
- distance = core::localcontrol()->radius();
-
- if (mode() == Track) {
-
- float cosangle; // cosine of an angle
- float angle; // angle in radians
- math::Vector3f n; // normal of a plane
+ else
+ {
+ _target_location.assign(0.0f, 0.0f, 1.0f);
+ _distance = _multiplier * 2.0f;
+ }
+ // FIXME Bad solution below
- // freelook target
- target_axis.change_direction(90 * target_direction);
- target_axis.change_pitch(90 * target_pitch);
-
- // rotate scene axis towards target axis
- n.assign(math::crossproduct(camera_scene_axis.forward(), target_axis.forward()));
- if (!(n.length() < MIN_DELTA)) {
+ math::Vector3f n (math::crossproduct(_target_axis.forward(), desired_axis.forward()));
+ float l = n.length();
+ float d = math::dotproduct(_target_axis.forward(), desired_axis.forward());
+ float a = (d > 0.0f ? 1.0f - d : 1.0f);
+ if ((a > MIN_DELTA) && (l > MIN_DELTA))
+ {
n.normalize();
- cosangle = math::dotproduct(camera_scene_axis.forward(), target_axis.forward());
- angle = acos(cosangle) * seconds; // * 180.0f / M_PI;
- if (angle > MIN_DELTA)
- camera_scene_axis.rotate(n, -angle);
+ _target_axis.rotate(n, -ROTATESPEED * a);
+
}
-
- n.assign(math::crossproduct(camera_scene_axis.left(), target_axis.left()));
- if (!(n.length() < MIN_DELTA)) {
+
+ n.assign (math::crossproduct(_target_axis.up(), desired_axis.up()));
+ l = n.length();
+ d = math::dotproduct(_target_axis.up(), desired_axis.up());
+ a = (d > 0.0f ? 1.0f - d : 1.0f);
+ if ((a > MIN_DELTA) && (l > MIN_DELTA))
+ {
n.normalize();
- cosangle = math::dotproduct(camera_scene_axis.left(), target_axis.left());
- angle = acos(cosangle) * seconds; // * 180.0f / M_PI;
- if (angle > MIN_DELTA)
- camera_scene_axis.rotate(n, -angle);
+ _target_axis.rotate(n, -ROTATESPEED * a);
+
}
- n.assign(math::crossproduct(camera_scene_axis.up(), target_axis.up()));
- if (!(n.length() < MIN_DELTA)) {
- n.normalize();
- cosangle = math::dotproduct(camera_scene_axis.up(), target_axis.up());
- angle = acos(cosangle) * seconds; // * 180.0f / M_PI;
- if (angle > MIN_DELTA)
- camera_scene_axis.rotate(n, -angle);
+ _axis.assign(_target_axis);
+ _axis.change_direction(_freelook_direction);
+ _axis.change_pitch(_freelook_pitch);
+ break;
+ }
+
+ case Cockpit:
+ {
+ // 1st person view
+ if (target())
+ {
+ _target_location.assign(target()->location());
+ _target_axis.assign(target()->axis());
+ _distance = 0.0f;
}
-
- if (core::localcontrol()->model() && core::localcontrol()->model()->radius()) {
- const float modelscale = core::localcontrol()->radius() / core::localcontrol()->model()->radius();
+ else
+ {
+ _target_location.clear();
+ _target_axis.clear();
+ _distance = 0.0f;
+ }
+
+ _axis.assign(_target_axis);
+ _axis.change_direction(_freelook_direction);
+ _axis.change_pitch(_freelook_pitch);
+ break;
+ }
+ case Free:
+ {
+ // look at self
+ if (target())
+ {
+ _target_location.assign(target()->location());
+ _axis.assign(target()->axis());
- camera_target -= camera_scene_axis.forward() * math::max(FRUSTUMFRONT / WORLDSCALE, core::localcontrol()->model()->box().max().x() * modelscale);
- camera_target += camera_scene_axis.up() * math::max(FRUSTUMFRONT / WORLDSCALE, core::localcontrol()->model()->box().max().z() * modelscale);
- } else {
- camera_target -= camera_scene_axis.forward() * math::max(FRUSTUMFRONT / WORLDSCALE, FRUSTUMFRONT / WORLDSCALE + core::localcontrol()->radius());
- camera_target += camera_scene_axis.up() * math::max(FRUSTUMFRONT / WORLDSCALE, FRUSTUMFRONT / WORLDSCALE + core::localcontrol()->radius());
+ _distance = target()->radius() * _multiplier * 2.0f;
+ }
+ else
+ {
+ _target_location.clear();
+ _axis.clear();
+
+ _distance = _multiplier * 2.0f;
}
- distance = math::max(FRUSTUMFRONT / WORLDSCALE, FRUSTUMFRONT / WORLDSCALE + camera_zoom * core::localcontrol()->radius()) + 0.001f;
-
- } else if (mode() == Free) {
-
- camera_scene_axis.assign(target_axis);
-
- direction_target = direction_current - 90 * target_direction;
- pitch_target = pitch_current - 90 * target_pitch;
-
- // adjust direction
- d = degrees180f(direction_current - direction_target);
- direction_current = degrees360f(direction_current - d * seconds);
- camera_scene_axis.change_direction(direction_current);
-
- // adjust pitch
- d = degrees180f(pitch_current - pitch_target);
- pitch_current = degrees360f(pitch_current - d * seconds);
- camera_scene_axis.change_pitch(pitch_current);
-
- distance = math::max(FRUSTUMFRONT / WORLDSCALE, FRUSTUMFRONT / WORLDSCALE + camera_zoom * core::localcontrol()->radius()) + 0.001f;
-
- } else if (mode() == Cockpit) {
+ _target_axis.rotate(math::Vector3f(0.0f, 0.0f, 1.0f), -M_PI * _movement_direction * elapsed);
+ _target_axis.change_pitch(180.0f * _movement_pitch * elapsed);
- camera_scene_axis.assign(target_axis);
-
- direction_target = + 90 * target_direction;
- pitch_target = + 90 * target_pitch;
-
- // adjust direction
- d = degrees180f(direction_current - direction_target);
- direction_current = degrees360f(direction_current - d * seconds);
- camera_scene_axis.change_direction(direction_current);
-
- // adjust pitch
- d = degrees180f(pitch_current - pitch_target);
- pitch_current = degrees360f(pitch_current - d * seconds);
- camera_scene_axis.change_pitch(pitch_current);
-
- if (core::localcontrol()->model()) {
- const float modelscale = core::localcontrol()->radius() / core::localcontrol()->model()->radius();
- camera_target += (core::localcontrol()->model()->box().max().x() * modelscale) *
- core::localcontrol()->axis().forward();
- } else {
- camera_target += (core::localcontrol()->radius()) *
- core::localcontrol()->axis().forward();
+ _axis.assign(_axis * _target_axis);
+ _axis.change_direction(_freelook_direction);
+ _axis.change_pitch(_freelook_pitch);
+ break;
+ }
+ case Overview:
+ {
+ if (target())
+ {
+ _target_location.assign(target()->location());
+ _target_axis.assign(target()->axis());
+ _distance = 2.0f * target()->radius() * _multiplier;
+
+ _target_axis.change_direction(180.0f);
+
+ // default pitch angle
+ _target_axis.change_pitch(-5.0f);
+ }
+ else
+ {
+ _target_location.clear();
+ _target_axis.clear();
+
+ _distance = 2.0f * _multiplier;
}
- distance = (FRUSTUMFRONT / WORLDSCALE) - 0.001f;
+
+ _axis.assign(_target_axis);
+ break;
}
}
-
- // calculate eye position
- camera_eye = camera_target - (distance * camera_scene_axis.forward());
- camera_axis.assign(camera_scene_axis);
+
+ _distance += FRUSTUMFRONT / WORLDSCALE;
+ _location.assign(_target_location - _axis.forward() * _distance);
}
-void Camera::frustum()
+void Camera::draw()
{
// Change to the projection matrix and set our viewing volume large enough for the skysphere
gl::matrixmode(GL_PROJECTION);
gl::loadidentity();
- gl::frustum(-FRUSTUMSIZE, FRUSTUMSIZE, -FRUSTUMSIZE / State::aspect(), FRUSTUMSIZE / State::aspect(), FRUSTUMFRONT, core::range::maxdistance * WORLDSCALE);
+ gl::frustum(-FRUSTUMSIZE, FRUSTUMSIZE, -FRUSTUMSIZE / State::aspect(), FRUSTUMSIZE / State::aspect(), FRUSTUMFRONT, FARPLANE);
gl::matrixmode(GL_MODELVIEW);
gl::loadidentity();
@@ -376,25 +298,25 @@ void Camera::frustum()
gl::rotate(-90.0f, 1.0f , 0.0f, 0.0f);
// apply the transpose of the axis transformation (the axis is orhtonormal)
- math::Matrix4f matrix;
- matrix.assign(camera_scene_axis);
+ math::Matrix4f matrix(_axis);
gl::multmatrix(matrix.transpose());
- gl::scale(4.0f, 4.0f, 4.0f);
-
- gl::translate(-1.0f * camera_eye);
+ // apply world scale
+ gl::scale(WORLDSCALE, WORLDSCALE, WORLDSCALE);
+ // apply camera eye translation
+ gl::translate(-1.0f * _location);
}
-void Camera::frustum_default(float distance, float cx, float cy)
+void Camera::draw(const float center_x, const float center_y)
{
// Change to the projection matrix and set our viewing volume large enough for the skysphere
gl::matrixmode(GL_PROJECTION);
gl::loadidentity();
- // move eye to (cx, cy)
+ // move projection center to (cx, cy)
// note: the factor 2.0f probably has to be 1.0f/frustum_size
- gl::translate(2.0f*(-State::width() * 0.5f + cx) / State::width() , 2.0f*(State::height() * 0.5f - cy) / State::height(), 0.0f);
+ gl::translate(2.0f*(-State::width() * 0.5f + center_x) / State::width() , 2.0f * (State::height() * 0.5f - center_y) / State::height(), 0.0f);
gl::frustum(-FRUSTUMSIZE, FRUSTUMSIZE, -FRUSTUMSIZE / State::aspect(), FRUSTUMSIZE / State::aspect(), FRUSTUMFRONT, 1023.0f);
@@ -404,10 +326,13 @@ void Camera::frustum_default(float distance, float cx, float cy)
// map world coordinates to opengl coordinates
gl::rotate(90.0f, 0.0f, 1.0f, 0.0f);
gl::rotate(-90.0f, 1.0f , 0.0f, 0.0f);
+
+ // apply the transpose of the axis transformation (the axis is orhtonormal)
+ math::Matrix4f matrix(_axis);
+ gl::multmatrix(matrix.transpose());
- gl::translate(distance + 1.0f, 0.0f, 0.0f);
- camera_eye.assign(-distance - 1.0f, 0.0f, 0.0f);
- camera_axis.clear();
+ // apply camera eye translation
+ gl::translate(-1.0f * _location);
}
void Camera::ortho()
@@ -420,22 +345,7 @@ void Camera::ortho()
gl::matrixmode(GL_MODELVIEW);
gl::loadidentity();
}
+
-void Camera::set_direction(float direction)
-{
- target_direction = direction;
- math::clamp(target_direction, -1.0f, 1.0f);
-}
+} // namespace render
-void Camera::set_pitch(float pitch)
-{
- target_pitch = pitch;
- math::clamp(target_pitch, -1.0f, 1.0f);
-}
-
-void Camera::reset()
-{
- set_mode(camera_mode);
-}
-
-}
diff --git a/src/render/camera.h b/src/render/camera.h
index cc6eaa5..4d01fa2 100644
--- a/src/render/camera.h
+++ b/src/render/camera.h
@@ -7,114 +7,235 @@
#ifndef __INCLUDED_RENDER_CAMERA_H__
#define __INCLUDED_RENDER_CAMERA_H__
-#include "math/mathlib.h"
#include "core/range.h"
+#include "math/vector3f.h"
+#include "math/axis.h"
+
+namespace core
+{
+ class Entity;
+}
namespace render
{
const float WORLDSCALE = 4.0f;
-const float FARPLANE = core::range::maxdistance;
+
const float FRUSTUMSIZE = 0.5f;
const float FRUSTUMFRONT = 1.0f;
+const float FARPLANE = core::range::maxdistance * WORLDSCALE;
-/// camera functions
+/**
+ * @brief The Camera class draws a camera transformation determined by its current settings
+ * */
class Camera
{
public:
-
- /// enum indicating the camera mode
- enum Mode {Free, Track, Cockpit, Overview};
-
- /// initialize the camera
- static void init();
-
- /// shutdown the camera
- static void shutdown();
-
- /// gameworld coordinates of the camera eye
- static inline const math::Vector3f & eye() {
- return camera_eye;
+ /**
+ * @brief enum indicating the camera mode
+ * */
+ enum Mode {Track, Cockpit, Free, Overview};
+
+ /**
+ * @brief default constructor
+ * */
+ Camera(const Mode mode = Track);
+
+ /**
+ * @brief destructor
+ * */
+ ~Camera();
+
+ /* --- inspectors ------------------------------------------ */
+
+ /**
+ * @brief current camera mode
+ * */
+ inline const Mode mode() const
+ {
+ return _mode;
}
-
- /// gameworld coordinates of the camera target
- static inline const math::Vector3f & target() {
- return camera_target;
+
+ /**
+ * @brief distance between the camera eye and the target
+ * */
+ inline const float distance() const
+ {
+ return _distance;
}
-
- /// gameworld camera axis
- static inline const math::Axis & axis() {
- return camera_axis;
+
+ /**
+ * @brief distance multiplier
+ * The distance multiplier can be used to zoom the camera in or out
+ * */
+ inline const float multiplier() const
+ {
+ return _multiplier;
}
-
- /// current camera mode
- static inline Mode mode() {
- return camera_mode;
+
+ /**
+ * @brief camera eye location, translation part of the camera transformation
+ * */
+ inline const math::Vector3f & location() const
+ {
+ return _location;
}
-
- /// reset the current mode
- static void reset();
-
- /// progress the camera
- static void frame(float elapsed);
-
- /// enable camera frustum projection
- /** The camera frustum projection is used to draw the world
- */
- static void frustum();
-
- /// enable default frustum projection
- /** The default frustum projection is used to draw Gui 3D models
- */
- static void frustum_default(float distance, float cx, float cy);
-
- /// enable orthographic projection
- /** The ortographic projetion is used to draw the user interface
- */
+
+ /**
+ * @brief camera target location,point the camera is looking at
+ * */
+ inline const math::Vector3f & target_location() const
+ {
+ return _target_location;
+ }
+
+ /**
+ * @brief camera eye axis, rotation part of the camera transformation
+ * */
+ inline const math::Axis & axis() const
+ {
+ return _axis;
+ }
+
+ /**
+ * @brief the entity the camera is currently looking at
+ * */
+ inline const core::Entity *target()
+ {
+ return _target_entity;
+ }
+
+ /**
+ * @brief free look direction angle, in degrees
+ * */
+ inline const float freelook_direction() const
+ {
+ return _freelook_direction;
+ }
+
+ /**
+ * @brief free look pitch angle, in degrees
+ * */
+ inline const float freelook_pitch() const
+ {
+ return _freelook_pitch;
+ }
+
+ /**
+ * @brief free look direction rotation speed, -1..1
+ * */
+ inline const float movement_direction() const
+ {
+ return _movement_direction;
+ }
+
+ /**
+ * @brief free look pitch rotation speed, -1..1
+ * */
+ inline const float movement_pitch() const
+ {
+ return _movement_pitch;
+ }
+
+ /* --- mutators -------------------------------------------- */
+
+ /**
+ * @brief set the current camera mode
+ * */
+ void set_mode(const Mode mode);
+
+ /**
+ * @brief set next camera mode
+ * */
+ void cycle_mode_next();
+
+ /**
+ * @brief set previous camera mode
+ * */
+ void cycle_mode_previous();
+
+ /**
+ * @brief set camera target
+ * */
+ void set_target(const core::Entity *entity = 0);
+
+ /**
+ * @brief set distance multiplier
+ * */
+ void set_multiplier(const float multiplier);
+
+ /**
+ * @brief set the free look direction angle, in degrees
+ * */
+ void set_freelook_direction(const float angle);
+
+ /**
+ * @brief set the free look pitch angle, in degrees
+ * */
+ void set_freelook_pitch(const float angle);
+
+ /**
+ * @brief set the free look direction rotation speed, -1..1
+ * */
+ void set_movement_direction(const float speed);
+
+ /**
+ * @brief set the free look pitch rotation speed, -1..1
+ * */
+ void set_movement_pitch(const float speed);
+
+ /* --- actors ---------------------------------------------- */
+
+ void reset();
+
+ /**
+ * @brief update the camera location and axis.
+ * */
+ void frame(const float elapsed);
+
+ /**
+ * @brief draw the actual camera transformation
+ * This method is used to draw the camera projection for the world render
+ * and applies WORLDSCALE.
+ * */
+ void draw();
+
+ /**
+ * @brief draw the actual camera transformation
+ * This method variant is used by the user interface 3D model widget
+ * and ignores WORLDSCALE.
+ * */
+ void draw(const float center_x, const float center_y);
+
+ /* --- static ---------------------------------------------- */
+
+ /**
+ * @brief set the current transformation matrix to a orthographic projection
+ * This method is used while drawing the user interface.
+ * */
static void ortho();
- /// set target zoom
- static void set_zoom(float zoom);
-
- /// set target direction
- static void set_direction(float direction);
-
- /// set target pitch
- static void set_pitch(float pitch);
-
- /// switch to next camera mode
- static void view_next();
-
- /// wtich to previous camera mode
- static void view_previous();
-
- /// set specified camera mode
- static void set_mode(Mode newmode);
-
private:
- static math::Vector3f camera_eye;
- static math::Vector3f camera_target;
- static math::Axis camera_axis;
- static math::Axis camera_scene_axis;
- static Mode camera_mode;
- static Mode camera_previous_mode;
-
-
- // current and target yaw angle in XZ plane, positive is looking left
- static float direction_current;
- static float direction_target;
- static float target_direction;
-
- // current and target pitch angle in XY, positive is looking up
- static float pitch_current;
- static float pitch_target;
- static float target_pitch;
-
- static float distance;
- static float camera_zoom;
-
-};
-
-} // namespace client
-
-#endif // __INCLUDED_RENDER_CAMERA_H__
+ Mode _mode;
+
+ float _distance;
+ float _multiplier;
+ math::Vector3f _location;
+ math::Axis _axis;
+
+ const core::Entity * _target_entity;
+ math::Vector3f _target_location;
+ math::Axis _target_axis;
+
+ float _freelook_direction;
+ float _freelook_pitch;
+
+ float _movement_direction;
+ float _movement_pitch;
+
+
+}; // class camera
+
+} // namespace render
+
+#endif // __INCLUDED_RENDER_CAMERA_H__
diff --git a/src/render/draw.cc b/src/render/draw.cc
index c9ccafe..f354780 100644
--- a/src/render/draw.cc
+++ b/src/render/draw.cc
@@ -19,6 +19,7 @@
#include "model/material.h"
#include "model/model.h"
+#include "render/camera.h"
#include "render/debugdrawer.h"
#include "render/draw.h"
#include "render/dust.h"
@@ -54,6 +55,10 @@ math::Vector3f v7(-1, -1, -1);
core::Zone *zone = 0;
+Camera _camera_control(Camera::Track);
+Camera _camera_overview(Camera::Overview);
+Camera *_camera = &_camera_control;
+
bool draw_particles = true;
bool draw_lights = true;
@@ -79,11 +84,50 @@ bool compare_entity_distance(const core::Entity * entityfirst, const core::Entit
LightEnvironment lightenv_zone;
+Camera & camera()
+{
+ return *_camera;
+}
+
/* ---- Prepare the renderer state --------------------------------- */
void pass_prepare(float seconds)
{
- using namespace model;
+ // initialize camera
+ const core::Entity *previous_target = _camera->target();
+
+ if (core::localplayer()->view())
+ {
+ _camera = &_camera_overview;
+ _camera->set_target(core::localplayer()->view());
+ _camera->set_multiplier(2.0f);
+ }
+ else if (core::localcontrol())
+ {
+ if (core::localcontrol()->state() == core::Entity::Destroyed)
+ {
+ _camera = &_camera_overview;
+ _camera->set_multiplier(1.0f);
+ }
+ else
+ {
+ _camera = &_camera_control;
+ }
+ _camera->set_target(core::localcontrol());
+ }
+ else
+ {
+ _camera = &_camera_overview;
+ _camera->set_target(0);
+ }
+
+ if (_camera->target() != previous_target)
+ {
+ _camera->reset();
+ }
+
+ _camera->frame(seconds);
+ _camera->draw();
// render settings for this pass_prepare
draw_lights = true;
@@ -121,7 +165,7 @@ void pass_prepare(float seconds)
if (!ext_render(entity)) {
new RenderExt(entity);
}
- entity->extension((size_t) core::Extension::Render)->frame(seconds);
+ ext_render(entity)->frame(seconds, *_camera);
if (entity->type() == core::Entity::Globe)
{
@@ -146,7 +190,7 @@ void pass_prepare(float seconds)
else
{
// add entity to draw lists
- if (entity->visible() || !ext_render(entity)->behind())
+ if (entity->visible() && !ext_render(entity)->behind())
{
drawlist_entities.push_back(entity);
}
@@ -194,11 +238,11 @@ void draw_pass_sky()
gl::enable(GL_TEXTURE_CUBE_MAP);
gl::push();
- gl::translate(Camera::eye());
+ gl::translate(_camera->location());
gl::color(1.0f, 1.0f, 1.0f, 1.0f);
- const float r = 128.0f;
+ const float r = core::range::maxdistance * 0.5f;
gl::begin((r_wireframe && r_wireframe->value()) ? gl::LineLoop : gl::Quads);
@@ -239,10 +283,10 @@ void draw_pass_sky()
gl::texcoord(-1, 1, -1); gl::vertex(-r, r, -r);
gl::end();
-
- gl::disable(GL_TEXTURE_CUBE_MAP);
gl::pop();
+
+ gl::disable(GL_TEXTURE_CUBE_MAP);
Stats::quads += 6;
}
@@ -298,18 +342,19 @@ void draw_sphere(const math::Color & color, float radius)
}
}
-void draw_globe_corona(const math::Vector3f location, const math::Color & color, const float radius, const size_t corona_id)
+void draw_globe_corona(const Camera & camera, const math::Vector3f & location, const math::Color & color, const float radius, const size_t corona_id)
{
// draw the globe's corona
if (corona_id) {
- math::Vector3f v = location - Camera::eye();
+ math::Vector3f v(location - camera.location());
v.normalize();
- float a = dotproduct(v, Camera::axis().forward());
+ float a = dotproduct(v, camera.axis().forward());
if (a > 0.1f) {
- gl::enable(GL_BLEND);
+
gl::disable(GL_DEPTH_TEST);
gl::depthmask(GL_FALSE); // disable depth buffer writes
gl::enable(GL_TEXTURE_2D);
+ gl::enable(GL_BLEND);
Textures::bind(corona_id);
@@ -320,21 +365,21 @@ void draw_globe_corona(const math::Vector3f location, const math::Color & color,
gl::begin(gl::Quads);
gl::texcoord(0, 1);
- gl::vertex((Camera::axis().up() - Camera::axis().left()) * radius * 4.0f);
+ gl::vertex((camera.axis().up() - camera.axis().left()) * radius * 4.0f);
gl::texcoord(0, 0);
- gl::vertex((Camera::axis().up() + Camera::axis().left()) * radius * 4.0f);
+ gl::vertex((camera.axis().up() + camera.axis().left()) * radius * 4.0f);
gl::texcoord(1, 0);
- gl::vertex((Camera::axis().up() * -1 + Camera::axis().left()) * radius * 4.0f);
+ gl::vertex((camera.axis().up() * -1.0f + camera.axis().left()) * radius * 4.0f);
gl::texcoord(1, 1);
- gl::vertex((Camera::axis().up() * -1 - Camera::axis().left()) * radius * 4.0f);
+ gl::vertex((camera.axis().up() * -1.0f - camera.axis().left()) * radius * 4.0f);
gl::end();
Stats::quads++;
+ gl::disable(GL_BLEND);
gl::disable(GL_TEXTURE_2D);
- gl::enable(GL_DEPTH_TEST);
gl::depthmask(GL_TRUE); // enable depth buffer writes
- gl::disable(GL_BLEND);
+ gl::enable(GL_DEPTH_TEST);
}
}
}
@@ -410,10 +455,10 @@ void draw_pass_globes()
math::Vector3f location(globe->location());
float radius = globe->radius();
- if (ext_render(globe)->distance() > (FARPLANE - globe->radius())) {
+ if (ext_render(globe)->distance() > (core::range::maxdistance - globe->radius())) {
// globe is behind the far plane, make a fake size calculation
- location = Camera::eye() + (location - Camera::eye()) * ((FARPLANE - globe->radius()) / ext_render(globe)->distance());
- radius *= (FARPLANE - globe->radius()) / (ext_render(globe)->distance());
+ location = _camera->location() + (location - _camera->location()) * ((core::range::maxdistance - globe->radius()) / ext_render(globe)->distance());
+ radius *= (core::range::maxdistance - globe->radius()) / (ext_render(globe)->distance());
gl::depthmask(GL_FALSE);
@@ -428,7 +473,7 @@ void draw_pass_globes()
if (globe->corona_id()) {
// draw globe corona
// corona is rendered in camera space
- draw_globe_corona(location, globe->color(), radius, globe->corona_id());
+ draw_globe_corona(*_camera, location, globe->color(), radius, globe->corona_id());
}
}
@@ -446,7 +491,7 @@ void draw_pass_globes()
draw_sphere(globe->color(), radius);
- if (globe->rings_id()) {
+ if (globe->rings_id()) {
if (!globe->texture_id()) {
gl::enable(GL_TEXTURE_2D);
}
@@ -463,7 +508,7 @@ void draw_pass_globes()
gl::enable(GL_LIGHTING);
}
- if (ext_render(globe)->distance() > (FARPLANE - globe->radius())) {
+ if (ext_render(globe)->distance() > (core::range::maxdistance - globe->radius())) {
gl::depthmask(GL_TRUE);
lightenv_zone.draw();
}
@@ -1009,13 +1054,13 @@ void draw_model_lights(model::Model *model, const float scale,
gl::color(color);
gl::texcoord(1, 0);
- gl::vertex(location + (Camera::axis().up() - Camera::axis().left()) * light_size);
+ gl::vertex(location + (_camera->axis().up() - _camera->axis().left()) * light_size);
gl::texcoord(0, 0);
- gl::vertex(location + (Camera::axis().up() + Camera::axis().left()) * light_size);
+ gl::vertex(location + (_camera->axis().up() + _camera->axis().left()) * light_size);
gl::texcoord(0, 1);
- gl::vertex(location + (Camera::axis().up() * -1 + Camera::axis().left()) * light_size);
+ gl::vertex(location + (_camera->axis().up() * -1 + _camera->axis().left()) * light_size);
gl::texcoord(1, 1);
- gl::vertex(location + (Camera::axis().up() * -1 - Camera::axis().left()) * light_size);
+ gl::vertex(location + (_camera->axis().up() * -1 - _camera->axis().left()) * light_size);
nbquads++;
}
@@ -1041,7 +1086,7 @@ void draw_model_lights(model::Model *model, const float scale,
// calulcate viewing angle factor
flare_axis.assign(entity_axis * flare->axis());
- a = math::absf(dotproduct(flare_axis.forward(), Camera::axis().forward()));
+ a = math::absf(dotproduct(flare_axis.forward(), _camera->axis().forward()));
if (a < 0.001f) {
continue; // next flare
}
@@ -1166,7 +1211,7 @@ void draw_pass_model_fx(float elapsed)
if (draw_particles && ext_render(entity)->particles().size()) {
for (RenderExt::ParticleSystems::iterator it = ext_render(entity)->particles().begin(); it != ext_render(entity)->particles().end(); ++it) {
- (*it)->draw(elapsed);
+ (*it)->draw(elapsed, *_camera);
}
}
}
@@ -1207,11 +1252,11 @@ void draw_pass_spacegrid()
float s = 1.0f / gridsize;
float z = -4.0f;
- float dx = Camera::target().x() - floorf(Camera::target().x());
- float dy = Camera::target().y() - floorf(Camera::target().y());
+ float dx = _camera->target_location().x() - floorf(_camera->target_location().x());
+ float dy = _camera->target_location().y() - floorf(_camera->target_location().y());
gl::push();
- gl::translate(Camera::target());
+ gl::translate(_camera->target_location());
gl::color(0, 0, 1.0f);
gl::normal(0, 0, 1.0f);
@@ -1316,7 +1361,7 @@ void draw(float seconds)
math::Color dust_color(core::localplayer()->zone()->ambient_color());
float s = math::max(math::max(dust_color[0], dust_color[1]), dust_color[2]);
dust_color *= 0.8f / s;
- Dust::draw(dust_color); // draw spacedust
+ Dust::draw(*_camera, dust_color); // draw spacedust
}
// draw entity lights, flares and particles
@@ -1406,7 +1451,7 @@ void draw_inidicators(const core::EntityControlable *entity)
// these are in model-space coordinates
- const float r = entity->model()->radius(); // entity radius
+ const float r = entity->model()->radius(); // model radius
const float l = r * 1.8f * entity->thrust(); // thrust indicator lenght
const float b = r * 0.1f; // direction box size
diff --git a/src/render/draw.h b/src/render/draw.h
index d1c7998..0bac3e2 100644
--- a/src/render/draw.h
+++ b/src/render/draw.h
@@ -8,7 +8,7 @@
#define __INCLUDED_RENDER_DRAW_H__
#include "core/gameinterface.h"
-
+#include "render/camera.h"
#include "math/axis.h"
#include "math/vector3f.h"
@@ -34,7 +34,7 @@ void reset();
void draw_sphere(const math::Color & color, float radius);
/// draw globe corona
-void draw_globe_corona(const math::Vector3f location, const math::Color & color, const float radius, const size_t corona_id);
+void draw_globe_corona(const Camera & camera, const math::Vector3f & location, const math::Color & color, const float radius, const size_t corona_id);
/// draw globe rings
void draw_globe_rings(const math::Color & color, const size_t rings_id);
@@ -51,6 +51,9 @@ void draw_model_fragments(model::Model *model,
const float enginetime, const bool detail, const bool power, const float thrust
);
+/// returns the current camera
+Camera & camera();
+
class Stats
{
public:
diff --git a/src/render/dust.cc b/src/render/dust.cc
index 1ca422c..32d2081 100644
--- a/src/render/dust.cc
+++ b/src/render/dust.cc
@@ -20,9 +20,8 @@ core::Cvar *r_dustsize;
const float LOWSPEEDLIMIT = 5.0f;
const float TRAILLENGHT = 0.25f;
-const float DUSTDISTANCE = 8.0f;
-float *dust = 0;
+float *dust = 0;
size_t dustsize = 0;
void Dust::init()
@@ -54,7 +53,7 @@ void Dust::reset()
}
}
-void Dust::draw(math::Color const &dustcolor)
+void Dust::draw(const Camera &camera, const math::Color &dustcolor)
{
float alpha = 0.0f;
float traillength = 0.0f;
@@ -90,7 +89,7 @@ void Dust::draw(math::Color const &dustcolor)
return;
}
-
+ const float dust_distance = camera.distance() * camera.multiplier();
if (!dust) {
con_debug << " generating dust..." << std::endl;
@@ -98,9 +97,9 @@ void Dust::draw(math::Color const &dustcolor)
dust = (float *) malloc(sizeof(float) * dustsize * 3);
for (size_t i = 0; i < dustsize; i++) {
- dust[i*3] = core::localcontrol()->location().x() + (math::randomf(2) - 1) * (DUSTDISTANCE + core::localcontrol()->radius() * 2.0f);
- dust[i*3+1] = core::localcontrol()->location().y() + (math::randomf(2) - 1) * (DUSTDISTANCE + core::localcontrol()->radius() * 2.0f);
- dust[i*3+2] = core::localcontrol()->location().z() + (math::randomf(2) - 1) * (DUSTDISTANCE + core::localcontrol()->radius() * 2.0f);
+ dust[i*3] = core::localcontrol()->location().x() + (math::randomf(2) - 1) * (dust_distance + core::localcontrol()->radius() * 2.0f);
+ dust[i*3+1] = core::localcontrol()->location().y() + (math::randomf(2) - 1) * (dust_distance + core::localcontrol()->radius() * 2.0f);
+ dust[i*3+2] = core::localcontrol()->location().z() + (math::randomf(2) - 1) * (dust_distance + core::localcontrol()->radius() * 2.0f);
}
}
@@ -123,9 +122,9 @@ void Dust::draw(math::Color const &dustcolor)
v[j] = dust[i*3+j] - core::localcontrol()->axis().forward()[j] * traillength;
}
- if (dsquare > (2.0f * core::localcontrol()->radius() + DUSTDISTANCE)*(2.0f * core::localcontrol()->radius() + DUSTDISTANCE)) {
+ if (dsquare > (2.0f * core::localcontrol()->radius() + dust_distance)*(2.0f * core::localcontrol()->radius() + dust_distance)) {
for (size_t j = 0; j < 3; j++) {
- dust[i*3+j] = core::localcontrol()->location()[j] + (math::randomf(2) - 1) * (DUSTDISTANCE + core::localcontrol()->radius() * 2.0f);
+ dust[i*3+j] = core::localcontrol()->location()[j] + (math::randomf(2) - 1) * (dust_distance + core::localcontrol()->radius() * 2.0f);
v[j] = dust[i*3+j] - core::localcontrol()->axis().forward()[j] * traillength;
}
}
diff --git a/src/render/dust.h b/src/render/dust.h
index 4653550..a42cb25 100644
--- a/src/render/dust.h
+++ b/src/render/dust.h
@@ -7,6 +7,9 @@
#ifndef __INCLUDED_RENDER_DUST_H__
#define __INCLUDED_RENDER_DUST_H__
+#include "math/color.h"
+#include "render/camera.h"
+
namespace render
{
@@ -19,7 +22,7 @@ public:
static void shutdown();
- static void draw(math::Color const &dustcolor);
+ static void draw(const Camera &camera, const math::Color &dustcolor);
static void reset();
};
diff --git a/src/render/particleejector.cc b/src/render/particleejector.cc
index 22ddf2d..51be345 100644
--- a/src/render/particleejector.cc
+++ b/src/render/particleejector.cc
@@ -38,7 +38,7 @@ void ParticleEjector::clear()
ejector_last_eject = 0;
}
-void ParticleEjector::frame(const float seconds, const math::Vector3f & ps_location, const math::Axis & ps_axis, const float thrust_factor)
+void ParticleEjector::frame(const float seconds, const Camera &camera, const math::Vector3f & ps_location, const math::Axis & ps_axis, const float thrust_factor)
{
unsigned long now = core::application()->timestamp();
@@ -166,12 +166,13 @@ void ParticleEjector::frame(const float seconds, const math::Vector3f & ps_locat
break;
}
- if (particles().size()) {
- draw(ps_location, ps_axis);
+ if (particles().size())
+ {
+ draw(camera, ps_location, ps_axis);
}
}
-void ParticleEjector::draw(const math::Vector3f & ps_location, const math::Axis & ps_axis)
+void ParticleEjector::draw(const Camera &camera, const math::Vector3f & ps_location, const math::Axis & ps_axis)
{
}
@@ -188,22 +189,22 @@ ParticleEjectorSprite::~ParticleEjectorSprite()
}
-void ParticleEjectorSprite::draw(const math::Vector3f & ps_location, const math::Axis & ps_axis)
+void ParticleEjectorSprite::draw(const Camera &camera, const math::Vector3f & ps_location, const math::Axis & ps_axis)
{
math::Vector3f quad[4];
Textures::bind(texture());
gl::begin(gl::Quads);
- quad[0].assign((Camera::axis().up() - Camera::axis().left()));
- quad[1].assign((Camera::axis().up() + Camera::axis().left()));
- quad[2].assign((Camera::axis().up() * -1 + Camera::axis().left()));
- quad[3].assign((Camera::axis().up() * -1 - Camera::axis().left()));
+ quad[0].assign((camera.axis().up() - camera.axis().left()));
+ quad[1].assign((camera.axis().up() + camera.axis().left()));
+ quad[2].assign((camera.axis().up() * -1 + camera.axis().left()));
+ quad[3].assign((camera.axis().up() * -1 - camera.axis().left()));
for (Particles::iterator it = particles().begin(); it != particles().end(); it++) {
Particle *particle = (*it);
math::Axis rotation;
- rotation.rotate(Camera::axis().forward(), particle->rotation());
+ rotation.rotate(camera.axis().forward(), particle->rotation());
math::Vector3f l(attached() ? ps_location + ps_axis * particle->location() : particle->location());
const float r = particle->radius();
@@ -235,7 +236,7 @@ ParticleEjectorFlare::~ParticleEjectorFlare()
}
-void ParticleEjectorFlare::draw(const math::Vector3f & ps_location, const math::Axis & ps_axis)
+void ParticleEjectorFlare::draw(const Camera &camera, const math::Vector3f & ps_location, const math::Axis & ps_axis)
{
Textures::bind(texture());
gl::begin(gl::Quads);
@@ -274,7 +275,7 @@ ParticleEjectorTrail::~ParticleEjectorTrail()
}
-void ParticleEjectorTrail::draw(const math::Vector3f & ps_location, const math::Axis & ps_axis)
+void ParticleEjectorTrail::draw(const Camera &camera, const math::Vector3f & ps_location, const math::Axis & ps_axis)
{
if (!particles().size()) {
return;
@@ -292,7 +293,7 @@ void ParticleEjectorTrail::draw(const math::Vector3f & ps_location, const math::
gl::color((*first)->color());
//math::Vector3f first_location(attached() ? ps_location + ps_axis * (*first)->location() : (*first)->location());
- math::Vector3f first_normal(math::crossproduct(((*first)->location() - ps_location), ((*first)->location() - Camera::eye())));
+ math::Vector3f first_normal(math::crossproduct(((*first)->location() - ps_location), ((*first)->location() - camera.location())));
first_normal.normalize();
math::Vector3f next_normal(first_normal);
@@ -312,7 +313,7 @@ void ParticleEjectorTrail::draw(const math::Vector3f & ps_location, const math::
Stats::quads++;
while (next != particles().end()) {
- next_normal.assign(math::crossproduct(((*next)->location() - (*first)->location()), ((*next)->location() - Camera::eye())));
+ next_normal.assign(math::crossproduct(((*next)->location() - (*first)->location()), ((*next)->location() - camera.location())));
next_normal.normalize();
gl::color((*first)->color());
@@ -353,7 +354,7 @@ ParticleEjectorStreak::~ParticleEjectorStreak()
}
-void ParticleEjectorStreak::draw(const math::Vector3f & ps_location, const math::Axis & ps_axis)
+void ParticleEjectorStreak::draw(const Camera &camera, const math::Vector3f & ps_location, const math::Axis & ps_axis)
{
if (!particles().size()) {
return;
@@ -377,7 +378,7 @@ void ParticleEjectorStreak::draw(const math::Vector3f & ps_location, const math:
math::Vector3f first_location(attached() ? ps_location + ps_axis * (*first)->location() : (*first)->location());
math::Vector3f next_location(attached() ? ps_location + ps_axis * (*next)->location() : (*next)->location());
- normal.assign(math::crossproduct((first_location - Camera::eye()), (next_location - Camera::eye())));
+ normal.assign(math::crossproduct((first_location - camera.location()), (next_location - camera.location())));
normal.normalize();
gl::color((*first)->color());
diff --git a/src/render/particleejector.h b/src/render/particleejector.h
index d68b32f..57a46d7 100644
--- a/src/render/particleejector.h
+++ b/src/render/particleejector.h
@@ -9,6 +9,7 @@
#include <deque>
+#include "render/camera.h"
#include "render/particleejectorscript.h"
#include "render/particle.h"
@@ -53,7 +54,7 @@ public:
/**
* @brief updated the particles attached to the ejector, and drawn them
* */
- void frame(const float seconds, const math::Vector3f & ps_location, const math::Axis & ps_axis, const float thrust_factor);
+ void frame(const float seconds, const Camera &camera, const math::Vector3f & ps_location, const math::Axis & ps_axis, const float thrust_factor);
/**
* @brief remove all particles
@@ -66,7 +67,7 @@ protected:
return ejector_particles;
}
- virtual void draw(const math::Vector3f & ps_location, const math::Axis & ps_axis);
+ virtual void draw(const Camera &camera, const math::Vector3f & ps_location, const math::Axis & ps_axis);
private:
unsigned long ejector_timestamp;
@@ -85,7 +86,7 @@ public:
virtual ~ParticleEjectorSprite();
protected:
- virtual void draw(const math::Vector3f & ps_location, const math::Axis & ps_axis);
+ virtual void draw(const Camera &camera, const math::Vector3f & ps_location, const math::Axis & ps_axis);
};
/**
@@ -98,7 +99,7 @@ public:
virtual ~ParticleEjectorFlare();
protected:
- virtual void draw(const math::Vector3f & ps_location, const math::Axis & ps_axis);
+ virtual void draw(const Camera &camera, const math::Vector3f & ps_location, const math::Axis & ps_axis);
};
/**
@@ -110,7 +111,7 @@ public:
virtual ~ParticleEjectorTrail();
protected:
- virtual void draw(const math::Vector3f & ps_location, const math::Axis & ps_axis);
+ virtual void draw(const Camera &camera, const math::Vector3f & ps_location, const math::Axis & ps_axis);
};
/**
@@ -122,7 +123,7 @@ public:
virtual ~ParticleEjectorStreak();
protected:
- virtual void draw(const math::Vector3f & ps_location, const math::Axis & ps_axis);
+ virtual void draw(const Camera &camera, const math::Vector3f & ps_location, const math::Axis & ps_axis);
};
} // namespace render
diff --git a/src/render/particlesystem.cc b/src/render/particlesystem.cc
index abc4f0c..74ee498 100644
--- a/src/render/particlesystem.cc
+++ b/src/render/particlesystem.cc
@@ -137,7 +137,7 @@ void ParticleSystem::clear()
(*it)->clear();
}
}
-void ParticleSystem::draw(const float seconds)
+void ParticleSystem::draw(const float seconds, const Camera &camera)
{
// clear particles for docked entities
if ( entity() && (entity()->type() == core::Entity::Controlable)) {
@@ -231,7 +231,7 @@ void ParticleSystem::draw(const float seconds)
}
ejector->enable(ejector_active);
- (*it)->frame(seconds, current_location, current_axis * ejector->axis(), thrust_factor);
+ (*it)->frame(seconds, camera, current_location, current_axis * ejector->axis(), thrust_factor);
}
}
diff --git a/src/render/particlesystem.h b/src/render/particlesystem.h
index 974806f..7675021 100644
--- a/src/render/particlesystem.h
+++ b/src/render/particlesystem.h
@@ -11,6 +11,7 @@
#include "core/entity.h"
+#include "render/camera.h"
#include "render/particlesystemscript.h"
#include "render/particleejector.h"
@@ -30,7 +31,7 @@ public:
ParticleSystem(const ParticleSystemScript *script, const core::Entity *entity, const model::Particles *modelclass);
~ParticleSystem();
- void draw(const float seconds);
+ void draw(const float seconds, const Camera &camera);
/**
* @brief clear all particles from all ejectors
diff --git a/src/render/render.cc b/src/render/render.cc
index 88b2577..b2c2984 100644
--- a/src/render/render.cc
+++ b/src/render/render.cc
@@ -125,8 +125,6 @@ void init(int width, int height)
}
r_mipmap->set_info("[bool] use hardware generated mipmaps (recommended on)");
- Camera::init();
-
Textures::init();
Text::init();
@@ -279,8 +277,6 @@ void shutdown()
Textures::shutdown();
- Camera::shutdown();
-
Dust::shutdown();
State::shutdown();
diff --git a/src/render/renderext.cc b/src/render/renderext.cc
index c66f036..c311be9 100644
--- a/src/render/renderext.cc
+++ b/src/render/renderext.cc
@@ -103,7 +103,11 @@ RenderExt::~RenderExt()
void RenderExt::frame(float elapsed)
{
- state_distance = math::distance(Camera::eye(), entity()->location());
+}
+
+void RenderExt::frame(float elapsed, const Camera & camera)
+{
+ state_distance = math::distance(camera.location(), entity()->location());
state_visible = entity()->visible();
state_detailvisible = false;
@@ -139,7 +143,7 @@ void RenderExt::frame(float elapsed)
return;
}
- if ((controlable == core::localcontrol()) && (Camera::mode() == Camera::Cockpit)) {
+ if ((controlable == core::localcontrol()) && (camera.mode() == camera.Cockpit)) {
state_visible = false;
return;
}
@@ -233,7 +237,7 @@ void RenderExt::frame(float elapsed)
}
}
- if (math::dotproduct(Camera::axis().forward(), entity()->location() + Camera::axis().forward() * entity()->radius() - Camera::eye()) < 0.0f) {
+ if (math::dotproduct(camera.axis().forward(), entity()->location() + camera.axis().forward() * entity()->radius() - camera.location()) < 0.0f) {
state_behind = true;
}
}
diff --git a/src/render/renderext.h b/src/render/renderext.h
index 65fc5ed..3186a9c 100644
--- a/src/render/renderext.h
+++ b/src/render/renderext.h
@@ -75,6 +75,8 @@ public:
}
virtual void frame(float elapsed);
+
+ virtual void frame(float elapsed, const Camera & camera);
private:
diff --git a/src/ui/modelview.cc b/src/ui/modelview.cc
index f1676b1..25a3865 100755
--- a/src/ui/modelview.cc
+++ b/src/ui/modelview.cc
@@ -38,6 +38,8 @@ ModelView::ModelView(Widget *parent) : Widget(parent)
modelview_axis.change_direction(180);
modelview_axis.change_pitch(-15);
+ modelview_camera.set_mode(render::Camera::Free);
+
modelview_mode = Model;
}
@@ -54,6 +56,8 @@ void ModelView::reset()
{
set_background(false);
+ modelview_camera.set_mode(render::Camera::Free);
+
modelview_axis.clear();
modelview_axis.change_direction(180);
modelview_axis.change_pitch(-15);
@@ -104,13 +108,13 @@ bool ModelView::on_mousewheel(const math::Vector2f & direction)
{
if (direction.y() > 0 )
{
- modelview_zoom -= 0.25f;
+ modelview_zoom -= 0.1f;
if (modelview_zoom < 1.0f)
modelview_zoom = 1.0f;
return true;
} else if (direction.y() < 0 )
{
- modelview_zoom += 0.25f;
+ modelview_zoom += 0.1f;
if (modelview_zoom > 5.0f)
modelview_zoom = 5.0f;
return true;
@@ -203,7 +207,9 @@ void ModelView::draw_globe()
const float reference_radius = radius() * minwidget / minscreen;
// gl 3d mode
- render::Camera::frustum_default(modelview_zoom, center.x(), center.y());
+ modelview_camera.set_multiplier(modelview_zoom);
+ modelview_camera.frame(0);
+ modelview_camera.draw(center.x(), center.y());
// set up light environment
render::Light *light = new render::Light(
@@ -246,7 +252,7 @@ void ModelView::draw_globe()
if (modelview_globecoronaname.size()) {
size_t corona_id = render::Textures::load("textures/" + modelview_globecoronaname);
- render::draw_globe_corona(math::Vector3f(0.0f, 0.0f, 0.0f), modelview_color_primary, reference_radius, corona_id);
+ render::draw_globe_corona(modelview_camera, math::Vector3f(0.0f, 0.0f, 0.0f), modelview_color_primary, reference_radius, corona_id);
}
}
@@ -311,8 +317,10 @@ void ModelView::draw_model()
const float modelscale = reference_radius / model->radius();
// gl 3d mode
- render::Camera::frustum_default(modelview_zoom, center.x(), center.y());
-
+ modelview_camera.set_multiplier(modelview_zoom);
+ modelview_camera.frame(0);
+ modelview_camera.draw(center.x(), center.y());
+
// set up light environment
render::Light *light = new render::Light(
math::Vector3f(LIGHT_DISTANCE * reference_radius, 0, 0),
diff --git a/src/ui/modelview.h b/src/ui/modelview.h
index f9566cd..7fd11a9 100755
--- a/src/ui/modelview.h
+++ b/src/ui/modelview.h
@@ -9,6 +9,7 @@
#include "math/axis.h"
#include "ui/widget.h"
+#include "render/camera.h"
namespace ui
{
@@ -137,6 +138,8 @@ private:
math::Axis modelview_axis;
math::Vector2f modelview_cursor;
bool modelview_dragging;
+
+ render::Camera modelview_camera;
};
}