From bc2e712dc96dedf08118fafb8af9e144ddb64df9 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Thu, 10 Feb 2011 15:11:43 +0200 Subject: [PATCH] Changed: #1193 Added camera control panel. --- .../3d/object_viewer_qt/src/CMakeLists.txt | 2 +- .../object_viewer_qt/src/camera_control.cpp | 281 ++++++++++++++++++ .../3d/object_viewer_qt/src/camera_control.h | 125 ++++++++ .../object_viewer_qt/src/images/cam_add.png | Bin 0 -> 5732 bytes .../object_viewer_qt/src/images/cam_del.png | Bin 0 -> 5960 bytes .../3d/object_viewer_qt/src/images/rmfill.png | Bin 0 -> 2874 bytes .../3d/object_viewer_qt/src/images/rmline.png | Bin 0 -> 3832 bytes .../object_viewer_qt/src/images/rmpoints.png | Bin 0 -> 5289 bytes .../3d/object_viewer_qt/src/main_window.cpp | 98 ++---- .../3d/object_viewer_qt/src/main_window.h | 8 +- .../3d/object_viewer_qt/src/object_viewer.cpp | 202 ++++++------- .../3d/object_viewer_qt/src/object_viewer.h | 8 +- .../object_viewer_qt/src/object_viewer_qt.qrc | 9 +- 13 files changed, 540 insertions(+), 193 deletions(-) create mode 100644 code/nel/tools/3d/object_viewer_qt/src/camera_control.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/camera_control.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/images/cam_add.png create mode 100644 code/nel/tools/3d/object_viewer_qt/src/images/cam_del.png create mode 100644 code/nel/tools/3d/object_viewer_qt/src/images/rmfill.png create mode 100644 code/nel/tools/3d/object_viewer_qt/src/images/rmline.png create mode 100644 code/nel/tools/3d/object_viewer_qt/src/images/rmpoints.png diff --git a/code/nel/tools/3d/object_viewer_qt/src/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/CMakeLists.txt index 5a690018f..6bfa4eb96 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/CMakeLists.txt @@ -22,7 +22,7 @@ SET(OBJECT_VIEWER_HDR main_window.h graphics_viewport.h animation_dialog.h vegetable_dialog.h global_wind_dialog.h day_night_dialog.h sun_color_dialog.h vegetable_noise_value_widget.h vegetable_density_page.h vegetable_landscape_page.h vegetable_scale_page.h vegetable_appearance_page.h vegetable_rotate_page.h - tune_mrm_dialog.h tune_timer_dialog.h + tune_mrm_dialog.h tune_timer_dialog.h camera_control.h extension_system/iplugin_manager.h extension_system/plugin_manager.h) SET(OBJECT_VIEWER_UIS animation_form.ui animation_set_form.ui settings_form.ui diff --git a/code/nel/tools/3d/object_viewer_qt/src/camera_control.cpp b/code/nel/tools/3d/object_viewer_qt/src/camera_control.cpp new file mode 100644 index 000000000..2216fb88d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/camera_control.cpp @@ -0,0 +1,281 @@ +/* + Object Viewer Qt + Copyright (C) 2010 Dzmitry Kamiahin + + 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 "stdpch.h" +#include "camera_control.h" + +// STL includes + +// Qt includes + +// NeL includes +#include "nel/misc/debug.h" +#include "nel/3d/u_driver.h" +#include "nel/3d/u_scene.h" +#include +#include + +// Project includes +#include "modules.h" + +static int camId = 0; + +namespace NLQT +{ + +CCameraItem::CCameraItem(const QString &name): + _cameraFocal(75), + _speed(5.0), + _active(false), + _name(name) +{ + _camera = Modules::objView().getScene()->createCamera(); + _camera.setTransformMode (NL3D::UTransformable::DirectMatrix); + reset(); +} + +CCameraItem::~CCameraItem() +{ +} + +void CCameraItem::setActive(bool active) +{ + if (active) + { + sint w = Modules::objView().getDriver()->getWindowWidth(); + sint h = Modules::objView().getDriver()->getWindowHeight(); + _camera.setPerspective(_cameraFocal * float(NLMISC::Pi) / 180.f, float(w) / h, 0.1f, 1000); + Modules::objView().getScene()->setCam(_camera); + setupListener(); + } + else + { + _hotSpot = Modules::objView().get3dMouseListener()->getHotSpot(); + } + _active = active; +} + +void CCameraItem::setSpeed(float value) +{ + _speed = value; + Modules::objView().get3dMouseListener()->setSpeed(_speed); +} + +void CCameraItem::reset() +{ + _hotSpot = NLMISC::CVector(0, 0, 0); + float radius=10.f; + + // Setup camera + _camera.lookAt(_hotSpot + NLMISC::CVector(0.57735f, 0.57735f, 0.57735f) * radius, _hotSpot); + + if (_active) + setupListener(); +} + +void CCameraItem::setupListener() +{ + NL3D::U3dMouseListener *_mouseListener = Modules::objView().get3dMouseListener(); + _mouseListener->setMatrix (_camera.getMatrix()); + _mouseListener->setFrustrum (_camera.getFrustum()); + _mouseListener->setViewport (NL3D::CViewport()); + _mouseListener->setHotSpot (_hotSpot); + Modules::objView().get3dMouseListener()->setSpeed(_speed); +} + +CCameraControl::CCameraControl(QWidget *parent) + : QObject(parent), + _currentCamera(0) +{ + _camToolBar = new QToolBar(tr("CameraControl"), parent); + + _fpsAction = _camToolBar->addAction(tr("Fly")); + _fpsAction->setStatusTip(tr("Set firstPerson camera mode")); + _fpsAction->setCheckable(true); + + _edit3dAction = _camToolBar->addAction(tr("Edit")); + _edit3dAction->setStatusTip(tr("Set edit3d camera mode")); + _edit3dAction->setCheckable(true); + + QActionGroup *cameraModeGroup = new QActionGroup(this); + cameraModeGroup->addAction(_fpsAction); + cameraModeGroup->addAction(_edit3dAction); + _edit3dAction->setChecked(true); + + connect(_fpsAction, SIGNAL(triggered()), this, SLOT(setFirstPersonMode())); + connect(_edit3dAction, SIGNAL(triggered()), this, SLOT(setEditMode())); + + _renderModeMenu = new QMenu(tr("Render Mode"), _camToolBar); + _renderModeMenu->setIcon(QIcon(":/images/polymode.png")); + _camToolBar->addAction(_renderModeMenu->menuAction()); + connect(_renderModeMenu->menuAction(), SIGNAL(triggered()), this, SLOT(setRenderMode())); + + QSignalMapper *modeMapper = new QSignalMapper(this); + + _pointRenderModeAction = _renderModeMenu->addAction(tr("Point mode")); + _pointRenderModeAction->setIcon(QIcon(":/images/rmpoints.png")); + _pointRenderModeAction->setStatusTip(tr("Set point render mode")); + connect(_pointRenderModeAction, SIGNAL(triggered()), modeMapper, SLOT(map())); + modeMapper->setMapping(_pointRenderModeAction, 0); + + _lineRenderModeAction = _renderModeMenu->addAction(tr("Line mode")); + _lineRenderModeAction->setStatusTip(tr("Set line render mode")); + _lineRenderModeAction->setIcon(QIcon(":/images/rmline.png")); + connect(_lineRenderModeAction, SIGNAL(triggered()), modeMapper, SLOT(map())); + modeMapper->setMapping(_lineRenderModeAction, 1); + + _fillRenderModeAction = _renderModeMenu->addAction(tr("Fill mode")); + _fillRenderModeAction->setIcon(QIcon(":/images/rmfill.png")); + _fillRenderModeAction->setStatusTip(tr("Set fill render mode")); + connect(_fillRenderModeAction, SIGNAL(triggered()), modeMapper, SLOT(map())); + modeMapper->setMapping(_fillRenderModeAction, 2); + + connect(modeMapper, SIGNAL(mapped(int)), this, SLOT(setRenderMode(int))); + + _camToolBar->addSeparator(); + _speedLabel = new QLabel(tr("Speed:"), _camToolBar); + _camToolBar->addWidget(_speedLabel); + _speedSpinBox = new QSpinBox(_camToolBar); + _speedSpinBox->setMinimum(1); + _speedSpinBox->setMaximum(1000); + _camToolBar->addWidget(_speedSpinBox); + connect(_speedSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setSpeed(int))); + + _camToolBar->addSeparator(); + _addCamAction = _camToolBar->addAction(tr("Create camera")); + _addCamAction->setIcon(QIcon(":/images/cam_add.png")); + _addCamAction->setStatusTip(tr("Create new camera")); + connect(_addCamAction, SIGNAL(triggered()), this, SLOT(addCamera())); + + _delCamAction = _camToolBar->addAction(tr("Delete camera")); + _delCamAction->setIcon(QIcon(":/images/cam_del.png")); + _delCamAction->setStatusTip(tr("Delete current camera")); + connect(_delCamAction, SIGNAL(triggered()), this, SLOT(delCamera())); + + _listCamComboBox = new QComboBox(_camToolBar); + connect(_listCamComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changeCamera(int))); + _listCamComboBox->setCurrentIndex(createCamera(tr("defaultCamera"))); + _camToolBar->addWidget(_listCamComboBox); + + _camToolBar->addSeparator(); + _resetCamAction = _camToolBar->addAction(tr("Reset camera")); + _resetCamAction->setStatusTip(tr("Reset current camera")); + //_resetCamAction->setShortcut(tr("Ctrl+R")); + connect(_resetCamAction, SIGNAL(triggered()), this, SLOT(resetCamera())); +} + +CCameraControl::~CCameraControl() +{ +} + +void CCameraControl::setEditMode() +{ + Modules::objView().get3dMouseListener()->setMouseMode(NL3D::U3dMouseListener::edit3d); +} + +void CCameraControl::setFirstPersonMode() +{ + Modules::objView().get3dMouseListener()->setMouseMode(NL3D::U3dMouseListener::firstPerson); +} + +void CCameraControl::addCamera() +{ + _listCamComboBox->setCurrentIndex(createCamera(tr("%1_Camera").arg(++camId))); +} + +void CCameraControl::delCamera() +{ + int index = _listCamComboBox->currentIndex(); + _listCamComboBox->setCurrentIndex(index - 1); + + _listCamComboBox->removeItem(index); + delete _cameraList[index]; + _cameraList.erase(_cameraList.begin() + index); +} + +void CCameraControl::setSpeed(int value) +{ + nlassert(_currentCamera); + _currentCamera->setSpeed(value); +} + +void CCameraControl::changeCamera(int index) +{ + if (_currentCamera) + _currentCamera->setActive(false); + + if (index == 0) + _delCamAction->setEnabled(false); + else + _delCamAction->setEnabled(true); + + _currentCamera = _cameraList[index]; + + nlassert(_currentCamera); + _currentCamera->setActive(true); + _speedSpinBox->setValue(int(_currentCamera->getSpeed())); +} + +void CCameraControl::setRenderMode(int value) +{ + switch (value) + { + case 0: + Modules::objView().getDriver()->setPolygonMode (NL3D::UDriver::Point); + break; + case 1: + Modules::objView().getDriver()->setPolygonMode (NL3D::UDriver::Line); + break; + case 2: + Modules::objView().getDriver()->setPolygonMode (NL3D::UDriver::Filled); + break; + } +} + +void CCameraControl::setRenderMode() +{ + switch (Modules::objView().getDriver()->getPolygonMode()) + { + case NL3D::UDriver::Filled: + Modules::objView().getDriver()->setPolygonMode (NL3D::UDriver::Line); + break; + case NL3D::UDriver::Line: + Modules::objView().getDriver()->setPolygonMode (NL3D::UDriver::Point); + break; + case NL3D::UDriver::Point: + Modules::objView().getDriver()->setPolygonMode (NL3D::UDriver::Filled); + break; + } +} + +void CCameraControl::resetCamera() +{ + nlassert(_currentCamera); + _currentCamera->reset(); +} + +int CCameraControl::createCamera(const QString &name) +{ + CCameraItem *newCamera = new CCameraItem(name); + _cameraList.push_back(newCamera); + _listCamComboBox->addItem(newCamera->getName()); + return _cameraList.size() - 1; +} + +} /* namespace NLQT */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/camera_control.h b/code/nel/tools/3d/object_viewer_qt/src/camera_control.h new file mode 100644 index 000000000..50d10a230 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/camera_control.h @@ -0,0 +1,125 @@ +/* + Object Viewer Qt + Copyright (C) 2010 Dzmitry Kamiahin + + 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 . + +*/ + +#ifndef CAMERA_CONTROL_H +#define CAMERA_CONTROL_H + +// STL includes + +// Qt includes +#include +#include +#include +#include +#include +#include +#include + +// NeL includes +#include +#include "nel/misc/vector.h" + +// Project includes + +namespace NLQT +{ + +class CCameraItem +{ +public: + CCameraItem(const QString &name); + ~CCameraItem(); + + void setSpeed(float value); + float getSpeed() + { + return _speed; + } + void setActive(bool active); + void setName(const QString &name) + { + _name = name; + } + QString getName() const + { + return _name; + } + void reset(); + +private: + void setupListener(); + + NL3D::UCamera _camera; + NLMISC::CVector _hotSpot; + + float _cameraFocal; + float _speed; + bool _active; + QString _name; +}; + +class CCameraControl: public QObject +{ + Q_OBJECT + +public: + CCameraControl(QWidget *parent = 0); + ~CCameraControl(); + + QToolBar *getToolBar() const + { + return _camToolBar; + } + +public Q_SLOTS: + void setEditMode(); + void setFirstPersonMode(); + void addCamera(); + void delCamera(); + void setSpeed(int value); + void changeCamera(int index); + void setRenderMode(int value); + void setRenderMode(); + void resetCamera(); + +private: + int createCamera(const QString &name); + + QAction *_fpsAction; + QAction *_edit3dAction; + QAction *_pointRenderModeAction; + QAction *_lineRenderModeAction; + QAction *_fillRenderModeAction; + QAction *_addCamAction; + QAction *_delCamAction; + QAction *_resetCamAction; + QSpinBox *_speedSpinBox; + QComboBox *_listCamComboBox; + QMenu *_renderModeMenu; + QLabel *_speedLabel; + QToolBar *_camToolBar; + + CCameraItem *_currentCamera; + std::vector _cameraList; + +}; /* class CCameraControl */ + +} /* namespace NLQT */ + +#endif // CAMERA_CONTROL_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/images/cam_add.png b/code/nel/tools/3d/object_viewer_qt/src/images/cam_add.png new file mode 100644 index 0000000000000000000000000000000000000000..dbc579d43616f667179ce23faebc8b2ef53b134c GIT binary patch literal 5732 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 RH&_t{^t6qURa%aZ{s(A!6!`!E literal 0 HcmV?d00001 diff --git a/code/nel/tools/3d/object_viewer_qt/src/images/cam_del.png b/code/nel/tools/3d/object_viewer_qt/src/images/cam_del.png new file mode 100644 index 0000000000000000000000000000000000000000..1f6bee21f7a08713cf98594c32ca212aba846846 GIT binary patch literal 5960 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 YzbsLHmH{U1@&Et;07*qoM6N<$g4I!16#xJL literal 0 HcmV?d00001 diff --git a/code/nel/tools/3d/object_viewer_qt/src/images/rmline.png b/code/nel/tools/3d/object_viewer_qt/src/images/rmline.png new file mode 100644 index 0000000000000000000000000000000000000000..82d9783e1b23c72488ce0e350f7c0221544102f2 GIT binary patch literal 3832 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 literal 0 HcmV?d00001 diff --git a/code/nel/tools/3d/object_viewer_qt/src/images/rmpoints.png b/code/nel/tools/3d/object_viewer_qt/src/images/rmpoints.png new file mode 100644 index 0000000000000000000000000000000000000000..b7a4b2f28281921252e311f1838f3d4951dbea9f GIT binary patch literal 5289 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�NovQ?o0)TW;{-0llUs+i6)`kMs0DPa~vpe1Tx5Hfvpbpmjiz}#IIQ%Yq z_+gJHH~bJW_Dx3W7-Q5LkZ9(J^u^xe<(-Zq2LpHOPLWjg+<;PycgY z0)TWz-2CASgI5bhAy7L;uK{?O;6os&59se^7jO>27)dL(3H=sirQs(qFml2( z4G+(;nGOI_YUYLY`;W&4($^+K8$#pKdwKh)R*;@FK-$ z@96GfJAC3FOt9&*!vMYr;6VTlMaBSWdE3<^iKOoj*1&pVha+Z2Ig7 zfM?Mq!`lWQqBi-CLhUC3pV_Cg6rbG&@I9b!9nb~vgL^f3;IsX97!;pf2GI4Qp62{qp|<4B&vaclOXf00000NkvXXu0mjf3keOw literal 0 HcmV?d00001 diff --git a/code/nel/tools/3d/object_viewer_qt/src/main_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/main_window.cpp index ece609dac..5a75e7423 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/main_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/main_window.cpp @@ -49,6 +49,7 @@ #include "sun_color_dialog.h" #include "tune_mrm_dialog.h" #include "tune_timer_dialog.h" +#include "camera_control.h" using namespace std; using namespace NLMISC; @@ -58,13 +59,13 @@ namespace NLQT CMainWindow::CMainWindow(QWidget *parent) : QMainWindow(parent), - _isGraphicsInitialized(false), - _isGraphicsEnabled(false), - _isSoundInitialized(false), - _isSoundEnabled(false), - _GraphicsViewport(NULL), - _lastDir("."), - _mouseMode(NL3D::U3dMouseListener::edit3d) + _isGraphicsInitialized(false), + _isGraphicsEnabled(false), + _isSoundInitialized(false), + _isSoundEnabled(false), + _GraphicsViewport(NULL), + _lastDir("."), + _mouseMode(NL3D::U3dMouseListener::edit3d) { nldebug("CMainWindow::CMainWindow:"); setObjectName("CMainWindow"); @@ -83,7 +84,7 @@ CMainWindow::CMainWindow(QWidget *parent) _GraphicsViewport->init(); _isGraphicsInitialized = true; - + if (_isSoundEnabled) { Modules::sound().init(); @@ -144,7 +145,7 @@ CMainWindow::~CMainWindow() delete _TuneTimerDialog; delete _ParticleControlDialog; delete _ParticleWorkspaceDialog; - + if (_isSoundInitialized) Modules::sound().releaseGraphics(); @@ -162,7 +163,7 @@ void CMainWindow::setVisible(bool visible) { QMainWindow::setVisible(true); if (_isSoundInitialized) - Modules::sound().initGraphics(); + Modules::sound().initGraphics(); _mainTimer->start(); _statusBarTimer->start(1000); } @@ -202,7 +203,7 @@ void CMainWindow::open() tr("NeL skeleton file (*.skel)")); Q_FOREACH(QString fileName, list) - loadFile(fileName, skelFileName); + loadFile(fileName, skelFileName); _AnimationSetDialog->updateListObject(); _AnimationSetDialog->updateListAnim(); @@ -220,43 +221,6 @@ void CMainWindow::resetScene() _SkeletonTreeModel->resetTreeModel(); } -void CMainWindow::changeRenderMode() -{ - // Change render mode - switch (Modules::objView().getDriver()->getPolygonMode()) - { - case NL3D::UDriver::Filled: - Modules::objView().getDriver()->setPolygonMode (NL3D::UDriver::Line); - break; - case NL3D::UDriver::Line: - Modules::objView().getDriver()->setPolygonMode (NL3D::UDriver::Point); - break; - case NL3D::UDriver::Point: - Modules::objView().getDriver()->setPolygonMode (NL3D::UDriver::Filled); - break; - } -} - -void CMainWindow::resetCamera() -{ - Modules::objView().resetCamera(); -} - -void CMainWindow::changeCameraMode() -{ - switch (_mouseMode) - { - case NL3D::U3dMouseListener::edit3d: - Modules::objView().get3dMouseListener()->setMouseMode(NL3D::U3dMouseListener::firstPerson); - _mouseMode = NL3D::U3dMouseListener::firstPerson; - break; - case NL3D::U3dMouseListener::firstPerson: - _mouseMode = NL3D::U3dMouseListener::edit3d; - Modules::objView().get3dMouseListener()->setMouseMode(NL3D::U3dMouseListener::edit3d); - break; - } -} - void CMainWindow::reloadTextures() { Modules::objView().reloadTextures(); @@ -286,10 +250,10 @@ void CMainWindow::updateStatusBar() if (_isGraphicsInitialized) { _statusInfo->setText(QString("%1, Nb tri: %2 , Texture used (Mb): %3 , fps: %4 ").arg( - Modules::objView().getDriver()->getVideocardInformation()).arg( - _numTri).arg( - _texMem, 0,'f',4).arg( - _fps, 0,'f',2)); + Modules::objView().getDriver()->getVideocardInformation()).arg( + _numTri).arg( + _texMem, 0,'f',4).arg( + _fps, 0,'f',2)); } } @@ -314,18 +278,11 @@ void CMainWindow::createActions() _resetCameraAction = new QAction(tr("Reset camera"), this); _resetCameraAction->setShortcut(tr("Ctrl+R")); _resetCameraAction->setStatusTip(tr("Reset current camera")); - connect(_resetCameraAction, SIGNAL(triggered()), this, SLOT(resetCamera())); _renderModeAction = new QAction("Change render mode", this); _renderModeAction->setIcon(QIcon(":/images/polymode.png")); _renderModeAction->setShortcut(tr("Ctrl+M")); _renderModeAction->setStatusTip(tr("Change render mode (Line, Point, Filled)")); - connect(_renderModeAction, SIGNAL(triggered()), this, SLOT(changeRenderMode())); - - _cameraModeAction = new QAction("Change camera mode", this); - _cameraModeAction->setShortcut(tr("Ctrl+W")); - _cameraModeAction->setStatusTip(tr("Change camera mode (edit3d, firstPerson)")); - connect(_cameraModeAction, SIGNAL(triggered()), this, SLOT(changeCameraMode())); _resetSceneAction = new QAction(tr("&Reset scene"), this); _resetSceneAction->setStatusTip(tr("Reset current scene")); @@ -366,7 +323,6 @@ void CMainWindow::createMenus() _viewMenu->addAction(_setBackColorAction); _viewMenu->addAction(_resetCameraAction); _viewMenu->addAction(_renderModeAction); - _viewMenu->addAction(_cameraModeAction); _viewMenu->addAction(_SetupFog->toggleViewAction()); _sceneMenu = menuBar()->addMenu(tr("&Scene")); @@ -457,6 +413,12 @@ void CMainWindow::createToolBars() _toolsBar->addAction(_TuneTimerDialog->toggleViewAction()); _toolsBar->addAction(_SkeletonScaleDialog->toggleViewAction()); _toolsBar->addAction(_TuneMRMDialog->toggleViewAction()); + + _cameraControl = new CCameraControl(this); + this->addToolBar(_cameraControl->getToolBar()); + + connect(_resetCameraAction, SIGNAL(triggered()), _cameraControl, SLOT(resetCamera())); + connect(_renderModeAction, SIGNAL(triggered()), _cameraControl, SLOT(setRenderMode())); } void CMainWindow::createStatusBar() @@ -555,7 +517,7 @@ bool CMainWindow::loadFile(const QString &fileName, const QString &skelName) bool loaded; if (fileInfo.suffix() == "ig") loaded = Modules::objView().loadInstanceGroup(fileName.toStdString()); - else + else loaded = Modules::objView().loadMesh(fileName.toStdString(), skelName.toStdString()); if (!loaded) @@ -646,17 +608,17 @@ void CMainWindow::updateRender() // 14. Update Debug (stuff for dev) // ... - - // 15. Calc FPS - static sint64 lastTime = NLMISC::CTime::getPerformanceTime (); - sint64 newTime = NLMISC::CTime::getPerformanceTime (); - _fps = float(1.0 / NLMISC::CTime::ticksToSecond (newTime-lastTime)); + + // 15. Calc FPS + static sint64 lastTime = NLMISC::CTime::getPerformanceTime (); + sint64 newTime = NLMISC::CTime::getPerformanceTime (); + _fps = float(1.0 / NLMISC::CTime::ticksToSecond (newTime-lastTime)); lastTime = newTime; if (_isGraphicsInitialized && !Modules::objView().getDriver()->isLost()) { // 01. Render Driver (background color) - //Modules::objView().getDriver()->activate(); + //Modules::objView().getDriver()->activate(); Modules::objView().renderDriver(); // clear all buffers // 02. Render Sky (sky scene) @@ -681,7 +643,7 @@ void CMainWindow::updateRender() Modules::objView().renderDebug2D(); // 10. Get profile information - NL3D::CPrimitiveProfile in, out; + NL3D::CPrimitiveProfile in, out; Modules::objView().getDriver()->profileRenderedPrimitives (in, out); _numTri = in.NLines+in.NPoints+in.NQuads*2+in.NTriangles+in.NTriangleStrips; diff --git a/code/nel/tools/3d/object_viewer_qt/src/main_window.h b/code/nel/tools/3d/object_viewer_qt/src/main_window.h index 9cc146aee..8864b1c6b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/main_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/main_window.h @@ -56,6 +56,8 @@ class CSunColorDialog; class CTuneMRMDialog; class CTuneTimerDialog; +class CCameraControl; + class CMainWindow : public QMainWindow { Q_OBJECT @@ -79,9 +81,6 @@ public: private Q_SLOTS: void open(); void resetScene(); - void changeRenderMode(); - void resetCamera(); - void changeCameraMode(); void reloadTextures(); void settings(); void about(); @@ -122,6 +121,8 @@ private: CSkeletonTreeModel *_SkeletonTreeModel; CTuneTimerDialog *_TuneTimerDialog; + CCameraControl *_cameraControl; + QPalette _originalPalette; QString _lastDir; @@ -143,7 +144,6 @@ private: QAction *_frameDelayAction; QAction *_lightGroupAction; QAction *_reloadTexturesAction; - QAction *_cameraModeAction; QAction *_resetCameraAction; QAction *_resetSceneAction; QAction *_saveScreenshotAction; diff --git a/code/nel/tools/3d/object_viewer_qt/src/object_viewer.cpp b/code/nel/tools/3d/object_viewer_qt/src/object_viewer.cpp index ac34152fa..07882f14a 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/object_viewer.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/object_viewer.cpp @@ -23,7 +23,6 @@ // STL includes // NeL includes -#include #include #include #include @@ -59,13 +58,13 @@ namespace NLQT CObjectViewer::CObjectViewer() : _IDriver(0), - _CScene(0), - _Driver(0), - _Scene(0), - _TextContext(0), - _CameraFocal(75), - _CurrentInstance(""), - _BloomEffect(false) + _CScene(0), + _Driver(0), + _Scene(0), + _TextContext(0), + _CameraFocal(75), + _CurrentInstance(""), + _BloomEffect(false) { } @@ -115,19 +114,11 @@ void CObjectViewer::init(nlWindow wnd, uint16 w, uint16 h) _Scene->enableLightingSystem(true); - // create the camera - UCamera camera = _Scene->getCam(); - camera.setTransformMode (UTransformable::DirectMatrix); - - setSizeViewport(w, h); - NLMISC::CVector hotSpot=NLMISC::CVector(0,0,0); _MouseListener = _Driver->create3dMouseListener(); _MouseListener->setMouseMode(U3dMouseListener::edit3d); - resetCamera(); - // set the cache size for the font manager(in bytes) _Driver->setFontManagerMaxMemory(2097152); @@ -184,7 +175,7 @@ void CObjectViewer::release() void CObjectViewer::updateInput() { _Driver->EventServer.pump(); - + // New matrix from camera _Scene->getCam().setTransformMode(NL3D::UTransformable::DirectMatrix); _Scene->getCam().setMatrix (_MouseListener->getViewMatrix()); @@ -218,53 +209,38 @@ void CObjectViewer::renderDebug2D() void CObjectViewer::reloadTextures() { - // For each instances - std::vector listObjects; - getListObjects(listObjects); - - for (size_t i = 0; i < listObjects.size(); ++i) - { - // Get the shape - NL3D::UInstance instance = getEntity(listObjects[i]).getInstance(); - - // For each material - if (!instance.empty()) - { - uint numMaterial = instance.getNumMaterials(); - uint mat; - for (mat = 0; mat < numMaterial; mat++) - { - // Get the material - NL3D::CMaterial *material = instance.getMaterial(mat).getObjectPtr(); - - // For each texture - int tex; - for (tex = 0; tex < NL3D::IDRV_MAT_MAXTEXTURES; tex++) - { - ITexture *texture = material->getTexture(tex); - - // Touch it! - if (texture) - getIDriver()->invalidateShareTexture(*texture); - } - } - } - } -} + // For each instances + std::vector listObjects; + getListObjects(listObjects); -void CObjectViewer::resetCamera() -{ - CVector hotSpot = CVector (0,0,0); - float radius=10.f; - - // Setup camera - _Scene->getCam().lookAt(hotSpot + CVector(0.57735f, 0.57735f, 0.57735f) * radius, hotSpot); - - // Setup mouse listener - _MouseListener->setMatrix (_Scene->getCam().getMatrix()); - _MouseListener->setFrustrum (_Scene->getCam().getFrustum()); - _MouseListener->setViewport (CViewport()); - _MouseListener->setHotSpot (hotSpot); + for (size_t i = 0; i < listObjects.size(); ++i) + { + // Get the shape + NL3D::UInstance instance = getEntity(listObjects[i]).getInstance(); + + // For each material + if (!instance.empty()) + { + uint numMaterial = instance.getNumMaterials(); + uint mat; + for (mat = 0; mat < numMaterial; mat++) + { + // Get the material + NL3D::CMaterial *material = instance.getMaterial(mat).getObjectPtr(); + + // For each texture + int tex; + for (tex = 0; tex < NL3D::IDRV_MAT_MAXTEXTURES; tex++) + { + ITexture *texture = material->getTexture(tex); + + // Touch it! + if (texture) + getIDriver()->invalidateShareTexture(*texture); + } + } + } + } } void CObjectViewer::saveScreenshot(const std::string &nameFile, bool jpg, bool png, bool tga) @@ -316,11 +292,11 @@ bool CObjectViewer::loadMesh(const std::string &meshFileName, const std::string // if we can't create entity, skip it if (Entity.empty()) return false; - - CAABBox bbox; - Entity.getShapeAABBox(bbox); - setCamera(bbox , Entity, true); - + + CAABBox bbox; + Entity.getShapeAABBox(bbox); + setCamera(bbox , Entity, true); + _MouseListener->setMatrix(_Scene->getCam().getMatrix()); USkeleton Skeleton = _Scene->createSkeleton(skelFileName); @@ -348,57 +324,57 @@ bool CObjectViewer::loadInstanceGroup(const std::string &igName) { CPath::addSearchPath (CFile::getPath(igName)); UInstanceGroup *ig = UInstanceGroup::createInstanceGroup(igName); - if (ig == 0) + if (ig == 0) return false; ig->addToScene(*_Scene, _Driver); ig->unfreezeHRC(); _ListIG.push_back(ig); return true; } - -void CObjectViewer::setCamera(NLMISC::CAABBox &bbox, NL3D::UTransform &entity, bool high_z) -{ - CVector pos(0.f, 0.f, 0.f); - CQuat quat(0.f, 0.f, 0.f, 0.f); - NL3D::UInstance inst; - inst.cast(entity); - if (!inst.empty()) - { - inst.getDefaultPos(pos); - inst.getDefaultRotQuat(quat); - } - - // fix scale (some shapes have a different value) - entity.setScale(1.f, 1.f, 1.f); - UCamera Camera = _Scene->getCam(); - CVector max_radius = bbox.getHalfSize(); - CVector center = bbox.getCenter(); - entity.setPivot(center); - center += pos; - float fov = float(_CameraFocal * (float)Pi/180.0); - float radius = max(max(max_radius.x, max_radius.y), max_radius.z); - if (radius == 0.f) radius = 1.f; - float left, right, bottom, top, znear, zfar; - Camera.getFrustum(left, right, bottom, top, znear, zfar); - float dist = radius / (tan(fov/2)); - CVector eye(center); - - CVector ax(quat.getAxis()); - - if (ax.isNull() || ax == CVector::I) - { - ax = CVector::J; - } - else if (ax == -CVector::K) - { - ax = -CVector::J; - } - - eye -= ax * (dist+radius); - if (high_z) - eye.z += max_radius.z/1.0f; - get3dMouseListener()->setHotSpot(center); - Camera.lookAt(eye, center); + +void CObjectViewer::setCamera(NLMISC::CAABBox &bbox, NL3D::UTransform &entity, bool high_z) +{ + CVector pos(0.f, 0.f, 0.f); + CQuat quat(0.f, 0.f, 0.f, 0.f); + NL3D::UInstance inst; + inst.cast(entity); + if (!inst.empty()) + { + inst.getDefaultPos(pos); + inst.getDefaultRotQuat(quat); + } + + // fix scale (some shapes have a different value) + entity.setScale(1.f, 1.f, 1.f); + UCamera Camera = _Scene->getCam(); + CVector max_radius = bbox.getHalfSize(); + CVector center = bbox.getCenter(); + entity.setPivot(center); + center += pos; + float fov = float(_CameraFocal * (float)Pi/180.0); + float radius = max(max(max_radius.x, max_radius.y), max_radius.z); + if (radius == 0.f) radius = 1.f; + float left, right, bottom, top, znear, zfar; + Camera.getFrustum(left, right, bottom, top, znear, zfar); + float dist = radius / (tan(fov/2)); + CVector eye(center); + + CVector ax(quat.getAxis()); + + if (ax.isNull() || ax == CVector::I) + { + ax = CVector::J; + } + else if (ax == -CVector::K) + { + ax = -CVector::J; + } + + eye -= ax * (dist+radius); + if (high_z) + eye.z += max_radius.z/1.0f; + get3dMouseListener()->setHotSpot(center); + Camera.lookAt(eye, center); } void CObjectViewer::resetScene() diff --git a/code/nel/tools/3d/object_viewer_qt/src/object_viewer.h b/code/nel/tools/3d/object_viewer_qt/src/object_viewer.h index 2cdefe426..b74544a3c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/object_viewer.h +++ b/code/nel/tools/3d/object_viewer_qt/src/object_viewer.h @@ -100,8 +100,6 @@ public: void reloadTextures(); - void resetCamera(); - /// Make a screenshot of the current scene and save. void saveScreenshot(const std::string &nameFile, bool jpg, bool png, bool tga); @@ -188,19 +186,19 @@ public: { return _Driver; } - + NL3D::IDriver *getIDriver() const { return _IDriver; } - + /// Get a game interface for scene. /// @return pointer to the scene. inline NL3D::UScene *getScene() const { return _Scene; } - + NL3D::CScene *getCScene() const { return _CScene; diff --git a/code/nel/tools/3d/object_viewer_qt/src/object_viewer_qt.qrc b/code/nel/tools/3d/object_viewer_qt/src/object_viewer_qt.qrc index 5b14b74f6..1957bf1ea 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/object_viewer_qt.qrc +++ b/code/nel/tools/3d/object_viewer_qt/src/object_viewer_qt.qrc @@ -36,8 +36,13 @@ images/save-as.png images/save.png images/insert-horizontal.png - images/polymode.png - + images/polymode.png + images/rmfill.png + images/rmline.png + images/rmpoints.png + images/cam_del.png + images/cam_add.png + images/Emitter.bmp images/Force.bmp