From 219ca94ded51707a954ad2bf35e6c27783fd54bf Mon Sep 17 00:00:00 2001 From: maelstrom Date: Mon, 1 Sep 2025 20:31:49 +0200 Subject: [PATCH] feat(physics): hinges 1 --- core/src/objects/joint/rotate.cpp | 2 +- core/src/objects/joint/rotatev.cpp | 2 +- core/src/objects/part/basepart.cpp | 8 ++++---- core/src/physics/world.cpp | 24 ++++++++++++++++-------- core/src/physics/world.h | 3 +-- 5 files changed, 23 insertions(+), 16 deletions(-) diff --git a/core/src/objects/joint/rotate.cpp b/core/src/objects/joint/rotate.cpp index 566071c..2883143 100644 --- a/core/src/objects/joint/rotate.cpp +++ b/core/src/objects/joint/rotate.cpp @@ -20,7 +20,7 @@ void Rotate::buildJoint() { part1.lock()->cframe = newFrame; // Do NOT use Abs() in this scenario. For some reason that breaks it - PhysHingeJointInfo jointInfo(c0, c1); + PhysRotatingJointInfo jointInfo(c0, c1); this->joint = workspace->CreateJoint(jointInfo, part0.lock(), part1.lock()); jointWorkspace = workspace; } \ No newline at end of file diff --git a/core/src/objects/joint/rotatev.cpp b/core/src/objects/joint/rotatev.cpp index 89f4803..c049814 100644 --- a/core/src/objects/joint/rotatev.cpp +++ b/core/src/objects/joint/rotatev.cpp @@ -21,7 +21,7 @@ void RotateV::buildJoint() { CFrame newFrame = part0.lock()->cframe * (c0 * c1.Inverse()); part1.lock()->cframe = newFrame; // Do NOT use Abs() in this scenario. For some reason that breaks it - PhysMotorJointInfo jointInfo((part0.lock()->cframe * c0).Position(), -(part0.lock()->cframe * c0).LookVector().Unit()); + PhysRotatingJointInfo jointInfo(c0, c1, true); this->joint = workspace->CreateJoint(jointInfo, part0.lock(), part1.lock()); jointWorkspace = workspace; diff --git a/core/src/objects/part/basepart.cpp b/core/src/objects/part/basepart.cpp index a165fbf..5e770f2 100644 --- a/core/src/objects/part/basepart.cpp +++ b/core/src/objects/part/basepart.cpp @@ -285,10 +285,10 @@ void BasePart::MakeJoints() { joint->part1 = otherPart->shared(); joint->c0 = contact0; joint->c1 = contact1; - // If both parts touch directly, this can cause friction in Rotate and RotateV joints, so we leave a little extra space - if (joint->IsA("Rotate") || joint->IsA("RotateV")) - joint->c1 = joint->c1 + joint->c1.LookVector() * 0.02f, - joint->c0 = joint->c0 - joint->c0.LookVector() * 0.02f; + // // If both parts touch directly, this can cause friction in Rotate and RotateV joints, so we leave a little extra space + // if (joint->IsA("Rotate") || joint->IsA("RotateV")) + // joint->c1 = joint->c1 + joint->c1.LookVector() * 0.02f, + // joint->c0 = joint->c0 - joint->c0.LookVector() * 0.02f; dataModel()->GetService()->AddChild(joint); joint->UpdateProperty("Part0"); } diff --git a/core/src/physics/world.cpp b/core/src/physics/world.cpp index aae64da..88291d2 100644 --- a/core/src/physics/world.cpp +++ b/core/src/physics/world.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -37,6 +36,7 @@ #include #include #include +#include #include static JPH::TempAllocator* allocator; @@ -217,15 +217,23 @@ PhysJoint PhysWorld::createJoint(PhysJointInfo& type, std::shared_ptr settings.mAxisX2 = convert(info->c1.RightVector()); settings.mAxisY2 = convert(info->c1.UpVector()); constraint = settings.Create(*part0->rigidBody.bodyImpl, *part1->rigidBody.bodyImpl); - } else if (PhysHingeJointInfo* info = dynamic_cast(&type)) { - JPH::ConeConstraintSettings settings; + } else if (PhysRotatingJointInfo* info = dynamic_cast(&type)) { + JPH::SixDOFConstraintSettings settings; settings.mSpace = JPH::EConstraintSpace::LocalToBodyCOM; - settings.mPoint1 = convert(info->c0.Position()); - settings.mTwistAxis1 = convert(info->c0.LookVector()); - settings.mPoint2 = convert(info->c1.Position()); - settings.mTwistAxis2 = convert(info->c1.LookVector()); - settings.mHalfConeAngle = 0.0f; + settings.mPosition1 = convert(info->c0.Position()); + settings.mAxisX1 = convert(info->c0.RightVector()); + settings.mAxisY1 = convert(info->c0.UpVector()); + settings.mPosition2 = convert(info->c1.Position()); + settings.mAxisX2 = convert(info->c1.RightVector()); + settings.mAxisY2 = convert(info->c1.UpVector()); + settings.MakeFixedAxis(JPH::SixDOFConstraintSettings::RotationX); + settings.MakeFixedAxis(JPH::SixDOFConstraintSettings::RotationY); + settings.MakeFixedAxis(JPH::SixDOFConstraintSettings::TranslationX); + settings.MakeFixedAxis(JPH::SixDOFConstraintSettings::TranslationY); + settings.MakeFixedAxis(JPH::SixDOFConstraintSettings::TranslationZ); + settings.mMotorSettings[JPH::SixDOFConstraintSettings::EAxis::RotationZ] = JPH::MotorSettings(5.f, 0.f); constraint = settings.Create(*part0->rigidBody.bodyImpl, *part1->rigidBody.bodyImpl); + // static_cast(constraint)->SetMotorState(JPH::SixDOFConstraintSettings::EAxis::RotationZ, JPH::EMotorState::Velocity); } else { panic(); } diff --git a/core/src/physics/world.h b/core/src/physics/world.h index 1bc07d6..231457f 100644 --- a/core/src/physics/world.h +++ b/core/src/physics/world.h @@ -18,8 +18,7 @@ class PhysWorld; struct PhysJointInfo { virtual ~PhysJointInfo() = default; protected: PhysJointInfo() = default; }; struct PhysFixedJointInfo : PhysJointInfo { CFrame c0; CFrame c1; inline PhysFixedJointInfo(CFrame c0, CFrame c1) : c0(c0), c1(c1) {} }; -struct PhysHingeJointInfo : PhysJointInfo { CFrame c0; CFrame c1; inline PhysHingeJointInfo(CFrame c0, CFrame c1) : c0(c0), c1(c1) {} }; -struct PhysMotorJointInfo : PhysJointInfo { Vector3 anchorPoint; Vector3 rotationAxis; inline PhysMotorJointInfo(Vector3 anchorPoint, Vector3 rotationAxis) : anchorPoint(anchorPoint), rotationAxis(rotationAxis) {} }; +struct PhysRotatingJointInfo : PhysJointInfo { CFrame c0; CFrame c1; bool motorized; inline PhysRotatingJointInfo(CFrame c0, CFrame c1, bool motorized = false) : c0(c0), c1(c1), motorized(motorized) {} }; class PhysWorld; struct PhysJoint {