From 1fdd0f4831d56c9cf0fc7d667256d6bbcd872119 Mon Sep 17 00:00:00 2001 From: maelstrom Date: Thu, 17 Apr 2025 17:03:43 +0200 Subject: [PATCH] feat(datatypes): added instance reference data type --- core/src/datatypes/meta.h | 4 ++- core/src/datatypes/ref.cpp | 34 +++++++++++++++++++++ core/src/datatypes/ref.h | 25 ++++++++++++++++ core/src/objects/snap.cpp | 60 ++++++++++++++++++++++++++++++-------- core/src/objects/snap.h | 5 +++- editor/mainwindow.cpp | 32 ++++++++++---------- 6 files changed, 130 insertions(+), 30 deletions(-) create mode 100644 core/src/datatypes/ref.cpp create mode 100644 core/src/datatypes/ref.h diff --git a/core/src/datatypes/meta.h b/core/src/datatypes/meta.h index 68affde..2d43028 100644 --- a/core/src/datatypes/meta.h +++ b/core/src/datatypes/meta.h @@ -4,6 +4,7 @@ #include #include "base.h" #include "datatypes/color3.h" +#include "datatypes/ref.h" #include "vector.h" #include "cframe.h" @@ -24,7 +25,8 @@ namespace Data { String, Vector3, CFrame, - Color3 + Color3, + InstanceRef > __VARIANT_TYPE; class Variant { diff --git a/core/src/datatypes/ref.cpp b/core/src/datatypes/ref.cpp new file mode 100644 index 0000000..2e937f5 --- /dev/null +++ b/core/src/datatypes/ref.cpp @@ -0,0 +1,34 @@ +#include "datatypes/ref.h" +#include "color3.h" +#include "meta.h" // IWYU pragma: keep +#include +#include "objects/base/instance.h" + +Data::InstanceRef::InstanceRef() {}; +Data::InstanceRef::InstanceRef(std::weak_ptr instance) : ref(instance) {}; +Data::InstanceRef::~InstanceRef() = default; + +const Data::TypeInfo Data::InstanceRef::TYPE = { + .name = "Instance", + // .deserializer = &Data::InstanceRef::Deserialize, +}; + +const Data::TypeInfo& Data::InstanceRef::GetType() const { return Data::InstanceRef::TYPE; }; + +const Data::String Data::InstanceRef::ToString() const { + return ref.expired() ? "" : ref.lock()->name; +} + +Data::InstanceRef::operator std::weak_ptr() { + return ref; +} + +// Serialization + +void Data::InstanceRef::Serialize(pugi::xml_node node) const { + // node.text().set(this->ToHex()); +} + +// Data::Variant Data::Color3::Deserialize(pugi::xml_node node) { +// return Color3::FromHex(node.text().get()); +// } diff --git a/core/src/datatypes/ref.h b/core/src/datatypes/ref.h new file mode 100644 index 0000000..cc4196a --- /dev/null +++ b/core/src/datatypes/ref.h @@ -0,0 +1,25 @@ +#pragma once + +#include "base.h" +#include + +class Instance; + +namespace Data { + class InstanceRef : Base { + std::weak_ptr ref; + public: + InstanceRef(); + InstanceRef(std::weak_ptr); + ~InstanceRef(); + + virtual const TypeInfo& GetType() const override; + static const TypeInfo TYPE; + + operator std::weak_ptr(); + + virtual const Data::String ToString() const override; + virtual void Serialize(pugi::xml_node node) const override; + // static Data::Variant Deserialize(pugi::xml_node node); + }; +} diff --git a/core/src/objects/snap.cpp b/core/src/objects/snap.cpp index 803ddd7..3101d76 100644 --- a/core/src/objects/snap.cpp +++ b/core/src/objects/snap.cpp @@ -1,8 +1,11 @@ #include "snap.h" +#include "datatypes/cframe.h" +#include "datatypes/ref.h" #include "datatypes/vector.h" #include "workspace.h" #include "part.h" +#include #include const InstanceType Snap::TYPE = { @@ -16,30 +19,63 @@ const InstanceType* Snap::GetClass() { } Snap::Snap(): Instance(&TYPE) { + this->memberMap = std::make_unique(MemberMap { + .super = std::move(this->memberMap), + .members = { + { "Part0", { + .backingField = &part0, + .type = &Data::InstanceRef::TYPE, + .codec = fieldCodecOf>(), + // .updateCallback = memberFunctionOf(&Part::onUpdated, this), + }}, { "Part1", { + .backingField = &part1, + .type = &Data::InstanceRef::TYPE, + .codec = fieldCodecOf>(), + // .updateCallback = memberFunctionOf(&Part::onUpdated, this), + }}, { "C0", { + .backingField = &c0, + .type = &Data::CFrame::TYPE, + .codec = fieldCodecOf(), + // .updateCallback = memberFunctionOf(&Part::onUpdated, this), + }}, { "C1", { + .backingField = &c0, + .type = &Data::CFrame::TYPE, + .codec = fieldCodecOf(), + // .updateCallback = memberFunctionOf(&Part::onUpdated, this), + }}, + } + }); } Snap::~Snap() { } void Snap::OnWorkspaceAdded(std::optional> oldWorkspace, std::shared_ptr newWorkspace) { - if (part0.expired() || part1.expired()) return; - - printVec((part0.lock()->cframe * (c1.Inverse() * c0)).Rotation().ToEulerAnglesXYZ()); - printVec(part1.lock()->cframe.Rotation().ToEulerAnglesXYZ()); + // Remove the existing joint if it does + if (this->joint && oldWorkspace) { + oldWorkspace.value()->physicsWorld->destroyJoint(this->joint); + this->joint = nullptr; + } + + buildJoint(); +} + +void Snap::OnWorkspaceRemoved(std::optional> oldWorkspace) { + if (!this->joint) return; + + if (!oldWorkspace) oldWorkspace.value()->physicsWorld->destroyJoint(this->joint); + this->joint = nullptr; +} + +void Snap::buildJoint() { + if (part0.expired() || part1.expired() || !workspace()) return; // Update Part1's rotation and cframe prior to creating the joint as reactphysics3d locks rotation based on how it // used to be rather than specifying an anchor rotation, so whatever. Data::CFrame newFrame = part0.lock()->cframe * (c1.Inverse() * c0); part1.lock()->cframe = newFrame; - newWorkspace->SyncPartPhysics(part1.lock()); + workspace().value()->SyncPartPhysics(part1.lock()); rp::FixedJointInfo jointInfo(part0.lock()->rigidBody, part1.lock()->rigidBody, (c0.Inverse() * c1).Position()); this->joint = dynamic_cast(workspace().value()->physicsWorld->createJoint(jointInfo)); -} - -void Snap::OnWorkspaceRemoved(std::optional> oldWorkspace) { - if (!this->joint || !oldWorkspace) return; - - oldWorkspace.value()->physicsWorld->destroyJoint(this->joint); - this->joint = nullptr; } \ No newline at end of file diff --git a/core/src/objects/snap.h b/core/src/objects/snap.h index e11d7d5..fe13ed1 100644 --- a/core/src/objects/snap.h +++ b/core/src/objects/snap.h @@ -7,10 +7,13 @@ class Part; class Snap : public Instance { - rp::FixedJoint* joint; + rp::FixedJoint* joint = nullptr; protected: void OnWorkspaceAdded(std::optional> oldWorkspace, std::shared_ptr newWorkspace) override; void OnWorkspaceRemoved(std::optional> oldWorkspace) override; + + void buildJoint(); + void breakJoint(); public: const static InstanceType TYPE; diff --git a/editor/mainwindow.cpp b/editor/mainwindow.cpp index 1292ecc..49f35b2 100644 --- a/editor/mainwindow.cpp +++ b/editor/mainwindow.cpp @@ -151,25 +151,25 @@ MainWindow::MainWindow(QWidget *parent) .color = glm::vec3(0.639216f, 0.635294f, 0.647059f), })); gWorkspace()->SyncPartPhysics(ui->mainWidget->lastPart); - // auto part0 = ui->mainWidget->lastPart; + auto part0 = ui->mainWidget->lastPart; - // gWorkspace()->AddChild(ui->mainWidget->lastPart = Part::New({ - // .position = glm::vec3(1.6691498, 0.82489049, -0.73040605), - // // .rotation = glm::vec3(0.5, 2, 1), - // .rotation = glm::vec3(-2.6415927, 1.1415926, -2.141639), - // .size = glm::vec3(4, 1.2, 2), - // .color = glm::vec3(0.639216f, 0.635294f, 0.647059f), - // })); - // gWorkspace()->SyncPartPhysics(ui->mainWidget->lastPart); - // auto part1 = ui->mainWidget->lastPart; + gWorkspace()->AddChild(ui->mainWidget->lastPart = Part::New({ + .position = glm::vec3(1.6691498, 0.82489049, -0.73040605), + // .rotation = glm::vec3(0.5, 2, 1), + .rotation = glm::vec3(-2.6415927, 1.1415926, -2.141639), + .size = glm::vec3(4, 1.2, 2), + .color = glm::vec3(0.639216f, 0.635294f, 0.647059f), + })); + gWorkspace()->SyncPartPhysics(ui->mainWidget->lastPart); + auto part1 = ui->mainWidget->lastPart; - // auto snap = Snap::New(); - // snap->part0 = part0; - // snap->part1 = part1; - // snap->c0 = part1->cframe; - // snap->c1 = part0->cframe; + auto snap = Snap::New(); + snap->part0 = part0; + snap->part1 = part1; + snap->c0 = part1->cframe; + snap->c1 = part0->cframe; - // gWorkspace()->AddChild(snap); + gWorkspace()->AddChild(snap); } void MainWindow::closeEvent(QCloseEvent* evt) {