/* ui/modelview.cc This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2 */ #include "auxiliary/functions.h" #include "core/application.h" #include "ui/modelview.h" #include "ui/paint.h" #include "ui/ui.h" #include "sys/sys.h" #include "render/camera.h" #include "render/draw.h" #include "render/render.h" namespace ui { ModelView::ModelView(Widget *parent, const char *modelname) : Widget(parent) { set_border(false); set_background(false); set_label("modelview"); set_modelname(modelname); modelview_zoom = 1.0f; modelview_dragging = false; modelview_axis.clear(); modelview_axis.change_direction(180); modelview_axis.change_pitch(-15); } ModelView::~ModelView() {} void ModelView::print(const size_t indent) const { std::string marker(""); con_print << aux::pad_left(marker, indent*2) << label() << " \"" << modelname() << "\"" << std::endl; } void ModelView::set_modelname(const char *modelname) { if (modelname) modelview_modelname.assign(modelname); else modelview_modelname.clear(); set_background(false); modelview_axis.clear(); modelview_axis.change_direction(180); modelview_axis.change_pitch(-15); modelview_zoom = 1.0f; modelview_radius = 0.75f; } void ModelView::set_color(const math::Color & color) { modelview_color.assign(color); } void ModelView::set_zoom(const float zoom) { modelview_zoom = zoom; math::clamp(modelview_zoom, 1.0f, 10.0f); } bool ModelView::on_keypress(const int key, const unsigned int modifier) { if (key == 512 + SDL_BUTTON_WHEELUP) { modelview_zoom -= 0.5f; if (modelview_zoom < 1.0f) modelview_zoom = 1.0f; return true; } else if (key == 512 + SDL_BUTTON_WHEELDOWN) { modelview_zoom += 0.5f; if (modelview_zoom > 10.0f) modelview_zoom = 10.0f; return true; } else if (key == 512 + SDL_BUTTON_LEFT) { modelview_dragging = true; return true; } return false; } bool ModelView::on_keyrelease(const int key, const unsigned int modifier) { if (key == 512 + SDL_BUTTON_LEFT) { modelview_dragging = false; return true; } return false; } void ModelView::on_mousemove(const math::Vector2f &cursor) { if ((width() <= 0) || (height() <= 0)) { return; } if (modelview_dragging) { const math::Vector2f pos(cursor - modelview_cursor); const math::Vector3f up(0.0f, 0.0f, 1.0f); const float zrot = 2.0f * M_PI * pos.x() / width(); modelview_axis.rotate(up, -zrot); const math::Vector3f left(0.0f, 1.0f, 0.0f); const float yrot = 2.0f * M_PI * pos.y() / height(); modelview_axis.rotate(left, yrot); modelview_cursor.assign(cursor); } modelview_cursor.assign(cursor); } void ModelView::on_mouseover(const math::Vector2f &cursor) { modelview_cursor.assign(cursor); modelview_dragging = false; } void ModelView::draw_background() { Paint::set_color(1.0f, 1.0f, 1.0f); Paint::draw_bitmap(global_location(), size(), "textures/common/notex"); } void ModelView::draw() { if (!modelview_modelname.size()) { return; } Paint::set_color(1.0f, 1.0f, 1.0f); model::Model *model = model::Model::load(modelview_modelname); if (!model) { modelview_modelname.clear(); set_background(true); return; } math ::Vector2f center(global_location() + size() * 0.5f); gl::clear(GL_DEPTH_BUFFER_BIT); const float minscreen(math::min(root()->width(),root()->height())); const float minwidget(math::min(width(), height())); const float reference_radius = radius() * minwidget / minscreen; const float modelscale = reference_radius / model->radius(); // gl 3d mode render::Camera::frustum_default(modelview_zoom, center.x(), center.y()); // reset lighting render::pass_reset_lights(); // enable lighting gl::enable(GL_LIGHTING); // apply manipulation gl::push(); gl::multmatrix(modelview_axis); gl::scale(modelscale, modelscale, modelscale); gl::disable(GL_BLEND); gl::depthmask(GL_TRUE); // enable writing to the depth buffer gl::enable(GL_DEPTH_TEST); gl::enable(GL_CULL_FACE); // enable culling gl::enable(GL_COLOR_MATERIAL); // enable color tracking // enable vertex arrays glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); render::State::set_normalize(true); render::draw_model_fragments(model, core::localplayer()->color(), core::localplayer()->color_second(), core::application()->time(), true, true, 0.0f); render::State::set_normalize(false); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); gl::disable(GL_LIGHTING); gl::disable(GL_COLOR_MATERIAL); // disable color tracking gl::disable(GL_CULL_FACE); // disable culling gl::enable(GL_BLEND); // enable alpha blending gl::pop(); /* // draw manipulation marker if (has_mouse_focus() && modelview_dragging) { gl::push(); gl::multmatrix(modelview_manipaxis); const float r = model->radius(); glAlphaFunc(GL_GREATER, 0.5f); gl::enable(GL_ALPHA_TEST); gl::color(1.0f, 1.0f, 1.0f, 1.0f); render::Textures::bind("bitmaps/ui/rotate"); gl::enable(GL_TEXTURE_2D); gl::begin(gl::Quads); gl::texcoord(0.0f, 0.0f); gl::vertex(r, 0.0f, r); gl::texcoord(1.0f, 0.0f); gl::vertex(r, 0.0f, -r); gl::texcoord(1.0f, 1.0f); gl::vertex(-r, 0.0f, -r); gl::texcoord(0.0f, 1.0f); gl::vertex(-r, 0.0f, r); gl::texcoord(1.0f, 1.0f); gl::vertex(r, r, 0.0f); gl::texcoord(0.0f, 1.0f); gl::vertex(r, -r, 0.0f); gl::texcoord(0.0f, 0.0f); gl::vertex(-r, -r, 0.0f); gl::texcoord(1.0f, 0.0f); gl::vertex(-r, r, 0.0f); gl::end(); gl::disable(GL_TEXTURE_2D); gl::disable(GL_ALPHA_TEST); gl::pop(); } */ gl::depthmask(GL_TRUE); // enable depth buffer writing gl::disable(GL_DEPTH_TEST); // disable depth buffer testing // gl 2d mode render::Camera::ortho(); } void ModelView::draw_border() { Paint::set_color(palette()->foreground()); Paint::draw_border(global_location(), size()); } }