Skip to content

Commit

Permalink
Add support for Jolts FixedConstraint joint
Browse files Browse the repository at this point in the history
  • Loading branch information
BastiaanOlij committed Jan 15, 2025
1 parent 4ce466d commit 5d383ee
Show file tree
Hide file tree
Showing 16 changed files with 349 additions and 1 deletion.
12 changes: 12 additions & 0 deletions doc/classes/FixedJoint3D.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="FixedJoint3D" inherits="Joint3D" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
A physics joint that attaches two 3D physics bodies at a single point, with no allowed movement between the two bodies.
</brief_description>
<description>
A physics joint that attaches two 3D physics bodies at a single point, with no allowed movement between the two bodies.
[b]Note:[/b] This joint is only implemented for the Jolt Physics Engine.
</description>
<tutorials>
</tutorials>
</class>
16 changes: 15 additions & 1 deletion doc/classes/PhysicsServer3D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -886,6 +886,17 @@
<description>
</description>
</method>
<method name="joint_make_fixed">
<return type="void" />
<param index="0" name="joint" type="RID" />
<param index="1" name="body_A" type="RID" />
<param index="2" name="local_A" type="Vector3" />
<param index="3" name="body_B" type="RID" />
<param index="4" name="local_B" type="Vector3" />
<description>
Make the joint a fixed joint.
</description>
</method>
<method name="joint_make_generic_6dof">
<return type="void" />
<param index="0" name="joint" type="RID" />
Expand Down Expand Up @@ -1380,7 +1391,10 @@
<constant name="JOINT_TYPE_6DOF" value="4" enum="JointType">
The [Joint3D] is a [Generic6DOFJoint3D].
</constant>
<constant name="JOINT_TYPE_MAX" value="5" enum="JointType">
<constant name="JOINT_TYPE_FIXED" value="5" enum="JointType">
The [Joint3D] is a [FixedJoint3D].
</constant>
<constant name="JOINT_TYPE_MAX" value="6" enum="JointType">
Represents the size of the [enum JointType] enum.
</constant>
<constant name="PIN_JOINT_BIAS" value="0" enum="PinJointParam">
Expand Down
4 changes: 4 additions & 0 deletions modules/godot_physics_3d/godot_physics_server_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1220,6 +1220,10 @@ void GodotPhysicsServer3D::joint_clear(RID p_joint) {
}
}

void GodotPhysicsServer3D::joint_make_fixed(RID p_joint, RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) {
ERR_FAIL_MSG("Fixed joint constraints are not supported in Godot Physics");
}

void GodotPhysicsServer3D::joint_make_pin(RID p_joint, RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) {
GodotBody3D *body_A = body_owner.get_or_null(p_body_A);
ERR_FAIL_NULL(body_A);
Expand Down
2 changes: 2 additions & 0 deletions modules/godot_physics_3d/godot_physics_server_3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,8 @@ class GodotPhysicsServer3D : public PhysicsServer3D {

virtual void joint_clear(RID p_joint) override; //resets type

virtual void joint_make_fixed(RID p_joint, RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) override;

virtual void joint_make_pin(RID p_joint, RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) override;

virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) override;
Expand Down
121 changes: 121 additions & 0 deletions modules/jolt_physics/joints/jolt_fixed_joint_3d.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/**************************************************************************/
/* jolt_pin_joint_3d.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/

#include "jolt_fixed_joint_3d.h"

#include "../misc/jolt_type_conversions.h"
#include "../objects/jolt_body_3d.h"
#include "../spaces/jolt_space_3d.h"

#include "Jolt/Physics/Constraints/FixedConstraint.h"

JPH::Constraint *JoltFixedJoint3D::_build_fixed(JPH::Body *p_jolt_body_a, JPH::Body *p_jolt_body_b, const Transform3D &p_shifted_ref_a, const Transform3D &p_shifted_ref_b) {
JPH::FixedConstraintSettings constraint_settings;
constraint_settings.mSpace = JPH::EConstraintSpace::LocalToBodyCOM;
constraint_settings.mPoint1 = to_jolt_r(p_shifted_ref_a.origin);
constraint_settings.mPoint2 = to_jolt_r(p_shifted_ref_b.origin);

if (p_jolt_body_a == nullptr) {
return constraint_settings.Create(JPH::Body::sFixedToWorld, *p_jolt_body_b);
} else if (p_jolt_body_b == nullptr) {
return constraint_settings.Create(*p_jolt_body_a, JPH::Body::sFixedToWorld);
} else {
return constraint_settings.Create(*p_jolt_body_a, *p_jolt_body_b);
}
}

void JoltFixedJoint3D::_points_changed() {
rebuild();
_wake_up_bodies();
}

JoltFixedJoint3D::JoltFixedJoint3D(const JoltJoint3D &p_old_joint, JoltBody3D *p_body_a, JoltBody3D *p_body_b, const Vector3 &p_local_a, const Vector3 &p_local_b) :
JoltJoint3D(p_old_joint, p_body_a, p_body_b, Transform3D({}, p_local_a), Transform3D({}, p_local_b)) {
rebuild();
}

void JoltFixedJoint3D::set_local_a(const Vector3 &p_local_a) {
local_ref_a = Transform3D({}, p_local_a);
_points_changed();
}

void JoltFixedJoint3D::set_local_b(const Vector3 &p_local_b) {
local_ref_b = Transform3D({}, p_local_b);
_points_changed();
}

float JoltFixedJoint3D::get_applied_force() const {
JPH::FixedConstraint *constraint = static_cast<JPH::FixedConstraint *>(jolt_ref.GetPtr());
ERR_FAIL_NULL_V(constraint, 0.0f);

JoltSpace3D *space = get_space();
ERR_FAIL_NULL_V(space, 0.0f);

const float last_step = space->get_last_step();
if (unlikely(last_step == 0.0f)) {
return 0.0f;
}

return constraint->GetTotalLambdaPosition().Length() / last_step;
}

void JoltFixedJoint3D::rebuild() {
destroy();

JoltSpace3D *space = get_space();

if (space == nullptr) {
return;
}

const JPH::BodyID body_ids[2] = {
body_a != nullptr ? body_a->get_jolt_id() : JPH::BodyID(),
body_b != nullptr ? body_b->get_jolt_id() : JPH::BodyID()
};

const JoltWritableBodies3D jolt_bodies = space->write_bodies(body_ids, 2);

JPH::Body *jolt_body_a = static_cast<JPH::Body *>(jolt_bodies[0]);
JPH::Body *jolt_body_b = static_cast<JPH::Body *>(jolt_bodies[1]);

ERR_FAIL_COND(jolt_body_a == nullptr && jolt_body_b == nullptr);

Transform3D shifted_ref_a;
Transform3D shifted_ref_b;

_shift_reference_frames(Vector3(), Vector3(), shifted_ref_a, shifted_ref_b);

jolt_ref = _build_fixed(jolt_body_a, jolt_body_b, shifted_ref_a, shifted_ref_b);

space->add_joint(this);

_update_enabled();
_update_iterations();
}
61 changes: 61 additions & 0 deletions modules/jolt_physics/joints/jolt_fixed_joint_3d.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**************************************************************************/
/* jolt_fixed_joint_3d.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/

#ifndef JOLT_FIXED_JOINT_3D_H
#define JOLT_FIXED_JOINT_3D_H

#include "jolt_joint_3d.h"

#include "Jolt/Jolt.h"

#include "Jolt/Physics/Constraints/FixedConstraint.h"

class JoltFixedJoint3D final : public JoltJoint3D {
static JPH::Constraint *_build_fixed(JPH::Body *p_jolt_body_a, JPH::Body *p_jolt_body_b, const Transform3D &p_shifted_ref_a, const Transform3D &p_shifted_ref_b);

void _points_changed();

public:
JoltFixedJoint3D(const JoltJoint3D &p_old_joint, JoltBody3D *p_body_a, JoltBody3D *p_body_b, const Vector3 &p_local_a, const Vector3 &p_local_b);

virtual PhysicsServer3D::JointType get_type() const override { return PhysicsServer3D::JOINT_TYPE_FIXED; }

Vector3 get_local_a() const { return local_ref_a.origin; }
void set_local_a(const Vector3 &p_local_a);

Vector3 get_local_b() const { return local_ref_b.origin; }
void set_local_b(const Vector3 &p_local_b);

float get_applied_force() const;

virtual void rebuild() override;
};

#endif // JOLT_FIXED_JOINT_3D_H
19 changes: 19 additions & 0 deletions modules/jolt_physics/jolt_physics_server_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "jolt_physics_server_3d.h"

#include "joints/jolt_cone_twist_joint_3d.h"
#include "joints/jolt_fixed_joint_3d.h"
#include "joints/jolt_generic_6dof_joint_3d.h"
#include "joints/jolt_hinge_joint_3d.h"
#include "joints/jolt_joint_3d.h"
Expand Down Expand Up @@ -1229,6 +1230,24 @@ void JoltPhysicsServer3D::joint_clear(RID p_joint) {
}
}

void JoltPhysicsServer3D::joint_make_fixed(RID p_joint, RID p_body_a, const Vector3 &p_local_a, RID p_body_b, const Vector3 &p_local_b) {
JoltJoint3D *old_joint = joint_owner.get_or_null(p_joint);
ERR_FAIL_NULL(old_joint);

JoltBody3D *body_a = body_owner.get_or_null(p_body_a);
ERR_FAIL_NULL(body_a);

JoltBody3D *body_b = body_owner.get_or_null(p_body_b);
ERR_FAIL_COND(body_a == body_b);

JoltJoint3D *new_joint = memnew(JoltFixedJoint3D(*old_joint, body_a, body_b, p_local_a, p_local_b));

memdelete(old_joint);
old_joint = nullptr;

joint_owner.replace(p_joint, new_joint);
}

void JoltPhysicsServer3D::joint_make_pin(RID p_joint, RID p_body_a, const Vector3 &p_local_a, RID p_body_b, const Vector3 &p_local_b) {
JoltJoint3D *old_joint = joint_owner.get_or_null(p_joint);
ERR_FAIL_NULL(old_joint);
Expand Down
2 changes: 2 additions & 0 deletions modules/jolt_physics/jolt_physics_server_3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,8 @@ class JoltPhysicsServer3D final : public PhysicsServer3D {
virtual RID joint_create() override;
virtual void joint_clear(RID p_joint) override;

virtual void joint_make_fixed(RID p_joint, RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) override;

virtual void joint_make_pin(RID p_joint, RID p_body_a, const Vector3 &p_local_a, RID p_body_b, const Vector3 &p_local_b) override;

virtual void pin_joint_set_param(RID p_joint, PhysicsServer3D::PinJointParam p_param, real_t p_value) override;
Expand Down
51 changes: 51 additions & 0 deletions scene/3d/physics/joints/fixed_joint_3d.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**************************************************************************/
/* fixed_joint_3d.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/

#include "fixed_joint_3d.h"

void FixedJoint3D::_bind_methods() {
}

void FixedJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
Vector3 fixedpos = get_global_transform().origin;
Vector3 local_a = body_a->to_local(fixedpos);
Vector3 local_b;

if (body_b) {
local_b = body_b->to_local(fixedpos);
} else {
local_b = fixedpos;
}

PhysicsServer3D::get_singleton()->joint_make_fixed(p_joint, body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b);
}

FixedJoint3D::FixedJoint3D() {
}
48 changes: 48 additions & 0 deletions scene/3d/physics/joints/fixed_joint_3d.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**************************************************************************/
/* fixed_joint_3d.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/

#ifndef FIXED_JOINT_3D_H
#define FIXED_JOINT_3D_H

#include "scene/3d/physics/joints/joint_3d.h"

class FixedJoint3D : public Joint3D {
GDCLASS(FixedJoint3D, Joint3D);

public:
protected:
virtual void _configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) override;
static void _bind_methods();

public:
FixedJoint3D();
};

#endif // FIXED_JOINT_3D_H
Loading

0 comments on commit 5d383ee

Please sign in to comment.