From d100932a9ef6f07cd909a70350a06add10557711 Mon Sep 17 00:00:00 2001 From: maelstrom Date: Wed, 30 Apr 2025 16:45:46 +0200 Subject: [PATCH] fix(part): non-touching parts whos surfaces are on the same plane were joining --- core/src/datatypes/vector.cpp | 8 ++++++++ core/src/datatypes/vector.h | 3 +++ core/src/objects/part.cpp | 27 +++++++++++++++++++++++++++ core/src/objects/part.h | 1 + 4 files changed, 39 insertions(+) diff --git a/core/src/datatypes/vector.cpp b/core/src/datatypes/vector.cpp index 44e4193..119d1fe 100644 --- a/core/src/datatypes/vector.cpp +++ b/core/src/datatypes/vector.cpp @@ -62,6 +62,14 @@ bool Data::Vector3::operator ==(Data::Vector3 other) const { return this->X() == other.X() && this->Y() == other.Y() && this->Z() == other.Z(); } +bool Data::Vector3::operator <(Data::Vector3 other) const { + return X() < other.X() && Y() < other.Y() && Z() < other.Z(); +} + +bool Data::Vector3::operator >(Data::Vector3 other) const { + return X() > other.X() && Y() > other.Y() && Z() > other.Z(); +} + Data::Vector3 Data::Vector3::Cross(Data::Vector3 other) const { return glm::cross(this->vector, other.vector); } diff --git a/core/src/datatypes/vector.h b/core/src/datatypes/vector.h index 100966f..3442bc1 100644 --- a/core/src/datatypes/vector.h +++ b/core/src/datatypes/vector.h @@ -52,6 +52,9 @@ namespace Data { Data::Vector3 operator -(Data::Vector3) const; Data::Vector3 operator -() const; + bool operator <(Data::Vector3) const; + bool operator >(Data::Vector3) const; + bool operator ==(Data::Vector3) const; }; } diff --git a/core/src/objects/part.cpp b/core/src/objects/part.cpp index 61e4e7a..3c952a4 100644 --- a/core/src/objects/part.cpp +++ b/core/src/objects/part.cpp @@ -13,6 +13,8 @@ #include "objects/joint/snap.h" #include "rendering/renderer.h" #include "rendering/surface.h" +#include +#include #include #include @@ -181,6 +183,30 @@ bool Part::checkJointContinuityUp(std::shared_ptr otherPart) { return true; } +bool Part::checkSurfacesTouching(CFrame surfaceFrame, Vector3 myFace, Vector3 otherFace, std::shared_ptr otherPart) { + // Vector3 otherPartCenterToMine = surfaceFrame.Inverse() * otherPart->cframe.Position(); + 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 myFarCorner0 = Vector3::ONE * (size / 2.f); + Vector3 myFarCorner1 = -Vector3::ONE * (size / 2.f); + + // https://stackoverflow.com/a/306332/16255372 + float myTop = glm::max(myFarCorner0.X(), myFarCorner1.X()); + float myBot = glm::min(myFarCorner0.X(), myFarCorner1.X()); + float myRight = glm::max(myFarCorner0.Y(), myFarCorner1.Y()); + float myLeft = glm::min(myFarCorner0.Y(), myFarCorner1.Y()); + float otherTop = glm::max(farCorner0.X(), farCorner1.X()); + float otherBot = glm::min(farCorner0.X(), farCorner1.X()); + float otherRight = glm::max(farCorner0.Y(), farCorner1.Y()); + float otherLeft = glm::min(farCorner0.Y(), farCorner1.Y()); + + bool horizOverlap = myLeft < otherRight && myRight > otherLeft; + bool vertOverlap = myBot < otherTop && myTop > otherBot; + + return horizOverlap && vertOverlap; +} + std::optional> makeJointFromSurfaces(SurfaceType a, SurfaceType b) { if (a == SurfaceWeld || b == SurfaceWeld || a == SurfaceGlue || b == SurfaceGlue) return Weld::New(); if ((a == SurfaceStuds && (b == SurfaceInlets || b == SurfaceUniversal)) @@ -225,6 +251,7 @@ void Part::MakeJoints() { if (dot > -0.99) continue; // Surface is pointing opposite to ours if (abs(surfacePointLocalToMyFrame.Z()) > 0.05) continue; // Surfaces are within 0.05 studs of one another + if (!checkSurfacesTouching(surfaceFrame, myFace, otherFace, otherPart)) continue; // Surface do not overlap if (!checkJointContinuity(otherPart)) continue; SurfaceType mySurface = surfaceFromFace(faceFromNormal(myFace)); diff --git a/core/src/objects/part.h b/core/src/objects/part.h index 5cc1769..7a01762 100644 --- a/core/src/objects/part.h +++ b/core/src/objects/part.h @@ -43,6 +43,7 @@ protected: bool checkJointContinuity(std::shared_ptr); bool checkJointContinuityUp(std::shared_ptr); bool checkJointContinuityDown(std::shared_ptr); + bool checkSurfacesTouching(CFrame surfaceFrame, Vector3 myFace, Vector3 otherFace, std::shared_ptr otherPart); friend JointInstance;