From 495c54e187ddbb7514c983e1829a69d82ccad5f3 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Thu, 7 Apr 2011 20:18:11 +0000 Subject: [PATCH] Add View3D class to bundle Layout3D with a camera and a pipeline Store lighting in Layout3D Add get_bounds method to Layout3D Use View3D in designer --- source/3d/layout.cpp | 20 +++++++ source/3d/layout.h | 8 +++ source/3d/view.cpp | 58 ++++++++++++++++++ source/3d/view.h | 39 ++++++++++++ source/designer/cameracontroller.cpp | 34 +++-------- source/designer/cameracontroller.h | 9 ++- source/designer/designer.cpp | 88 ++++++++++------------------ source/designer/designer.h | 12 ++-- 8 files changed, 173 insertions(+), 95 deletions(-) create mode 100644 source/3d/view.cpp create mode 100644 source/3d/view.h diff --git a/source/3d/layout.cpp b/source/3d/layout.cpp index 0a9ee2d..2881e8d 100644 --- a/source/3d/layout.cpp +++ b/source/3d/layout.cpp @@ -18,6 +18,10 @@ Layout3D::Layout3D(Layout &l): layout(l), catalogue(layout.get_catalogue()) { + // South, 15° from zenith + sun.set_position(0, -0.259, 0.966, 0); + lighting.attach(0, sun); + layout.signal_track_added.connect(sigc::mem_fun(this, &Layout3D::track_added)); layout.signal_track_removed.connect(sigc::mem_fun(this, &Layout3D::track_removed)); layout.signal_vehicle_added.connect(sigc::mem_fun(this, &Layout3D::vehicle_added)); @@ -36,6 +40,22 @@ Layout3D::~Layout3D() delete vehicles.begin()->second; } +void Layout3D::get_bounds(Vector &minp, Vector &maxp) const +{ + minp = maxp = Vector(); + + for(TrackMap::const_iterator i=tracks.begin(); i!=tracks.end(); ++i) + { + Vector tmin; + Vector tmax; + i->second->get_bounds(0, tmin, tmax); + minp.x = min(minp.x, tmin.x); + minp.y = min(minp.y, tmin.y); + maxp.x = max(maxp.x, tmax.x); + maxp.y = max(maxp.y, tmax.y); + } +} + void Layout3D::add_track(Track3D &t) { if(tracks.count(&t.get_track())) diff --git a/source/3d/layout.h b/source/3d/layout.h index bb9d427..6dbdb7b 100644 --- a/source/3d/layout.h +++ b/source/3d/layout.h @@ -10,12 +10,15 @@ Distributed under the GPL #include #include +#include +#include #include #include "libr2c2/layout.h" #include "catalogue.h" namespace R2C2 { +class Object3D; class Track3D; class Vehicle3D; @@ -33,12 +36,16 @@ private: Msp::GL::InstanceScene scene; Msp::GL::SimpleScene ep_scene; Msp::GL::InstanceScene path_scene; + Msp::GL::Light sun; + Msp::GL::Lighting lighting; public: Layout3D(Layout &); ~Layout3D(); + Layout &get_layout() const { return layout; } const Catalogue3D &get_catalogue() const { return catalogue; } + void get_bounds(Vector &, Vector &) const; void add_track(Track3D &); void remove_track(Track3D &); @@ -52,6 +59,7 @@ public: Msp::GL::Scene &get_scene() { return scene; } Msp::GL::Scene &get_endpoint_scene() { return ep_scene; } Msp::GL::Scene &get_path_scene() { return path_scene; } + const Msp::GL::Lighting &get_lighting() const { return lighting; } private: void track_added(Track &); diff --git a/source/3d/view.cpp b/source/3d/view.cpp new file mode 100644 index 0000000..006abda --- /dev/null +++ b/source/3d/view.cpp @@ -0,0 +1,58 @@ +/* $Id$ + +This file is part of R²C² +Copyright © 2011 Mikkosoft Productions, Mikko Rasa +Distributed under the GPL +*/ + +#include +#include "layout.h" +#include "track.h" +#include "view.h" + +using namespace std; +using namespace Msp; + +namespace R2C2 { + +View3D::View3D(Layout3D &l, unsigned w, unsigned h): + layout(l), + pipeline(w, h) +{ + pipeline.set_camera(&camera); + pipeline.add_renderable_for_pass(layout.get_scene(), 0); + + GL::PipelinePass *pass = &pipeline.add_pass(0); + pass->lighting = &layout.get_lighting(); + pass->depth_test = &GL::DepthTest::lequal(); + + camera.set_up_direction(GL::Vector3(0, 0, 1)); + // Y+, 60° down + camera.set_look_direction(GL::Vector3(0, 0.5, -0.866)); + + view_all(); +} + +void View3D::view_all(bool tight) +{ + Vector minp; + Vector maxp; + + layout.get_bounds(minp, maxp); + + float t = tan(camera.get_field_of_view()/2)*2; + float size = max((maxp.y-minp.y+0.1), (maxp.x-minp.x+0.1)/camera.get_aspect()); + float dist = size/t; + if(!tight) + dist += sin(camera.get_field_of_view()/2)*size; + GL::Vector3 center((minp.x+maxp.x)/2, (minp.y+maxp.y)/2, 0); + const GL::Vector3 &look = camera.get_look_direction(); + camera.set_position(GL::Vector3(center.x-look.x*dist, center.y-look.y*dist, center.z-look.z*dist)); +} + +void View3D::render() +{ + pipeline.render_all(); +} + +} // namespace R2C2 diff --git a/source/3d/view.h b/source/3d/view.h new file mode 100644 index 0000000..f18f0a1 --- /dev/null +++ b/source/3d/view.h @@ -0,0 +1,39 @@ +/* $Id$ + +This file is part of R²C² +Copyright © 2011 Mikkosoft Productions, Mikko Rasa +Distributed under the GPL +*/ + +#ifndef R2C2_3D_VIEW_H_ +#define R2C2_3D_VIEW_H_ + +#include +#include + +namespace R2C2 { + +class Layout3D; + +class View3D +{ +protected: + Layout3D &layout; + Msp::GL::Camera camera; + Msp::GL::Pipeline pipeline; + +public: + View3D(Layout3D &, unsigned, unsigned); + + Layout3D &get_layout() const { return layout; } + Msp::GL::Camera &get_camera() { return camera; } + Msp::GL::Pipeline &get_pipeline() { return pipeline; } + + void view_all(bool = false); + + void render(); +}; + +} // namespace R2C2 + +#endif diff --git a/source/designer/cameracontroller.cpp b/source/designer/cameracontroller.cpp index 9770320..4706cee 100644 --- a/source/designer/cameracontroller.cpp +++ b/source/designer/cameracontroller.cpp @@ -1,23 +1,23 @@ /* $Id$ This file is part of R²C² -Copyright © 2010 Mikkosoft Productions, Mikko Rasa +Copyright © 2010-2011 Mikkosoft Productions, Mikko Rasa Distributed under the GPL */ #include #include +#include "3d/layout.h" #include "cameracontroller.h" -#include "designer.h" using namespace std; using namespace Msp; using namespace R2C2; -CameraController::CameraController(Designer &d, Graphics::EventSource &es, GL::Camera &c): - designer(d), +CameraController::CameraController(View3D &v, Graphics::EventSource &es): + view(v), event_source(es), - camera(c), + camera(view.get_camera()), move_x(0), move_y(0), drag_mode(NONE) @@ -46,27 +46,7 @@ void CameraController::set_look_direction(const GL::Vector3 &look) void CameraController::view_all() { - Vector minp; - Vector maxp; - - const Layout3D::TrackMap &tracks = designer.get_layout_3d().get_tracks(); - for(Layout3D::TrackMap::const_iterator i=tracks.begin(); i!=tracks.end(); ++i) - { - Vector tmin; - Vector tmax; - i->second->get_bounds(0, tmin, tmax); - minp.x = min(minp.x, tmin.x); - minp.y = min(minp.y, tmin.y); - maxp.x = max(maxp.x, tmax.x); - maxp.y = max(maxp.y, tmax.y); - } - - float t = tan(camera.get_field_of_view()/2)*2; - float size = max((maxp.y-minp.y+0.1), (maxp.x-minp.x+0.1)/camera.get_aspect()); - float dist = size/t+size*0.25; - GL::Vector3 center((minp.x+maxp.x)/2, (minp.y+maxp.y)/2, 0); - const GL::Vector3 &look = camera.get_look_direction(); - camera.set_position(GL::Vector3(center.x-look.x*dist, center.y-look.y*dist, center.z-look.z*dist)); + view.view_all(); } void CameraController::move(float x, float y) @@ -84,7 +64,7 @@ void CameraController::adjust_distance(float delta) const GL::Vector3 &pos = camera.get_position(); const GL::Vector3 &look = camera.get_look_direction(); float dist = get_distance(); - float low = designer.get_layout().get_catalogue().get_gauge()*5; + float low = view.get_layout().get_layout().get_catalogue().get_gauge()*5; if(dist+delta #include - -class Designer; +#include "3d/view.h" /** Moves the camera based on keyboard and mouse events. Controls are as follows: @@ -38,7 +37,7 @@ private: DISTANCE }; - Designer &designer; + R2C2::View3D &view; Msp::Graphics::EventSource &event_source; Msp::GL::Camera &camera; int move_x; @@ -48,7 +47,7 @@ private: DragMode drag_mode; public: - CameraController(Designer &, Msp::Graphics::EventSource &, Msp::GL::Camera &); + CameraController(R2C2::View3D &, Msp::Graphics::EventSource &); void top_down(); void set_look_direction(const Msp::GL::Vector3 &); diff --git a/source/designer/designer.cpp b/source/designer/designer.cpp index bfb3d56..366a948 100644 --- a/source/designer/designer.cpp +++ b/source/designer/designer.cpp @@ -56,8 +56,7 @@ Designer::Designer(int argc, char **argv): cur_zone(0), mode(SELECT), manipulator(*this, root, selection), - measure(*this), - camera_ctl(*this, root, camera) + measure(*this) { window.set_title("Railway Designer"); window.signal_close.connect(sigc::bind(sigc::mem_fun(this, &Designer::exit), 0)); @@ -92,35 +91,27 @@ Designer::Designer(int argc, char **argv): } // Setup OpenGL - pipeline = new GL::Pipeline(window.get_width(), window.get_height(), false); - pipeline->set_camera(&camera); - pipeline->add_renderable_for_pass(layout_3d->get_scene(), 0); - if(base_object) - pipeline->add_renderable(*base_object); - pipeline->add_renderable_for_pass(layout_3d->get_path_scene(), "unlit"); - pipeline->add_renderable_for_pass(layout_3d->get_endpoint_scene(), "unlit"); + cat_view = new View3D(*cat_layout_3d, window.get_width(), window.get_height()); - light.set_position(0, -0.259, 0.966, 0); - lighting.attach(0, light); + main_view = new View3D(*layout_3d, window.get_width(), window.get_height()); + GL::Pipeline *pipeline = &main_view->get_pipeline(); - GL::PipelinePass *pass = &pipeline->add_pass(0); - pass->lighting = &lighting; - pass->depth_test = &GL::DepthTest::lequal(); - - pass = &pipeline->add_pass("unlit"); + GL::PipelinePass *pass = &pipeline->add_pass("unlit"); pass->depth_test = &GL::DepthTest::lequal(); pass->blend = &GL::Blend::alpha(); pass = &pipeline->add_pass("blended"); - pass->lighting = &lighting; + pass->lighting = &layout_3d->get_lighting(); pass->depth_test = &GL::DepthTest::lequal(); pass->blend = &GL::Blend::alpha(); pass = &pipeline->add_pass("overlay"); pass->blend = &GL::Blend::alpha(); - camera.set_up_direction(GL::Vector3(0, 0, 1)); - camera.set_look_direction(GL::Vector3(0, 0.5, -0.866)); + if(base_object) + pipeline->add_renderable(*base_object); + pipeline->add_renderable_for_pass(layout_3d->get_path_scene(), "unlit"); + pipeline->add_renderable_for_pass(layout_3d->get_endpoint_scene(), "unlit"); // Setup UI root.signal_key_press.connect(sigc::mem_fun(this, &Designer::key_press)); @@ -155,7 +146,10 @@ Designer::Designer(int argc, char **argv): overlay = new Overlay3D(ui_res.get_default_font()); pipeline->add_renderable_for_pass(*overlay, "overlay"); - camera_ctl.view_all(); + camera_ctl = new CameraController(*main_view, root); + cat_view->get_camera().set_look_direction(GL::Vector3(0, 0.13053, -0.99144)); + cat_view->view_all(true); + main_view->view_all(); const Layout3D::TrackMap &tracks = layout_3d->get_tracks(); for(Layout3D::TrackMap::const_iterator i=tracks.begin(); i!=tracks.end(); ++i) @@ -166,11 +160,14 @@ Designer::~Designer() { for(vector::iterator i=toolbars.begin(); i!=toolbars.end(); ++i) delete *i; + delete camera_ctl; + delete track_wrap; delete overlay; - delete pipeline; + delete main_view; delete base_object; delete layout_3d; delete layout; + delete cat_view; delete cat_layout_3d; } @@ -341,8 +338,8 @@ Vector Designer::map_pointer_to_ground(int x, int y) { float xf = x*2.0/window.get_width()-1.0; float yf = y*2.0/window.get_height()-1.0; - GL::Vector4 vec = camera.unproject(GL::Vector4(xf, yf, 0, 0)); - const GL::Vector3 &pos = camera.get_position(); + GL::Vector4 vec = main_view->get_camera().unproject(GL::Vector4(xf, yf, 0, 0)); + const GL::Vector3 &pos = main_view->get_camera().get_position(); return Vector(pos.x-vec.x*pos.z/vec.z, pos.y-vec.y*pos.z/vec.z); } @@ -358,7 +355,7 @@ void Designer::tick() window.tick(); root.tick(); - camera_ctl.tick(dt); + camera_ctl->tick(dt); for(list::iterator i=new_tracks.begin(); i!=new_tracks.end(); ++i) layout_3d->get_track(**i).get_path().set_mask(0); @@ -513,37 +510,16 @@ void Designer::pointer_motion(int x, int y) } } -void Designer::apply_camera() -{ - if(mode==CATALOGUE) - { - GL::matrix_mode(GL::PROJECTION); - GL::load_identity(); - GL::frustum_centered(0.11046, 0.082843, 0.1, 10); - GL::matrix_mode(GL::MODELVIEW); - GL::load_identity(); - GL::translate(0, 0, -1); - } - else - camera.apply(); -} - void Designer::render() { GL::Framebuffer::system().clear(GL::COLOR_BUFFER_BIT|GL::DEPTH_BUFFER_BIT); - if(mode==CATALOGUE) - { - apply_camera(); - cat_layout_3d->get_scene().render(); - } - else + View3D *view = (mode==CATALOGUE ? cat_view : main_view); + view->render(); + if(mode==MEASURE) { - pipeline->render_all(); - GL::Bind bind_depth(GL::DepthTest::lequal()); - if(mode==MEASURE) - measure.render(); + measure.render(); } GL::matrix_mode(GL::PROJECTION); @@ -575,14 +551,12 @@ Track *Designer::pick_track(int x, int y) { float xx = x*2.0/window.get_width()-1.0; float yy = y*2.0/window.get_height()-1.0; - if(mode==CATALOGUE) - return catalogue.get_layout().pick_track(Vector(0, 0, 1), Vector(xx*0.05523, yy*0.042421, -0.1)); - else - { - const GL::Vector3 &cpos = camera.get_position(); - GL::Vector4 cray = camera.unproject(GL::Vector4(xx, yy, 0, 0)); - return layout->pick_track(Vector(cpos.x, cpos.y, cpos.z), Vector(cray.x, cray.y, cray.z)); - } + + View3D &view = *(mode==CATALOGUE ? cat_view : main_view); + const GL::Vector3 &cpos = view.get_camera().get_position(); + GL::Vector4 cray = view.get_camera().unproject(GL::Vector4(xx, yy, 0, 0)); + + return view.get_layout().get_layout().pick_track(Vector(cpos.x, cpos.y, cpos.z), Vector(cray.x, cray.y, cray.z)); } void Designer::update_track_icon(Track3D &track) diff --git a/source/designer/designer.h b/source/designer/designer.h index a50c5b8..cbf01d0 100644 --- a/source/designer/designer.h +++ b/source/designer/designer.h @@ -26,6 +26,7 @@ Distributed under the GPL #include "3d/layout.h" #include "3d/overlay.h" #include "3d/track.h" +#include "3d/view.h" #include "cameracontroller.h" #include "manipulator.h" #include "measure.h" @@ -55,24 +56,23 @@ private: R2C2::Catalogue catalogue; R2C2::Layout3D *cat_layout_3d; + R2C2::View3D *cat_view; + std::string filename; R2C2::Layout *layout; R2C2::Layout3D *layout_3d; + R2C2::View3D *main_view; R2C2::Overlay3D *overlay; Msp::GL::Object *base_object; R2C2::Route *cur_route; R2C2::Zone *cur_zone; std::list new_tracks; - Msp::GL::Pipeline *pipeline; - Msp::GL::Camera camera; - Msp::GL::Lighting lighting; - Msp::GL::Light light; Mode mode; Selection selection; Manipulator manipulator; Measure measure; - CameraController camera_ctl; + CameraController *camera_ctl; TrackWrap *track_wrap; Msp::Time::TimeStamp last_tick; @@ -90,7 +90,7 @@ public: const R2C2::Catalogue &get_catalogue() const { return catalogue; } R2C2::Layout &get_layout() { return *layout; } R2C2::Layout3D &get_layout_3d() { return *layout_3d; } - const CameraController &get_camera_controller() const { return camera_ctl; } + const CameraController &get_camera_controller() const { return *camera_ctl; } const Msp::GLtk::Resources &get_ui_resources() const { return ui_res; } Msp::GLtk::Root &get_root() { return root; } -- 2.43.0