mirror of
https://github.com/rwengine/openrw.git
synced 2024-09-15 06:52:34 +02:00
Implement semi-functional world viewer widget
This commit is contained in:
parent
5b76eb72f3
commit
8ede36c59d
@ -16,11 +16,21 @@
|
|||||||
|
|
||||||
|
|
||||||
ViewerWidget::ViewerWidget(QWidget* parent, const QGLWidget* shareWidget, Qt::WindowFlags f)
|
ViewerWidget::ViewerWidget(QWidget* parent, const QGLWidget* shareWidget, Qt::WindowFlags f)
|
||||||
: QGLWidget(parent, shareWidget, f), gworld(nullptr), activeModel(nullptr),
|
: QGLWidget(parent, shareWidget, f)
|
||||||
selectedFrame(nullptr), dummyObject(nullptr), currentObjectID(0),
|
, gworld(nullptr)
|
||||||
_lastModel(nullptr), canimation(nullptr), viewDistance(1.f), dragging(false),
|
, activeModel(nullptr)
|
||||||
_frameWidgetDraw(nullptr), _frameWidgetGeom(nullptr)
|
, selectedFrame(nullptr)
|
||||||
|
, dummyObject(nullptr)
|
||||||
|
, currentObjectID(0)
|
||||||
|
, _lastModel(nullptr)
|
||||||
|
, canimation(nullptr)
|
||||||
|
, viewDistance(1.f)
|
||||||
|
, dragging(false)
|
||||||
|
, moveFast(false)
|
||||||
|
, _frameWidgetDraw(nullptr)
|
||||||
|
, _frameWidgetGeom(nullptr)
|
||||||
{
|
{
|
||||||
|
setFocusPolicy(Qt::StrongFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WidgetVertex {
|
struct WidgetVertex {
|
||||||
@ -75,7 +85,7 @@ void ViewerWidget::paintGL()
|
|||||||
|
|
||||||
glViewport(0, 0, width(), height());
|
glViewport(0, 0, width(), height());
|
||||||
|
|
||||||
if( gworld == nullptr ) return;
|
if( world() == nullptr ) return;
|
||||||
|
|
||||||
auto& r = *renderer;
|
auto& r = *renderer;
|
||||||
|
|
||||||
@ -86,35 +96,36 @@ void ViewerWidget::paintGL()
|
|||||||
dummyObject->skeleton->interpolate(1.f);
|
dummyObject->skeleton->interpolate(1.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(activeModel) {
|
gworld->_work->update();
|
||||||
gworld->_work->update();
|
|
||||||
|
|
||||||
r.getRenderer()->invalidate();
|
r.getRenderer()->invalidate();
|
||||||
|
|
||||||
Model* model = activeModel;
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
if( model != _lastModel ) {
|
glm::mat4 m(1.f);
|
||||||
_lastModel = model;
|
|
||||||
emit modelChanged(_lastModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
r.getRenderer()->useProgram(r.worldProg);
|
||||||
|
|
||||||
glm::mat4 m(1.f);
|
|
||||||
|
|
||||||
r.getRenderer()->useProgram(r.worldProg);
|
ViewCamera vc;
|
||||||
|
|
||||||
ViewCamera vc;
|
float viewFov = glm::radians(45.f);
|
||||||
|
|
||||||
float viewFov = glm::radians(45.f);
|
vc.frustum.far = 500.f;
|
||||||
|
vc.frustum.near = 0.1f;
|
||||||
|
vc.frustum.fov = viewFov;
|
||||||
|
vc.frustum.aspectRatio = width()/(height()*1.f);
|
||||||
|
|
||||||
vc.frustum.far = 500.f;
|
Model* model = activeModel;
|
||||||
vc.frustum.near = 0.1f;
|
if( model != _lastModel ) {
|
||||||
vc.frustum.fov = viewFov;
|
_lastModel = model;
|
||||||
vc.frustum.aspectRatio = width()/(height()*1.f);
|
emit modelChanged(_lastModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 eye(sin(viewAngles.x) * cos(viewAngles.y), cos(viewAngles.x) * cos(viewAngles.y), sin(viewAngles.y));
|
||||||
|
|
||||||
|
if( model )
|
||||||
|
{
|
||||||
glm::mat4 proj = vc.frustum.projection();
|
glm::mat4 proj = vc.frustum.projection();
|
||||||
glm::vec3 eye(sin(viewAngles.x) * cos(viewAngles.y), cos(viewAngles.x) * cos(viewAngles.y), sin(viewAngles.y));
|
|
||||||
glm::mat4 view = glm::lookAt(eye * viewDistance, glm::vec3(0.f, 0.f, 0.f), glm::vec3(0.f, 0.f, 1.f));
|
glm::mat4 view = glm::lookAt(eye * viewDistance, glm::vec3(0.f, 0.f, 0.f), glm::vec3(0.f, 0.f, 1.f));
|
||||||
|
|
||||||
r.getRenderer()->setSceneParameters({ proj, view, glm::vec4(0.15f), glm::vec4(0.7f), glm::vec4(1.f), glm::vec4(0.f), 90.f, vc.frustum.far });
|
r.getRenderer()->setSceneParameters({ proj, view, glm::vec4(0.15f), glm::vec4(0.7f), glm::vec4(1.f), glm::vec4(0.f), 90.f, vc.frustum.far });
|
||||||
@ -122,14 +133,21 @@ void ViewerWidget::paintGL()
|
|||||||
r.getRenderer()->invalidate();
|
r.getRenderer()->invalidate();
|
||||||
|
|
||||||
r.setupRender();
|
r.setupRender();
|
||||||
if( model )
|
|
||||||
{
|
|
||||||
r.renderModel(model, m, dummyObject);
|
|
||||||
|
|
||||||
drawFrameWidget(model->frames[model->rootFrameIdx]);
|
r.renderModel(model, m, dummyObject);
|
||||||
}
|
|
||||||
|
drawFrameWidget(model->frames[model->rootFrameIdx]);
|
||||||
r.renderPostProcess();
|
r.renderPostProcess();
|
||||||
}
|
}
|
||||||
|
else if (world()->allObjects.size() > 0)
|
||||||
|
{
|
||||||
|
vc.frustum.fov = glm::radians(90.f);
|
||||||
|
vc.frustum.far = 1000.f;
|
||||||
|
vc.position = viewPosition;
|
||||||
|
vc.rotation = glm::angleAxis(glm::half_pi<float>() + viewAngles.x, glm::vec3(0.f, 0.f, 1.f))
|
||||||
|
* glm::angleAxis(viewAngles.y, glm::vec3(0.f, 1.f, 0.f));
|
||||||
|
r.renderWorld(world(), vc, 0.f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewerWidget::drawFrameWidget(ModelFrame* f, const glm::mat4& m)
|
void ViewerWidget::drawFrameWidget(ModelFrame* f, const glm::mat4& m)
|
||||||
@ -244,6 +262,35 @@ void ViewerWidget::setRenderer(GameRenderer *render)
|
|||||||
renderer = render;
|
renderer = render;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ViewerWidget::keyPressEvent(QKeyEvent* e)
|
||||||
|
{
|
||||||
|
if (e->key() == Qt::Key_Shift)
|
||||||
|
moveFast = true;
|
||||||
|
|
||||||
|
glm::vec3 movement;
|
||||||
|
if (e->key() == Qt::Key_W)
|
||||||
|
movement.y += moveFast ? 10.f : 1.f;
|
||||||
|
if (e->key() == Qt::Key_S)
|
||||||
|
movement.y -= moveFast ? 10.f : 1.f;
|
||||||
|
if (e->key() == Qt::Key_A)
|
||||||
|
movement.x -= moveFast ? 10.f : 1.f;
|
||||||
|
if (e->key() == Qt::Key_D)
|
||||||
|
movement.x += moveFast? 10.f : 1.f;
|
||||||
|
|
||||||
|
if (movement.length() > 0.f)
|
||||||
|
{
|
||||||
|
movement = (glm::angleAxis(viewAngles.x, glm::vec3(0.f, 0.f, 1.f))
|
||||||
|
* glm::angleAxis(viewAngles.y, glm::vec3(-1.f, 0.f, 0.f))) * movement;
|
||||||
|
viewPosition += movement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewerWidget::keyReleaseEvent(QKeyEvent* e)
|
||||||
|
{
|
||||||
|
if (e->key() == Qt::Key_Shift)
|
||||||
|
moveFast = false;
|
||||||
|
}
|
||||||
|
|
||||||
Model* ViewerWidget::currentModel() const
|
Model* ViewerWidget::currentModel() const
|
||||||
{
|
{
|
||||||
return activeModel;
|
return activeModel;
|
||||||
|
@ -38,10 +38,12 @@ class ViewerWidget : public QGLWidget
|
|||||||
|
|
||||||
float viewDistance;
|
float viewDistance;
|
||||||
glm::vec2 viewAngles;
|
glm::vec2 viewAngles;
|
||||||
|
glm::vec3 viewPosition;
|
||||||
|
|
||||||
bool dragging;
|
bool dragging;
|
||||||
QPointF dstart;
|
QPointF dstart;
|
||||||
glm::vec2 dastart;
|
glm::vec2 dastart;
|
||||||
|
bool moveFast;
|
||||||
|
|
||||||
DrawBuffer* _frameWidgetDraw;
|
DrawBuffer* _frameWidgetDraw;
|
||||||
GeometryBuffer* _frameWidgetGeom;
|
GeometryBuffer* _frameWidgetGeom;
|
||||||
@ -83,10 +85,12 @@ signals:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual void mousePressEvent(QMouseEvent*);
|
void keyPressEvent(QKeyEvent*) override;
|
||||||
virtual void mouseReleaseEvent(QMouseEvent*);
|
void keyReleaseEvent(QKeyEvent*) override;
|
||||||
virtual void mouseMoveEvent(QMouseEvent*);
|
void mousePressEvent(QMouseEvent*) override;
|
||||||
virtual void wheelEvent(QWheelEvent*);
|
void mouseReleaseEvent(QMouseEvent*) override;
|
||||||
|
void mouseMoveEvent(QMouseEvent*) override;
|
||||||
|
void wheelEvent(QWheelEvent*) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "views/WorldViewer.hpp"
|
#include "views/WorldViewer.hpp"
|
||||||
#include <ViewerWidget.hpp>
|
#include <ViewerWidget.hpp>
|
||||||
|
|
||||||
|
#include <engine/GameState.hpp>
|
||||||
#include <engine/GameWorld.hpp>
|
#include <engine/GameWorld.hpp>
|
||||||
#include <render/GameRenderer.hpp>
|
#include <render/GameRenderer.hpp>
|
||||||
|
|
||||||
@ -57,11 +58,9 @@ ViewerWindow::ViewerWindow(QWidget* parent, Qt::WindowFlags flags)
|
|||||||
m_views[ViewMode::Model] = new ModelViewer(viewerWidget);
|
m_views[ViewMode::Model] = new ModelViewer(viewerWidget);
|
||||||
m_viewNames[ViewMode::Model] = "Model";
|
m_viewNames[ViewMode::Model] = "Model";
|
||||||
|
|
||||||
#if 0
|
|
||||||
//------------- World Viewer
|
//------------- World Viewer
|
||||||
m_views[ViewMode::World] = new WorldViewer(viewerWidget);
|
m_views[ViewMode::World] = new WorldViewer(viewerWidget);
|
||||||
m_viewNames[ViewMode::World] = "World";
|
m_viewNames[ViewMode::World] = "World";
|
||||||
#endif
|
|
||||||
|
|
||||||
//------------- display mode switching
|
//------------- display mode switching
|
||||||
viewSwitcher = new QStackedWidget;
|
viewSwitcher = new QStackedWidget;
|
||||||
@ -73,10 +72,14 @@ ViewerWindow::ViewerWindow(QWidget* parent, Qt::WindowFlags flags)
|
|||||||
connect(this, SIGNAL(loadedData(GameWorld*)), viewer, SLOT(showData(GameWorld*)));
|
connect(this, SIGNAL(loadedData(GameWorld*)), viewer, SLOT(showData(GameWorld*)));
|
||||||
|
|
||||||
auto viewerButton = new QPushButton(m_viewNames[i].c_str());
|
auto viewerButton = new QPushButton(m_viewNames[i].c_str());
|
||||||
signalMapper->setMapping(viewerButton, i++);
|
signalMapper->setMapping(m_views[i], i);
|
||||||
|
signalMapper->setMapping(viewerButton, i);
|
||||||
connect(viewerButton, SIGNAL(clicked()), signalMapper, SLOT(map()));
|
connect(viewerButton, SIGNAL(clicked()), signalMapper, SLOT(map()));
|
||||||
switchPanel->addWidget(viewerButton);
|
switchPanel->addWidget(viewerButton);
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
|
// Map world viewer loading placements to switch to the world viewer
|
||||||
|
connect(m_views[ViewMode::World], SIGNAL(placementsLoaded(QString)), signalMapper, SLOT(map()));
|
||||||
|
|
||||||
switchView(ViewMode::Object);
|
switchView(ViewMode::Object);
|
||||||
|
|
||||||
@ -100,6 +103,9 @@ ViewerWindow::ViewerWindow(QWidget* parent, Qt::WindowFlags flags)
|
|||||||
QMenu* anim = mb->addMenu("&Animation");
|
QMenu* anim = mb->addMenu("&Animation");
|
||||||
anim->addAction("Load &Animations", this, SLOT(openAnimations()));
|
anim->addAction("Load &Animations", this, SLOT(openAnimations()));
|
||||||
|
|
||||||
|
QMenu* map = mb->addMenu("&Map");
|
||||||
|
map->addAction("Load IPL", m_views[ViewMode::World], SLOT(loadPlacements()));
|
||||||
|
|
||||||
this->setCentralWidget(mainwidget);
|
this->setCentralWidget(mainwidget);
|
||||||
|
|
||||||
updateRecentGames();
|
updateRecentGames();
|
||||||
@ -151,6 +157,7 @@ void ViewerWindow::loadGame(const QString &path)
|
|||||||
gameData = new GameData( &engineLog, &work, gameDir.absolutePath().toStdString() );
|
gameData = new GameData( &engineLog, &work, gameDir.absolutePath().toStdString() );
|
||||||
gameWorld = new GameWorld( &engineLog, &work, gameData );
|
gameWorld = new GameWorld( &engineLog, &work, gameData );
|
||||||
renderer = new GameRenderer(&engineLog, gameData );
|
renderer = new GameRenderer(&engineLog, gameData );
|
||||||
|
gameWorld->state = new GameState;
|
||||||
viewerWidget->setRenderer(renderer);
|
viewerWidget->setRenderer(renderer);
|
||||||
|
|
||||||
gameWorld->data->load();
|
gameWorld->data->load();
|
||||||
|
@ -23,9 +23,7 @@ class ViewerWindow : public QMainWindow
|
|||||||
enum ViewMode {
|
enum ViewMode {
|
||||||
Object = 0,
|
Object = 0,
|
||||||
Model = 1,
|
Model = 1,
|
||||||
#if 0
|
|
||||||
World = 2,
|
World = 2,
|
||||||
#endif
|
|
||||||
_Count
|
_Count
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -35,6 +33,7 @@ class ViewerWindow : public QMainWindow
|
|||||||
GameData* gameData;
|
GameData* gameData;
|
||||||
GameWorld* gameWorld;
|
GameWorld* gameWorld;
|
||||||
GameRenderer* renderer;
|
GameRenderer* renderer;
|
||||||
|
GameState* state;
|
||||||
|
|
||||||
/** Contains the OGL context */
|
/** Contains the OGL context */
|
||||||
ViewerWidget* viewerWidget;
|
ViewerWidget* viewerWidget;
|
||||||
|
38
rwviewer/views/ViewerInterface.hpp
Normal file
38
rwviewer/views/ViewerInterface.hpp
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#ifndef _RWVIEWER_VIEWERINTERFACE_HPP_
|
||||||
|
#define _RWVIEWER_VIEWERINTERFACE_HPP_
|
||||||
|
#include <engine/GameWorld.hpp>
|
||||||
|
|
||||||
|
#include <ViewerWidget.hpp>
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class ViewerInterface : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ViewerInterface(QWidget* parent = 0, Qt::WindowFlags f = 0)
|
||||||
|
: QWidget(parent, f)
|
||||||
|
, m_world(nullptr)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void setViewerWidget( ViewerWidget* widget ) = 0;
|
||||||
|
|
||||||
|
GameWorld* world() { return m_world; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void worldChanged() { }
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void showData(GameWorld* world)
|
||||||
|
{
|
||||||
|
m_world = world;
|
||||||
|
worldChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
GameWorld* m_world;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
38
rwviewer/views/WorldViewer.cpp
Normal file
38
rwviewer/views/WorldViewer.cpp
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#include "WorldViewer.hpp"
|
||||||
|
#include "ViewerWidget.hpp"
|
||||||
|
|
||||||
|
#include <QFileDialog>
|
||||||
|
|
||||||
|
WorldViewer::WorldViewer(ViewerWidget* viewer, QWidget* parent, Qt::WindowFlags f)
|
||||||
|
: ViewerInterface(parent, f)
|
||||||
|
{
|
||||||
|
mainLayout = new QVBoxLayout;
|
||||||
|
|
||||||
|
viewerWidget = viewer;
|
||||||
|
viewerWidget->setMinimumSize(250,250);
|
||||||
|
|
||||||
|
this->setLayout(mainLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldViewer::setViewerWidget(ViewerWidget* widget)
|
||||||
|
{
|
||||||
|
viewerWidget = widget;
|
||||||
|
// Clear the active model
|
||||||
|
widget->showModel(nullptr);
|
||||||
|
mainLayout->addWidget(viewerWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldViewer::loadPlacements(const QString& file)
|
||||||
|
{
|
||||||
|
world()->placeItems(file.toStdString());
|
||||||
|
placementsLoaded(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldViewer::loadPlacements()
|
||||||
|
{
|
||||||
|
QFileDialog dialog(this, "Open Placements", "", "Placement (*.ipl)");
|
||||||
|
if(dialog.exec()) {
|
||||||
|
loadPlacements(dialog.selectedFiles()[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
33
rwviewer/views/WorldViewer.hpp
Normal file
33
rwviewer/views/WorldViewer.hpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#ifndef _RWVIEWER_WORLDVIEWER_HPP_
|
||||||
|
#define _RWVIEWER_WORLDVIEWER_HPP_
|
||||||
|
#include <engine/GameData.hpp>
|
||||||
|
#include <engine/GameWorld.hpp>
|
||||||
|
|
||||||
|
#include "ViewerInterface.hpp"
|
||||||
|
|
||||||
|
#include <QTreeView>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QSplitter>
|
||||||
|
#include <QLayout>
|
||||||
|
|
||||||
|
class WorldViewer : public ViewerInterface
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
QVBoxLayout* mainLayout;
|
||||||
|
ViewerWidget* viewerWidget;
|
||||||
|
public:
|
||||||
|
WorldViewer(ViewerWidget *viewer = 0, QWidget* parent = 0, Qt::WindowFlags f = 0);
|
||||||
|
|
||||||
|
void setViewerWidget( ViewerWidget* widget ) override;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void placementsLoaded(const QString& file);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void loadPlacements(const QString& file);
|
||||||
|
void loadPlacements();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user