fix(model): clicking selects root model unless alt is pressed

This commit is contained in:
maelstrom 2025-06-10 20:02:16 +02:00
parent 3f7ad90f5b
commit 166950f08d
8 changed files with 50 additions and 8 deletions

View file

@ -1,4 +1,4 @@
#include "model.h"
Model::Model(): Instance(&TYPE) {}
Model::Model(): PVInstance(&TYPE) {}
Model::~Model() = default;

View file

@ -2,11 +2,12 @@
#include "objects/annotation.h"
#include "objects/base/instance.h"
#include "objects/pvinstance.h"
#include <memory>
// Group object for Parts
class DEF_INST_(explorer_icon="model") Model : public Instance {
class DEF_INST_(explorer_icon="model") Model : public PVInstance {
AUTOGEN_PREAMBLE
public:

View file

@ -22,7 +22,7 @@
Part::Part(): Part(PartConstructParams { .size = glm::vec3(2, 1.2, 4), .color = Color3(0.639216f, 0.635294f, 0.647059f) }) {
}
Part::Part(PartConstructParams params): Instance(&TYPE), cframe(CFrame::FromEulerAnglesXYZ((Vector3)params.rotation) + params.position),
Part::Part(PartConstructParams params): PVInstance(&TYPE), cframe(CFrame::FromEulerAnglesXYZ((Vector3)params.rotation) + params.position),
size(params.size), color(params.color), anchored(params.anchored), locked(params.locked) {
}

View file

@ -13,6 +13,7 @@
#include <reactphysics3d/reactphysics3d.h>
#include <vector>
#include "annotation.h"
#include "objects/pvinstance.h"
namespace rp = reactphysics3d;
@ -29,7 +30,7 @@ struct PartConstructParams {
class Workspace;
class DEF_INST_(explorer_icon="part") Part : public Instance {
class DEF_INST_(explorer_icon="part") Part : public PVInstance {
AUTOGEN_PREAMBLE
protected:
// Joints where this part is Part0

View file

@ -0,0 +1,4 @@
#include "pvinstance.h"
PVInstance::PVInstance(const InstanceType* type): Instance(type) {}
PVInstance::~PVInstance() = default;

View file

@ -0,0 +1,13 @@
#pragma once
#include "objects/annotation.h"
#include "objects/base/instance.h"
class DEF_INST_ABSTRACT PVInstance : public Instance {
AUTOGEN_PREAMBLE
protected:
PVInstance(const InstanceType*);
public:
~PVInstance();
};

View file

@ -1,6 +1,7 @@
#include <GL/glew.h>
#include <glm/common.hpp>
#include <glm/vector_relational.hpp>
#include <memory>
#include <qnamespace.h>
#include <qsoundeffect.h>
#include <string>
@ -13,6 +14,7 @@
#include "common.h"
#include "math_helper.h"
#include "objects/base/instance.h"
#include "objects/pvinstance.h"
#include "partassembly.h"
#include "physics/util.h"
#include "rendering/renderer.h"
@ -390,6 +392,17 @@ void MainGLWidget::mousePressEvent(QMouseEvent* evt) {
if (!rayHit || !partFromBody(rayHit->body)) { setSelection({}); return; }
std::shared_ptr<Part> part = partFromBody(rayHit->body);
if (part->locked) { setSelection({}); return; }
std::shared_ptr<PVInstance> selObject = part;
// Traverse to the root model
if (~evt->modifiers() & Qt::AltModifier) {
std::optional<std::shared_ptr<Instance>> nextParent = selObject->GetParent();
while (nextParent.value() && nextParent.value()->IsA("Model")) {
selObject = std::dynamic_pointer_cast<PVInstance>(nextParent.value()); nextParent = selObject->GetParent();
}
}
initialFrame = part->cframe;
initialHitPos = rayHit->worldPoint;
initialHitNormal = rayHit->worldNormal;
@ -419,20 +432,20 @@ void MainGLWidget::mousePressEvent(QMouseEvent* evt) {
//part.selected = true;
isMouseDragging = true;
draggingObject = part;
if (evt->modifiers() & Qt::ControlModifier) {
if (evt->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier)) {
std::vector<std::shared_ptr<Instance>> currentSelection = getSelection();
for (size_t i = 0; i < currentSelection.size(); i++) {
std::shared_ptr<Instance> inst = currentSelection[i];
if (inst == part) {
if (inst == selObject) {
currentSelection.erase(currentSelection.begin() + i);
goto skipAddPart;
}
}
currentSelection.push_back(part);
currentSelection.push_back(selObject);
skipAddPart:
setSelection(currentSelection);
} else
setSelection({ part });
setSelection({ selObject });
// Disable bit so that we can ignore the part while raycasting
// part->rigidBody->getCollider(0)->setCollisionCategoryBits(0b10);

View file

@ -15,6 +15,7 @@
#include <qmessagebox.h>
#include <qmimedata.h>
#include <qnamespace.h>
#include <qsoundeffect.h>
#include <qstylefactory.h>
#include <qstylehints.h>
#include <qmdisubwindow.h>
@ -61,6 +62,13 @@ void logQtMessage(QtMsgType type, const QMessageLogContext &context, const QStri
// if (defaultMessageHandler) defaultMessageHandler(type, context, msg);
}
inline void playSound(QString path) {
QSoundEffect *sound = new QSoundEffect;
sound->setSource(QUrl::fromLocalFile(path));
sound->play();
sound->connect(sound, &QSoundEffect::playingChanged, [=]() { /* Thank you QSound source code! */ sound->deleteLater(); return false; });
}
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
@ -383,6 +391,7 @@ void MainWindow::connectActionHandlers() {
model->SetParent(firstParent);
setSelection({ model });
playSound("./assets/excluded/electronicpingshort.wav");
});
connect(ui->actionUngroupObjects, &QAction::triggered, this, [&]() {
@ -401,6 +410,7 @@ void MainWindow::connectActionHandlers() {
}
setSelection(newSelection);
playSound("./assets/excluded/electronicpingshort.wav");
});
connect(ui->actionSaveModel, &QAction::triggered, this, [&]() {