diff --git a/armoury/src/gearview.cpp b/armoury/src/gearview.cpp index dff97c8..d898f4f 100644 --- a/armoury/src/gearview.cpp +++ b/armoury/src/gearview.cpp @@ -339,6 +339,7 @@ void GearView::updatePart() gearAddition.bodyId = physis_get_race_code(fallbackRace, fallbackSubrace, currentGender); mdlPart->addModel(mdl, + glm::vec3(), sanitizeMdlPath(mdlPath), materials, currentLod, @@ -389,7 +390,7 @@ void GearView::updatePart() } } - mdlPart->addModel(mdl, sanitizeMdlPath(mdlPath), materials, currentLod); + mdlPart->addModel(mdl, glm::vec3(), sanitizeMdlPath(mdlPath), materials, currentLod); } } @@ -412,7 +413,7 @@ void GearView::updatePart() } } - mdlPart->addModel(mdl, sanitizeMdlPath(mdlPath), materials, currentLod); + mdlPart->addModel(mdl, glm::vec3(), sanitizeMdlPath(mdlPath), materials, currentLod); } } @@ -435,7 +436,7 @@ void GearView::updatePart() } } - mdlPart->addModel(mdl, sanitizeMdlPath(mdlPath), materials, currentLod); + mdlPart->addModel(mdl, glm::vec3(), sanitizeMdlPath(mdlPath), materials, currentLod); } } @@ -452,7 +453,7 @@ void GearView::updatePart() if (cache.fileExists(QLatin1String(skinmtrl_path.c_str()))) { auto mat = physis_material_parse(cache.lookupFile(QLatin1String(skinmtrl_path.c_str()))); - mdlPart->addModel(mdl, sanitizeMdlPath(mdlPath), {mat}, currentLod); + mdlPart->addModel(mdl, glm::vec3(), sanitizeMdlPath(mdlPath), {mat}, currentLod); } } } diff --git a/mdlviewer/src/mainwindow.cpp b/mdlviewer/src/mainwindow.cpp index 61f6675..1826ca5 100644 --- a/mdlviewer/src/mainwindow.cpp +++ b/mdlviewer/src/mainwindow.cpp @@ -49,7 +49,7 @@ void MainWindow::setupFileMenu(QMenu *menu) auto buffer = physis_read_file(fileName.toStdString().c_str()); - part->addModel(physis_mdl_parse(buffer), QStringLiteral("mdl"), {}, 0); + part->addModel(physis_mdl_parse(buffer), glm::vec3(), QStringLiteral("mdl"), {}, 0); }); } diff --git a/parts/mdl/mdlpart.cpp b/parts/mdl/mdlpart.cpp index d4bc531..92953f8 100644 --- a/parts/mdl/mdlpart.cpp +++ b/parts/mdl/mdlpart.cpp @@ -71,7 +71,13 @@ void MDLPart::clear() Q_EMIT modelChanged(); } -void MDLPart::addModel(physis_MDL mdl, const QString &name, std::vector materials, int lod, uint16_t fromBodyId, uint16_t toBodyId) +void MDLPart::addModel(physis_MDL mdl, + glm::vec3 position, + const QString &name, + std::vector materials, + int lod, + uint16_t fromBodyId, + uint16_t toBodyId) { qDebug() << "Adding model to MDLPart"; @@ -79,6 +85,7 @@ void MDLPart::addModel(physis_MDL mdl, const QString &name, std::vectormodels = models; } +void MDLPart::enableFreemode() +{ + vkWindow->freeMode = true; +} + +bool MDLPart::event(QEvent *event) +{ + switch (event->type()) { + case QEvent::KeyPress: + case QEvent::KeyRelease: + vkWindow->event(event); + break; + } + return QWidget::event(event); +} + void MDLPart::reloadBoneData() { if (skeleton) { diff --git a/parts/mdl/mdlpart.h b/parts/mdl/mdlpart.h index 886334b..2ba6f4a 100644 --- a/parts/mdl/mdlpart.h +++ b/parts/mdl/mdlpart.h @@ -52,7 +52,13 @@ public Q_SLOTS: void clear(); /// Adds a new MDL with a list of materials used. - void addModel(physis_MDL mdl, const QString &name, std::vector materials, int lod, uint16_t fromBodyId = 101, uint16_t toBodyId = 101); + void addModel(physis_MDL mdl, + glm::vec3 position, + const QString &name, + std::vector materials, + int lod, + uint16_t fromBodyId = 101, + uint16_t toBodyId = 101); void removeModel(const physis_MDL &mdl); @@ -65,6 +71,11 @@ public Q_SLOTS: void reloadBoneData(); void reloadRenderer(); + void enableFreemode(); + +protected: + bool event(QEvent *event) override; + private: RenderMaterial createMaterial(const physis_Material &mat); diff --git a/parts/mdl/vulkanwindow.cpp b/parts/mdl/vulkanwindow.cpp index e9daa84..a94dee9 100644 --- a/parts/mdl/vulkanwindow.cpp +++ b/parts/mdl/vulkanwindow.cpp @@ -60,6 +60,8 @@ bool VulkanWindow::event(QEvent *e) case QEvent::MouseButtonPress: { auto mouseEvent = dynamic_cast(e); + part->setFocus(Qt::FocusReason::MouseFocusReason); + if (mouseEvent->button() == Qt::MouseButton::LeftButton || mouseEvent->button() == Qt::MouseButton::RightButton) { part->lastX = mouseEvent->position().x(); part->lastY = mouseEvent->position().y(); @@ -105,6 +107,42 @@ bool VulkanWindow::event(QEvent *e) part->cameraDistance -= (scrollEvent->angleDelta().y() / 120.0f) * 0.1f; // FIXME: why 120? part->cameraDistance = std::clamp(part->cameraDistance, 1.0f, 4.0f); } break; + case QEvent::KeyPress: { + auto keyEvent = dynamic_cast(e); + + switch (keyEvent->key()) { + case Qt::Key_W: + pressed_keys[0] = true; + break; + case Qt::Key_A: + pressed_keys[1] = true; + break; + case Qt::Key_S: + pressed_keys[2] = true; + break; + case Qt::Key_D: + pressed_keys[3] = true; + break; + } + } break; + case QEvent::KeyRelease: { + auto keyEvent = dynamic_cast(e); + + switch (keyEvent->key()) { + case Qt::Key_W: + pressed_keys[0] = false; + break; + case Qt::Key_A: + pressed_keys[1] = false; + break; + case Qt::Key_S: + pressed_keys[2] = false; + break; + case Qt::Key_D: + pressed_keys[3] = false; + break; + } + } break; default: break; } @@ -130,9 +168,42 @@ void VulkanWindow::render() ImGui::Render(); - glm::vec3 position(part->cameraDistance * sin(part->yaw), part->cameraDistance * part->pitch, part->cameraDistance * cos(part->yaw)); + if (freeMode) { + float movX = 0.0f; + float movY = 0.0f; - m_renderer->view = glm::lookAt(part->position + position, part->position, glm::vec3(0, -1, 0)); + if (pressed_keys[0]) { + movY = -0.05f; + } + + if (pressed_keys[1]) { + movX = -0.05f; + } + + if (pressed_keys[2]) { + movY = 0.05f; + } + + if (pressed_keys[3]) { + movX = 0.05f; + } + + glm::vec3 forward, right; + forward = normalize(glm::angleAxis(part->yaw, glm::vec3(0, 1, 0)) * glm::angleAxis(part->pitch, glm::vec3(1, 0, 0)) * glm::vec3(0, 0, 1)); + right = normalize(glm::angleAxis(part->yaw, glm::vec3(0, 1, 0)) * glm::vec3(1, 0, 0)); + + part->position += right * movX * 2.0f; + part->position += forward * movY * 2.0f; + + m_renderer->view = glm::mat4(1.0f); + m_renderer->view = glm::translate(m_renderer->view, part->position); + m_renderer->view *= glm::mat4_cast(glm::angleAxis(part->yaw, glm::vec3(0, 1, 0)) * glm::angleAxis(part->pitch, glm::vec3(1, 0, 0))); + m_renderer->view = glm::inverse(m_renderer->view); + } else { + glm::vec3 position(part->cameraDistance * sin(part->yaw), part->cameraDistance * part->pitch, part->cameraDistance * cos(part->yaw)); + + m_renderer->view = glm::lookAt(part->position + position, part->position, glm::vec3(0, -1, 0)); + } m_renderer->render(models); m_instance->presentQueued(this); diff --git a/parts/mdl/vulkanwindow.h b/parts/mdl/vulkanwindow.h index d9b8ceb..4d559f2 100644 --- a/parts/mdl/vulkanwindow.h +++ b/parts/mdl/vulkanwindow.h @@ -20,10 +20,12 @@ public: void render(); std::vector models; + bool freeMode = false; private: bool m_initialized = false; Renderer *m_renderer; QVulkanInstance *m_instance; MDLPart *part; + bool pressed_keys[4] = {}; }; \ No newline at end of file