From d23206b1fc42953b34c4c5b14104d3a74f2c8fa1 Mon Sep 17 00:00:00 2001 From: maelstrom Date: Sun, 13 Jul 2025 18:20:50 +0200 Subject: [PATCH] refactor(part): refactored part into basepart --- client/src/main.cpp | 6 +- core/src/datatypes/color3.cpp | 1 + core/src/datatypes/color3.h | 1 + core/src/handles.cpp | 16 ++--- core/src/handles.h | 4 +- core/src/objects/joint/jointinstance.cpp | 4 +- core/src/objects/joint/jointinstance.h | 14 ++-- core/src/objects/joint/rotate.cpp | 2 +- core/src/objects/joint/rotatev.cpp | 2 +- core/src/objects/joint/snap.cpp | 2 +- core/src/objects/joint/weld.cpp | 2 +- core/src/objects/meta.cpp | 3 +- .../objects/{part.cpp => part/basepart.cpp} | 65 +++++++++---------- core/src/objects/{part.h => part/basepart.h} | 27 ++++---- core/src/objects/part/part.cpp | 8 +++ core/src/objects/part/part.h | 16 +++++ core/src/objects/service/workspace.cpp | 26 ++++---- core/src/objects/service/workspace.h | 22 +++---- core/src/partassembly.cpp | 14 ++-- core/src/partassembly.h | 8 +-- core/src/physics/util.h | 8 +-- core/src/rendering/defaultmeshes.cpp | 32 +++++++++ core/src/rendering/renderer.cpp | 24 +++---- docs/autogen.md | 2 +- editor/mainglwidget.cpp | 6 +- editor/mainglwidget.h | 4 +- editor/placedocument.cpp | 4 +- 27 files changed, 189 insertions(+), 134 deletions(-) rename core/src/objects/{part.cpp => part/basepart.cpp} (84%) rename core/src/objects/{part.h => part/basepart.h} (83%) create mode 100644 core/src/objects/part/part.cpp create mode 100644 core/src/objects/part/part.h diff --git a/client/src/main.cpp b/client/src/main.cpp index 4e28a6a..f9999f4 100644 --- a/client/src/main.cpp +++ b/client/src/main.cpp @@ -1,6 +1,6 @@ #include #include -#include "objects/part.h" +#include "objects/part/part.h" #include "rendering/renderer.h" #include "common.h" @@ -15,7 +15,7 @@ void mouseCallback(GLFWwindow* window, double xpos, double ypos); void mouseButtonCallback(GLFWwindow* window, int button, int action, int mods); void resizeCallback(GLFWwindow* window, int width, int height); -std::shared_ptr lastPart; +std::shared_ptr lastPart; int main() { Logger::init(); @@ -58,7 +58,7 @@ int main() { for (std::shared_ptr inst : gWorkspace()->GetChildren()) { if (inst->GetClass()->className != "Part") continue; - std::shared_ptr part = std::dynamic_pointer_cast(inst); + std::shared_ptr part = std::dynamic_pointer_cast(inst); gWorkspace()->SyncPartPhysics(part); } diff --git a/core/src/datatypes/color3.cpp b/core/src/datatypes/color3.cpp index cbd5647..4c83fa1 100644 --- a/core/src/datatypes/color3.cpp +++ b/core/src/datatypes/color3.cpp @@ -6,6 +6,7 @@ #include #include +Color3::Color3() {}; Color3::Color3(float r, float g, float b) : r(std::clamp(r, 0.f, 1.f)), g(std::clamp(g, 0.f, 1.f)), b(std::clamp(b, 0.f, 1.f)) {}; Color3::Color3(const glm::vec3& vec) : r(std::clamp(vec.x, 0.f, 1.f)), g(std::clamp(vec.y, 0.f, 1.f)), b(std::clamp(vec.z, 0.f, 1.f)) {}; diff --git a/core/src/datatypes/color3.h b/core/src/datatypes/color3.h index a61feb2..d6ebb5d 100644 --- a/core/src/datatypes/color3.h +++ b/core/src/datatypes/color3.h @@ -14,6 +14,7 @@ class DEF_DATA Color3 { public: DEF_DATA_CTOR Color3(float r, float g, float b); + Color3(); Color3(const glm::vec3&); virtual ~Color3(); diff --git a/core/src/handles.cpp b/core/src/handles.cpp index d8c480c..93a1df2 100644 --- a/core/src/handles.cpp +++ b/core/src/handles.cpp @@ -27,11 +27,11 @@ static CFrame XYZToZXY(glm::vec3(0, 0, 0), -glm::vec3(1, 0, 0), glm::vec3(0, 0, static rp3d::PhysicsCommon common; static rp3d::PhysicsWorld* world = common.createPhysicsWorld(); -std::shared_ptr getHandleAdornee() { +std::shared_ptr getHandleAdornee() { std::shared_ptr selection = gDataModel->GetService(); for (std::weak_ptr inst : selection->Get()) { - if (!inst.expired() && inst.lock()->IsA()) - return inst.lock()->CastTo().expect(); + if (!inst.expired() && inst.lock()->IsA()) + return inst.lock()->CastTo().expect(); } return {}; @@ -82,8 +82,8 @@ static int getAABBOfSelection(glm::vec3& pos, glm::vec3& size, glm::vec3& min, g int count = 0; std::shared_ptr selection = gDataModel->GetService(); for (std::weak_ptr inst : selection->Get()) { - if (inst.expired() || !inst.lock()->IsA()) continue; - std::shared_ptr part = inst.lock()->CastTo().expect(); + if (inst.expired() || !inst.lock()->IsA()) continue; + std::shared_ptr part = inst.lock()->CastTo().expect(); if (count == 0) min = part->position(), max = part->position(); @@ -99,12 +99,12 @@ static int getAABBOfSelection(glm::vec3& pos, glm::vec3& size, glm::vec3& min, g return count; } -static std::shared_ptr getFirstSelectedPart() { +static std::shared_ptr getFirstSelectedPart() { std::shared_ptr selection = gDataModel->GetService(); for (std::weak_ptr inst : selection->Get()) { - if (inst.expired() || !inst.lock()->IsA()) continue; + if (inst.expired() || !inst.lock()->IsA()) continue; - return inst.lock()->CastTo().expect(); + return inst.lock()->CastTo().expect(); } return {}; diff --git a/core/src/handles.h b/core/src/handles.h index eaaf83e..f98c79d 100644 --- a/core/src/handles.h +++ b/core/src/handles.h @@ -1,7 +1,7 @@ #pragma once #include "datatypes/cframe.h" -#include "objects/part.h" +#include "objects/part/part.h" #include #include @@ -36,7 +36,7 @@ struct Handles { bool worldMode = false; }; -std::shared_ptr getHandleAdornee(); +std::shared_ptr getHandleAdornee(); CFrame getHandleCFrame(HandleFace face); CFrame partCFrameFromHandlePos(HandleFace face, Vector3 newPos); Vector3 handleSize(HandleFace face); diff --git a/core/src/objects/joint/jointinstance.cpp b/core/src/objects/joint/jointinstance.cpp index 69e90ad..e425a06 100644 --- a/core/src/objects/joint/jointinstance.cpp +++ b/core/src/objects/joint/jointinstance.cpp @@ -4,7 +4,7 @@ #include "datatypes/ref.h" #include "objects/datamodel.h" #include "objects/service/jointsservice.h" -#include "objects/part.h" +#include "objects/part/part.h" #include "objects/service/workspace.h" #include #include @@ -54,6 +54,6 @@ void JointInstance::onUpdated(std::string property) { oldPart1 = part1; } -std::optional> JointInstance::workspaceOfPart(std::shared_ptr part) { +std::optional> JointInstance::workspaceOfPart(std::shared_ptr part) { return part->workspace(); } \ No newline at end of file diff --git a/core/src/objects/joint/jointinstance.h b/core/src/objects/joint/jointinstance.h index bc12a21..3b57ab4 100644 --- a/core/src/objects/joint/jointinstance.h +++ b/core/src/objects/joint/jointinstance.h @@ -8,31 +8,31 @@ //this is necessary ebcause we use std::weak_ptr without including it in this file #ifdef __AUTOGEN_EXTRA_INCLUDES__ -#include "../part.h" +#include "objects/part/part.h" #endif -class Part; +class BasePart; class Workspace; class DEF_INST_ABSTRACT JointInstance : public Instance { AUTOGEN_PREAMBLE - std::weak_ptr oldPart0; - std::weak_ptr oldPart1; + std::weak_ptr oldPart0; + std::weak_ptr oldPart1; protected: // The workspace the joint was created in, if it exists std::weak_ptr jointWorkspace; void OnAncestryChanged(std::optional>, std::optional>) override; - std::optional> workspaceOfPart(std::shared_ptr); + std::optional> workspaceOfPart(std::shared_ptr); void onUpdated(std::string property); virtual void buildJoint() = 0; virtual void breakJoint() = 0; public: - DEF_PROP_(on_update=onUpdated) std::weak_ptr part0; - DEF_PROP_(on_update=onUpdated) std::weak_ptr part1; + DEF_PROP_(on_update=onUpdated) std::weak_ptr part0; + DEF_PROP_(on_update=onUpdated) std::weak_ptr part1; DEF_PROP_(on_update=onUpdated) CFrame c0; DEF_PROP_(on_update=onUpdated) CFrame c1; diff --git a/core/src/objects/joint/rotate.cpp b/core/src/objects/joint/rotate.cpp index 1b2ae1b..a2623f4 100644 --- a/core/src/objects/joint/rotate.cpp +++ b/core/src/objects/joint/rotate.cpp @@ -1,6 +1,6 @@ #include "rotate.h" #include "objects/service/jointsservice.h" -#include "objects/part.h" +#include "objects/part/part.h" #include "objects/service/workspace.h" #include "rendering/renderer.h" #include diff --git a/core/src/objects/joint/rotatev.cpp b/core/src/objects/joint/rotatev.cpp index ae84fe1..11a9faf 100644 --- a/core/src/objects/joint/rotatev.cpp +++ b/core/src/objects/joint/rotatev.cpp @@ -1,6 +1,6 @@ #include "rotatev.h" #include "objects/service/jointsservice.h" -#include "objects/part.h" +#include "objects/part/part.h" #include "objects/service/workspace.h" #include "rendering/renderer.h" #include diff --git a/core/src/objects/joint/snap.cpp b/core/src/objects/joint/snap.cpp index cd42b48..90c405a 100644 --- a/core/src/objects/joint/snap.cpp +++ b/core/src/objects/joint/snap.cpp @@ -4,7 +4,7 @@ #include "objects/datamodel.h" #include "objects/joint/jointinstance.h" #include "objects/service/jointsservice.h" -#include "objects/part.h" +#include "objects/part/part.h" #include "objects/service/workspace.h" #include #include diff --git a/core/src/objects/joint/weld.cpp b/core/src/objects/joint/weld.cpp index 85c3d42..79e2e6f 100644 --- a/core/src/objects/joint/weld.cpp +++ b/core/src/objects/joint/weld.cpp @@ -4,7 +4,7 @@ #include "objects/datamodel.h" #include "objects/joint/jointinstance.h" #include "objects/service/jointsservice.h" -#include "objects/part.h" +#include "objects/part/part.h" #include "objects/service/workspace.h" #include #include diff --git a/core/src/objects/meta.cpp b/core/src/objects/meta.cpp index 704c0f2..17e993d 100644 --- a/core/src/objects/meta.cpp +++ b/core/src/objects/meta.cpp @@ -8,7 +8,7 @@ #include "objects/message.h" #include "objects/service/jointsservice.h" #include "objects/model.h" -#include "objects/part.h" +#include "objects/part/part.h" #include "objects/joint/snap.h" #include "objects/script.h" #include "objects/service/script/scriptcontext.h" @@ -21,6 +21,7 @@ std::map INSTANCE_MAP = { { "Instance", &Instance::TYPE }, { "DataModel", &DataModel::TYPE }, + { "BasePart", &BasePart::TYPE }, { "Part", &Part::TYPE }, { "Snap", &Snap::TYPE }, { "Weld", &Weld::TYPE }, diff --git a/core/src/objects/part.cpp b/core/src/objects/part/basepart.cpp similarity index 84% rename from core/src/objects/part.cpp rename to core/src/objects/part/basepart.cpp index 4633923..2c976c2 100644 --- a/core/src/objects/part.cpp +++ b/core/src/objects/part/basepart.cpp @@ -1,5 +1,5 @@ -#include "part.h" -#include "base/instance.h" +#include "basepart.h" +#include "objects/base/instance.h" #include "common.h" #include "datatypes/base.h" #include "datatypes/cframe.h" @@ -19,15 +19,14 @@ #include #include -Part::Part(): Part(PartConstructParams { .size = glm::vec3(2, 1.2, 4), .color = Color3(0.639216f, 0.635294f, 0.647059f) }) { +BasePart::BasePart(const InstanceType* type): BasePart(type, PartConstructParams { .size = glm::vec3(2, 1.2, 4), .color = Color3(0.639216f, 0.635294f, 0.647059f) }) { } -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) { - +BasePart::BasePart(const InstanceType* type, PartConstructParams params): PVInstance(type), cframe(CFrame::FromEulerAnglesXYZ((Vector3)params.rotation) + params.position), + size(params.size), color(params.color), anchored(params.anchored), locked(params.locked) { } -Part::~Part() { +BasePart::~BasePart() { // This relies on physicsCommon still existing. Be very careful. if (this->rigidBody && workspace()) { workspace().value()->DestroyRigidBody(rigidBody); @@ -36,12 +35,12 @@ Part::~Part() { } -void Part::OnAncestryChanged(std::optional> child, std::optional> newParent) { +void BasePart::OnAncestryChanged(std::optional> child, std::optional> newParent) { if (this->rigidBody) this->rigidBody->setIsActive(workspace().has_value()); if (workspace()) - workspace().value()->SyncPartPhysics(std::dynamic_pointer_cast(this->shared_from_this())); + workspace().value()->SyncPartPhysics(std::dynamic_pointer_cast(this->shared_from_this())); // Destroy joints if (!workspace()) BreakJoints(); @@ -49,22 +48,22 @@ void Part::OnAncestryChanged(std::optional> child, std // TODO: Sleeping bodies that touch this one also need to be updated } -void Part::OnWorkspaceAdded(std::optional> oldWorkspace, std::shared_ptr newWorkspace) { - newWorkspace->AddBody(shared()); +void BasePart::OnWorkspaceAdded(std::optional> oldWorkspace, std::shared_ptr newWorkspace) { + newWorkspace->AddBody(shared()); } -void Part::OnWorkspaceRemoved(std::shared_ptr oldWorkspace) { +void BasePart::OnWorkspaceRemoved(std::shared_ptr oldWorkspace) { if (simulationTicket.has_value()) - oldWorkspace->RemoveBody(shared()); + oldWorkspace->RemoveBody(shared()); } -void Part::onUpdated(std::string property) { +void BasePart::onUpdated(std::string property) { // Reset velocity if (property != "Velocity") velocity = Vector3::ZERO; if (workspace()) - workspace().value()->SyncPartPhysics(std::dynamic_pointer_cast(this->shared_from_this())); + workspace().value()->SyncPartPhysics(std::dynamic_pointer_cast(this->shared_from_this())); // When position/rotation/size is manually edited, break all joints, they don't apply anymore if (property != "Anchored") @@ -88,7 +87,7 @@ static Vector3 verts[8] { {1, 1, 1}, }; -Vector3 Part::GetAABB() { +Vector3 BasePart::GetAABB() { Vector3 min(0, 0, 0); Vector3 max(0, 0, 0); for (Vector3 vert : verts) { @@ -99,7 +98,7 @@ Vector3 Part::GetAABB() { return (min - max).Abs() / 2; } -void Part::BreakJoints() { +void BasePart::BreakJoints() { for (std::weak_ptr joint : primaryJoints) { if (joint.expired()) continue; joint.lock()->Destroy(); @@ -120,7 +119,7 @@ static Vector3 FACES[6] = { {0, 0, -1}, }; -SurfaceType Part::surfaceFromFace(NormalId face) { +SurfaceType BasePart::surfaceFromFace(NormalId face) { switch (face) { case Top: return topSurface; case Bottom: return bottomSurface; @@ -132,7 +131,7 @@ SurfaceType Part::surfaceFromFace(NormalId face) { return SurfaceType::Smooth; // Unreachable } -float Part::GetSurfaceParamA(Vector3 face) { +float BasePart::GetSurfaceParamA(Vector3 face) { switch (faceFromNormal(face)) { case Top: return topParamA; case Bottom: return bottomParamA; @@ -144,7 +143,7 @@ float Part::GetSurfaceParamA(Vector3 face) { return 0; // Unreachable } -float Part::GetSurfaceParamB(Vector3 face) { +float BasePart::GetSurfaceParamB(Vector3 face) { switch (faceFromNormal(face)) { case Top: return topParamB; case Bottom: return bottomParamB; @@ -156,14 +155,14 @@ float Part::GetSurfaceParamB(Vector3 face) { return 0; // Unreachable } -bool Part::checkJointContinuity(std::shared_ptr otherPart) { +bool BasePart::checkJointContinuity(std::shared_ptr otherPart) { // Make sure that the two parts don't depend on one another return checkJointContinuityUp(otherPart) && checkJointContinuityDown(otherPart); } -bool Part::checkJointContinuityDown(std::shared_ptr otherPart) { - if (shared() == otherPart) return false; +bool BasePart::checkJointContinuityDown(std::shared_ptr otherPart) { + if (shared() == otherPart) return false; for (auto joint : primaryJoints) { if (joint.expired() || joint.lock()->part1.expired()) continue; if (!joint.lock()->part1.lock()->checkJointContinuityDown(otherPart)) @@ -172,8 +171,8 @@ bool Part::checkJointContinuityDown(std::shared_ptr otherPart) { return true; } -bool Part::checkJointContinuityUp(std::shared_ptr otherPart) { - if (shared() == otherPart) return false; +bool BasePart::checkJointContinuityUp(std::shared_ptr otherPart) { + if (shared() == otherPart) return false; for (auto joint : secondaryJoints) { if (joint.expired() || joint.lock()->part0.expired()) continue; if (!joint.lock()->part0.lock()->checkJointContinuityUp(otherPart)) @@ -182,7 +181,7 @@ bool Part::checkJointContinuityUp(std::shared_ptr otherPart) { return true; } -bool Part::checkSurfacesTouching(CFrame surfaceFrame, Vector3 size, Vector3 myFace, Vector3 otherFace, std::shared_ptr otherPart) { +bool BasePart::checkSurfacesTouching(CFrame surfaceFrame, Vector3 size, Vector3 myFace, Vector3 otherFace, std::shared_ptr otherPart) { Vector3 farCorner0 = surfaceFrame.Inverse() * otherPart->cframe * (Vector3::ONE * (otherPart->size / 2.f)); Vector3 farCorner1 = surfaceFrame.Inverse() * otherPart->cframe * (-Vector3::ONE * (otherPart->size / 2.f)); @@ -218,7 +217,7 @@ std::optional> makeJointFromSurfaces(SurfaceType return std::nullopt; } -void Part::MakeJoints() { +void BasePart::MakeJoints() { // Algorithm: Find nearby parts // Make sure parts are not dependant on each other (via primary/secondaryJoints) // Find matching surfaces (surface normal dot product < -0.999) @@ -233,8 +232,8 @@ void Part::MakeJoints() { for (auto it = workspace().value()->GetDescendantsStart(); it != workspace().value()->GetDescendantsEnd(); it++) { std::shared_ptr obj = *it; if (obj == shared_from_this()) continue; // Skip ourselves - if (obj->GetClass()->className != "Part") continue; // TODO: Replace this with a .IsA call instead of comparing the class name directly - std::shared_ptr otherPart = obj->CastTo().expect(); + if (!obj->IsA()) continue; + std::shared_ptr otherPart = obj->CastTo().expect(); for (Vector3 myFace : FACES) { Vector3 myWorldNormal = cframe.Rotation() * myFace; @@ -278,8 +277,8 @@ void Part::MakeJoints() { auto joint_ = makeJointFromSurfaces(mySurface, otherSurface); if (!joint_) continue; std::shared_ptr joint = joint_.value(); - joint->part0 = shared(); - joint->part1 = otherPart->shared(); + joint->part0 = shared(); + joint->part1 = otherPart->shared(); joint->c0 = contact0; joint->c1 = contact1; dataModel().value()->GetService()->AddChild(joint); @@ -291,7 +290,7 @@ void Part::MakeJoints() { } } -void Part::trackJoint(std::shared_ptr joint) { +void BasePart::trackJoint(std::shared_ptr joint) { if (!joint->part0.expired() && joint->part0.lock() == shared_from_this()) { for (auto it = primaryJoints.begin(); it != primaryJoints.end();) { // Clean expired refs @@ -325,7 +324,7 @@ void Part::trackJoint(std::shared_ptr joint) { } } -void Part::untrackJoint(std::shared_ptr joint) { +void BasePart::untrackJoint(std::shared_ptr joint) { for (auto it = primaryJoints.begin(); it != primaryJoints.end();) { // Clean expired refs if (it->expired() || it->lock() == joint) { diff --git a/core/src/objects/part.h b/core/src/objects/part/basepart.h similarity index 83% rename from core/src/objects/part.h rename to core/src/objects/part/basepart.h index bc3a622..53f5f36 100644 --- a/core/src/objects/part.h +++ b/core/src/objects/part/basepart.h @@ -14,7 +14,7 @@ #include #include #include -#include "annotation.h" +#include "objects/annotation.h" #include "objects/pvinstance.h" namespace rp = reactphysics3d; @@ -34,11 +34,11 @@ class Workspace; #ifndef __SIMULATION_TICKET #define __SIMULATION_TICKET -class Part; -typedef std::list>::iterator SimulationTicket; +class BasePart; +typedef std::list>::iterator SimulationTicket; #endif -class DEF_INST_(explorer_icon="part") Part : public PVInstance { +class DEF_INST_ABSTRACT_(explorer_icon="part") BasePart : public PVInstance { AUTOGEN_PREAMBLE protected: // Joints where this part is Part0 @@ -50,10 +50,10 @@ protected: void untrackJoint(std::shared_ptr); SurfaceType surfaceFromFace(NormalId); - bool checkJointContinuity(std::shared_ptr); - bool checkJointContinuityUp(std::shared_ptr); - bool checkJointContinuityDown(std::shared_ptr); - bool checkSurfacesTouching(CFrame surfaceFrame, Vector3 size, Vector3 myFace, Vector3 otherFace, std::shared_ptr otherPart); + bool checkJointContinuity(std::shared_ptr); + bool checkJointContinuityUp(std::shared_ptr); + bool checkJointContinuityDown(std::shared_ptr); + bool checkSurfacesTouching(CFrame surfaceFrame, Vector3 size, Vector3 myFace, Vector3 otherFace, std::shared_ptr otherPart); friend JointInstance; friend Workspace; @@ -62,6 +62,9 @@ protected: virtual void OnWorkspaceRemoved(std::shared_ptr oldWorkspace) override; void OnAncestryChanged(std::optional> child, std::optional> newParent) override; void onUpdated(std::string); + + BasePart(const InstanceType*); + BasePart(const InstanceType*, PartConstructParams params); public: DEF_PROP_CATEGORY(DATA) DEF_PROP_(on_update=onUpdated) Vector3 velocity; @@ -116,13 +119,7 @@ public: float GetSurfaceParamA(Vector3 face); float GetSurfaceParamB(Vector3 face); - Part(); - Part(PartConstructParams params); - ~Part() override; - - static inline std::shared_ptr New() { return std::make_shared(); }; - static inline std::shared_ptr New(PartConstructParams params) { return std::make_shared(params); }; - static inline std::shared_ptr Create() { return std::make_shared(); }; + ~BasePart() override; inline Vector3 position() { return cframe.Position(); } diff --git a/core/src/objects/part/part.cpp b/core/src/objects/part/part.cpp new file mode 100644 index 0000000..5bb66a2 --- /dev/null +++ b/core/src/objects/part/part.cpp @@ -0,0 +1,8 @@ +#include "part.h" + +Part::Part(): BasePart(&TYPE) { +} + +Part::Part(PartConstructParams params): BasePart(&TYPE, params) { + +} \ No newline at end of file diff --git a/core/src/objects/part/part.h b/core/src/objects/part/part.h new file mode 100644 index 0000000..1d5e8ce --- /dev/null +++ b/core/src/objects/part/part.h @@ -0,0 +1,16 @@ +#pragma once + +#include "basepart.h" +#include "objects/annotation.h" + +class DEF_INST Part : public BasePart { + AUTOGEN_PREAMBLE + +public: + Part(); + Part(PartConstructParams params); + + static inline std::shared_ptr New() { return std::make_shared(); }; + static inline std::shared_ptr New(PartConstructParams params) { return std::make_shared(params); }; + static inline std::shared_ptr Create() { return std::make_shared(); }; +}; \ No newline at end of file diff --git a/core/src/objects/service/workspace.cpp b/core/src/objects/service/workspace.cpp index 3c1816d..c729640 100644 --- a/core/src/objects/service/workspace.cpp +++ b/core/src/objects/service/workspace.cpp @@ -4,7 +4,7 @@ #include "datatypes/vector.h" #include "logger.h" #include "objects/base/instance.h" -#include "objects/part.h" +#include "objects/part/part.h" #include "objects/service/jointsservice.h" #include "objects/joint/jointinstance.h" #include "objects/datamodel.h" @@ -39,8 +39,8 @@ void PhysicsEventListener::onContact(const rp::CollisionCallback::CallbackData& continue; ContactItem contact; - contact.part0 = reinterpret_cast(pair.getBody1()->getUserData())->shared(); - contact.part1 = reinterpret_cast(pair.getBody2()->getUserData())->shared(); + contact.part0 = reinterpret_cast(pair.getBody1()->getUserData())->shared(); + contact.part1 = reinterpret_cast(pair.getBody2()->getUserData())->shared(); contact.action = type == reactphysics3d::CollisionCallback::ContactPair::EventType::ContactStart ? ContactItem::CONTACTITEM_TOUCHED : ContactItem::CONTACTITEM_TOUCHENDED; workspace->contactQueue.push(contact); @@ -55,8 +55,8 @@ void PhysicsEventListener::onTrigger(const rp::OverlapCallback::CallbackData& da auto type = pair.getEventType(); if (type == rp::OverlapCallback::OverlapPair::EventType::OverlapStay) continue; - auto part0 = reinterpret_cast(pair.getBody1()->getUserData())->shared(); - auto part1 = reinterpret_cast(pair.getBody2()->getUserData())->shared(); + auto part0 = reinterpret_cast(pair.getBody1()->getUserData())->shared(); + auto part1 = reinterpret_cast(pair.getBody2()->getUserData())->shared(); if (type == reactphysics3d::OverlapCallback::OverlapPair::EventType::OverlapStart) { part0->Touched->Fire({ (Variant)InstanceRef(part1) }); @@ -85,8 +85,8 @@ void Workspace::InitService() { // Sync all parts for (auto it = this->GetDescendantsStart(); it != this->GetDescendantsEnd(); it++) { std::shared_ptr obj = *it; - if (!obj->IsA()) continue; - std::shared_ptr part = obj->CastTo().expect(); + if (!obj->IsA()) continue; + std::shared_ptr part = obj->CastTo().expect(); part->MakeJoints(); } @@ -105,7 +105,7 @@ void Workspace::InitService() { } } -void Workspace::updatePartPhysics(std::shared_ptr part) { +void Workspace::updatePartPhysics(std::shared_ptr part) { rp::Transform transform = part->cframe; if (!part->rigidBody) { part->rigidBody = physicsWorld->createRigidBody(transform); @@ -162,7 +162,7 @@ void Workspace::ProcessContactEvents() { contactQueueLock.unlock(); } -void Workspace::SyncPartPhysics(std::shared_ptr part) { +void Workspace::SyncPartPhysics(std::shared_ptr part) { if (globalPhysicsLock.try_lock()) { updatePartPhysics(part); globalPhysicsLock.unlock(); @@ -192,7 +192,7 @@ void Workspace::PhysicsStep(float deltaTime) { queueLock.unlock(); // TODO: Add list of tracked parts in workspace based on their ancestry using inWorkspace property of Instance - for (std::shared_ptr part : simulatedBodies) { + for (std::shared_ptr part : simulatedBodies) { // If the part's body is dirty, update it now instead if (part->rigidBodyDirty) { updatePartPhysics(part); @@ -261,7 +261,7 @@ class NearestRayHit : public rp::RaycastCallback { return 1; } - std::shared_ptr part = partFromBody(raycastInfo.body); + std::shared_ptr part = partFromBody(raycastInfo.body); FilterResult result = filter.value()(part); if (result == FilterResult::BLOCK) { nearestHit = std::nullopt; @@ -305,14 +305,14 @@ rp::Joint* Workspace::CreateJoint(const rp::JointInfo& jointInfo) { return joint; } -void Workspace::AddBody(std::shared_ptr part) { +void Workspace::AddBody(std::shared_ptr part) { queueLock.lock(); bodyQueue.push_back({part, QueueItem::QUEUEITEM_ADD}); part->rigidBodyDirty = true; queueLock.unlock(); } -void Workspace::RemoveBody(std::shared_ptr part) { +void Workspace::RemoveBody(std::shared_ptr part) { queueLock.lock(); bodyQueue.push_back({part, QueueItem::QUEUEITEM_REMOVE}); queueLock.unlock(); diff --git a/core/src/objects/service/workspace.h b/core/src/objects/service/workspace.h index 4cb8e21..ce4975a 100644 --- a/core/src/objects/service/workspace.h +++ b/core/src/objects/service/workspace.h @@ -32,7 +32,7 @@ enum FilterResult { PASS, // The object is transparent, ignore it }; -class Part; +class BasePart; class Snap; class Weld; class Rotate; @@ -40,13 +40,13 @@ class RotateV; #ifndef __SIMULATION_TICKET #define __SIMULATION_TICKET -typedef std::list>::iterator SimulationTicket; +typedef std::list>::iterator SimulationTicket; #endif -typedef std::function)> RaycastFilter; +typedef std::function)> RaycastFilter; struct QueueItem { - std::shared_ptr part; + std::shared_ptr part; enum { QUEUEITEM_ADD, QUEUEITEM_REMOVE, @@ -54,8 +54,8 @@ struct QueueItem { }; struct ContactItem { - std::shared_ptr part0; - std::shared_ptr part1; + std::shared_ptr part0; + std::shared_ptr part1; enum { CONTACTITEM_TOUCHED, CONTACTITEM_TOUCHENDED, @@ -78,7 +78,7 @@ class DEF_INST_SERVICE_(explorer_icon="workspace") Workspace : public Service { friend PhysicsEventListener; - std::list> simulatedBodies; + std::list> simulatedBodies; std::list bodyQueue; std::queue contactQueue; std::mutex contactQueueLock; @@ -86,7 +86,7 @@ class DEF_INST_SERVICE_(explorer_icon="workspace") Workspace : public Service { static rp::PhysicsCommon* physicsCommon; PhysicsEventListener physicsEventListener; - void updatePartPhysics(std::shared_ptr part); + void updatePartPhysics(std::shared_ptr part); protected: void InitService() override; bool initialized = false; @@ -103,10 +103,10 @@ public: // static inline std::shared_ptr New() { return std::make_shared(); }; static inline std::shared_ptr Create() { return std::make_shared(); }; - void AddBody(std::shared_ptr part); - void RemoveBody(std::shared_ptr part); + void AddBody(std::shared_ptr part); + void RemoveBody(std::shared_ptr part); void DestroyRigidBody(rp::RigidBody* rigidBody); - void SyncPartPhysics(std::shared_ptr part); + void SyncPartPhysics(std::shared_ptr part); rp::Joint* CreateJoint(const rp::JointInfo& jointInfo); void DestroyJoint(rp::Joint* joint); diff --git a/core/src/partassembly.cpp b/core/src/partassembly.cpp index cb50510..a1a1a4d 100644 --- a/core/src/partassembly.cpp +++ b/core/src/partassembly.cpp @@ -5,13 +5,13 @@ #include "datatypes/vector.h" #include "math_helper.h" #include "objects/base/instance.h" -#include "objects/part.h" +#include "objects/part/part.h" #include "objects/service/selection.h" #include #include #include -PartAssembly::PartAssembly(std::vector> parts, bool worldMode) : parts(parts) { +PartAssembly::PartAssembly(std::vector> parts, bool worldMode) : parts(parts) { if (parts.size() == 0) return; if (parts.size() == 1 && !worldMode) { _assemblyOrigin = parts[0]->cframe; @@ -36,19 +36,19 @@ PartAssembly::PartAssembly(std::vector> parts, bool worldM } PartAssembly PartAssembly::FromSelection(std::vector> newSelection) { - std::vector> selection; + std::vector> selection; for (std::shared_ptr obj : newSelection) { if (!obj->IsA()) continue; - if (obj->IsA()) - selection.push_back(obj->CastTo().expect()); + if (obj->IsA()) + selection.push_back(obj->CastTo().expect()); // Add object descendants for (DescendantsIterator it = obj->GetDescendantsStart(); it != obj->GetDescendantsEnd(); it++) { - if (!(*it)->IsA()) continue; + if (!(*it)->IsA()) continue; - selection.push_back((*it)->CastTo().expect()); + selection.push_back((*it)->CastTo().expect()); } } diff --git a/core/src/partassembly.h b/core/src/partassembly.h index d0eee58..fc858a2 100644 --- a/core/src/partassembly.h +++ b/core/src/partassembly.h @@ -4,12 +4,12 @@ #include #include -class Part; +class BasePart; class Instance; class Selection; struct PartTransformState { - std::shared_ptr part; + std::shared_ptr part; Vector3 size; CFrame cframe; }; @@ -19,9 +19,9 @@ class PartAssembly { Vector3 _bounds; Vector3 _size; - std::vector> parts; + std::vector> parts; public: - PartAssembly(std::vector>, bool worldMode = false); + PartAssembly(std::vector>, bool worldMode = false); static PartAssembly FromSelection(std::vector> selection); static PartAssembly FromSelection(std::shared_ptr selection); diff --git a/core/src/physics/util.h b/core/src/physics/util.h index 10042ad..b2c4936 100644 --- a/core/src/physics/util.h +++ b/core/src/physics/util.h @@ -7,7 +7,7 @@ #include #include #include -#include "objects/part.h" +#include "objects/part/part.h" namespace rp = reactphysics3d; @@ -32,8 +32,8 @@ inline glm::quat rpToGlm(rp::Quaternion quat) { } // Make this std::optional -inline std::shared_ptr partFromBody(rp::Body* body) { - Part* raw = reinterpret_cast(body->getUserData()); - std::shared_ptr shared = std::dynamic_pointer_cast(raw->shared_from_this()); +inline std::shared_ptr partFromBody(rp::Body* body) { + BasePart* raw = reinterpret_cast(body->getUserData()); + std::shared_ptr shared = std::dynamic_pointer_cast(raw->shared_from_this()); return shared; } \ No newline at end of file diff --git a/core/src/rendering/defaultmeshes.cpp b/core/src/rendering/defaultmeshes.cpp index a9cbae1..918786e 100644 --- a/core/src/rendering/defaultmeshes.cpp +++ b/core/src/rendering/defaultmeshes.cpp @@ -43,6 +43,36 @@ static float CUBE_VERTICES[] = { }; +static float WEDGE_VERTICES[] = { + // positions // normals // texture coords + + 0.5, 0.5, 0.5, -0.0, -0.0, 1.0, 0.625, 0.75, + -0.5, -0.5, 0.5, -0.0, -0.0, 1.0, 0.375, 1.0, + 0.5, -0.5, 0.5, -0.0, -0.0, 1.0, 0.375, 0.75, + -0.5, -0.5, 0.5, -1.0, -0.0, -0.0, 0.375, 0.0, + -0.5, 0.5, 0.5, -1.0, -0.0, -0.0, 0.625, 0.0, + -0.5, -0.5, -0.5, -1.0, -0.0, -0.0, 0.375, 0.25, + 0.5, -0.5, -0.5, -0.0, -1.0, -0.0, 0.375, 0.5, + -0.5, -0.5, 0.5, -0.0, -1.0, -0.0, 0.125, 0.75, + -0.5, -0.5, -0.5, -0.0, -1.0, -0.0, 0.125, 0.5, + 0.5, -0.5, -0.5, 1.0, -0.0, -0.0, 0.375, 0.5, + 0.5, 0.5, 0.5, 1.0, -0.0, -0.0, 0.625, 0.75, + 0.5, -0.5, 0.5, 1.0, -0.0, -0.0, 0.375, 0.75, + -0.5, 0.5, 0.5, -0.0, 0.7071, -0.7071, 0.875, 0.75, + 0.5, -0.5, -0.5, -0.0, 0.7071, -0.7071, 0.375, 0.5, + -0.5, -0.5, -0.5, -0.0, 0.7071, -0.7071, 0.375, 0.25, + 0.5, 0.5, 0.5, -0.0, -0.0, 1.0, 0.625, 0.75, + -0.5, 0.5, 0.5, -0.0, -0.0, 1.0, 0.625, 1.0, + -0.5, -0.5, 0.5, -0.0, -0.0, 1.0, 0.375, 1.0, + 0.5, -0.5, -0.5, -0.0, -1.0, -0.0, 0.375, 0.5, + 0.5, -0.5, 0.5, -0.0, -1.0, -0.0, 0.375, 0.75, + -0.5, -0.5, 0.5, -0.0, -1.0, -0.0, 0.125, 0.75, + -0.5, 0.5, 0.5, -0.0, 0.7071, -0.7071, 0.875, 0.75, + 0.5, 0.5, 0.5, -0.0, 0.7071, -0.7071, 0.625, 0.75, + 0.5, -0.5, -0.5, -0.0, 0.7071, -0.7071, 0.375, 0.5, + +}; + static float SPHERE_VERTICES[] = { // positions // normals // texture coords @@ -1730,6 +1760,7 @@ static float CYLINDER_VERTICES[] = { }; Mesh* CUBE_MESH; +Mesh* WEDGE_MESH; Mesh* SPHERE_MESH; Mesh* ARROW_MESH; Mesh* OUTLINE_MESH; @@ -1737,6 +1768,7 @@ Mesh* CYLINDER_MESH; void initMeshes() { CUBE_MESH = new Mesh(sizeof(CUBE_VERTICES) / sizeof(float) / 8, CUBE_VERTICES); + WEDGE_MESH = new Mesh(sizeof(WEDGE_VERTICES) / sizeof(float) / 8, WEDGE_VERTICES); SPHERE_MESH = new Mesh(sizeof(SPHERE_VERTICES) / sizeof(float) / 8, SPHERE_VERTICES); ARROW_MESH = new Mesh(sizeof(ARROW_VERTICES) / sizeof(float) / 8, ARROW_VERTICES); OUTLINE_MESH = new Mesh(sizeof(OUTLINE_VERTICES) / sizeof(float) / 8, OUTLINE_VERTICES); diff --git a/core/src/rendering/renderer.cpp b/core/src/rendering/renderer.cpp index 392113e..eca8ff6 100644 --- a/core/src/rendering/renderer.cpp +++ b/core/src/rendering/renderer.cpp @@ -31,9 +31,9 @@ #include "shader.h" #include "mesh.h" #include "defaultmeshes.h" -#include "../camera.h" -#include "../common.h" -#include "../objects/part.h" +#include "camera.h" +#include "common.h" +#include "objects/part/part.h" #include "skybox.h" #include "enum/surface.h" #include "texture3d.h" @@ -170,11 +170,11 @@ void renderParts() { shader->set("viewPos", camera.cameraPos); // Sort by nearest - std::map> sorted; + std::map> sorted; for (auto it = gWorkspace()->GetDescendantsStart(); it != gWorkspace()->GetDescendantsEnd(); it++) { std::shared_ptr inst = *it; if (inst->GetClass()->className != "Part") continue; - std::shared_ptr part = std::dynamic_pointer_cast(inst); + std::shared_ptr part = std::dynamic_pointer_cast(inst); if (part->transparency > 0.00001) { float distance = glm::length(glm::vec3(Vector3(camera.cameraPos) - part->position())); sorted[distance] = part; @@ -207,8 +207,8 @@ void renderParts() { // TODO: Same as todo in src/physics/simulation.cpp // According to LearnOpenGL, std::map automatically sorts its contents. - for (std::map>::reverse_iterator it = sorted.rbegin(); it != sorted.rend(); it++) { - std::shared_ptr part = it->second; + for (std::map>::reverse_iterator it = sorted.rbegin(); it != sorted.rend(); it++) { + std::shared_ptr part = it->second; glm::mat4 model = part->cframe; // if (part->name == "camera") model = camera.getLookAt(); model = glm::scale(model, (glm::vec3)part->size); @@ -268,7 +268,7 @@ void renderSurfaceExtras() { for (auto it = gWorkspace()->GetDescendantsStart(); it != gWorkspace()->GetDescendantsEnd(); it++) { std::shared_ptr inst = *it; if (!inst->IsA("Part")) continue; - std::shared_ptr part = std::dynamic_pointer_cast(inst); + std::shared_ptr part = std::dynamic_pointer_cast(inst); for (int i = 0; i < 6; i++) { NormalId face = (NormalId)i; SurfaceType type = part->GetSurfaceFromFace(face); @@ -396,7 +396,7 @@ void renderAABB() { // Sort by nearest for (std::shared_ptr inst : gWorkspace()->GetChildren()) { if (inst->GetClass()->className != "Part") continue; - std::shared_ptr part = std::dynamic_pointer_cast(inst); + std::shared_ptr part = std::dynamic_pointer_cast(inst); glm::mat4 model = CFrame::IDENTITY + part->cframe.Position(); printf("AABB is supposedly (%f, %f, %f)\n", part->GetAABB().X(), part->GetAABB().Y(), part->GetAABB().Z()); model = glm::scale(model, (glm::vec3)part->GetAABB()); @@ -436,7 +436,7 @@ void renderWireframe() { // Sort by nearest for (std::shared_ptr inst : gWorkspace()->GetChildren()) { if (inst->GetClass()->className != "Part") continue; - std::shared_ptr part = std::dynamic_pointer_cast(inst); + std::shared_ptr part = std::dynamic_pointer_cast(inst); glm::mat4 model = part->cframe; model = glm::scale(model, (glm::vec3)part->size); wireframeShader->set("model", model); @@ -478,8 +478,8 @@ void renderOutlines() { std::shared_ptr selection = gDataModel->GetService(); for (auto inst : selection->Get()) { - if (inst->GetClass() != &Part::TYPE) continue; - std::shared_ptr part = std::dynamic_pointer_cast(inst); + if (inst->GetClass() != &BasePart::TYPE) continue; + std::shared_ptr part = std::dynamic_pointer_cast(inst); if (first) min = part->position(), max = part->position(); diff --git a/docs/autogen.md b/docs/autogen.md index ed7a7b1..4c5f66c 100644 --- a/docs/autogen.md +++ b/docs/autogen.md @@ -105,7 +105,7 @@ However, Autogen cannot tell where this class came from to automatically include block via `__AUTOGEN_EXTRA_INCLUDES__`: #ifdef __AUTOGEN_EXTRA_INCLUDES__ - #include "objects/part.h" + #include "objects/part/part.h" #endif class Part; diff --git a/editor/mainglwidget.cpp b/editor/mainglwidget.cpp index 3c650d1..3d3a0f0 100755 --- a/editor/mainglwidget.cpp +++ b/editor/mainglwidget.cpp @@ -59,7 +59,7 @@ void MainGLWidget::resizeGL(int w, int h) { glm::vec2 firstPoint; glm::vec2 secondPoint; -extern std::weak_ptr draggingObject; +extern std::weak_ptr draggingObject; extern std::optional draggingHandle; extern Shader* shader; void MainGLWidget::paintGL() { @@ -125,7 +125,7 @@ std::vector initialTransforms; bool tryMouseContextMenu = false; bool isMouseDragging = false; -std::weak_ptr draggingObject; +std::weak_ptr draggingObject; std::optional draggingHandle; Vector3 initialHitPos; Vector3 initialHitNormal; @@ -396,7 +396,7 @@ void MainGLWidget::mousePressEvent(QMouseEvent* evt) { std::shared_ptr selection = gDataModel->GetService(); std::optional rayHit = gWorkspace()->CastRayNearest(camera.cameraPos, pointDir, 50000); if (!rayHit || !partFromBody(rayHit->body)) { selection->Set({}); return; } - std::shared_ptr part = partFromBody(rayHit->body); + std::shared_ptr part = partFromBody(rayHit->body); if (part->locked) { selection->Set({}); return; } std::shared_ptr selObject = part; diff --git a/editor/mainglwidget.h b/editor/mainglwidget.h index 160908e..f59dffb 100644 --- a/editor/mainglwidget.h +++ b/editor/mainglwidget.h @@ -1,7 +1,7 @@ #ifndef MAINGLWIDGET_H #define MAINGLWIDGET_H -#include "objects/part.h" +#include "objects/part/part.h" #include "qevent.h" #include #include @@ -15,7 +15,7 @@ class MainGLWidget : public QOpenGLWidget { public: MainGLWidget(QWidget *parent = nullptr); void updateCycle(); - std::shared_ptr lastPart; + std::shared_ptr lastPart; void buildContextMenu(); protected: diff --git a/editor/placedocument.cpp b/editor/placedocument.cpp index 98e9a8d..c9ccfcd 100644 --- a/editor/placedocument.cpp +++ b/editor/placedocument.cpp @@ -130,7 +130,7 @@ void PlaceDocument::closeEvent(QCloseEvent *closeEvent) { closeEvent->ignore(); } -std::shared_ptr shit; +std::shared_ptr shit; void PlaceDocument::timerEvent(QTimerEvent* evt) { if (evt->timerId() != timer.timerId()) { QWidget::timerEvent(evt); @@ -148,7 +148,7 @@ void PlaceDocument::init() { timer.start(33, this); placeWidget->buildContextMenu(); - std::shared_ptr lastPart; + std::shared_ptr lastPart; // Baseplate gWorkspace()->AddChild(lastPart = Part::New({ .position = glm::vec3(0, -5, 0),