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 /src/render
parent26c8cf4d74062fb12871ae9d5298d8ceaab7a2cf (diff)
Reimplemented camera handling enabling 360-degree freelook.
Diffstat (limited to 'src/render')
-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
13 files changed, 557 insertions, 471 deletions
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: