refactor(part): refactored part into basepart

This commit is contained in:
maelstrom 2025-07-13 18:20:50 +02:00
parent 0196d80944
commit d23206b1fc
27 changed files with 189 additions and 134 deletions

View file

@ -1,6 +1,6 @@
#include <GL/glew.h> #include <GL/glew.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include "objects/part.h" #include "objects/part/part.h"
#include "rendering/renderer.h" #include "rendering/renderer.h"
#include "common.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 mouseButtonCallback(GLFWwindow* window, int button, int action, int mods);
void resizeCallback(GLFWwindow* window, int width, int height); void resizeCallback(GLFWwindow* window, int width, int height);
std::shared_ptr<Part> lastPart; std::shared_ptr<BasePart> lastPart;
int main() { int main() {
Logger::init(); Logger::init();
@ -58,7 +58,7 @@ int main() {
for (std::shared_ptr<Instance> inst : gWorkspace()->GetChildren()) { for (std::shared_ptr<Instance> inst : gWorkspace()->GetChildren()) {
if (inst->GetClass()->className != "Part") continue; if (inst->GetClass()->className != "Part") continue;
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst); std::shared_ptr<BasePart> part = std::dynamic_pointer_cast<BasePart>(inst);
gWorkspace()->SyncPartPhysics(part); gWorkspace()->SyncPartPhysics(part);
} }

View file

@ -6,6 +6,7 @@
#include <iomanip> #include <iomanip>
#include <algorithm> #include <algorithm>
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(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)) {}; 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)) {};

View file

