1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-09-03 00:59:47 +02:00

Implement semi-functional world viewer widget

This commit is contained in:
Daniel Evans 2016-05-16 00:06:51 +01:00
parent 5b76eb72f3
commit 8ede36c59d
7 changed files with 204 additions and 38 deletions

View File

@ -16,11 +16,21 @@
ViewerWidget::ViewerWidget(QWidget* parent, const QGLWidget* shareWidget, Qt::WindowFlags f)
: QGLWidget(parent, shareWidget, f), gworld(nullptr), activeModel(nullptr),
selectedFrame(nullptr), dummyObject(nullptr), currentObjectID(0),
_lastModel(nullptr), canimation(nullptr), viewDistance(1.f), dragging(false),
_frameWidgetDraw(nullptr), _frameWidgetGeom(nullptr)
: QGLWidget(parent, shareWidget, f)
, gworld(nullptr)
, activeModel(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 {
@ -75,7 +85,7 @@ void ViewerWidget::paintGL()
glViewport(0, 0, width(), height());
if( gworld == nullptr ) return;
if( world() == nullptr ) return;
auto& r = *renderer;
@ -86,35 +96,36 @@ void ViewerWidget::paintGL()
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 ) {
_lastModel = model;
emit modelChanged(_lastModel);
}
glm::mat4 m(1.f);
glEnable(GL_DEPTH_TEST);
glm::mat4 m(1.f);
r.getRenderer()->useProgram(r.worldProg);
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;
vc.frustum.near = 0.1f;
vc.frustum.fov = viewFov;
vc.frustum.aspectRatio = width()/(height()*1.f);
Model* model = activeModel;
if( model != _lastModel ) {
_lastModel = model;
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::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));
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.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();
}
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)
@ -244,6 +262,35 @@ void ViewerWidget::setRenderer(GameRenderer *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
{
return activeModel;

View File

@ -38,10 +38,12 @@ class ViewerWidget : public QGLWidget
float viewDistance;
glm::vec2 viewAngles;
glm::vec3 viewPosition;
bool dragging;
QPointF dstart;
glm::vec2 dastart;
bool moveFast;
DrawBuffer* _frameWidgetDraw;
GeometryBuffer* _frameWidgetGeom;
@ -83,10 +85,12 @@ signals:
protected:
virtual void mousePressEvent(QMouseEvent*);
virtual void mouseReleaseEvent(QMouseEvent*);
virtual void mouseMoveEvent(QMouseEvent*);
virtual void wheelEvent(QWheelEvent*);
void keyPressEvent(QKeyEvent*) override;
void keyReleaseEvent(QKeyEvent*) override;
void mousePressEvent(QMouseEvent*) override;
void mouseReleaseEvent(QMouseEvent*) override;
void mouseMoveEvent(QMouseEvent*) override;
void wheelEvent(QWheelEvent*) override;
};
#endif

View File

@ -4,6 +4,7 @@
#include "views/WorldViewer.hpp"
#include <ViewerWidget.hpp>
#include <engine/GameState.hpp>
#include <engine/GameWorld.hpp>
#include <render/GameRenderer.hpp>
@ -57,11 +58,9 @@ ViewerWindow::ViewerWindow(QWidget* parent, Qt::WindowFlags flags)
m_views[ViewMode::Model] = new ModelViewer(viewerWidget);
m_viewNames[ViewMode::Model] = "Model";
#if 0
//------------- World Viewer
m_views[ViewMode::World] = new WorldViewer(viewerWidget);
m_viewNames[ViewMode::World] = "World";
#endif
//------------- display mode switching
viewSwitcher = new QStackedWidget;
@ -73,10 +72,14 @@ ViewerWindow::ViewerWindow(QWidget* parent, Qt::WindowFlags flags)
connect(this, SIGNAL(loadedData(GameWorld*)), viewer, SLOT(showData(GameWorld*)));
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()));
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);
@ -100,6 +103,9 @@ ViewerWindow::ViewerWindow(QWidget* parent, Qt::WindowFlags flags)
QMenu* anim = mb->addMenu("&Animation");
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);
updateRecentGames();
@ -151,6 +157,7 @@ void ViewerWindow::loadGame(const QString &path)
gameData = new GameData( &engineLog, &work, gameDir.absolutePath().toStdString() );
gameWorld = new GameWorld( &engineLog, &work, gameData );
renderer = new GameRenderer(&engineLog, gameData );
gameWorld->state = new GameState;
viewerWidget->setRenderer(renderer);
gameWorld->data->load();

View File

@ -23,9 +23,7 @@ class ViewerWindow : public QMainWindow
enum ViewMode {
Object = 0,
Model = 1,
#if 0
World = 2,
#endif
_Count
};
@ -35,6 +33,7 @@ class ViewerWindow : public QMainWindow
GameData* gameData;
GameWorld* gameWorld;
GameRenderer* renderer;
GameState* state;
/** Contains the OGL context */
ViewerWidget* viewerWidget;

View 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

View 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]);
}
}

View 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