diff --git a/core/src/objects/joint/rotate.cpp b/core/src/objects/joint/rotate.cpp index 9ab6d72..566071c 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 - PhysJointHingeInfo jointInfo((part0.lock()->cframe * c0).Position(), -(part0.lock()->cframe * c0).LookVector().Unit()); + PhysHingeJointInfo 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 82d2699..89f4803 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 - PhysJointMotorInfo jointInfo((part0.lock()->cframe * c0).Position(), -(part0.lock()->cframe * c0).LookVector().Unit()); + PhysMotorJointInfo jointInfo((part0.lock()->cframe * c0).Position(), -(part0.lock()->cframe * c0).LookVector().Unit()); this->joint = workspace->CreateJoint(jointInfo, part0.lock(), part1.lock()); jointWorkspace = workspace; diff --git a/core/src/objects/joint/snap.cpp b/core/src/objects/joint/snap.cpp index 2b4b777..cc6ada8 100644 --- a/core/src/objects/joint/snap.cpp +++ b/core/src/objects/joint/snap.cpp @@ -23,7 +23,7 @@ void Snap::buildJoint() { CFrame newFrame = part0.lock()->cframe * (c0 * c1.Inverse()); part1.lock()->cframe = newFrame; - PhysJointSnapInfo jointInfo((c0.Inverse() * c1).Position()); + PhysFixedJointInfo 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/weld.cpp b/core/src/objects/joint/weld.cpp index 49875e7..4fb3d56 100644 --- a/core/src/objects/joint/weld.cpp +++ b/core/src/objects/joint/weld.cpp @@ -23,7 +23,7 @@ void Weld::buildJoint() { CFrame newFrame = part0.lock()->cframe * (c0 * c1.Inverse()); part1.lock()->cframe = newFrame; - PhysJointWeldInfo jointInfo((c0.Inverse() * c1).Position()); + PhysFixedJointInfo 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/part/basepart.cpp b/core/src/objects/part/basepart.cpp index 84a3bb7..a165fbf 100644 --- a/core/src/objects/part/basepart.cpp +++ b/core/src/objects/part/basepart.cpp @@ -285,6 +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; dataModel()->GetService()->AddChild(joint); joint->UpdateProperty("Part0"); } diff --git a/core/src/physics/world.cpp b/core/src/physics/world.cpp index 439d033..aae64da 100644 --- a/core/src/physics/world.cpp +++ b/core/src/physics/world.cpp @@ -1,5 +1,4 @@ #include "world.h" -#include "Jolt/Geometry/AABox.h" #include "datatypes/vector.h" #include "enum/part.h" #include "logger.h" @@ -27,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -37,7 +37,6 @@ #include #include #include -#include #include static JPH::TempAllocator* allocator; @@ -208,17 +207,24 @@ PhysJoint PhysWorld::createJoint(PhysJointInfo& type, std::shared_ptr ) { Logger::fatalError("Failed to create joint between two parts due to the call being invalid"); panic(); }; JPH::TwoBodyConstraint* constraint; - if (PhysJointGlueInfo* _ = dynamic_cast(&type)) { + if (PhysFixedJointInfo* info = dynamic_cast(&type)) { JPH::FixedConstraintSettings settings; - settings.mAutoDetectPoint = true; // TODO: Replace this with anchor point + settings.mSpace = JPH::EConstraintSpace::LocalToBodyCOM; + settings.mPoint1 = convert(info->c0.Position()); + settings.mAxisX1 = convert(info->c0.RightVector()); + settings.mAxisY1 = convert(info->c0.UpVector()); + settings.mPoint2 = convert(info->c1.Position()); + settings.mAxisX2 = convert(info->c1.RightVector()); + settings.mAxisY2 = convert(info->c1.UpVector()); constraint = settings.Create(*part0->rigidBody.bodyImpl, *part1->rigidBody.bodyImpl); - } else if (PhysJointWeldInfo* _ = dynamic_cast(&type)) { - JPH::FixedConstraintSettings settings; - settings.mAutoDetectPoint = true; // TODO: Replace this with anchor point - constraint = settings.Create(*part0->rigidBody.bodyImpl, *part1->rigidBody.bodyImpl); - } else if (PhysJointSnapInfo* _ = dynamic_cast(&type)) { - JPH::FixedConstraintSettings settings; - settings.mAutoDetectPoint = true; // TODO: Replace this with anchor point + } else if (PhysHingeJointInfo* info = dynamic_cast(&type)) { + JPH::ConeConstraintSettings 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; constraint = settings.Create(*part0->rigidBody.bodyImpl, *part1->rigidBody.bodyImpl); } else { panic(); diff --git a/core/src/physics/world.h b/core/src/physics/world.h index cdbdde1..1bc07d6 100644 --- a/core/src/physics/world.h +++ b/core/src/physics/world.h @@ -1,5 +1,6 @@ #pragma once +#include "datatypes/cframe.h" #include "datatypes/vector.h" #include "enum/part.h" #include "utils.h" @@ -16,11 +17,9 @@ class BasePart; class PhysWorld; struct PhysJointInfo { virtual ~PhysJointInfo() = default; protected: PhysJointInfo() = default; }; -struct PhysJointGlueInfo : PhysJointInfo { Vector3 anchorPoint; inline PhysJointGlueInfo(Vector3 anchorPoint) : anchorPoint(anchorPoint) {} }; -struct PhysJointWeldInfo : PhysJointInfo { Vector3 anchorPoint; inline PhysJointWeldInfo(Vector3 anchorPoint) : anchorPoint(anchorPoint) {} }; -struct PhysJointSnapInfo : PhysJointInfo { Vector3 anchorPoint; inline PhysJointSnapInfo(Vector3 anchorPoint) : anchorPoint(anchorPoint) {} }; -struct PhysJointHingeInfo : PhysJointInfo { Vector3 anchorPoint; Vector3 rotationAxis; inline PhysJointHingeInfo(Vector3 anchorPoint, Vector3 rotationAxis) : anchorPoint(anchorPoint), rotationAxis(rotationAxis) {} }; -struct PhysJointMotorInfo : PhysJointInfo { Vector3 anchorPoint; Vector3 rotationAxis; inline PhysJointMotorInfo(Vector3 anchorPoint, Vector3 rotationAxis) : anchorPoint(anchorPoint), rotationAxis(rotationAxis) {} }; +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) {} }; class PhysWorld; struct PhysJoint {