353 lines
13 KiB
C++
353 lines
13 KiB
C++
/*
|
|
Stanley Designer
|
|
Ivan Pelipenko peri4ko@yandex.ru
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#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 <QGraphicsRectItem>
|
|
#include <QImageReader>
|
|
#include <QMessageBox>
|
|
|
|
|
|
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<QTreeWidgetItem*> 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<GLObjectBase * > ol = view->view()->objects(true);
|
|
qDebug() << ol.size();
|
|
foreach (GLObjectBase * i, ol) {
|
|
i->VBO().rebuffer();
|
|
}
|
|
}
|
|
|
|
|