diff --git a/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin_manager.h b/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin_manager.h index f5537fc32..18605f133 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin_manager.h +++ b/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin_manager.h @@ -41,6 +41,7 @@ class IPluginManager: public QObject public: IPluginManager(QObject *parent = 0): QObject(parent) {} + virtual ~IPluginManager() {} // Object pool operations virtual void addObject(QObject *obj) = 0; diff --git a/code/nel/tools/3d/object_viewer_qt/src/graphics_viewport.h b/code/nel/tools/3d/object_viewer_qt/src/graphics_viewport.h index 6dd6632c7..fd2adf510 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/graphics_viewport.h +++ b/code/nel/tools/3d/object_viewer_qt/src/graphics_viewport.h @@ -51,7 +51,7 @@ namespace NLQT @class CGraphicsViewport @brief Responsible for interaction between Qt and NeL. Initializes CObjectViewer, CParticleEditor and CVegetableEditor subsystem. */ -class CGraphicsViewport : public QNLWidget +class CGraphicsViewport : public QNLWidget, public NLMISC::IEventEmitter { Q_OBJECT 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 80a486b15..60246db4e 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 @@ -27,6 +27,8 @@ // NeL includes #include +#include +#include // Project includes #include "modules.h" @@ -102,7 +104,7 @@ CMainWindow::CMainWindow(QWidget *parent) connect(_mainTimer, SIGNAL(timeout()), this, SLOT(updateRender())); // timer->start(); // <- timeout 0 // it's heavy on cpu, though, when no 3d driver initialized :) - _mainTimer->start(25); // 25fps + _mainTimer->start(20); // 25fps _statusBarTimer = new QTimer(this); connect(_statusBarTimer, SIGNAL(timeout()), this, SLOT(updateStatusBar())); @@ -168,9 +170,10 @@ void CMainWindow::open() { QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Open NeL data file"), _lastDir, - tr("All NeL files (*.shape *.ps);;" + tr("All NeL files (*.shape *.ps *.ig);;" "NeL shape files (*.shape);;" - "NeL particle system files (*.ps)")); + "NeL particle system files (*.ps)" + "NeL Instance Group files (*.ig)")); setCursor(Qt::WaitCursor); if (!fileNames.isEmpty()) @@ -183,7 +186,7 @@ void CMainWindow::open() tr("NeL skeleton file (*.skel)")); Q_FOREACH(QString fileName, list) - loadFile(fileName, skelFileName); + loadFile(fileName, skelFileName); _AnimationSetDialog->updateListObject(); _AnimationSetDialog->updateListAnim(); @@ -201,6 +204,24 @@ void CMainWindow::resetScene() _SkeletonTreeModel->resetTreeModel(); } +void CMainWindow::changeRenderMode() +{ +} + +void CMainWindow::resetCamera() +{ + Modules::objView().resetCamera(); +} + +void CMainWindow::changeCameraMode() +{ +} + +void CMainWindow::reloadTextures() +{ + Modules::objView().reloadTextures(); +} + void CMainWindow::settings() { CSettingsDialog _settingsDialog(this); @@ -219,7 +240,7 @@ void CMainWindow::updateStatusBar() { if (_isGraphicsInitialized) { - _statusInfo->setText(QString("%1, Nb tri: %2, Texture used (Mb): %3, fps: %4 ").arg( + _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( @@ -334,6 +355,11 @@ void CMainWindow::createActions() _setBackColorAction->setIcon(QIcon(":/images/ico_bgcolor.png")); _setBackColorAction->setStatusTip(tr("Set background color")); + _resetCameraAction = new QAction(tr("R&eset camera"), this); + _resetCameraAction->setShortcut(tr("Ctrl+R")); + _resetCameraAction->setStatusTip(tr("Reset current camera")); + connect(_resetCameraAction, SIGNAL(triggered()), this, SLOT(resetCamera())); + _resetSceneAction = new QAction(tr("&Reset scene"), this); _resetSceneAction->setStatusTip(tr("Reset current scene")); connect(_resetSceneAction, SIGNAL(triggered()), this, SLOT(resetScene())); @@ -368,6 +394,7 @@ void CMainWindow::createMenus() _viewMenu->setObjectName("ovqt.Menu.View"); _viewMenu->addAction(_setBackColorAction); _viewMenu->addAction(_SetupFog->toggleViewAction()); + _viewMenu->addAction(_resetCameraAction); _sceneMenu = menuBar()->addMenu(tr("&Scene")); _sceneMenu->setObjectName("ovqt.Menu.Scene"); @@ -533,7 +560,14 @@ void CMainWindow::createDialogs() bool CMainWindow::loadFile(const QString &fileName, const QString &skelName) { - if (!Modules::objView().loadMesh(fileName.toStdString(), skelName.toStdString())) + QFileInfo fileInfo(fileName); + bool loaded; + if (fileInfo.suffix() == "ig") + loaded = Modules::objView().loadInstanceGroup(fileName.toStdString()); + else + loaded = Modules::objView().loadMesh(fileName.toStdString(), skelName.toStdString()); + + if (!loaded) { statusBar()->showMessage(tr("Loading canceled"),2000); return false; 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 9abf29e0a..40bb56975 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 @@ -77,6 +77,10 @@ public: private Q_SLOTS: void open(); void resetScene(); + void changeRenderMode(); + void resetCamera(); + void changeCameraMode(); + void reloadTextures(); void settings(); void about(); void updateStatusBar(); @@ -136,6 +140,13 @@ private: QAction *_openAction; QAction *_exitAction; QAction *_setBackColorAction; + QAction *_renderModeAction; + QAction *_frameDelayAction; + QAction *_lightGroupAction; + QAction *_tuneMRMAction; + QAction *_reloadTexturesAction; + QAction *_cameraModeAction; + QAction *_resetCameraAction; QAction *_resetSceneAction; QAction *_saveScreenshotAction; QAction *_settingsAction; 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 780d5fc60..5f9ef5706 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 @@ -40,6 +40,7 @@ #include #include #include +#include #include // Project includes @@ -56,7 +57,6 @@ namespace NLQT CObjectViewer::CObjectViewer() : _Driver(NULL), _TextContext(NULL), - _phi(0), _psi(0),_dist(20), _CameraFocal(75), _CurrentInstance(""), _BloomEffect(false), @@ -114,17 +114,13 @@ void CObjectViewer::init(nlWindow wnd, uint16 w, uint16 h) setSizeViewport(w, h); - // camera will look at entities - updateCamera(0,0,0); - NLMISC::CVector hotSpot=NLMISC::CVector(0,0,0); _MouseListener = _Driver->create3dMouseListener(); - _MouseListener->setMatrix(Modules::objView().getScene()->getCam().getMatrix()); - _MouseListener->setFrustrum(Modules::objView().getScene()->getCam().getFrustum()); - _MouseListener->setHotSpot(hotSpot); _MouseListener->setMouseMode(U3dMouseListener::edit3d); + resetCamera(); + // set the cache size for the font manager(in bytes) _Driver->setFontManagerMaxMemory(2097152); @@ -207,6 +203,25 @@ void CObjectViewer::renderDebug2D() { } +void CObjectViewer::reloadTextures() +{ +} + +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); +} + void CObjectViewer::saveScreenshot(const std::string &nameFile, bool jpg, bool png, bool tga) { //H_AUTO2 @@ -249,10 +264,16 @@ bool CObjectViewer::loadMesh(const std::string &meshFileName, const std::string if (_Entities.count(fileName) != 0) return false; - CPath::addSearchPath(CFile::getPath(meshFileName), false, false); + CPath::addSearchPath(CFile::getPath(meshFileName)); // create instance of the mesh character UInstance Entity = _Scene->createInstance(meshFileName); + + CAABBox bbox; + Entity.getShapeAABBox(bbox); + setCamera(bbox , Entity, true); + + _MouseListener->setMatrix(_Scene->getCam().getMatrix()); USkeleton Skeleton = _Scene->createSkeleton(skelFileName); @@ -278,6 +299,63 @@ bool CObjectViewer::loadMesh(const std::string &meshFileName, const std::string return true; } +bool CObjectViewer::loadInstanceGroup(const std::string &igName) +{ + CPath::addSearchPath (CFile::getPath(igName)); + UInstanceGroup *ig = UInstanceGroup::createInstanceGroup(igName); + if (ig == NULL) + 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::resetScene() { deleteEntities(); @@ -286,41 +364,16 @@ void CObjectViewer::resetScene() //.. // to load files with the same name but located in different directories - CPath::clearMap(); + //CPath::clearMap(); // load and set search paths from config - Modules::config().configSearchPaths(); + //Modules::config().configSearchPaths(); _CurrentInstance = ""; nlinfo("Scene cleared"); } -void CObjectViewer::updateCamera(float deltaPsi, float deltaPhi, float deltaDist) -{ - _phi += deltaPhi; - _psi += deltaPsi; - _dist += deltaDist; - - if(_phi < -NLMISC::Pi/2) _phi -= deltaPhi; - if(_phi > NLMISC::Pi/2) _phi -= deltaPsi; - if (_dist < 1) _dist = 1; - - NLMISC::CQuat q0,q1,q2; - NLMISC::CVector up(0,0,1); - NLMISC::CVector v(0,0,1); - - q0.setAngleAxis(v,_psi); - v = NLMISC::CVector(0,1,0); - q1.setAngleAxis(v,_phi); - q2 = q0 * q1; - NLMISC::CMatrix m0; - m0.setRot(q2); - NLMISC::CVector camera = m0 * NLMISC::CVector(_dist,0,0); - - _Scene->getCam().lookAt(camera, up); -} - void CObjectViewer::updateAnimatePS(uint64 deltaTime) { static sint64 firstTime = NLMISC::CTime::getLocalTime(); @@ -417,6 +470,13 @@ void CObjectViewer::saveConfig() void CObjectViewer::deleteEntities() { _Entities.clear(); + + for(size_t i = 0; i < _ListIG.size(); ++i) + { + _ListIG[i]->removeFromScene(*_Scene); + delete _ListIG[i]; + } + _ListIG.clear(); } void CObjectViewer::cfcbBackgroundColor(NLMISC::CConfigFile::CVar &var) 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 36cd66010..f52f5ca85 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 @@ -45,6 +45,7 @@ class USkeleton; class UTextContext; class UPlayListManager; class U3dMouseListener; +class UInstanceGroup; } namespace NLQT @@ -95,6 +96,10 @@ public: /// Render Debug 2D (stuff for dev). void renderDebug2D(); + 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); @@ -104,15 +109,13 @@ public: /// @return true if file have been loaded, false if file have not been loaded. bool loadMesh (const std::string &meshFileName, const std::string &skelFileName); + bool loadInstanceGroup(const std::string &igName); + + void setCamera(NLMISC::CAABBox &bbox, NL3D::UTransform &entity, bool high_z); + /// Reset current scene. void resetScene(); - /// Update the navigation camera.(Note: deprecated) - /// @param deltaPsi - delta angle horizontal (radians). - /// @param deltaPhi - delta angle vertical (radians). - /// @param deltaDist - delta distance. - void updateCamera(float deltaPsi, float deltaPhi, float deltaDist); - /// Update the animation time for Particle System animation. /// @param deltaTime - set the manual animation time. void updateAnimatePS(uint64 deltaTime = 0); @@ -236,13 +239,11 @@ private: NL3D::UCamera *_Camera; NL3D::UTextContext *_TextContext; NL3D::U3dMouseListener *_MouseListener; + std::vector _ListIG; // The entities storage CEntities _Entities; - /// Camera parameters. - float _phi, _psi, _dist; - float _CameraFocal; std::string _FontName; diff --git a/code/nel/tools/3d/object_viewer_qt/src/particle_node.cpp b/code/nel/tools/3d/object_viewer_qt/src/particle_node.cpp index 7c63f92b1..b9b8268c2 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/particle_node.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/particle_node.cpp @@ -290,7 +290,10 @@ bool CWorkspaceNode::loadPS() throw(NLMISC::EStream) Modules::psEdit().getScene()->deleteInstance(trs); return false; } - Modules::psEdit().getScene()->setShapeBank(oldSB); + if (oldSB) + { + Modules::psEdit().getScene()->setShapeBank(oldSB); + } setup(*psm); unload(); // commit new values