/* Stanley Designer Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "qglview_window.h" #include "loader_qgl.h" #include "loader_ase.h" #include "loader_3ds.h" #include "loader_obj.h" #include "loader_dae.h" #include #include #include QGLViewWindow::QGLViewWindow(QWidget * parent): QMainWindow(parent), Ui::QGLViewWindow() { setupUi(this); session.setFile("session_qglview_test.conf"); session.addEntry(this); icon_geo = QIcon(":/icons/type-geo.png"); icon_camera = QIcon(":/icons/type-camera.png"); icon_light = QIcon(":/icons/type-light.png"); QAction * a = new QAction(QIcon(":/icons/edit-delete.png"), "Remove"); connect(a, SIGNAL(triggered()), this, SLOT(removeObjects())); treeObjects->addAction(a); spinViewLineWidth->setValue(lineThickness()*2); sel_obj = nullptr; view->view()->camera()->setAim(QVector3D()); view->view()->camera()->setPos(QVector3D(2, 2, 2)); // view->setFrameShape(QFrame::NoFrame); view->view()->setRenderer(new RendererSimple(view->view())); view->view()->setMouseRotateEnabled(true); view->view()->setMouseSelectionEnabled(true); view->view()->setSelectionHaloEnabled(true); view->view()->setHoverHaloEnabled(true); view->view()->setHoverHaloFillAlpha(0.); view->view()->setSelectionHaloFillAlpha(0.); view->view()->setBackColor(Qt::lightGray); view->view()->setDepthStart(0.1); view->view()->setDepthEnd(100000.); spinFOV->setValue(view->view()->FOV()); spinDepthStart->setValue(view->view()->depthStart()); spinDepthEnd->setValue(view->view()->depthEnd()); groupHoverHalo->setChecked(view->view()->isHoverHaloEnabled()); groupSelectionHalo->setChecked(view->view()->isSelectionHaloEnabled()); spinHoverHaloFill->setValue(view->view()->hoverHaloFillAlpha()); spinSelectionHaloFill->setValue(view->view()->selectionHaloFillAlpha()); colorHoverHalo->setColor(view->view()->hoverHaloColor()); colorSelectionHalo->setColor(view->view()->selectionHaloColor()); checkFXAA->setChecked(view->view()->isFeatureEnabled(QGLView::qglFXAA)); checkMSAA->setChecked(view->view()->isFeatureEnabled(QGLView::qglMSAA)); colorBack->setColor(view->view()->backColor()); colorAmbient->setColor(view->view()->ambientColor()); checkCameraOrbit->setChecked(view->view()->isCameraOrbit()); groupShadows->setChecked(view->view()->isFeatureEnabled(QGLView::qglShadowsEnabled)); groupEyeAccomodation->setChecked(view->view()->isFeatureEnabled(QGLView::qglEyeAccomodationEnabled)); groupBloom->setChecked(view->view()->isFeatureEnabled(QGLView::qglBloomEnabled)); groupMotionBlur->setChecked(view->view()->isFeatureEnabled(QGLView::qglMotionBlurEnabled)); groupReflections->setChecked(view->view()->isFeatureEnabled(QGLView::qglReflectionsEnabled)); checkSoftShadows->setChecked(view->view()->isFeatureEnabled(QGLView::qglShadowsSoftEnabled)); groupSSAO->setChecked(view->view()->isFeatureEnabled(QGLView::qglSSAOEnabled)); spinAccom->setValue(view->view()->feature(QGLView::qglEyeAccomodationTime).toDouble()); spinAccomMS->setValue(view->view()->feature(QGLView::qglEyeAccomodationMaxSpeed).toDouble()); checkReflectionsBlur->setChecked(view->view()->isFeatureEnabled(QGLView::qglReflectionsBlur)); spinShadowmapSize->setValue(view->view()->feature(QGLView::qglShadowsMapSize).toInt()); spinMotionBlurFactor->setValue(view->view()->feature(QGLView::qglMotionBlurFactor).toDouble()); spinMotionBlurSteps->setValue(view->view()->feature(QGLView::qglMotionBlurSteps).toInt()); spinBloomFactor->setValue(view->view()->feature(QGLView::qglBloomFactor).toDouble()); spinBloomRadius->setValue(view->view()->feature(QGLView::qglBloomRadius).toInt()); spinBloomThreshold->setValue(view->view()->feature(QGLView::qglBloomThreshold).toDouble()); spinSSAORadius->setValue(view->view()->feature(QGLView::qglSSAORadius).toInt()); groupDOF->setChecked(view->view()->isFeatureEnabled(QGLView::qglDepthOfFieldEnabled)); checkDOFAutoFocus->setChecked(view->view()->isFeatureEnabled(QGLView::qglDepthOfFieldAutoFocusEnabled)); spinDOFFocus->setValue(view->view()->feature(QGLView::qglDepthOfFieldFocus).toDouble()); spinDOFDiaphragm->setValue(view->view()->feature(QGLView::qglDepthOfFieldDiaphragm).toDouble()); spinDOFSpeed->setValue(view->view()->feature(QGLView::qglDepthOfFieldAutoFocusSpeed).toDouble()); axis = new GLObjectBase(); GLObjectBase * obj; float al = 1.; obj = new GLPrimitiveLine(QVector3D(0, 0, -al), QVector3D(0, 0, al)); obj->material().color_diffuse = Qt::darkBlue; obj->setAcceptLight(false); axis->addChild(obj); obj = new GLPrimitiveLine(QVector3D(-al, 0, 0), QVector3D(al, 0, 0)); obj->material().color_diffuse = Qt::darkRed; obj->setAcceptLight(false); axis->addChild(obj); obj = new GLPrimitiveLine(QVector3D(0, -al, 0), QVector3D(0, al, 0)); obj->material().color_diffuse = Qt::darkGreen; obj->setAcceptLight(false); axis->addChild(obj); view->view()->addObject(axis); cam_light = new Light(); cam_light->intensity = 0.5; cam_light->setName("Camera_Light"); view->view()->camera()->addChild(cam_light); view->view()->start(-1); startTimer(1000/60); connect(view->view(), SIGNAL(selectionChanged(GLObjectBase*,GLObjectBase*)), this, SLOT(selectionChanged(GLObjectBase*,GLObjectBase*))); connect(view->view(), SIGNAL(keyEvent(Qt::Key, Qt::KeyboardModifiers)), this, SLOT(view_keyEvent(Qt::Key, Qt::KeyboardModifiers))); connect(matEditor, SIGNAL(changed()), this, SLOT(materialChanged())); //view->view()->addObject(&partsys); partsys.material().color_diffuse = Qt::red; treeProps->assignObject(&partsys); session.load(); } QGLViewWindow::~QGLViewWindow() { session.save(); //delete ps; } void QGLViewWindow::changeEvent(QEvent * e) { QMainWindow::changeEvent(e); if (e->type() == QEvent::LanguageChange) { retranslateUi(this); return; } } void QGLViewWindow::timerEvent(QTimerEvent * ) { //static double t = 0.; //cam_light->intensity = checkCameraLight->isChecked() ? 0.5 : 0.; cam_light->setVisible(checkCameraLight->isChecked()); //((RendererSimple*)(view->view()->renderer()))->mpos = view->view()->mapFromGlobal(QCursor::pos()); statusBar()->showMessage(QString("FPS: %1").arg(QString::number(view->view()->currentFPS(), 'f', 2))); } void QGLViewWindow::loadFile(const QString & path) { prev_path = path; importFile(path); } void QGLViewWindow::importFile(const QString & path) { QApplication::setOverrideCursor(Qt::WaitCursor); QFileInfo fi(path); GLObjectBase * o = nullptr; if (fi.suffix().toLower() == "qgl") o = loadFromQGLFile(path); if (fi.suffix().toLower() == "ase") o = loadFromASEFile(path); if (fi.suffix().toLower() == "3ds") o = loadFrom3DSFile(path); if (fi.suffix().toLower() == "obj") o = loadFromOBJFile(path); if (fi.suffix().toLower() == "dae") o = loadFromDAEFile(path); QApplication::restoreOverrideCursor(); if (!o) { QMessageBox::critical(this, "Import", "Can`t load " + path + "!"); return; } o->setName(fi.baseName()); view->view()->addObject(o); objectsTreeChanged(); } void QGLViewWindow::makeObjetTree(const GLObjectBase * o, QTreeWidgetItem * ti) { if (o == axis) return; for (int i = 0; i < o->childCount(); ++i) { const GLObjectBase * co = o->child(i); QTreeWidgetItem * ci = new QTreeWidgetItem(ti); ci->setText(0, co->name()); ci->setData(0, Qt::UserRole, quintptr(co)); switch (co->type()) { case GLObjectBase::glMesh: ci->setIcon(0, icon_geo); break; case GLObjectBase::glLight: ci->setIcon(0, icon_light); break; case GLObjectBase::glCamera: ci->setIcon(0, icon_camera); break; default: break; } makeObjetTree(co, ci); } } void QGLViewWindow::selectionChanged(GLObjectBase * cur, GLObjectBase *) { sel_obj = cur; //qDebug() << "selected" << (cur != 0 ? cur->name() : "0"); labelName->setText(cur != nullptr ? cur->name() : ""); /**if (cur == 0) box->hide(); else { box->setScale(cur->boundingBox().size()); box->setPos(cur->boundingBox().pos()); Box3D b = cur->boundingBox().movedTo(-cur->boundingBox().center()); b.z = -b.z - b.height; ps->setEmitterRect(b); cur->addChild(box); box->show(); }*/ objectEditor->setObject(sel_obj); if (sel_obj == nullptr) return; matEditor->setMaterial(sel_obj->material()); //qDebug() << sel_obj->boundingBox(); } void QGLViewWindow::materialChanged() { if (sel_obj == nullptr) return; sel_obj->setMaterial(matEditor->material()); } void QGLViewWindow::on_comboRenderer_currentIndexChanged(int val) { GLRendererBase * pr = nullptr; switch (val) { case 0: view->view()->setRenderer(new RendererSimple(view->view()), &pr); break; case 1: view->view()->setRenderer(new RendererDeferredShading(view->view()), &pr); break; //case 2: view->view()->setRenderer(new RendererRT(view), &pr); break; } if (pr != nullptr) delete pr; } void QGLViewWindow::on_actionReset_triggered() { view->view()->removeObject(axis, false); view->view()->clearObjects(true); view->view()->addObject(axis); objectsTreeChanged(); } void QGLViewWindow::on_actionImport_triggered() { QStringList fl = QFileDialog::getOpenFileNames(this, "Select files", prev_path, "Supported types(*.qgl *.ase *.3ds *.obj *.dae);;" "QGLView(*.qgl);;" "Ascii Scene Export(*.ase);;" "3D Studio(*.3ds);;" "Wavefront OBJ(*.obj);;" "Collada(*.dae)"); if (fl.isEmpty()) return; prev_path = fl.back(); foreach (QString f, fl) importFile(f); } void QGLViewWindow::on_actionSave_triggered() { QString f = QFileDialog::getSaveFileName(this, "Select file", prev_path, "QGLView(*.qgl)"); if (f.isEmpty()) return; if (f.right(4).toLower() != ".qgl") f += ".qgl"; prev_path = f; view->view()->removeObject(axis); QApplication::setOverrideCursor(Qt::WaitCursor); saveToQGLFile(f, &(view->view()->rootObject())); QApplication::restoreOverrideCursor(); view->view()->addObject(axis); } void QGLViewWindow::on_actionSaveSelected_triggered() { if (!sel_obj) return; QString f = QFileDialog::getSaveFileName(this, "Select file", prev_path, "QGLView(*.qgl)"); if (f.isEmpty()) return; if (f.right(4).toLower() != ".qgl") f += ".qgl"; prev_path = f; QApplication::setOverrideCursor(Qt::WaitCursor); saveToQGLFile(f, sel_obj); QApplication::restoreOverrideCursor(); } void QGLViewWindow::on_actionOpen_triggered() { QString f = QFileDialog::getOpenFileName(this, "Select file", prev_path, "Supported types(*.qgl *.ase *.3ds *.obj *.dae);;" "QGLView(*.qgl);;" "Ascii Scene Export(*.ase);;" "3D Studio(*.3ds);;" "Wavefront OBJ(*.obj);;" "Collada(*.dae)"); if (f.isEmpty()) return; prev_path = f; importFile(f); } void QGLViewWindow::view_keyEvent(Qt::Key k, Qt::KeyboardModifiers m) { //qDebug() << k; double spd = 0.2; if (m.testFlag(Qt::ShiftModifier)) spd = 0.5; switch (k) { case Qt::Key_W: view->view()->camera()->moveForward(spd); break; case Qt::Key_S: view->view()->camera()->moveBackward(spd); break; case Qt::Key_A: view->view()->camera()->moveLeft(spd); break; case Qt::Key_D: view->view()->camera()->moveRight(spd); break; default: break; } } void QGLViewWindow::on_treeObjects_itemClicked(QTreeWidgetItem * ti, int) { ((GLObjectBase*)(ti->data(0, Qt::UserRole).toULongLong()))->select(); //qDebug() << ((GLObjectBase*)(ti->data(0, Qt::UserRole).toULongLong()))->type(); if (sel_obj->type() == GLObjectBase::glCamera) view->view()->setCamera((Camera*)sel_obj); } void QGLViewWindow::removeObjects() { QList sil = treeObjects->selectedItems(); foreach (QTreeWidgetItem * i, sil) { GLObjectBase * o = (GLObjectBase*)(i->data(0, Qt::UserRole).toULongLong()); delete o; } qDeleteAll(sil); } void QGLViewWindow::objectsTreeChanged() { treeObjects->clear(); makeObjetTree(&(view->view()->rootObject()), treeObjects->invisibleRootItem()); treeObjects->expandAll(); } void QGLViewWindow::on_pushButton_clicked() { //view->view()->removeLight(view->view()->lightsCount() - 1); //setWindowTitle(QString::number(view->view()->lightsCount())); QVector3D wp = view->view()->light(0)->worldPos(); view->view()->camera()->setPos(wp); view->view()->camera()->setAim(wp + (view->view()->light(0)->worldTransform() * QVector4D(view->view()->light(0)->direction)).toVector3D()*100); } void QGLViewWindow::on_pushButton_3_clicked() { QList ol = view->view()->objects(true); qDebug() << ol.size(); foreach (GLObjectBase * i, ol) { i->VBO().rebuffer(); } }