@ -14,6 +14,7 @@ class DEF_DATA Color3 {
public: public:
DEF_DATA_CTOR Color3(float r, float g, float b); DEF_DATA_CTOR Color3(float r, float g, float b);
Color3();
Color3(const glm::vec3&); Color3(const glm::vec3&);
virtual ~Color3(); virtual ~Color3();

View file

@ -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::PhysicsCommon common;
static rp3d::PhysicsWorld* world = common.createPhysicsWorld(); static rp3d::PhysicsWorld* world = common.createPhysicsWorld();
std::shared_ptr<Part> getHandleAdornee() { std::shared_ptr<BasePart> getHandleAdornee() {
std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>(); std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>();
for (std::weak_ptr<Instance> inst : selection->Get()) { for (std::weak_ptr<Instance> inst : selection->Get()) {
if (!inst.expired() && inst.lock()->IsA<Part>()) if (!inst.expired() && inst.lock()->IsA<BasePart>())
return inst.lock()->CastTo<Part>().expect(); return inst.lock()->CastTo<BasePart>().expect();
} }
return {}; return {};
@ -82,8 +82,8 @@ static int getAABBOfSelection(glm::vec3& pos, glm::vec3& size, glm::vec3& min, g
int count = 0; int count = 0;
std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>(); std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>();
for (std::weak_ptr<Instance> inst : selection->Get()) { for (std::weak_ptr<Instance> inst : selection->Get()) {
if (inst.expired() || !inst.lock()->IsA<Part>()) continue; if (inst.expired() || !inst.lock()->IsA<BasePart>()) continue;
std::shared_ptr<Part> part = inst.lock()->CastTo<Part>().expect(); std::shared_ptr<BasePart> part = inst.lock()->CastTo<BasePart>().expect();
if (count == 0) if (count == 0)
min = part->position(), max = part->position(); 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; return count;
} }
static std::shared_ptr<Part> getFirstSelectedPart() { static std::shared_ptr<BasePart> getFirstSelectedPart() {
std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>(); std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>();
for (std::weak_ptr<Instance> inst : selection->Get()) { for (std::weak_ptr<Instance> inst : selection->Get()) {
if (inst.expired() || !inst.lock()->IsA<Part>()) continue; if (inst.expired() || !inst.lock()->IsA<BasePart>()) continue;
return inst.lock()->CastTo<Part>().expect(); return inst.lock()->CastTo<BasePart>().expect();
} }
return {}; return {};

View file

@ -1,7 +1,7 @@
#pragma once #pragma once
#include "datatypes/cframe.h" #include "datatypes/cframe.h"
#include "objects/part.h" #include "objects/part/part.h"
#include <array> #include <array>
#include <memory> #include <memory>
@ -36,7 +36,7 @@ struct Handles {
bool worldMode = false; bool worldMode = false;
}; };
std::shared_ptr<Part> getHandleAdornee(); std::shared_ptr<BasePart> getHandleAdornee();
CFrame getHandleCFrame(HandleFace face); CFrame getHandleCFrame(HandleFace face);
CFrame partCFrameFromHandlePos(HandleFace face, Vector3 newPos); CFrame partCFrameFromHandlePos(HandleFace face, Vector3 newPos);
Vector3 handleSize(HandleFace face); Vector3 handleSize(HandleFace face);

View file

@ -4,7 +4,7 @@
#include "datatypes/ref.h" #include "datatypes/ref.h"
#include "objects/datamodel.h" #include "objects/datamodel.h"
#include "objects/service/jointsservice.h" #include "objects/service/jointsservice.h"
#include "objects/part.h" #include "objects/part/part.h"
#include "objects/service/workspace.h" #include "objects/service/workspace.h"
#include <memory> #include <memory>
#include <reactphysics3d/constraint/FixedJoint.h> #include <reactphysics3d/constraint/FixedJoint.h>
@ -54,6 +54,6 @@ void JointInstance::onUpdated(std::string property) {
oldPart1 = part1; oldPart1 = part1;
} }
std::optional<std::shared_ptr<Workspace>> JointInstance::workspaceOfPart(std::shared_ptr<Part> part) { std::optional<std::shared_ptr<Workspace>> JointInstance::workspaceOfPart(std::shared_ptr<BasePart> part) {
return part->workspace(); return part->workspace();
} }

View file

@ -8,31 +8,31 @@
//this is necessary ebcause we use std::weak_ptr<Part> without including it in this file //this is necessary ebcause we use std::weak_ptr<Part> without including it in this file
#ifdef __AUTOGEN_EXTRA_INCLUDES__ #ifdef __AUTOGEN_EXTRA_INCLUDES__
#include "../part.h" #include "objects/part/part.h"
#endif #endif
class Part; class BasePart;
class Workspace; class Workspace;
class DEF_INST_ABSTRACT JointInstance : public Instance { class DEF_INST_ABSTRACT JointInstance : public Instance {
AUTOGEN_PREAMBLE AUTOGEN_PREAMBLE
std::weak_ptr<Part> oldPart0; std::weak_ptr<BasePart> oldPart0;
std::weak_ptr<Part> oldPart1; std::weak_ptr<BasePart> oldPart1;
protected: protected:
// The workspace the joint was created in, if it exists // The workspace the joint was created in, if it exists
std::weak_ptr<Workspace> jointWorkspace; std::weak_ptr<Workspace> jointWorkspace;
void OnAncestryChanged(std::optional<std::shared_ptr<Instance>>, std::optional<std::shared_ptr<Instance>>) override; void OnAncestryChanged(std::optional<std::shared_ptr<Instance>>, std::optional<std::shared_ptr<Instance>>) override;
std::optional<std::shared_ptr<Workspace>> workspaceOfPart(std::shared_ptr<Part>); std::optional<std::shared_ptr<Workspace>> workspaceOfPart(std::shared_ptr<BasePart>);
void onUpdated(std::string property); void onUpdated(std::string property);
virtual void buildJoint() = 0; virtual void buildJoint() = 0;
virtual void breakJoint() = 0; virtual void breakJoint() = 0;
public: public:
DEF_PROP_(on_update=onUpdated) std::weak_ptr<Part> part0; DEF_PROP_(on_update=onUpdated) std::weak_ptr<BasePart> part0;
DEF_PROP_(on_update=onUpdated) std::weak_ptr<Part> part1; DEF_PROP_(on_update=onUpdated) std::weak_ptr<BasePart> part1;
DEF_PROP_(on_update=onUpdated) CFrame c0; DEF_PROP_(on_update=onUpdated) CFrame c0;
DEF_PROP_(on_update=onUpdated) CFrame c1; DEF_PROP_(on_update=onUpdated) CFrame c1;

View file

@ -1,6 +1,6 @@
#include "rotate.h" #include "rotate.h"
#include "objects/service/jointsservice.h" #include "objects/service/jointsservice.h"
#include "objects/part.h" #include "objects/part/part.h"
#include "objects/service/workspace.h" #include "objects/service/workspace.h"
#include "rendering/renderer.h" #include "rendering/renderer.h"
#include <reactphysics3d/constraint/HingeJoint.h> #include <reactphysics3d/constraint/HingeJoint.h>

View file

@ -1,6 +1,6 @@
#include "rotatev.h" #include "rotatev.h"
#include "objects/service/jointsservice.h" #include "objects/service/jointsservice.h"
#include "objects/part.h" #include "objects/part/part.h"
#include "objects/service/workspace.h" #include "objects/service/workspace.h"
#include "rendering/renderer.h" #include "rendering/renderer.h"
#include <reactphysics3d/constraint/HingeJoint.h> #include <reactphysics3d/constraint/HingeJoint.h>

View file

@ -4,7 +4,7 @@
#include "objects/datamodel.h" #include "objects/datamodel.h"
#include "objects/joint/jointinstance.h" #include "objects/joint/jointinstance.h"
#include "objects/service/jointsservice.h" #include "objects/service/jointsservice.h"
#include "objects/part.h" #include "objects/part/part.h"
#include "objects/service/workspace.h" #include "objects/service/workspace.h"
#include <memory> #include <memory>
#include <reactphysics3d/constraint/FixedJoint.h> #include <reactphysics3d/constraint/FixedJoint.h>

View file

@ -4,7 +4,7 @@
#include "objects/datamodel.h" #include "objects/datamodel.h"
#include "objects/joint/jointinstance.h" #include "objects/joint/jointinstance.h"
#include "objects/service/jointsservice.h" #include "objects/service/jointsservice.h"
#include "objects/part.h" #include "objects/part/part.h"
#include "objects/service/workspace.h" #include "objects/service/workspace.h"
#include <memory> #include <memory>
#include <reactphysics3d/constraint/FixedJoint.h> #include <reactphysics3d/constraint/FixedJoint.h>

View file

@ -8,7 +8,7 @@
#include "objects/message.h" #include "objects/message.h"
#include "objects/service/jointsservice.h" #include "objects/service/jointsservice.h"
#include "objects/model.h" #include "objects/model.h"
#include "objects/part.h" #include "objects/part/part.h"
#include "objects/joint/snap.h" #include "objects/joint/snap.h"
#include "objects/script.h" #include "objects/script.h"
#include "objects/service/script/scriptcontext.h" #include "objects/service/script/scriptcontext.h"
@ -21,6 +21,7 @@ std::map<std::string, const InstanceType*> INSTANCE_MAP = {
{ "Instance", &Instance::TYPE }, { "Instance", &Instance::TYPE },
{ "DataModel", &DataModel::TYPE }, { "DataModel", &DataModel::TYPE },
{ "BasePart", &BasePart::TYPE },
{ "Part", &Part::TYPE }, { "Part", &Part::TYPE },
{ "Snap", &Snap::TYPE }, { "Snap", &Snap::TYPE },
{ "Weld", &Weld::TYPE }, { "Weld", &Weld::TYPE },

View file

@ -1,5 +1,5 @@
#include "part.h" #include "basepart.h"
#include "base/instance.h" #include "objects/base/instance.h"
#include "common.h" #include "common.h"
#include "datatypes/base.h" #include "datatypes/base.h"
#include "datatypes/cframe.h" #include "datatypes/cframe.h"
@ -19,15 +19,14 @@
#include <memory> #include <memory>
#include <optional> #include <optional>
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), 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) { 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. // This relies on physicsCommon still existing. Be very careful.
if (this->rigidBody && workspace()) { if (this->rigidBody && workspace()) {
workspace().value()->DestroyRigidBody(rigidBody); workspace().value()->DestroyRigidBody(rigidBody);
@ -36,12 +35,12 @@ Part::~Part() {
} }
void Part::OnAncestryChanged(std::optional<std::shared_ptr<Instance>> child, std::optional<std::shared_ptr<Instance>> newParent) { void BasePart::OnAncestryChanged(std::optional<std::shared_ptr<Instance>> child, std::optional<std::shared_ptr<Instance>> newParent) {
if (this->rigidBody) if (this->rigidBody)
this->rigidBody->setIsActive(workspace().has_value()); this->rigidBody->setIsActive(workspace().has_value());
if (workspace()) if (workspace())
workspace().value()->SyncPartPhysics(std::dynamic_pointer_cast<Part>(this->shared_from_this())); workspace().value()->SyncPartPhysics(std::dynamic_pointer_cast<BasePart>(this->shared_from_this()));
// Destroy joints // Destroy joints
if (!workspace()) BreakJoints(); if (!workspace()) BreakJoints();
@ -49,22 +48,22 @@ void Part::OnAncestryChanged(std::optional<std::shared_ptr<Instance>> child, std
// TODO: Sleeping bodies that touch this one also need to be updated // TODO: Sleeping bodies that touch this one also need to be updated
} }
void Part::OnWorkspaceAdded(std::optional<std::shared_ptr<Workspace>> oldWorkspace, std::shared_ptr<Workspace> newWorkspace) { void BasePart::OnWorkspaceAdded(std::optional<std::shared_ptr<Workspace>> oldWorkspace, std::shared_ptr<Workspace> newWorkspace) {
newWorkspace->AddBody(shared<Part>()); newWorkspace->AddBody(shared<BasePart>());
} }
void Part::OnWorkspaceRemoved(std::shared_ptr<Workspace> oldWorkspace) { void BasePart::OnWorkspaceRemoved(std::shared_ptr<Workspace> oldWorkspace) {
if (simulationTicket.has_value()) if (simulationTicket.has_value())
oldWorkspace->RemoveBody(shared<Part>()); oldWorkspace->RemoveBody(shared<BasePart>());
} }
void Part::onUpdated(std::string property) { void BasePart::onUpdated(std::string property) {
// Reset velocity // Reset velocity
if (property != "Velocity") if (property != "Velocity")
velocity = Vector3::ZERO; velocity = Vector3::ZERO;
if (workspace()) if (workspace())
workspace().value()->SyncPartPhysics(std::dynamic_pointer_cast<Part>(this->shared_from_this())); workspace().value()->SyncPartPhysics(std::dynamic_pointer_cast<BasePart>(this->shared_from_this()));
// When position/rotation/size is manually edited, break all joints, they don't apply anymore // When position/rotation/size is manually edited, break all joints, they don't apply anymore
if (property != "Anchored") if (property != "Anchored")
@ -88,7 +87,7 @@ static Vector3 verts[8] {
{1, 1, 1}, {1, 1, 1},
}; };
Vector3 Part::GetAABB() { Vector3 BasePart::GetAABB() {
Vector3 min(0, 0, 0); Vector3 min(0, 0, 0);
Vector3 max(0, 0, 0); Vector3 max(0, 0, 0);
for (Vector3 vert : verts) { for (Vector3 vert : verts) {
@ -99,7 +98,7 @@ Vector3 Part::GetAABB() {
return (min - max).Abs() / 2; return (min - max).Abs() / 2;
} }
void Part::BreakJoints() { void BasePart::BreakJoints() {
for (std::weak_ptr<JointInstance> joint : primaryJoints) { for (std::weak_ptr<JointInstance> joint : primaryJoints) {
if (joint.expired()) continue; if (joint.expired()) continue;
joint.lock()->Destroy(); joint.lock()->Destroy();
@ -120,7 +119,7 @@ static Vector3 FACES[6] = {
{0, 0, -1}, {0, 0, -1},
}; };
SurfaceType Part::surfaceFromFace(NormalId face) { SurfaceType BasePart::surfaceFromFace(NormalId face) {
switch (face) { switch (face) {
case Top: return topSurface; case Top: return topSurface;
case Bottom: return bottomSurface; case Bottom: return bottomSurface;
@ -132,7 +131,7 @@ SurfaceType Part::surfaceFromFace(NormalId face) {
return SurfaceType::Smooth; // Unreachable return SurfaceType::Smooth; // Unreachable
} }
float Part::GetSurfaceParamA(Vector3 face) { float BasePart::GetSurfaceParamA(Vector3 face) {
switch (faceFromNormal(face)) { switch (faceFromNormal(face)) {
case Top: return topParamA; case Top: return topParamA;
case Bottom: return bottomParamA; case Bottom: return bottomParamA;
@ -144,7 +143,7 @@ float Part::GetSurfaceParamA(Vector3 face) {
return 0; // Unreachable return 0; // Unreachable
} }
float Part::GetSurfaceParamB(Vector3 face) { float BasePart::GetSurfaceParamB(Vector3 face) {
switch (faceFromNormal(face)) { switch (faceFromNormal(face)) {
case Top: return topParamB; case Top: return topParamB;
case Bottom: return bottomParamB; case Bottom: return bottomParamB;
@ -156,14 +155,14 @@ float Part::GetSurfaceParamB(Vector3 face) {
return 0; // Unreachable return 0; // Unreachable
} }
bool Part::checkJointContinuity(std::shared_ptr<Part> otherPart) { bool BasePart::checkJointContinuity(std::shared_ptr<BasePart> otherPart) {
// Make sure that the two parts don't depend on one another // Make sure that the two parts don't depend on one another
return checkJointContinuityUp(otherPart) && checkJointContinuityDown(otherPart); return checkJointContinuityUp(otherPart) && checkJointContinuityDown(otherPart);
} }
bool Part::checkJointContinuityDown(std::shared_ptr<Part> otherPart) { bool BasePart::checkJointContinuityDown(std::shared_ptr<BasePart> otherPart) {
if (shared<Part>() == otherPart) return false; if (shared<BasePart>() == otherPart) return false;
for (auto joint : primaryJoints) { for (auto joint : primaryJoints) {
if (joint.expired() || joint.lock()->part1.expired()) continue; if (joint.expired() || joint.lock()->part1.expired()) continue;
if (!joint.lock()->part1.lock()->checkJointContinuityDown(otherPart)) if (!joint.lock()->part1.lock()->checkJointContinuityDown(otherPart))
@ -172,8 +171,8 @@ bool Part::checkJointContinuityDown(std::shared_ptr<Part> otherPart) {
return true; return true;
} }
bool Part::checkJointContinuityUp(std::shared_ptr<Part> otherPart) { bool BasePart::checkJointContinuityUp(std::shared_ptr<BasePart> otherPart) {
if (shared<Part>() == otherPart) return false; if (shared<BasePart>() == otherPart) return false;
for (auto joint : secondaryJoints) { for (auto joint : secondaryJoints) {
if (joint.expired() || joint.lock()->part0.expired()) continue; if (joint.expired() || joint.lock()->part0.expired()) continue;
if (!joint.lock()->part0.lock()->checkJointContinuityUp(otherPart)) if (!joint.lock()->part0.lock()->checkJointContinuityUp(otherPart))
@ -182,7 +181,7 @@ bool Part::checkJointContinuityUp(std::shared_ptr<Part> otherPart) {
return true; return true;
} }
bool Part::checkSurfacesTouching(CFrame surfaceFrame, Vector3 size, Vector3 myFace, Vector3 otherFace, std::shared_ptr<Part> otherPart) { bool BasePart::checkSurfacesTouching(CFrame surfaceFrame, Vector3 size, Vector3 myFace, Vector3 otherFace, std::shared_ptr<BasePart> otherPart) {
Vector3 farCorner0 = surfaceFrame.Inverse() * otherPart->cframe * (Vector3::ONE * (otherPart->size / 2.f)); Vector3 farCorner0 = surfaceFrame.Inverse() * otherPart->cframe * (Vector3::ONE * (otherPart->size / 2.f));
Vector3 farCorner1 = 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<std::shared_ptr<JointInstance>> makeJointFromSurfaces(SurfaceType
return std::nullopt; return std::nullopt;
} }
void Part::MakeJoints() { void BasePart::MakeJoints() {
// Algorithm: Find nearby parts // Algorithm: Find nearby parts
// Make sure parts are not dependant on each other (via primary/secondaryJoints) // Make sure parts are not dependant on each other (via primary/secondaryJoints)
// Find matching surfaces (surface normal dot product < -0.999) // 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++) { for (auto it = workspace().value()->GetDescendantsStart(); it != workspace().value()->GetDescendantsEnd(); it++) {
std::shared_ptr<Instance> obj = *it; std::shared_ptr<Instance> obj = *it;
if (obj == shared_from_this()) continue; // Skip ourselves 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 if (!obj->IsA<BasePart>()) continue;
std::shared_ptr<Part> otherPart = obj->CastTo<Part>().expect(); std::shared_ptr<BasePart> otherPart = obj->CastTo<BasePart>().expect();
for (Vector3 myFace : FACES) { for (Vector3 myFace : FACES) {
Vector3 myWorldNormal = cframe.Rotation() * myFace; Vector3 myWorldNormal = cframe.Rotation() * myFace;
@ -278,8 +277,8 @@ void Part::MakeJoints() {
auto joint_ = makeJointFromSurfaces(mySurface, otherSurface); auto joint_ = makeJointFromSurfaces(mySurface, otherSurface);
if (!joint_) continue; if (!joint_) continue;
std::shared_ptr<JointInstance> joint = joint_.value(); std::shared_ptr<JointInstance> joint = joint_.value();
joint->part0 = shared<Part>(); joint->part0 = shared<BasePart>();
joint->part1 = otherPart->shared<Part>(); joint->part1 = otherPart->shared<BasePart>();
joint->c0 = contact0; joint->c0 = contact0;
joint->c1 = contact1; joint->c1 = contact1;
dataModel().value()->GetService<JointsService>()->AddChild(joint); dataModel().value()->GetService<JointsService>()->AddChild(joint);
@ -291,7 +290,7 @@ void Part::MakeJoints() {
} }
} }
void Part::trackJoint(std::shared_ptr<JointInstance> joint) { void BasePart::trackJoint(std::shared_ptr<JointInstance> joint) {
if (!joint->part0.expired() && joint->part0.lock() == shared_from_this()) { if (!joint->part0.expired() && joint->part0.lock() == shared_from_this()) {
for (auto it = primaryJoints.begin(); it != primaryJoints.end();) { for (auto it = primaryJoints.begin(); it != primaryJoints.end();) {
// Clean expired refs // Clean expired refs
@ -325,7 +324,7 @@ void Part::trackJoint(std::shared_ptr<JointInstance> joint) {
} }
} }
void Part::untrackJoint(std::shared_ptr<JointInstance> joint) { void BasePart::untrackJoint(std::shared_ptr<JointInstance> joint) {
for (auto it = primaryJoints.begin(); it != primaryJoints.end();) { for (auto it = primaryJoints.begin(); it != primaryJoints.end();) {
// Clean expired refs // Clean expired refs
if (it->expired() || it->lock() == joint) { if (it->expired() || it->lock() == joint) {

View file

@ -14,7 +14,7 @@
#include <optional> #include <optional>
#include <reactphysics3d/reactphysics3d.h> #include <reactphysics3d/reactphysics3d.h>
#include <vector> #include <vector>
#include "annotation.h" #include "objects/annotation.h"
#include "objects/pvinstance.h" #include "objects/pvinstance.h"
namespace rp = reactphysics3d; namespace rp = reactphysics3d;
@ -34,11 +34,11 @@ class Workspace;
#ifndef __SIMULATION_TICKET #ifndef __SIMULATION_TICKET
#define __SIMULATION_TICKET #define __SIMULATION_TICKET
class Part; class BasePart;
typedef std::list<std::shared_ptr<Part>>::iterator SimulationTicket; typedef std::list<std::shared_ptr<BasePart>>::iterator SimulationTicket;
#endif #endif
class DEF_INST_(explorer_icon="part") Part : public PVInstance { class DEF_INST_ABSTRACT_(explorer_icon="part") BasePart : public PVInstance {
AUTOGEN_PREAMBLE AUTOGEN_PREAMBLE
protected: protected:
// Joints where this part is Part0 // Joints where this part is Part0
@ -50,10 +50,10 @@ protected:
void untrackJoint(std::shared_ptr<JointInstance>); void untrackJoint(std::shared_ptr<JointInstance>);
SurfaceType surfaceFromFace(NormalId); SurfaceType surfaceFromFace(NormalId);
bool checkJointContinuity(std::shared_ptr<Part>); bool checkJointContinuity(std::shared_ptr<BasePart>);
bool checkJointContinuityUp(std::shared_ptr<Part>); bool checkJointContinuityUp(std::shared_ptr<BasePart>);
bool checkJointContinuityDown(std::shared_ptr<Part>); bool checkJointContinuityDown(std::shared_ptr<BasePart>);
bool checkSurfacesTouching(CFrame surfaceFrame, Vector3 size, Vector3 myFace, Vector3 otherFace, std::shared_ptr<Part> otherPart); bool checkSurfacesTouching(CFrame surfaceFrame, Vector3 size, Vector3 myFace, Vector3 otherFace, std::shared_ptr<BasePart> otherPart);
friend JointInstance; friend JointInstance;
friend Workspace; friend Workspace;
@ -62,6 +62,9 @@ protected:
virtual void OnWorkspaceRemoved(std::shared_ptr<Workspace> oldWorkspace) override; virtual void OnWorkspaceRemoved(std::shared_ptr<Workspace> oldWorkspace) override;
void OnAncestryChanged(std::optional<std::shared_ptr<Instance>> child, std::optional<std::shared_ptr<Instance>> newParent) override; void OnAncestryChanged(std::optional<std::shared_ptr<Instance>> child, std::optional<std::shared_ptr<Instance>> newParent) override;
void onUpdated(std::string); void onUpdated(std::string);
BasePart(const InstanceType*);
BasePart(const InstanceType*, PartConstructParams params);
public: public:
DEF_PROP_CATEGORY(DATA) DEF_PROP_CATEGORY(DATA)
DEF_PROP_(on_update=onUpdated) Vector3 velocity; DEF_PROP_(on_update=onUpdated) Vector3 velocity;
@ -116,13 +119,7 @@ public:
float GetSurfaceParamA(Vector3 face); float GetSurfaceParamA(Vector3 face);
float GetSurfaceParamB(Vector3 face); float GetSurfaceParamB(Vector3 face);
Part(); ~BasePart() override;
Part(PartConstructParams params);
~Part() override;
static inline std::shared_ptr<Part> New() { return std::make_shared<Part>(); };
static inline std::shared_ptr<Part> New(PartConstructParams params) { return std::make_shared<Part>(params); };
static inline std::shared_ptr<Instance> Create() { return std::make_shared<Part>(); };
inline Vector3 position() { return cframe.Position(); } inline Vector3 position() { return cframe.Position(); }

View file

@ -0,0 +1,8 @@
#include "part.h"
Part::Part(): BasePart(&TYPE) {
}
Part::Part(PartConstructParams params): BasePart(&TYPE, params) {
}

View file

@ -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<Part> New() { return std::make_shared<Part>(); };
static inline std::shared_ptr<Part> New(PartConstructParams params) { return std::make_shared<Part>(params); };
static inline std::shared_ptr<Instance> Create() { return std::make_shared<Part>(); };
};

View file

@ -4,7 +4,7 @@
#include "datatypes/vector.h" #include "datatypes/vector.h"
#include "logger.h" #include "logger.h"
#include "objects/base/instance.h" #include "objects/base/instance.h"
#include "objects/part.h" #include "objects/part/part.h"
#include "objects/service/jointsservice.h" #include "objects/service/jointsservice.h"
#include "objects/joint/jointinstance.h" #include "objects/joint/jointinstance.h"
#include "objects/datamodel.h" #include "objects/datamodel.h"
@ -39,8 +39,8 @@ void PhysicsEventListener::onContact(const rp::CollisionCallback::CallbackData&
continue; continue;
ContactItem contact; ContactItem contact;
contact.part0 = reinterpret_cast<Part*>(pair.getBody1()->getUserData())->shared<Part>(); contact.part0 = reinterpret_cast<BasePart*>(pair.getBody1()->getUserData())->shared<BasePart>();
contact.part1 = reinterpret_cast<Part*>(pair.getBody2()->getUserData())->shared<Part>(); contact.part1 = reinterpret_cast<BasePart*>(pair.getBody2()->getUserData())->shared<BasePart>();
contact.action = type == reactphysics3d::CollisionCallback::ContactPair::EventType::ContactStart ? ContactItem::CONTACTITEM_TOUCHED : ContactItem::CONTACTITEM_TOUCHENDED; contact.action = type == reactphysics3d::CollisionCallback::ContactPair::EventType::ContactStart ? ContactItem::CONTACTITEM_TOUCHED : ContactItem::CONTACTITEM_TOUCHENDED;
workspace->contactQueue.push(contact); workspace->contactQueue.push(contact);
@ -55,8 +55,8 @@ void PhysicsEventListener::onTrigger(const rp::OverlapCallback::CallbackData& da
auto type = pair.getEventType(); auto type = pair.getEventType();
if (type == rp::OverlapCallback::OverlapPair::EventType::OverlapStay) continue; if (type == rp::OverlapCallback::OverlapPair::EventType::OverlapStay) continue;
auto part0 = reinterpret_cast<Part*>(pair.getBody1()->getUserData())->shared<Part>(); auto part0 = reinterpret_cast<BasePart*>(pair.getBody1()->getUserData())->shared<BasePart>();
auto part1 = reinterpret_cast<Part*>(pair.getBody2()->getUserData())->shared<Part>(); auto part1 = reinterpret_cast<BasePart*>(pair.getBody2()->getUserData())->shared<BasePart>();
if (type == reactphysics3d::OverlapCallback::OverlapPair::EventType::OverlapStart) { if (type == reactphysics3d::OverlapCallback::OverlapPair::EventType::OverlapStart) {
part0->Touched->Fire({ (Variant)InstanceRef(part1) }); part0->Touched->Fire({ (Variant)InstanceRef(part1) });
@ -85,8 +85,8 @@ void Workspace::InitService() {
// Sync all parts // Sync all parts
for (auto it = this->GetDescendantsStart(); it != this->GetDescendantsEnd(); it++) { for (auto it = this->GetDescendantsStart(); it != this->GetDescendantsEnd(); it++) {
std::shared_ptr<Instance> obj = *it; std::shared_ptr<Instance> obj = *it;
if (!obj->IsA<Part>()) continue; if (!obj->IsA<BasePart>()) continue;
std::shared_ptr<Part> part = obj->CastTo<Part>().expect(); std::shared_ptr<BasePart> part = obj->CastTo<BasePart>().expect();
part->MakeJoints(); part->MakeJoints();
} }
@ -105,7 +105,7 @@ void Workspace::InitService() {
} }
} }
void Workspace::updatePartPhysics(std::shared_ptr<Part> part) { void Workspace::updatePartPhysics(std::shared_ptr<BasePart> part) {
rp::Transform transform = part->cframe; rp::Transform transform = part->cframe;
if (!part->rigidBody) { if (!part->rigidBody) {
part->rigidBody = physicsWorld->createRigidBody(transform); part->rigidBody = physicsWorld->createRigidBody(transform);
@ -162,7 +162,7 @@ void Workspace::ProcessContactEvents() {
contactQueueLock.unlock(); contactQueueLock.unlock();
} }
void Workspace::SyncPartPhysics(std::shared_ptr<Part> part) { void Workspace::SyncPartPhysics(std::shared_ptr<BasePart> part) {
if (globalPhysicsLock.try_lock()) { if (globalPhysicsLock.try_lock()) {
updatePartPhysics(part); updatePartPhysics(part);
globalPhysicsLock.unlock(); globalPhysicsLock.unlock();
@ -192,7 +192,7 @@ void Workspace::PhysicsStep(float deltaTime) {
queueLock.unlock(); queueLock.unlock();
// TODO: Add list of tracked parts in workspace based on their ancestry using inWorkspace property of Instance // TODO: Add list of tracked parts in workspace based on their ancestry using inWorkspace property of Instance
for (std::shared_ptr<Part> part : simulatedBodies) { for (std::shared_ptr<BasePart> part : simulatedBodies) {
// If the part's body is dirty, update it now instead // If the part's body is dirty, update it now instead
if (part->rigidBodyDirty) { if (part->rigidBodyDirty) {
updatePartPhysics(part); updatePartPhysics(part);
@ -261,7 +261,7 @@ class NearestRayHit : public rp::RaycastCallback {
return 1; return 1;
} }
std::shared_ptr<Part> part = partFromBody(raycastInfo.body); std::shared_ptr<BasePart> part = partFromBody(raycastInfo.body);
FilterResult result = filter.value()(part); FilterResult result = filter.value()(part);
if (result == FilterResult::BLOCK) { if (result == FilterResult::BLOCK) {
nearestHit = std::nullopt; nearestHit = std::nullopt;
@ -305,14 +305,14 @@ rp::Joint* Workspace::CreateJoint(const rp::JointInfo& jointInfo) {
return joint; return joint;
} }
void Workspace::AddBody(std::shared_ptr<Part> part) { void Workspace::AddBody(std::shared_ptr<BasePart> part) {
queueLock.lock(); queueLock.lock();
bodyQueue.push_back({part, QueueItem::QUEUEITEM_ADD}); bodyQueue.push_back({part, QueueItem::QUEUEITEM_ADD});
part->rigidBodyDirty = true; part->rigidBodyDirty = true;
queueLock.unlock(); queueLock.unlock();
} }
void Workspace::RemoveBody(std::shared_ptr<Part> part) { void Workspace::RemoveBody(std::shared_ptr<BasePart> part) {
queueLock.lock(); queueLock.lock();
bodyQueue.push_back({part, QueueItem::QUEUEITEM_REMOVE}); bodyQueue.push_back({part, QueueItem::QUEUEITEM_REMOVE});
queueLock.unlock(); queueLock.unlock();

View file

@ -32,7 +32,7 @@ enum FilterResult {
PASS, // The object is transparent, ignore it PASS, // The object is transparent, ignore it
}; };
class Part; class BasePart;
class Snap; class Snap;
class Weld; class Weld;
class Rotate; class Rotate;
@ -40,13 +40,13 @@ class RotateV;
#ifndef __SIMULATION_TICKET #ifndef __SIMULATION_TICKET
#define __SIMULATION_TICKET #define __SIMULATION_TICKET
typedef std::list<std::shared_ptr<Part>>::iterator SimulationTicket; typedef std::list<std::shared_ptr<BasePart>>::iterator SimulationTicket;
#endif #endif
typedef std::function<FilterResult(std::shared_ptr<Part>)> RaycastFilter; typedef std::function<FilterResult(std::shared_ptr<BasePart>)> RaycastFilter;
struct QueueItem { struct QueueItem {
std::shared_ptr<Part> part; std::shared_ptr<BasePart> part;
enum { enum {
QUEUEITEM_ADD, QUEUEITEM_ADD,
QUEUEITEM_REMOVE, QUEUEITEM_REMOVE,
@ -54,8 +54,8 @@ struct QueueItem {
}; };
struct ContactItem { struct ContactItem {
std::shared_ptr<Part> part0; std::shared_ptr<BasePart> part0;
std::shared_ptr<Part> part1; std::shared_ptr<BasePart> part1;
enum { enum {
CONTACTITEM_TOUCHED, CONTACTITEM_TOUCHED,
CONTACTITEM_TOUCHENDED, CONTACTITEM_TOUCHENDED,
@ -78,7 +78,7 @@ class DEF_INST_SERVICE_(explorer_icon="workspace") Workspace : public Service {
friend PhysicsEventListener; friend PhysicsEventListener;
std::list<std::shared_ptr<Part>> simulatedBodies; std::list<std::shared_ptr<BasePart>> simulatedBodies;
std::list<QueueItem> bodyQueue; std::list<QueueItem> bodyQueue;
std::queue<ContactItem> contactQueue; std::queue<ContactItem> contactQueue;
std::mutex contactQueueLock; std::mutex contactQueueLock;
@ -86,7 +86,7 @@ class DEF_INST_SERVICE_(explorer_icon="workspace") Workspace : public Service {
static rp::PhysicsCommon* physicsCommon; static rp::PhysicsCommon* physicsCommon;
PhysicsEventListener physicsEventListener; PhysicsEventListener physicsEventListener;
void updatePartPhysics(std::shared_ptr<Part> part); void updatePartPhysics(std::shared_ptr<BasePart> part);
protected: protected:
void InitService() override; void InitService() override;
bool initialized = false; bool initialized = false;
@ -103,10 +103,10 @@ public:
// static inline std::shared_ptr<Workspace> New() { return std::make_shared<Workspace>(); }; // static inline std::shared_ptr<Workspace> New() { return std::make_shared<Workspace>(); };
static inline std::shared_ptr<Instance> Create() { return std::make_shared<Workspace>(); }; static inline std::shared_ptr<Instance> Create() { return std::make_shared<Workspace>(); };
void AddBody(std::shared_ptr<Part> part); void AddBody(std::shared_ptr<BasePart> part);
void RemoveBody(std::shared_ptr<Part> part); void RemoveBody(std::shared_ptr<BasePart> part);
void DestroyRigidBody(rp::RigidBody* rigidBody); void DestroyRigidBody(rp::RigidBody* rigidBody);
void SyncPartPhysics(std::shared_ptr<Part> part); void SyncPartPhysics(std::shared_ptr<BasePart> part);
rp::Joint* CreateJoint(const rp::JointInfo& jointInfo); rp::Joint* CreateJoint(const rp::JointInfo& jointInfo);
void DestroyJoint(rp::Joint* joint); void DestroyJoint(rp::Joint* joint);

View file

@ -5,13 +5,13 @@
#include "datatypes/vector.h" #include "datatypes/vector.h"
#include "math_helper.h" #include "math_helper.h"
#include "objects/base/instance.h" #include "objects/base/instance.h"
#include "objects/part.h" #include "objects/part/part.h"
#include "objects/service/selection.h" #include "objects/service/selection.h"
#include <glm/common.hpp> #include <glm/common.hpp>
#include <memory> #include <memory>
#include <vector> #include <vector>
PartAssembly::PartAssembly(std::vector<std::shared_ptr<Part>> parts, bool worldMode) : parts(parts) { PartAssembly::PartAssembly(std::vector<std::shared_ptr<BasePart>> parts, bool worldMode) : parts(parts) {
if (parts.size() == 0) return; if (parts.size() == 0) return;
if (parts.size() == 1 && !worldMode) { if (parts.size() == 1 && !worldMode) {
_assemblyOrigin = parts[0]->cframe; _assemblyOrigin = parts[0]->cframe;
@ -36,19 +36,19 @@ PartAssembly::PartAssembly(std::vector<std::shared_ptr<Part>> parts, bool worldM
} }
PartAssembly PartAssembly::FromSelection(std::vector<std::shared_ptr<Instance>> newSelection) { PartAssembly PartAssembly::FromSelection(std::vector<std::shared_ptr<Instance>> newSelection) {
std::vector<std::shared_ptr<Part>> selection; std::vector<std::shared_ptr<BasePart>> selection;
for (std::shared_ptr<Instance> obj : newSelection) { for (std::shared_ptr<Instance> obj : newSelection) {
if (!obj->IsA<PVInstance>()) continue; if (!obj->IsA<PVInstance>()) continue;
if (obj->IsA<Part>()) if (obj->IsA<BasePart>())
selection.push_back(obj->CastTo<Part>().expect()); selection.push_back(obj->CastTo<BasePart>().expect());
// Add object descendants // Add object descendants
for (DescendantsIterator it = obj->GetDescendantsStart(); it != obj->GetDescendantsEnd(); it++) { for (DescendantsIterator it = obj->GetDescendantsStart(); it != obj->GetDescendantsEnd(); it++) {
if (!(*it)->IsA<Part>()) continue; if (!(*it)->IsA<BasePart>()) continue;
selection.push_back((*it)->CastTo<Part>().expect()); selection.push_back((*it)->CastTo<BasePart>().expect());
} }
} }

View file

@ -4,12 +4,12 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
class Part; class BasePart;
class Instance; class Instance;
class Selection; class Selection;
struct PartTransformState { struct PartTransformState {
std::shared_ptr<Part> part; std::shared_ptr<BasePart> part;
Vector3 size; Vector3 size;
CFrame cframe; CFrame cframe;
}; };
@ -19,9 +19,9 @@ class PartAssembly {
Vector3 _bounds; Vector3 _bounds;
Vector3 _size; Vector3 _size;
std::vector<std::shared_ptr<Part>> parts; std::vector<std::shared_ptr<BasePart>> parts;
public: public:
PartAssembly(std::vector<std::shared_ptr<Part>>, bool worldMode = false); PartAssembly(std::vector<std::shared_ptr<BasePart>>, bool worldMode = false);
static PartAssembly FromSelection(std::vector<std::shared_ptr<Instance>> selection); static PartAssembly FromSelection(std::vector<std::shared_ptr<Instance>> selection);
static PartAssembly FromSelection(std::shared_ptr<Selection> selection); static PartAssembly FromSelection(std::shared_ptr<Selection> selection);

View file

@ -7,7 +7,7 @@
#include <reactphysics3d/mathematics/Vector3.h> #include <reactphysics3d/mathematics/Vector3.h>
#include <reactphysics3d/mathematics/mathematics.h> #include <reactphysics3d/mathematics/mathematics.h>
#include <glm/ext.hpp> #include <glm/ext.hpp>
#include "objects/part.h" #include "objects/part/part.h"
namespace rp = reactphysics3d; namespace rp = reactphysics3d;
@ -32,8 +32,8 @@ inline glm::quat rpToGlm(rp::Quaternion quat) {
} }
// Make this std::optional // Make this std::optional
inline std::shared_ptr<Part> partFromBody(rp::Body* body) { inline std::shared_ptr<BasePart> partFromBody(rp::Body* body) {
Part* raw = reinterpret_cast<Part*>(body->getUserData()); BasePart* raw = reinterpret_cast<BasePart*>(body->getUserData());
std::shared_ptr<Part> shared = std::dynamic_pointer_cast<Part>(raw->shared_from_this()); std::shared_ptr<BasePart> shared = std::dynamic_pointer_cast<BasePart>(raw->shared_from_this());
return shared; return shared;
} }

View file

@ -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[] = { static float SPHERE_VERTICES[] = {
// positions // normals // texture coords // positions // normals // texture coords
@ -1730,6 +1760,7 @@ static float CYLINDER_VERTICES[] = {
}; };
Mesh* CUBE_MESH; Mesh* CUBE_MESH;
Mesh* WEDGE_MESH;
Mesh* SPHERE_MESH; Mesh* SPHERE_MESH;
Mesh* ARROW_MESH; Mesh* ARROW_MESH;
Mesh* OUTLINE_MESH; Mesh* OUTLINE_MESH;
@ -1737,6 +1768,7 @@ Mesh* CYLINDER_MESH;
void initMeshes() { void initMeshes() {
CUBE_MESH = new Mesh(sizeof(CUBE_VERTICES) / sizeof(float) / 8, CUBE_VERTICES); 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); SPHERE_MESH = new Mesh(sizeof(SPHERE_VERTICES) / sizeof(float) / 8, SPHERE_VERTICES);
ARROW_MESH = new Mesh(sizeof(ARROW_VERTICES) / sizeof(float) / 8, ARROW_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); OUTLINE_MESH = new Mesh(sizeof(OUTLINE_VERTICES) / sizeof(float) / 8, OUTLINE_VERTICES);

View file

@ -31,9 +31,9 @@
#include "shader.h" #include "shader.h"
#include "mesh.h" #include "mesh.h"
#include "defaultmeshes.h" #include "defaultmeshes.h"
#include "../camera.h" #include "camera.h"
#include "../common.h" #include "common.h"
#include "../objects/part.h" #include "objects/part/part.h"
#include "skybox.h" #include "skybox.h"
#include "enum/surface.h" #include "enum/surface.h"
#include "texture3d.h" #include "texture3d.h"
@ -170,11 +170,11 @@ void renderParts() {
shader->set("viewPos", camera.cameraPos); shader->set("viewPos", camera.cameraPos);
// Sort by nearest // Sort by nearest
std::map<float, std::shared_ptr<Part>> sorted; std::map<float, std::shared_ptr<BasePart>> sorted;
for (auto it = gWorkspace()->GetDescendantsStart(); it != gWorkspace()->GetDescendantsEnd(); it++) { for (auto it = gWorkspace()->GetDescendantsStart(); it != gWorkspace()->GetDescendantsEnd(); it++) {
std::shared_ptr<Instance> inst = *it; std::shared_ptr<Instance> inst = *it;
if (inst->GetClass()->className != "Part") continue; if (inst->GetClass()->className != "Part") continue;
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst); std::shared_ptr<BasePart> part = std::dynamic_pointer_cast<BasePart>(inst);
if (part->transparency > 0.00001) { if (part->transparency > 0.00001) {
float distance = glm::length(glm::vec3(Vector3(camera.cameraPos) - part->position())); float distance = glm::length(glm::vec3(Vector3(camera.cameraPos) - part->position()));
sorted[distance] = part; sorted[distance] = part;
@ -207,8 +207,8 @@ void renderParts() {
// TODO: Same as todo in src/physics/simulation.cpp // TODO: Same as todo in src/physics/simulation.cpp
// According to LearnOpenGL, std::map automatically sorts its contents. // According to LearnOpenGL, std::map automatically sorts its contents.
for (std::map<float, std::shared_ptr<Part>>::reverse_iterator it = sorted.rbegin(); it != sorted.rend(); it++) { for (std::map<float, std::shared_ptr<BasePart>>::reverse_iterator it = sorted.rbegin(); it != sorted.rend(); it++) {
std::shared_ptr<Part> part = it->second; std::shared_ptr<BasePart> part = it->second;
glm::mat4 model = part->cframe; glm::mat4 model = part->cframe;
// if (part->name == "camera") model = camera.getLookAt(); // if (part->name == "camera") model = camera.getLookAt();
model = glm::scale(model, (glm::vec3)part->size); model = glm::scale(model, (glm::vec3)part->size);
@ -268,7 +268,7 @@ void renderSurfaceExtras() {
for (auto it = gWorkspace()->GetDescendantsStart(); it != gWorkspace()->GetDescendantsEnd(); it++) { for (auto it = gWorkspace()->GetDescendantsStart(); it != gWorkspace()->GetDescendantsEnd(); it++) {
std::shared_ptr<Instance> inst = *it; std::shared_ptr<Instance> inst = *it;
if (!inst->IsA("Part")) continue; if (!inst->IsA("Part")) continue;
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst); std::shared_ptr<BasePart> part = std::dynamic_pointer_cast<BasePart>(inst);
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
NormalId face = (NormalId)i; NormalId face = (NormalId)i;
SurfaceType type = part->GetSurfaceFromFace(face); SurfaceType type = part->GetSurfaceFromFace(face);
@ -396,7 +396,7 @@ void renderAABB() {
// Sort by nearest // Sort by nearest
for (std::shared_ptr<Instance> inst : gWorkspace()->GetChildren()) { for (std::shared_ptr<Instance> inst : gWorkspace()->GetChildren()) {
if (inst->GetClass()->className != "Part") continue; if (inst->GetClass()->className != "Part") continue;
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst); std::shared_ptr<BasePart> part = std::dynamic_pointer_cast<BasePart>(inst);
glm::mat4 model = CFrame::IDENTITY + part->cframe.Position(); 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()); 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()); model = glm::scale(model, (glm::vec3)part->GetAABB());
@ -436,7 +436,7 @@ void renderWireframe() {
// Sort by nearest // Sort by nearest
for (std::shared_ptr<Instance> inst : gWorkspace()->GetChildren()) { for (std::shared_ptr<Instance> inst : gWorkspace()->GetChildren()) {
if (inst->GetClass()->className != "Part") continue; if (inst->GetClass()->className != "Part") continue;
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst); std::shared_ptr<BasePart> part = std::dynamic_pointer_cast<BasePart>(inst);
glm::mat4 model = part->cframe; glm::mat4 model = part->cframe;
model = glm::scale(model, (glm::vec3)part->size); model = glm::scale(model, (glm::vec3)part->size);
wireframeShader->set("model", model); wireframeShader->set("model", model);
@ -478,8 +478,8 @@ void renderOutlines() {
std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>(); std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>();
for (auto inst : selection->Get()) { for (auto inst : selection->Get()) {
if (inst->GetClass() != &Part::TYPE) continue; if (inst->GetClass() != &BasePart::TYPE) continue;
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst); std::shared_ptr<BasePart> part = std::dynamic_pointer_cast<BasePart>(inst);
if (first) if (first)
min = part->position(), max = part->position(); min = part->position(), max = part->position();

View file

@ -105,7 +105,7 @@ However, Autogen cannot tell where this class came from to automatically include
block via `__AUTOGEN_EXTRA_INCLUDES__`: block via `__AUTOGEN_EXTRA_INCLUDES__`:
#ifdef __AUTOGEN_EXTRA_INCLUDES__ #ifdef __AUTOGEN_EXTRA_INCLUDES__
#include "objects/part.h" #include "objects/part/part.h"
#endif #endif
class Part; class Part;

View file

@ -59,7 +59,7 @@ void MainGLWidget::resizeGL(int w, int h) {
glm::vec2 firstPoint; glm::vec2 firstPoint;
glm::vec2 secondPoint; glm::vec2 secondPoint;
extern std::weak_ptr<Part> draggingObject; extern std::weak_ptr<BasePart> draggingObject;
extern std::optional<HandleFace> draggingHandle; extern std::optional<HandleFace> draggingHandle;
extern Shader* shader; extern Shader* shader;
void MainGLWidget::paintGL() { void MainGLWidget::paintGL() {
@ -125,7 +125,7 @@ std::vector<PartTransformState> initialTransforms;
bool tryMouseContextMenu = false; bool tryMouseContextMenu = false;
bool isMouseDragging = false; bool isMouseDragging = false;
std::weak_ptr<Part> draggingObject; std::weak_ptr<BasePart> draggingObject;
std::optional<HandleFace> draggingHandle; std::optional<HandleFace> draggingHandle;
Vector3 initialHitPos; Vector3 initialHitPos;
Vector3 initialHitNormal; Vector3 initialHitNormal;
@ -396,7 +396,7 @@ void MainGLWidget::mousePressEvent(QMouseEvent* evt) {
std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>(); std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>();
std::optional<const RaycastResult> rayHit = gWorkspace()->CastRayNearest(camera.cameraPos, pointDir, 50000); std::optional<const RaycastResult> rayHit = gWorkspace()->CastRayNearest(camera.cameraPos, pointDir, 50000);
if (!rayHit || !partFromBody(rayHit->body)) { selection->Set({}); return; } if (!rayHit || !partFromBody(rayHit->body)) { selection->Set({}); return; }
std::shared_ptr<Part> part = partFromBody(rayHit->body); std::shared_ptr<BasePart> part = partFromBody(rayHit->body);
if (part->locked) { selection->Set({}); return; } if (part->locked) { selection->Set({}); return; }
std::shared_ptr<PVInstance> selObject = part; std::shared_ptr<PVInstance> selObject = part;

View file

@ -1,7 +1,7 @@
#ifndef MAINGLWIDGET_H #ifndef MAINGLWIDGET_H
#define MAINGLWIDGET_H #define MAINGLWIDGET_H
#include "objects/part.h" #include "objects/part/part.h"
#include "qevent.h" #include "qevent.h"
#include <QOpenGLWidget> #include <QOpenGLWidget>
#include <QWidget> #include <QWidget>
@ -15,7 +15,7 @@ class MainGLWidget : public QOpenGLWidget {
public: public:
MainGLWidget(QWidget *parent = nullptr); MainGLWidget(QWidget *parent = nullptr);
void updateCycle(); void updateCycle();
std::shared_ptr<Part> lastPart; std::shared_ptr<BasePart> lastPart;
void buildContextMenu(); void buildContextMenu();
protected: protected:

View file

@ -130,7 +130,7 @@ void PlaceDocument::closeEvent(QCloseEvent *closeEvent) {
closeEvent->ignore(); closeEvent->ignore();
} }
std::shared_ptr<Part> shit; std::shared_ptr<BasePart> shit;
void PlaceDocument::timerEvent(QTimerEvent* evt) { void PlaceDocument::timerEvent(QTimerEvent* evt) {
if (evt->timerId() != timer.timerId()) { if (evt->timerId() != timer.timerId()) {
QWidget::timerEvent(evt); QWidget::timerEvent(evt);
@ -148,7 +148,7 @@ void PlaceDocument::init() {
timer.start(33, this); timer.start(33, this);
placeWidget->buildContextMenu(); placeWidget->buildContextMenu();
std::shared_ptr<Part> lastPart; std::shared_ptr<BasePart> lastPart;
// Baseplate // Baseplate
gWorkspace()->AddChild(lastPart = Part::New({ gWorkspace()->AddChild(lastPart = Part::New({
.position = glm::vec3(0, -5, 0), .position = glm::vec3(0, -5, 0),