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:
parent
5b76eb72f3
commit
8ede36c59d
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
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