Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/client')
-rw-r--r--src/client/targets.cc146
-rw-r--r--src/client/targets.h3
-rw-r--r--src/client/view.cc232
3 files changed, 231 insertions, 150 deletions
diff --git a/src/client/targets.cc b/src/client/targets.cc
index b87f056..e53e530 100644
--- a/src/client/targets.cc
+++ b/src/client/targets.cc
@@ -24,9 +24,7 @@
#include "core/range.h"
#include "math/axis.h"
#include "math/vector3f.h"
-#include "render/gl.h"
-#include "render/render.h"
-#include "render/text.h"
+#include "render/camera.h"
namespace client {
@@ -377,145 +375,8 @@ void render_entity_sound(core::EntityControlable *entity)
state->location() - state->axis().forward() * entity->model()->maxbbox().y , state->axis().forward() * speed);
}
-void draw_entity_offscreen_target(core::Entity *entity, bool is_active_target)
-{
-
- math::Vector3f target(entity->state()->location() - render::Camera::eye());
- target = render::Camera::axis().transpose() * target;
-
- float cx = 0;
- float cy = 0;
-
- if ( target.y*target.y + target.z*target.z < 0.0001 ) {
- // X - bound, behind (front is visible)
- cx = 0.0f;
- cy = -0.5f;
-
- } else if (fabs(target.y) > fabs(target.z)) {
- // Y-bound
- cx = math::sgnf(target.y) * 0.5f;
- cy = 0.5f * target.z / fabs(target.y);
- } else {
- // Z-bound
- cx = 0.5f * target.y / fabs(target.z);
- cy = math::sgnf(target.z) * 0.5f;
- }
-
- const float r = 16;
- cx = (0.5f - cx) * (float) video::width;
- cy = (0.5f - cy) * (float)video::height;
-
- render::gl::disable(GL_TEXTURE_2D);
- render::gl::color(0, 0, 0, 1);
- render::gl::begin(render::gl::LineLoop);
- glVertex3f(cx+r, cy+2, 0);
- glVertex3f(cx, cy+r+2, 0);
- glVertex3f(cx-r, cy+2, 0);
- glVertex3f(cx, cy-r+2, 0);
- render::gl::end();
-
- if (entity->type() == core::Entity::Controlable) {
- render::gl::color(0, 1, 0, 1);
- } else {
- render::gl::color(1, 1, 1, 1);
- }
-
- render::gl::begin(render::gl::LineLoop);
- glVertex3f(cx+r, cy, 0);
- glVertex3f(cx, cy+r, 0);
- glVertex3f(cx-r, cy, 0);
- glVertex3f(cx, cy-r, 0);
- render::gl::end();
- render::gl::enable(GL_TEXTURE_2D);
-}
-
-void draw_entity_target(core::Entity *entity, bool is_active_target)
-{
- using math::Vector3f;
-
- // don't draw target if we're very close to it
- if (entity->state()->distance() < 0.001f)
- return;
-
- // don't draw target if it is outside the visible cone
- Vector3f target(entity->state()->location() - render::Camera::eye());
- if (math::dotproduct(render::Camera::axis().forward(), Vector3f::normalized(target)) < 0.75 ) {
- draw_entity_offscreen_target(entity, is_active_target);
- return;
- }
-
- // transform the target into the camera coordinate system
- target = render::Camera::axis().transpose() * target;
-
- // calculate the intersection between the line (0,0,0)-target and the frustum front
- float t = (render::Camera::frustum_front() + 0.001f) / target.x;
- Vector3f center(target *t);
-
- float cx = video::width * (0.5 - center.y);
- float cy = video::height * (0.5 - center.z * render::Camera::aspect());
-
- if ((cx < 0 ) || (cy < 0) || (cx > video::width) || (cy > video::height)) {
- draw_entity_offscreen_target(entity, is_active_target);
- return;
- }
-
- const float pointer_size = 48.0f;
- float r = pointer_size;
- if (!is_active_target)
- r *= 0.5;
-
- render::gl::disable(GL_TEXTURE_2D);
- // outer square shadow
- render::gl::color(0, 0, 0, 1);
- render::gl::begin(render::gl::LineLoop);
- glVertex3f(cx+r, cy+2, 0);
- glVertex3f(cx, cy+r+2, 0);
- glVertex3f(cx-r, cy+2, 0);
- glVertex3f(cx, cy-r+2, 0);
- render::gl::end();
-
- if (entity->type() == core::Entity::Controlable) {
- render::gl::color(0, 1, 0, 1);
- } else {
- render::gl::color(1, 1, 1, 1);
- }
- // outer square0
- render::gl::begin(render::gl::LineLoop);
- glVertex3f(cx+r, cy, 0);
- glVertex3f(cx, cy+r, 0);
- glVertex3f(cx-r, cy, 0);
- glVertex3f(cx, cy-r, 0);
- render::gl::end();
-
- render::gl::enable(GL_TEXTURE_2D);
-
- if (is_active_target) {
- // entity name and distance
- std::stringstream strdistance;
- float d = math::distance(core::localcontrol()->location(), entity->state()->location()) - entity->radius() - core::localcontrol()->radius();
- if (d > 0 ) {
- if (d > 100.0f) {
- strdistance << roundf(d * 0.1f) << "km";
- } else {
- strdistance << roundf(d * 100.0f) << "m";
- }
- } else {
- strdistance << "--";
- }
- if (entity->type() == core::Entity::Controlable) {
- render::Text::setcolor('B');
- } else {
- render::Text::setcolor('N');
- }
- render::Text::draw(cx-aux::text_length(entity->name()) * render::Text::fontwidth()*0.5f,
- cy-r-4-render::Text::fontheight(), entity->name());
-
- render::Text::draw(cx - aux::text_length(strdistance.str()) * render::Text::fontwidth() * 0.5f,
- cy+r+4, strdistance);
- }
-}
-// render targets and sounds
+// render targets and sounds (in world coordinates)
void draw()
{
core::Zone *zone = core::localplayer()->zone();
@@ -564,9 +425,6 @@ void draw()
if (entity->id() == current_target_id) {
current_target = entity;
- draw_entity_target(current_target, true);
- } else if (entity->type() == core::Entity::Controlable) {
- draw_entity_target(entity, false);
}
// check if the mouse is hovering the entity
diff --git a/src/client/targets.h b/src/client/targets.h
index f805305..0366415 100644
--- a/src/client/targets.h
+++ b/src/client/targets.h
@@ -22,6 +22,9 @@ void shutdown();
void reset();
+/// return true if the entity is a legal target
+bool is_legal_target(core::Entity *entity);
+
/// render targets and sounds
void draw();
diff --git a/src/client/view.cc b/src/client/view.cc
index 1fdbcdc..24cd72e 100644
--- a/src/client/view.cc
+++ b/src/client/view.cc
@@ -11,6 +11,7 @@
#include <sstream>
#include <iomanip>
+#include "auxiliary/functions.h"
#include "client/client.h"
#include "client/chat.h"
#include "client/console.h"
@@ -23,6 +24,7 @@
#include "render/camera.h"
#include "core/core.h"
#include "core/stats.h"
+#include "core/zone.h"
#include "math/mathlib.h"
#include "sys/sys.h"
@@ -105,6 +107,211 @@ void draw_loader()
gl::end();
}
+
+/*
+ FIXME should be merged with the render passes
+ and in the bbox pass
+*/
+
+void draw_entity_world_target(core::Entity *entity)
+{
+ using namespace render;
+
+ model::Model *model = entity->model();
+ if (!model)
+ return;
+
+ if (!model->docks().size())
+ return;
+
+ gl::enable(GL_DEPTH_TEST);
+ gl::push();
+ gl::translate(entity->state()->location());
+ gl::multmatrix(entity->state()->axis());
+
+ gl::color(0, 1.0f, 1.0f, 1.0f);
+
+ for (model::Model::Docks::iterator dit = model->docks().begin(); dit != model->docks().end(); dit++) {
+ model::Dock *dock = (*dit);
+ math::Vector3f maxbox(dock->location());
+ math::Vector3f minbox(dock->location());
+
+ for (size_t i=0; i < 3; i++) {
+ maxbox[i] += dock->radius();
+ minbox[i] -= dock->radius();
+ }
+
+ // top
+ gl::begin(gl::LineLoop);
+ gl::vertex(maxbox.x, maxbox.y, maxbox.z);
+ gl::vertex(minbox.x, maxbox.y, maxbox.z);
+ gl::vertex(minbox.x, minbox.y, maxbox.z);
+ gl::vertex(maxbox.x, minbox.y, maxbox.z);
+ gl::end();
+
+ // bottom
+ gl::begin(gl::LineLoop);
+ gl::vertex(maxbox.x, maxbox.y, minbox.z);
+ gl::vertex(minbox.x, maxbox.y, minbox.z);
+ gl::vertex(minbox.x, minbox.y, minbox.z);
+ gl::vertex(maxbox.x, minbox.y, minbox.z);
+ gl::end();
+
+ gl::begin(gl::Lines);
+ gl::vertex(maxbox.x, maxbox.y, maxbox.z);
+ gl::vertex(maxbox.x, maxbox.y, minbox.z);
+ gl::vertex(minbox.x, maxbox.y, maxbox.z);
+ gl::vertex(minbox.x, maxbox.y, minbox.z);
+ gl::vertex(minbox.x, minbox.y, maxbox.z);
+ gl::vertex(minbox.x, minbox.y, minbox.z);
+ gl::vertex(maxbox.x, minbox.y, maxbox.z);
+ gl::vertex(maxbox.x, minbox.y, minbox.z);
+ gl::end();
+ }
+
+ gl::pop();
+ gl::disable(GL_DEPTH_TEST);
+
+}
+
+void draw_entity_offscreen_target(core::Entity *entity, bool is_active_target)
+{
+
+ math::Vector3f target(entity->state()->location() - render::Camera::eye());
+ target = render::Camera::axis().transpose() * target;
+
+ float cx = 0;
+ float cy = 0;
+
+ if ( target.y*target.y + target.z*target.z < 0.0001 ) {
+ // X - bound, behind (front is visible)
+ cx = 0.0f;
+ cy = -0.5f;
+
+ } else if (fabs(target.y) > fabs(target.z)) {
+ // Y-bound
+ cx = math::sgnf(target.y) * 0.5f;
+ cy = 0.5f * target.z / fabs(target.y);
+ } else {
+ // Z-bound
+ cx = 0.5f * target.y / fabs(target.z);
+ cy = math::sgnf(target.z) * 0.5f;
+ }
+
+ const float r = 16;
+ cx = (0.5f - cx) * (float) video::width;
+ cy = (0.5f - cy) * (float)video::height;
+
+ render::gl::disable(GL_TEXTURE_2D);
+ render::gl::color(0, 0, 0, 1);
+ render::gl::begin(render::gl::LineLoop);
+ glVertex3f(cx+r, cy+2, 0);
+ glVertex3f(cx, cy+r+2, 0);
+ glVertex3f(cx-r, cy+2, 0);
+ glVertex3f(cx, cy-r+2, 0);
+ render::gl::end();
+
+ if (entity->type() == core::Entity::Controlable) {
+ render::gl::color(0, 1, 0, 1);
+ } else {
+ render::gl::color(1, 1, 1, 1);
+ }
+
+ render::gl::begin(render::gl::LineLoop);
+ glVertex3f(cx+r, cy, 0);
+ glVertex3f(cx, cy+r, 0);
+ glVertex3f(cx-r, cy, 0);
+ glVertex3f(cx, cy-r, 0);
+ render::gl::end();
+ render::gl::enable(GL_TEXTURE_2D);
+}
+
+void draw_entity_target(core::Entity *entity, bool is_active_target)
+{
+ using math::Vector3f;
+
+ // don't draw target if we're very close to it
+ if (entity->state()->distance() < 0.001f)
+ return;
+
+ // don't draw target if it is outside the visible cone
+ Vector3f target(entity->state()->location() - render::Camera::eye());
+ if (math::dotproduct(render::Camera::axis().forward(), Vector3f::normalized(target)) < 0.75 ) {
+ draw_entity_offscreen_target(entity, is_active_target);
+ return;
+ }
+
+ // transform the target into the camera coordinate system
+ target = render::Camera::axis().transpose() * target;
+
+ // calculate the intersection between the line (0,0,0)-target and the frustum front
+ float t = (render::Camera::frustum_front() + 0.001f) / target.x;
+ Vector3f center(target *t);
+
+ float cx = video::width * (0.5 - center.y);
+ float cy = video::height * (0.5 - center.z * render::Camera::aspect());
+
+ if ((cx < 0 ) || (cy < 0) || (cx > video::width) || (cy > video::height)) {
+ draw_entity_offscreen_target(entity, is_active_target);
+ return;
+ }
+
+ const float pointer_size = 48.0f;
+ float r = pointer_size;
+ if (!is_active_target)
+ r *= 0.5;
+
+ render::gl::disable(GL_TEXTURE_2D);
+ // outer square shadow
+ render::gl::color(0, 0, 0, 1);
+ render::gl::begin(render::gl::LineLoop);
+ glVertex3f(cx+r, cy+2, 0);
+ glVertex3f(cx, cy+r+2, 0);
+ glVertex3f(cx-r, cy+2, 0);
+ glVertex3f(cx, cy-r+2, 0);
+ render::gl::end();
+
+ if (entity->type() == core::Entity::Controlable) {
+ render::gl::color(0, 1, 0, 1);
+ } else {
+ render::gl::color(1, 1, 1, 1);
+ }
+ // outer square0
+ render::gl::begin(render::gl::LineLoop);
+ glVertex3f(cx+r, cy, 0);
+ glVertex3f(cx, cy+r, 0);
+ glVertex3f(cx-r, cy, 0);
+ glVertex3f(cx, cy-r, 0);
+ render::gl::end();
+
+ render::gl::enable(GL_TEXTURE_2D);
+
+ if (is_active_target) {
+ // entity name and distance
+ std::stringstream strdistance;
+ float d = math::distance(core::localcontrol()->location(), entity->state()->location()) - entity->radius() - core::localcontrol()->radius();
+ if (d > 0 ) {
+ if (d > 100.0f) {
+ strdistance << roundf(d * 0.1f) << "km";
+ } else {
+ strdistance << roundf(d * 100.0f) << "m";
+ }
+ } else {
+ strdistance << "--";
+ }
+ if (entity->type() == core::Entity::Controlable) {
+ render::Text::setcolor('B');
+ } else {
+ render::Text::setcolor('N');
+ }
+ render::Text::draw(cx-aux::text_length(entity->name()) * render::Text::fontwidth()*0.5f,
+ cy-r-4-render::Text::fontheight(), entity->name());
+
+ render::Text::draw(cx - aux::text_length(strdistance.str()) * render::Text::fontwidth() * 0.5f,
+ cy+r+4, strdistance);
+ }
+}
+
void draw_status()
{
using namespace render;
@@ -168,7 +375,21 @@ void draw_status()
}
// draw a basic HUD
- if (core::localcontrol()) {
+ if (core::localcontrol() && core::localcontrol()->zone()) {
+ core::Zone *zone = core::localcontrol()->zone();
+
+ // draw targets
+ for (core::Zone::Content::iterator it=zone->content().begin(); it != zone->content().end(); it++) {
+ core::Entity *entity = (*it);
+
+ if (targets::is_legal_target(entity)) {
+ if (entity == targets::current()) {
+ draw_entity_target(entity, true);
+ } else if (entity->type() == core::Entity::Controlable) {
+ draw_entity_target(entity, false);
+ }
+ }
+ }
unsigned int state = core::localcontrol()->eventstate();
if (state) {
@@ -472,6 +693,10 @@ void frame(float seconds)
if (core::application()->connected() && core::game()->serverframetime()) {
render::draw(seconds); // draw the world
+ targets::draw(); // validate current target, render sound
+
+ if (targets::current()) // draw target docks etc
+ draw_entity_world_target(targets::current());
}
// switch to orthographic projection to draw the GUI
@@ -501,11 +726,6 @@ void frame(float seconds)
if (draw_ui->value()) {
Text::setfont("bitmaps/fonts/gui", 12, 18);
- // draw the current targets
- if (core::application()->connected() && core::game()->serverframetime()) {
- targets::draw();
- }
-
// draw the player status
draw_status();