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

Huge rwviewer changes for new objects.

+ Change to Object Viewer to list all object types
This commit is contained in:
Daniel Evans 2014-09-19 00:10:05 +01:00
parent 713315efa2
commit 7d92fbb9f2
15 changed files with 375 additions and 78 deletions

View File

@ -34,6 +34,8 @@ typedef std::shared_ptr<ObjectInformation> ObjectInformationPtr;
*/
struct ObjectData : public ObjectInformation
{
static const ObjectClass class_id;
ObjectData()
: ObjectInformation(_class("OBJS")) { }
@ -73,6 +75,8 @@ typedef std::shared_ptr<ObjectData> ObjectDataPtr;
*/
struct CharacterData : public ObjectInformation
{
static const ObjectClass class_id;
CharacterData()
: ObjectInformation(_class("PEDS")) { }
@ -89,6 +93,8 @@ struct CharacterData : public ObjectInformation
*/
struct VehicleData : public ObjectInformation
{
static const ObjectClass class_id;
VehicleData()
: ObjectInformation(_class("CARS")) { }
@ -138,6 +144,8 @@ typedef std::shared_ptr<VehicleData> VehicleDataHandle;
struct CutsceneObjectData : public ObjectInformation
{
static const ObjectClass class_id;
CutsceneObjectData()
: ObjectInformation(_class("HIER")) { }

View File

@ -227,6 +227,11 @@ public:
/** Adds a particle to the rendering */
void addParticle(const FXParticle& particle);
Renderer* getRenderer()
{
return renderer;
}
};
#endif

View File

@ -88,6 +88,8 @@ public:
virtual void draw(const glm::mat4& model, DrawBuffer* draw, const DrawParameters& p) = 0;
virtual void drawArrays(const glm::mat4& model, DrawBuffer* draw, const DrawParameters& p) = 0;
virtual void invalidate() = 0;
};
class OpenGLRenderer : public Renderer
@ -138,6 +140,8 @@ public:
void draw(const glm::mat4& model, DrawBuffer* draw, const DrawParameters& p);
void drawArrays(const glm::mat4& model, DrawBuffer* draw, const DrawParameters& p);
void invalidate();
private:
DrawBuffer* currentDbuff;

View File

@ -0,0 +1,6 @@
#include "data/ObjectData.hpp"
const ObjectInformation::ObjectClass ObjectData::class_id = ObjectInformation::_class("OBJS");
const ObjectInformation::ObjectClass VehicleData::class_id = ObjectInformation::_class("CARS");
const ObjectInformation::ObjectClass CharacterData::class_id = ObjectInformation::_class("PEDS");
const ObjectInformation::ObjectClass CutsceneObjectData::class_id = ObjectInformation::_class("HIER");

View File

@ -79,8 +79,6 @@ GLuint compileProgram(const char* vertex, const char* fragment)
return prog;
}
void OpenGLRenderer::useDrawBuffer(DrawBuffer* dbuff)
{
if( dbuff != currentDbuff )
@ -229,3 +227,11 @@ void OpenGLRenderer::drawArrays(const glm::mat4& model, DrawBuffer* draw, const
glDrawArrays(draw->getFaceType(), p.start, p.count);
}
void OpenGLRenderer::invalidate()
{
currentDbuff = nullptr;
currentProgram = nullptr;
currentTexture = 0;
currentUBO = 0;
}

View File

@ -6,6 +6,10 @@ find_package(Qt5Core REQUIRED)
add_executable(rwviewer
main.cpp
ViewerWindow.cpp
ObjectViewer.cpp
models/ObjectListModel.cpp
ViewerWidget.cpp
ItemListModel.cpp
ItemListWidget.cpp

103
rwviewer/ObjectViewer.cpp Normal file
View File

@ -0,0 +1,103 @@
#include "ObjectViewer.hpp"
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <models/ObjectListModel.hpp>
#include "ViewerWidget.hpp"
ObjectViewer::ObjectViewer(ViewerWidget* viewer, QWidget* parent, Qt::WindowFlags f)
: QWidget(parent, f)
{
objectList = new QTableView;
QHBoxLayout* layout = new QHBoxLayout;
layout->addWidget(objectList);
QVBoxLayout* infoLayout = new QVBoxLayout;
layout->addItem(infoLayout);
previewWidget = viewer;
previewWidget->setMinimumSize(250,250);
QGridLayout* dataGrid = new QGridLayout;
dataGrid->addWidget(previewWidget, 0, 0, 1, 2);
previewID = new QLabel;
previewModel = new QLabel;
previewClass = new QLabel;
dataGrid->addWidget(new QLabel("ID"), 1, 0);
dataGrid->addWidget(previewID, 1, 1);
dataGrid->addWidget(new QLabel("Type"), 2, 0);
dataGrid->addWidget(previewClass, 2, 1);
dataGrid->addWidget(new QLabel("Model"), 3, 0);
dataGrid->addWidget(previewModel, 3, 1);
infoLayout->addItem(dataGrid);
infoLayout->addStretch(100);
this->setLayout(layout);
}
static std::map<ObjectInformation::ObjectClass, QString> gDataType =
{
{ ObjectInformation::_class("OBJS"), "Object" },
{ ObjectInformation::_class("CARS"), "Vehicle" },
{ ObjectInformation::_class("PEDS"), "Pedestrian" },
{ ObjectInformation::_class("HIER"), "Cutscene" }
};
void ObjectViewer::showItem(qint16 item)
{
auto def = world()->objectTypes[item];
if( def )
{
previewID->setText(QString::number(def->ID));
previewClass->setText(gDataType[def->class_type]);
if(def->class_type == ObjectData::class_id)
{
auto v = std::static_pointer_cast<ObjectData>(def);
previewModel->setText(QString::fromStdString(v->modelName));
}
else if(def->class_type == VehicleData::class_id)
{
auto v = std::static_pointer_cast<VehicleData>(def);
previewModel->setText(QString::fromStdString(v->modelName));
}
else if(def->class_type == CharacterData::class_id)
{
auto v = std::static_pointer_cast<CharacterData>(def);
previewModel->setText(QString::fromStdString(v->modelName));
}
previewWidget->showItem(item);
}
}
void ObjectViewer::showData(GameWorld *world)
{
_world = world;
// Loade all of the IDEs.
for(std::map<std::string, std::string>::iterator it = world->gameData.ideLocations.begin();
it != world->gameData.ideLocations.end();
++it) {
world->defineItems(it->second);
}
if( objectList->model() )
{
delete objectList->model();
}
objectList->setModel(new ObjectListModel(world, objectList));
connect(objectList->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(showItem(QModelIndex)));
}
void ObjectViewer::showItem(QModelIndex model)
{
showItem(model.internalId());
}

45
rwviewer/ObjectViewer.hpp Normal file
View File

@ -0,0 +1,45 @@
#pragma once
#ifndef _OBJECTVIEWER_HPP_
#define _OBJECTVIEWER_HPP_
#include <engine/GameData.hpp>
#include <engine/GameWorld.hpp>
#include <QGLWidget>
#include <QTableView>
#include <QLabel>
class ViewerWidget;
class ObjectViewer : public QWidget
{
Q_OBJECT
QTableView* objectList;
GameWorld* _world;
ViewerWidget* previewWidget;
QLabel* previewID;
QLabel* previewModel;
QLabel* previewClass;
public:
ObjectViewer(ViewerWidget *viewer = 0, QWidget* parent = 0, Qt::WindowFlags f = 0);
GameWorld* world()
{
return _world;
}
public slots:
void showItem(qint16 item);
void showData(GameWorld* world);
private slots:
void showItem(QModelIndex model);
};
#endif

View File

@ -39,9 +39,6 @@ void ViewerWidget::initializeGL()
timer.setInterval(16);
connect(&timer, SIGNAL(timeout()), SLOT(updateGL()));
timer.start();
glewExperimental = 1;
glewInit();
_frameWidgetDraw = new DrawBuffer;
_frameWidgetDraw->setFaceType(GL_LINES);
@ -74,17 +71,18 @@ void ViewerWidget::paintGL()
if(dummyObject) {
gworld->_work->update();
r.getRenderer()->invalidate();
if( dummyObject->model->model != _lastModel ) {
_lastModel = dummyObject->model->model;
emit modelChanged(_lastModel);
}
glEnable(GL_DEPTH_TEST);
glm::mat4 m;
//glUseProgram(r.worldProgram);
r.getRenderer()->useProgram(r.worldProg);
ViewCamera vc;
@ -100,6 +98,8 @@ void ViewerWidget::paintGL()
//r.uploadUBO<SceneUniformData>(r.uboScene,
//{ proj, view, glm::vec4(1.f), glm::vec4(1.f), glm::vec4(1.f), glm::vec4(0.f), 90.f, vc.frustum.far });
r.getRenderer()->invalidate();
if( dummyObject->model->model ) {
gworld->renderer.renderModel(dummyObject->model->model, m, dummyObject);
@ -175,29 +175,16 @@ void ViewerWidget::exportModel()
#endif
}
void ViewerWidget::dataLoaded(GameWorld *world)
{
gworld = world;
}
Model* ViewerWidget::currentModel() const
{
return _lastModel;
}
void ViewerWidget::setGamePath(const std::string &path)
{
if( gworld ) delete gworld;
gworld = new GameWorld(path);
gworld->gameData.loadIMG("/models/gta3");
gworld->gameData.loadIMG("/models/txd");
gworld->load();
for(auto it = gworld->gameData.ideLocations.begin();
it != gworld->gameData.ideLocations.end();
++it) {
gworld->defineItems(it->second);
}
emit dataLoaded(gworld);
}
void ViewerWidget::mousePressEvent(QMouseEvent* e)
{
dragging = true;

View File

@ -38,18 +38,16 @@ class ViewerWidget : public QGLWidget
void drawFrameWidget(ModelFrame* f, const glm::mat4& = {});
public:
ViewerWidget(QWidget* parent = 0, const QGLWidget* shareWidget = 0, Qt::WindowFlags f = 0);
ViewerWidget(QWidget* parent = 0, const QGLWidget* shareWidget = 0, Qt::WindowFlags f = 0);
virtual void initializeGL();
virtual void initializeGL();
virtual void resizeGL(int w, int h);
virtual void resizeGL(int w, int h);
virtual void paintGL();
virtual void paintGL();
Model *currentModel() const;
// TODO: Move this into the main window or elsewhere, doesn't really belong here.
void setGamePath(const std::string& path);
GameWorld* world();
public slots:
@ -60,10 +58,10 @@ public slots:
void exportModel();
signals:
void dataLoaded(GameWorld* world);
signals:
void fileOpened(const QString& file);
void modelChanged(Model* model);

View File

@ -1,36 +1,23 @@
#include "ViewerWindow.hpp"
#include "ObjectViewer.hpp"
#include <engine/GameWorld.hpp>
#include "ViewerWidget.hpp"
#include "ItemListWidget.hpp"
#include "ModelFramesWidget.hpp"
#include "AnimationListWidget.hpp"
#include <QMenuBar>
#include <QFileDialog>
#include <QApplication>
#include <QSettings>
#include <QDebug>
#include <fstream>
#include <QOffscreenSurface>
#include <ViewerWidget.hpp>
static int MaxRecentGames = 5;
ViewerWindow::ViewerWindow(QWidget* parent, Qt::WindowFlags flags): QMainWindow(parent, flags)
ViewerWindow::ViewerWindow(QWidget* parent, Qt::WindowFlags flags)
: QMainWindow(parent, flags), gameWorld(nullptr)
{
setMinimumSize(640, 480);
viewer = new ViewerWidget();
this->setCentralWidget(viewer);
itemsWidget = new ItemListWidget;
itemsWidget->setObjectName("archivewidget");
this->addDockWidget(Qt::LeftDockWidgetArea, itemsWidget);
frameswidget = new ModelFramesWidget;
frameswidget->setObjectName("frameswidget");
this->addDockWidget(Qt::RightDockWidgetArea, frameswidget);
animationswidget = new AnimationListWidget;
animationswidget->setObjectName("animationswidget");
this->addDockWidget(Qt::RightDockWidgetArea, animationswidget);
QMenuBar* mb = this->menuBar();
QMenu* file = mb->addMenu("&File");
@ -49,16 +36,24 @@ ViewerWindow::ViewerWindow(QWidget* parent, Qt::WindowFlags flags): QMainWindow(
connect(ex, SIGNAL(triggered()), QApplication::instance(), SLOT(closeAllWindows()));
QMenu* data = mb->addMenu("&Data");
data->addAction("Export &Model", viewer, SLOT(exportModel()));
//data->addAction("Export &Model", objectViewer, SLOT(exportModel()));
QMenu* anim = mb->addMenu("&Animation");
anim->addAction("Load &Animations", this, SLOT(openAnimations()));
connect(itemsWidget, SIGNAL(selectedItemChanged(qint16)), viewer, SLOT(showItem(qint16)));
connect(viewer, SIGNAL(dataLoaded(GameWorld*)), itemsWidget, SLOT(worldLoaded(GameWorld*)));
connect(viewer, SIGNAL(modelChanged(Model*)), frameswidget, SLOT(setModel(Model*)));
connect(animationswidget, SIGNAL(selectedAnimationChanged(Animation*)), viewer, SLOT(showAnimation(Animation*)));
viewerWidget = new ViewerWidget;
viewerWidget->context()->makeCurrent();
glewExperimental = 1;
glewInit();
objectViewer = new ObjectViewer(viewerWidget);
this->setCentralWidget(objectViewer);
connect(this, SIGNAL(loadedData(GameWorld*)), objectViewer, SLOT(showData(GameWorld*)));
connect(this, SIGNAL(loadedData(GameWorld*)), viewerWidget, SLOT(dataLoaded(GameWorld*)));
updateRecentGames();
}
@ -83,6 +78,7 @@ void ViewerWindow::closeEvent(QCloseEvent* event)
void ViewerWindow::openAnimations()
{
#if 0
QFileDialog dialog(this, "Open Animations", QDir::homePath(), "IFP Animations (*.ifp)");
if(dialog.exec()) {
std::ifstream dfile(dialog.selectedFiles().at(0).toStdString().c_str());
@ -108,6 +104,7 @@ void ViewerWindow::openAnimations()
animationswidget->setAnimations(anims);
}
#endif
}
void ViewerWindow::loadGame()
@ -126,7 +123,15 @@ void ViewerWindow::loadGame(const QString &path)
QDir gameDir( path );
if( gameDir.exists() && path.size() > 0 ) {
viewer->setGamePath( gameDir.absolutePath().toStdString() );
gameWorld = new GameWorld( gameDir.absolutePath().toStdString() );
gameWorld->load();
// Initalize all the archives.
gameWorld->gameData.loadIMG("/models/gta3");
gameWorld->gameData.loadIMG("/models/txd");
gameWorld->gameData.loadIMG("/anim/cuts");
loadedData(gameWorld);
}
QSettings settings("OpenRW", "rwviewer");

View File

@ -2,20 +2,23 @@
#ifndef _VIEWERWINDOW_HPP_
#define _VIEWERWINDOW_HPP_
#include <QMainWindow>
#include <engine/GameWorld.hpp>
#include <QGLContext>
class ModelFramesWidget;
class ItemListWidget;
class AnimationListWidget;
class ObjectViewer;
class ViewerWidget;
class ViewerWindow : public QMainWindow
{
Q_OBJECT
ViewerWidget* viewer;
ItemListWidget* itemsWidget;
ModelFramesWidget* frameswidget;
AnimationListWidget* animationswidget;
GameWorld* gameWorld;
/** Contains the OGL context */
ViewerWidget* viewerWidget;
ObjectViewer* objectViewer;
QGLContext* context;
public:
ViewerWindow(QWidget* parent = 0, Qt::WindowFlags flags = 0);
@ -26,9 +29,9 @@ public:
*/
void openGame(const QString& datFile);
virtual void showEvent(QShowEvent*);
virtual void showEvent(QShowEvent*);
virtual void closeEvent(QCloseEvent*);
virtual void closeEvent(QCloseEvent*);
public slots:
@ -38,6 +41,10 @@ public slots:
void loadGame( const QString& path );
signals:
void loadedData(GameWorld* world);
private slots:
void openRecent();

View File

@ -0,0 +1,89 @@
#include "ObjectListModel.hpp"
ObjectListModel::ObjectListModel(GameWorld *world, QObject *parent) :
QAbstractTableModel(parent), _world( world )
{
}
int ObjectListModel::rowCount(const QModelIndex &parent) const
{
return _world->objectTypes.size();
}
int ObjectListModel::columnCount(const QModelIndex &parent) const
{
return 3;
}
static std::map<ObjectInformation::ObjectClass, QString> gDataType =
{
{ ObjectInformation::_class("OBJS"), "Object" },
{ ObjectInformation::_class("CARS"), "Vehicle" },
{ ObjectInformation::_class("PEDS"), "Pedestrian" },
{ ObjectInformation::_class("HIER"), "Cutscene" }
};
QVariant ObjectListModel::data(const QModelIndex &index, int role) const
{
if ( role == Qt::DisplayRole ) {
auto id = index.internalId();
if( id == -1 ) return QVariant::Invalid;
if( index.column() == 0 )
{
return id;
}
else if ( index.column() == 1 )
{
auto object = world()->objectTypes[id];
if( gDataType[object->class_type].isEmpty() )
{
return QString("Unknown");
}
return gDataType[object->class_type];
}
else if( index.column() == 2 )
{
auto object = world()->objectTypes[id];
if(object->class_type == ObjectData::class_id)
{
auto v = std::static_pointer_cast<ObjectData>(object);
return QString::fromStdString(v->modelName);
}
else if(object->class_type == VehicleData::class_id)
{
auto v = std::static_pointer_cast<VehicleData>(object);
return QString::fromStdString(v->modelName);
}
else if(object->class_type == CharacterData::class_id)
{
auto v = std::static_pointer_cast<CharacterData>(object);
return QString::fromStdString(v->modelName);
}
}
}
return QVariant::Invalid;
}
QVariant ObjectListModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if(role == Qt::DisplayRole && orientation == Qt::Horizontal) {
switch(section) {
case 0:
return "ID";
case 1:
return "Type";
case 2:
return "Model";
}
}
return QVariant::Invalid;
}
QModelIndex ObjectListModel::index(int row, int column, const QModelIndex &parent) const
{
auto it = world()->objectTypes.begin();
for(int i = 0; i < row; i++) it++;
auto id = it->second->ID;
return hasIndex(row, column, parent) ? createIndex(row, column, id) : QModelIndex();
}

View File

@ -0,0 +1,30 @@
#ifndef _OBJECTLISTMODEL_HPP_
#define _OBJECTLISTMODEL_HPP_
#include <QAbstractItemModel>
#include <engine/GameWorld.hpp>
class ObjectListModel : public QAbstractTableModel
{
Q_OBJECT
GameWorld* _world;
public:
explicit ObjectListModel(GameWorld* _world, QObject *parent = 0);
GameWorld* world() const { return _world; }
virtual int rowCount(const QModelIndex& parent = QModelIndex()) const;
virtual int columnCount(const QModelIndex& parent = QModelIndex()) const;
virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
QModelIndex index(int row, int column, const QModelIndex &parent) const;
};
#endif // _OBJECTLISTMODEL_HPP_

View File

@ -15,12 +15,12 @@ BOOST_AUTO_TEST_CASE(test_object_data)
auto obj = l.objects[1100];
BOOST_ASSERT(def->type == ObjectInformation::_class("OBJS"));
std::shared_ptr<ObjectData> def = std::dynamic_pointer_cast<ObjectData>(def);
BOOST_ASSERT(def->class_type == ObjectInformation::_class("OBJS"));
BOOST_CHECK_EQUAL( def->modelName, "rd_corner1" );
BOOST_CHECK_EQUAL( def->textureName, "generic", );
BOOST_CHECK_EQUAL( def->textureName, "generic" );
BOOST_CHECK_EQUAL( def->numClumps, 1 );
BOOST_CHECK_EQUAL( def->drawDistance[0], 220 );
BOOST_CHECK_EQUAL( def->flags, 0 );
@ -34,12 +34,12 @@ BOOST_AUTO_TEST_CASE(test_object_data)
auto obj = l.objects[90];
BOOST_ASSERT(def->type == ObjectInformation::_class("CARS"));
std::shared_ptr<VehicleData> def = std::dynamic_pointer_cast<VehicleData>(def);
BOOST_ASSERT(def->type == ObjectInformation::_class("CARS"));
BOOST_CHECK_EQUAL( def->modelName, "landstal");
BOOST_CHECK_EQUAL( def->textureName, "landstal", );
BOOST_CHECK_EQUAL( def->textureName, "landstal" );
BOOST_CHECK_EQUAL( def->type, VehicleData::CAR );
BOOST_CHECK_EQUAL( def->handlingID, "LANDSTAL" );
BOOST_CHECK_EQUAL( def->gameName, "LANDSTK" );