2014-02-10 12:41:05 +00:00
|
|
|
#include "ViewerWidget.hpp"
|
2014-02-11 13:40:56 +00:00
|
|
|
#include <render/Model.hpp>
|
|
|
|
#include <glm/gtc/type_ptr.hpp>
|
2014-02-11 15:45:45 +00:00
|
|
|
#include <QMouseEvent>
|
2014-03-01 11:19:33 +00:00
|
|
|
#include <engine/GameObject.hpp>
|
|
|
|
#include <engine/Animator.hpp>
|
2014-06-10 00:46:48 +01:00
|
|
|
#include <QFileDialog>
|
|
|
|
#include <algorithm>
|
2014-02-10 12:41:05 +00:00
|
|
|
|
2014-02-11 05:46:29 +00:00
|
|
|
ViewerWidget::ViewerWidget(QWidget* parent, const QGLWidget* shareWidget, Qt::WindowFlags f)
|
2014-06-10 00:46:48 +01:00
|
|
|
: QGLWidget(parent, shareWidget, f), gworld(nullptr), dummyObject(nullptr), currentObjectID(0),
|
2014-06-08 01:58:49 +01:00
|
|
|
cmodel(nullptr), canimation(nullptr), viewDistance(1.f), dragging(false)
|
2014-02-11 05:46:29 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-02-10 12:41:05 +00:00
|
|
|
void ViewerWidget::initializeGL()
|
|
|
|
{
|
2014-02-10 17:22:07 +00:00
|
|
|
QGLWidget::initializeGL();
|
|
|
|
timer.setInterval(16);
|
|
|
|
connect(&timer, SIGNAL(timeout()), SLOT(updateGL()));
|
|
|
|
timer.start();
|
2014-02-11 05:46:29 +00:00
|
|
|
|
|
|
|
glewExperimental = 1;
|
|
|
|
glewInit();
|
2014-02-10 12:41:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ViewerWidget::resizeGL(int w, int h)
|
|
|
|
{
|
2014-02-10 17:22:07 +00:00
|
|
|
QGLWidget::resizeGL(w, h);
|
2014-02-11 05:46:29 +00:00
|
|
|
glViewport(0, 0, w, h);
|
2014-02-10 12:41:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ViewerWidget::paintGL()
|
|
|
|
{
|
|
|
|
glClearColor(0.3f, 0.3f, 0.3f, 1.f);
|
2014-02-11 13:40:56 +00:00
|
|
|
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
|
|
|
|
|
|
|
glViewport(0, 0, width(), height());
|
|
|
|
|
2014-06-08 01:58:49 +01:00
|
|
|
if( gworld == nullptr ) return;
|
|
|
|
|
2014-02-11 13:40:56 +00:00
|
|
|
auto& r = gworld->renderer;
|
|
|
|
|
|
|
|
r.camera.frustum.far = 100.f;
|
|
|
|
r.camera.frustum.near = 0.1f;
|
2014-05-27 00:08:14 +01:00
|
|
|
r.camera.frustum.fov = 90.f;
|
2014-02-11 13:40:56 +00:00
|
|
|
r.camera.frustum.aspectRatio = width()/(height()*1.f);
|
2014-03-01 11:19:33 +00:00
|
|
|
|
|
|
|
if(dummyObject && dummyObject->animator) {
|
|
|
|
dummyObject->animator->tick(1.f/60.f);
|
|
|
|
}
|
2014-02-11 13:40:56 +00:00
|
|
|
|
2014-02-12 06:42:07 +00:00
|
|
|
if(cmodel) {
|
2014-02-11 15:45:45 +00:00
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
|
2014-02-11 13:40:56 +00:00
|
|
|
glm::mat4 m;
|
|
|
|
|
|
|
|
glUseProgram(r.worldProgram);
|
2014-02-10 17:22:07 +00:00
|
|
|
|
2014-02-11 14:16:14 +00:00
|
|
|
glUniform1f(r.uniFogStart, 90.f);
|
|
|
|
glUniform1f(r.uniFogEnd, 100.f);
|
2014-02-11 13:40:56 +00:00
|
|
|
|
2014-02-11 14:16:14 +00:00
|
|
|
glUniform4f(r.uniAmbientCol, .1f, .1f, .1f, 1.f);
|
2014-02-11 13:40:56 +00:00
|
|
|
glUniform4f(r.uniDynamicCol, 1.f, 1.f, 1.f, 1.f);
|
|
|
|
//glUniform3f(uniSunDirection, sunDirection.x, sunDirection.y, sunDirection.z);
|
|
|
|
glUniform1f(r.uniMatDiffuse, 0.9f);
|
|
|
|
glUniform1f(r.uniMatAmbient, 0.1f);
|
|
|
|
|
|
|
|
glm::mat4 proj = r.camera.frustum.projection();
|
2014-02-11 15:45:45 +00:00
|
|
|
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));
|
2014-02-11 13:40:56 +00:00
|
|
|
glUniformMatrix4fv(r.uniView, 1, GL_FALSE, glm::value_ptr(view));
|
|
|
|
glUniformMatrix4fv(r.uniProj, 1, GL_FALSE, glm::value_ptr(proj));
|
|
|
|
|
2014-06-06 12:18:32 +01:00
|
|
|
gworld->renderer.renderModel(cmodel->model, m, dummyObject);
|
2014-02-10 17:22:07 +00:00
|
|
|
}
|
2014-02-10 12:41:05 +00:00
|
|
|
}
|
2014-02-10 17:22:07 +00:00
|
|
|
|
2014-02-11 05:46:29 +00:00
|
|
|
GameWorld* ViewerWidget::world()
|
|
|
|
{
|
|
|
|
return gworld;
|
|
|
|
}
|
|
|
|
|
2014-06-08 01:58:49 +01:00
|
|
|
void ViewerWidget::showItem(qint16 item)
|
2014-02-11 05:46:29 +00:00
|
|
|
{
|
2014-06-10 00:46:48 +01:00
|
|
|
currentObjectID = item;
|
2014-06-08 01:58:49 +01:00
|
|
|
// TODO: actually show items.
|
2014-02-11 05:46:29 +00:00
|
|
|
}
|
2014-02-11 15:45:45 +00:00
|
|
|
|
2014-03-01 11:19:33 +00:00
|
|
|
void ViewerWidget::showAnimation(Animation *anim)
|
|
|
|
{
|
|
|
|
canimation = anim;
|
|
|
|
if(dummyObject) {
|
|
|
|
if(dummyObject->animator == nullptr) {
|
|
|
|
dummyObject->animator = new Animator;
|
2014-06-06 12:18:32 +01:00
|
|
|
dummyObject->animator->setModel(dummyObject->model->model);
|
2014-03-01 11:19:33 +00:00
|
|
|
}
|
|
|
|
dummyObject->animator->setAnimation(canimation);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-10 00:46:48 +01:00
|
|
|
void ViewerWidget::exportModel()
|
|
|
|
{
|
|
|
|
QString toSv = QFileDialog::getSaveFileName(this,
|
|
|
|
"Export Model",
|
|
|
|
QDir::homePath(),
|
|
|
|
"Model (*.DFF)");
|
|
|
|
|
|
|
|
if( toSv.size() == 0 ) return;
|
|
|
|
|
|
|
|
auto it = world()->objectTypes.find(currentObjectID);
|
|
|
|
if( it != world()->objectTypes.end() ) {
|
|
|
|
for( auto& archive : world()->gameData.archives ) {
|
|
|
|
for(size_t i = 0; i < archive.second.getAssetCount(); ++i) {
|
|
|
|
auto& assetI = archive.second.getAssetInfoByIndex(i);
|
|
|
|
std::string q(assetI.name);
|
|
|
|
std::transform(q.begin(), q.end(), q.begin(), ::tolower);
|
|
|
|
if( q.find(it->second->modelName) != q.npos ) {
|
|
|
|
archive.second.saveAsset(q, toSv.toStdString());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-06 12:18:32 +01:00
|
|
|
ModelHandle* ViewerWidget::currentModel() const
|
2014-02-12 06:42:07 +00:00
|
|
|
{
|
|
|
|
return cmodel;
|
|
|
|
}
|
|
|
|
|
2014-06-08 01:58:49 +01:00
|
|
|
void ViewerWidget::setGamePath(const std::string &path)
|
2014-02-12 06:42:07 +00:00
|
|
|
{
|
2014-06-08 01:58:49 +01:00
|
|
|
if( gworld ) delete gworld;
|
|
|
|
gworld = new GameWorld(path);
|
|
|
|
|
2014-06-10 00:46:48 +01:00
|
|
|
gworld->gameData.loadIMG("/models/gta3");
|
|
|
|
gworld->gameData.loadIMG("/models/txd");
|
|
|
|
|
|
|
|
gworld->gameData.load();
|
2014-06-08 01:58:49 +01:00
|
|
|
for(auto it = gworld->gameData.ideLocations.begin();
|
|
|
|
it != gworld->gameData.ideLocations.end();
|
|
|
|
++it) {
|
|
|
|
gworld->defineItems(it->second);
|
|
|
|
}
|
|
|
|
|
|
|
|
emit dataLoaded(gworld);
|
2014-02-12 06:42:07 +00:00
|
|
|
}
|
|
|
|
|
2014-02-11 15:45:45 +00:00
|
|
|
void ViewerWidget::mousePressEvent(QMouseEvent* e)
|
|
|
|
{
|
|
|
|
dragging = true;
|
|
|
|
dstart = e->localPos();
|
|
|
|
dastart = viewAngles;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ViewerWidget::mouseReleaseEvent(QMouseEvent*)
|
|
|
|
{
|
|
|
|
dragging = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ViewerWidget::mouseMoveEvent(QMouseEvent* e)
|
|
|
|
{
|
|
|
|
if(dragging) {
|
|
|
|
auto d = e->localPos() - dstart;
|
|
|
|
viewAngles = dastart + glm::vec2(d.x(), d.y()) * 0.01f;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ViewerWidget::wheelEvent(QWheelEvent* e)
|
|
|
|
{
|
2014-05-27 00:08:14 +01:00
|
|
|
viewDistance = qMax(viewDistance - e->angleDelta().y() / 240.f, 0.5f);
|
2014-02-11 15:45:45 +00:00
|
|
|
}
|
|
|
|
|