nuclear@75: #include nuclear@73: #include "goatview.h" nuclear@74: #include "goat3d.h" nuclear@74: nuclear@74: goat3d *scene; nuclear@75: QSettings *settings; nuclear@75: nuclear@75: static long anim_time; nuclear@75: static float cam_theta, cam_phi, cam_dist = 8; nuclear@75: nuclear@73: nuclear@73: GoatView::GoatView() nuclear@73: { nuclear@73: make_menu(); nuclear@73: make_dock(); nuclear@73: make_center(); nuclear@73: nuclear@73: statusBar(); nuclear@73: nuclear@73: setWindowTitle("GoatView"); nuclear@75: resize(settings->value("main/size", QSize(1024, 768)).toSize()); nuclear@75: move(settings->value("main/pos", QPoint(100, 100)).toPoint()); nuclear@73: } nuclear@73: nuclear@73: GoatView::~GoatView() nuclear@73: { nuclear@73: } nuclear@73: nuclear@75: void GoatView::closeEvent(QCloseEvent *ev) nuclear@75: { nuclear@75: settings->setValue("main/size", size()); nuclear@75: settings->setValue("main/pos", pos()); nuclear@75: } nuclear@75: nuclear@73: bool GoatView::make_menu() nuclear@73: { nuclear@73: QMenu *menu_file = menuBar()->addMenu("&File"); nuclear@73: nuclear@73: QAction *act_open_sce = new QAction("&Open Scene", this); nuclear@73: act_open_sce->setShortcuts(QKeySequence::Open); nuclear@73: connect(act_open_sce, &QAction::triggered, this, &GoatView::open_scene); nuclear@73: menu_file->addAction(act_open_sce); nuclear@73: nuclear@73: QAction *act_open_anm = new QAction("Open &Animation", this); nuclear@73: connect(act_open_anm, &QAction::triggered, this, &GoatView::open_anim); nuclear@73: menu_file->addAction(act_open_anm); nuclear@73: nuclear@73: QAction *act_quit = new QAction("&Quit", this); nuclear@73: act_quit->setShortcuts(QKeySequence::Quit); nuclear@73: connect(act_quit, &QAction::triggered, [&](){qApp->quit();}); nuclear@73: menu_file->addAction(act_quit); nuclear@73: return true; nuclear@73: } nuclear@73: nuclear@73: bool GoatView::make_dock() nuclear@73: { nuclear@73: // ---- side-dock ---- nuclear@73: QWidget *dock_cont = new QWidget; nuclear@73: QVBoxLayout *dock_vbox = new QVBoxLayout; nuclear@73: dock_cont->setLayout(dock_vbox); nuclear@73: nuclear@73: QPushButton *bn_quit = new QPushButton("quit"); nuclear@73: dock_vbox->addWidget(bn_quit); nuclear@73: connect(bn_quit, &QPushButton::clicked, [&](){qApp->quit();}); nuclear@73: nuclear@73: QDockWidget *dock = new QDockWidget("Scene graph", this); nuclear@73: dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); nuclear@73: dock->setWidget(dock_cont); nuclear@73: addDockWidget(Qt::LeftDockWidgetArea, dock); nuclear@73: nuclear@73: // ---- bottom dock ---- nuclear@73: dock_cont = new QWidget; nuclear@73: QHBoxLayout *dock_hbox = new QHBoxLayout; nuclear@73: dock_cont->setLayout(dock_hbox); nuclear@73: nuclear@73: QSlider *slider_time = new QSlider(Qt::Orientation::Horizontal); nuclear@73: slider_time->setDisabled(true); nuclear@73: dock_hbox->addWidget(slider_time); nuclear@73: nuclear@73: dock = new QDockWidget("Animation", this); nuclear@73: dock->setAllowedAreas(Qt::BottomDockWidgetArea); nuclear@73: dock->setWidget(dock_cont); nuclear@73: addDockWidget(Qt::BottomDockWidgetArea, dock); nuclear@73: nuclear@73: return true; nuclear@73: } nuclear@73: nuclear@73: bool GoatView::make_center() nuclear@73: { nuclear@73: GoatViewport *vport = new GoatViewport; nuclear@73: setCentralWidget(vport); nuclear@73: return true; nuclear@73: } nuclear@73: nuclear@73: void GoatView::open_scene() nuclear@73: { nuclear@74: std::string fname = QFileDialog::getOpenFileName(this, "Open scene file", "", nuclear@74: "Goat3D Scene (*.goatsce);;All Files (*)").toStdString(); nuclear@74: if(fname.empty()) { nuclear@74: statusBar()->showMessage("Abort: No file selected!"); nuclear@74: return; nuclear@74: } nuclear@74: nuclear@74: if(scene) { nuclear@74: goat3d_free(scene); nuclear@74: } nuclear@74: nuclear@74: statusBar()->showMessage("opening scene file"); nuclear@74: if(!(scene = goat3d_create()) || goat3d_load(scene, fname.c_str()) == -1) { nuclear@74: statusBar()->showMessage("failed to load scene file"); nuclear@74: } nuclear@73: } nuclear@73: nuclear@73: void GoatView::open_anim() nuclear@73: { nuclear@73: statusBar()->showMessage("opening animation..."); nuclear@73: } nuclear@73: nuclear@73: nuclear@73: // ---- OpenGL viewport ---- nuclear@73: GoatViewport::GoatViewport() nuclear@73: : QGLWidget(QGLFormat(QGL::DepthBuffer)) nuclear@73: { nuclear@73: } nuclear@73: nuclear@73: GoatViewport::~GoatViewport() nuclear@73: { nuclear@73: } nuclear@73: nuclear@73: QSize GoatViewport::sizeHint() const nuclear@73: { nuclear@73: return QSize(800, 600); nuclear@73: } nuclear@73: nuclear@73: void GoatViewport::initializeGL() nuclear@73: { nuclear@75: glClearColor(0.1, 0.1, 0.1, 1); nuclear@73: } nuclear@73: nuclear@73: void GoatViewport::resizeGL(int xsz, int ysz) nuclear@73: { nuclear@73: glViewport(0, 0, xsz, ysz); nuclear@75: glMatrixMode(GL_PROJECTION); nuclear@75: glLoadIdentity(); nuclear@75: gluPerspective(60.0, (float)xsz / (float)ysz, 0.5, 5000.0); nuclear@73: } nuclear@73: nuclear@75: static void draw_node(goat3d_node *node); nuclear@75: nuclear@73: void GoatViewport::paintGL() nuclear@73: { nuclear@75: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); nuclear@75: nuclear@75: glMatrixMode(GL_MODELVIEW); nuclear@75: glLoadIdentity(); nuclear@75: glTranslatef(0, 0, -cam_dist); nuclear@75: glRotatef(cam_phi, 1, 0, 0); nuclear@75: glRotatef(cam_theta, 0, 1, 0); nuclear@75: nuclear@75: if(scene) { nuclear@75: int node_count = goat3d_get_node_count(scene); nuclear@75: for(int i=0; i