From df6e2ac98dbaafa98fee66ee118e1b1e41b35662 Mon Sep 17 00:00:00 2001 From: maelstrom Date: Wed, 30 Apr 2025 17:20:04 +0200 Subject: [PATCH] fix(part): hinge joint only made if other part intersects the hinge --- core/src/objects/joint/rotate.cpp | 2 +- core/src/objects/part.cpp | 8 +++++--- core/src/objects/part.h | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/core/src/objects/joint/rotate.cpp b/core/src/objects/joint/rotate.cpp index 10b7ce3..c0c5c89 100644 --- a/core/src/objects/joint/rotate.cpp +++ b/core/src/objects/joint/rotate.cpp @@ -28,7 +28,7 @@ void Rotate::buildJoint() { part1.lock()->cframe = newFrame; workspace->SyncPartPhysics(part1.lock()); // Do NOT use Abs() in this scenario. For some reason that breaks it - rp::HingeJointInfo jointInfo(part0.lock()->rigidBody, part1.lock()->rigidBody, newFrame.Position(), -(part0.lock()->cframe * c0).LookVector().Unit()); + rp::HingeJointInfo jointInfo(part0.lock()->rigidBody, part1.lock()->rigidBody, (part0.lock()->cframe * c0).Position(), -(part0.lock()->cframe * c0).LookVector().Unit()); this->joint = dynamic_cast(workspace->physicsWorld->createJoint(jointInfo)); jointWorkspace = workspace; diff --git a/core/src/objects/part.cpp b/core/src/objects/part.cpp index 3c952a4..21538d6 100644 --- a/core/src/objects/part.cpp +++ b/core/src/objects/part.cpp @@ -183,8 +183,7 @@ 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(); +bool Part::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)); @@ -251,12 +250,15 @@ 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 (!checkSurfacesTouching(surfaceFrame, size, myFace, otherFace, otherPart)) continue; // Surface do not overlap if (!checkJointContinuity(otherPart)) continue; SurfaceType mySurface = surfaceFromFace(faceFromNormal(myFace)); SurfaceType otherSurface = surfaceFromFace(faceFromNormal(otherFace)); + // If it is a hinge, only attach if actually touching the "hinge" + if (mySurface == SurfaceHinge && !checkSurfacesTouching(surfaceFrame, Vector3(0.4, 0.4, 0.4), myFace, otherFace, otherPart)) continue; + // Create contacts // Contact always occurs at the center of Part0's surface (even if that point does not overlap both surfaces) // Contact 0 is Part0's contact relative to Part0. It should point *opposite* the direction of its surface normal diff --git a/core/src/objects/part.h b/core/src/objects/part.h index e885033..cd7bf3c 100644 --- a/core/src/objects/part.h +++ b/core/src/objects/part.h @@ -43,7 +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); + bool checkSurfacesTouching(CFrame surfaceFrame, Vector3 size, Vector3 myFace, Vector3 otherFace, std::shared_ptr otherPart); friend JointInstance;