diff options
Diffstat (limited to 'src/render')
| -rw-r--r-- | src/render/camera.cc | 512 | ||||
| -rw-r--r-- | src/render/camera.h | 305 | ||||
| -rw-r--r-- | src/render/draw.cc | 113 | ||||
| -rw-r--r-- | src/render/draw.h | 7 | ||||
| -rw-r--r-- | src/render/dust.cc | 17 | ||||
| -rw-r--r-- | src/render/dust.h | 5 | ||||
| -rw-r--r-- | src/render/particleejector.cc | 33 | ||||
| -rw-r--r-- | src/render/particleejector.h | 13 | ||||
| -rw-r--r-- | src/render/particlesystem.cc | 4 | ||||
| -rw-r--r-- | src/render/particlesystem.h | 3 | ||||
| -rw-r--r-- | src/render/render.cc | 4 | ||||
| -rw-r--r-- | src/render/renderext.cc | 10 | ||||
| -rw-r--r-- | src/render/renderext.h | 2 | 
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: | 
