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