feat(datatypes): added instance reference data type

This commit is contained in:
maelstrom 2025-04-17 17:03:43 +02:00
parent 2569e3f56f
commit 1fdd0f4831
6 changed files with 130 additions and 30 deletions

View file

@ -4,6 +4,7 @@
#include <map>
#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 {

View file

@ -0,0 +1,34 @@
#include "datatypes/ref.h"
#include "color3.h"
#include "meta.h" // IWYU pragma: keep
#include <memory>
#include "objects/base/instance.h"
Data::InstanceRef::InstanceRef() {};
Data::InstanceRef::InstanceRef(std::weak_ptr<Instance> 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<Instance>() {
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());
// }

25
core/src/datatypes/ref.h Normal file
View file

@ -0,0 +1,25 @@
#pragma once
#include "base.h"
#include <memory>
class Instance;
namespace Data {
class InstanceRef : Base {
std::weak_ptr<Instance> ref;
public:
InstanceRef();
InstanceRef(std::weak_ptr<Instance>);
~InstanceRef();
virtual const TypeInfo& GetType() const override;
static const TypeInfo TYPE;
operator std::weak_ptr<Instance>();
virtual const Data::String ToString() const override;
virtual void Serialize(pugi::xml_node node) const override;
// static Data::Variant Deserialize(pugi::xml_node node);
};
}

View file

@ -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 <memory>
#include <reactphysics3d/constraint/FixedJoint.h>
const InstanceType Snap::TYPE = {
@ -16,30 +19,63 @@ const InstanceType* Snap::GetClass() {
}
Snap::Snap(): Instance(&TYPE) {
this->memberMap = std::make_unique<MemberMap>(MemberMap {
.super = std::move(this->memberMap),
.members = {
{ "Part0", {
.backingField = &part0,
.type = &Data::InstanceRef::TYPE,
.codec = fieldCodecOf<Data::InstanceRef, std::weak_ptr<Instance>>(),
// .updateCallback = memberFunctionOf(&Part::onUpdated, this),
}}, { "Part1", {
.backingField = &part1,
.type = &Data::InstanceRef::TYPE,
.codec = fieldCodecOf<Data::InstanceRef, std::weak_ptr<Instance>>(),
// .updateCallback = memberFunctionOf(&Part::onUpdated, this),
}}, { "C0", {
.backingField = &c0,
.type = &Data::CFrame::TYPE,
.codec = fieldCodecOf<Data::CFrame>(),
// .updateCallback = memberFunctionOf(&Part::onUpdated, this),
}}, { "C1", {
.backingField = &c0,
.type = &Data::CFrame::TYPE,
.codec = fieldCodecOf<Data::CFrame>(),
// .updateCallback = memberFunctionOf(&Part::onUpdated, this),
}},
}
});
}
Snap::~Snap() {
}
void Snap::OnWorkspaceAdded(std::optional<std::shared_ptr<Workspace>> oldWorkspace, std::shared_ptr<Workspace> newWorkspace) {
if (part0.expired() || part1.expired()) return;
// Remove the existing joint if it does
if (this->joint && oldWorkspace) {
oldWorkspace.value()->physicsWorld->destroyJoint(this->joint);
this->joint = nullptr;
}
printVec((part0.lock()->cframe * (c1.Inverse() * c0)).Rotation().ToEulerAnglesXYZ());
printVec(part1.lock()->cframe.Rotation().ToEulerAnglesXYZ());
buildJoint();
}
void Snap::OnWorkspaceRemoved(std::optional<std::shared_ptr<Workspace>> 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<rp::FixedJoint*>(workspace().value()->physicsWorld->createJoint(jointInfo));
}
void Snap::OnWorkspaceRemoved(std::optional<std::shared_ptr<Workspace>> oldWorkspace) {
if (!this->joint || !oldWorkspace) return;
oldWorkspace.value()->physicsWorld->destroyJoint(this->joint);
this->joint = nullptr;
}

View file

@ -7,10 +7,13 @@
class Part;
class Snap : public Instance {
rp::FixedJoint* joint;
rp::FixedJoint* joint = nullptr;
protected:
void OnWorkspaceAdded(std::optional<std::shared_ptr<Workspace>> oldWorkspace, std::shared_ptr<Workspace> newWorkspace) override;
void OnWorkspaceRemoved(std::optional<std::shared_ptr<Workspace>> oldWorkspace) override;
void buildJoint();
void breakJoint();
public:
const static InstanceType TYPE;

View file

@ -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) {