Path: blob/master/modules/jolt_physics/joints/jolt_joint_3d.cpp
10278 views
/**************************************************************************/1/* jolt_joint_3d.cpp */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#include "jolt_joint_3d.h"3132#include "../jolt_project_settings.h"33#include "../misc/jolt_type_conversions.h"34#include "../objects/jolt_body_3d.h"35#include "../spaces/jolt_space_3d.h"3637namespace {3839constexpr int JOINT_DEFAULT_SOLVER_PRIORITY = 1;4041} // namespace4243void JoltJoint3D::_shift_reference_frames(const Vector3 &p_linear_shift, const Vector3 &p_angular_shift, Transform3D &r_shifted_ref_a, Transform3D &r_shifted_ref_b) {44Vector3 origin_a = local_ref_a.origin;45Vector3 origin_b = local_ref_b.origin;4647if (body_a != nullptr) {48origin_a *= body_a->get_scale();49origin_a -= to_godot(body_a->get_jolt_shape()->GetCenterOfMass());50}5152if (body_b != nullptr) {53origin_b *= body_b->get_scale();54origin_b -= to_godot(body_b->get_jolt_shape()->GetCenterOfMass());55}5657const Basis &basis_a = local_ref_a.basis;58const Basis &basis_b = local_ref_b.basis;5960const Basis shifted_basis_a = basis_a * Basis::from_euler(p_angular_shift, EulerOrder::ZYX);61const Vector3 shifted_origin_a = origin_a - basis_a.xform(p_linear_shift);6263r_shifted_ref_a = Transform3D(shifted_basis_a, shifted_origin_a);64r_shifted_ref_b = Transform3D(basis_b, origin_b);65}6667void JoltJoint3D::_wake_up_bodies() {68if (body_a != nullptr) {69body_a->wake_up();70}7172if (body_b != nullptr) {73body_b->wake_up();74}75}7677void JoltJoint3D::_update_enabled() {78if (jolt_ref != nullptr) {79jolt_ref->SetEnabled(enabled);80}81}8283void JoltJoint3D::_update_iterations() {84if (jolt_ref != nullptr) {85jolt_ref->SetNumVelocityStepsOverride((JPH::uint)velocity_iterations);86jolt_ref->SetNumPositionStepsOverride((JPH::uint)position_iterations);87}88}8990void JoltJoint3D::_enabled_changed() {91_update_enabled();92_wake_up_bodies();93}9495void JoltJoint3D::_iterations_changed() {96_update_iterations();97_wake_up_bodies();98}99100String JoltJoint3D::_bodies_to_string() const {101return vformat("'%s' and '%s'", body_a != nullptr ? body_a->to_string() : "<unknown>", body_b != nullptr ? body_b->to_string() : "<World>");102}103104JoltJoint3D::JoltJoint3D(const JoltJoint3D &p_old_joint, JoltBody3D *p_body_a, JoltBody3D *p_body_b, const Transform3D &p_local_ref_a, const Transform3D &p_local_ref_b) :105enabled(p_old_joint.enabled),106collision_disabled(p_old_joint.collision_disabled),107body_a(p_body_a),108body_b(p_body_b),109rid(p_old_joint.rid),110local_ref_a(p_local_ref_a),111local_ref_b(p_local_ref_b) {112if (body_a != nullptr) {113body_a->add_joint(this);114}115116if (body_b != nullptr) {117body_b->add_joint(this);118}119120if (body_b == nullptr && JoltProjectSettings::joint_world_node == JOLT_JOINT_WORLD_NODE_A) {121// The joint scene nodes will, when omitting one of the two body nodes, always pass in a122// null `body_b` to indicate it being the "world node", regardless of which body node you123// leave blank. So we need to correct for that if we wish to use the arguably more intuitive124// alternative where `body_a` is the "world node" instead.125126SWAP(body_a, body_b);127SWAP(local_ref_a, local_ref_b);128}129}130131JoltJoint3D::~JoltJoint3D() {132if (body_a != nullptr) {133body_a->remove_joint(this);134}135136if (body_b != nullptr) {137body_b->remove_joint(this);138}139140destroy();141}142143JoltSpace3D *JoltJoint3D::get_space() const {144if (body_a != nullptr && body_b != nullptr) {145JoltSpace3D *space_a = body_a->get_space();146JoltSpace3D *space_b = body_b->get_space();147148if (space_a == nullptr || space_b == nullptr) {149return nullptr;150}151152ERR_FAIL_COND_V_MSG(space_a != space_b, nullptr, vformat("Joint was found to connect bodies in different physics spaces. This joint will effectively be disabled. This joint connects %s.", _bodies_to_string()));153154return space_a;155} else if (body_a != nullptr) {156return body_a->get_space();157} else if (body_b != nullptr) {158return body_b->get_space();159}160161return nullptr;162}163164void JoltJoint3D::set_enabled(bool p_enabled) {165if (enabled == p_enabled) {166return;167}168169enabled = p_enabled;170171_enabled_changed();172}173174int JoltJoint3D::get_solver_priority() const {175return JOINT_DEFAULT_SOLVER_PRIORITY;176}177178void JoltJoint3D::set_solver_priority(int p_priority) {179if (p_priority != JOINT_DEFAULT_SOLVER_PRIORITY) {180WARN_PRINT(vformat("Joint solver priority is not supported when using Jolt Physics. Any such value will be ignored. This joint connects %s.", _bodies_to_string()));181}182}183184void JoltJoint3D::set_solver_velocity_iterations(int p_iterations) {185if (velocity_iterations == p_iterations) {186return;187}188189velocity_iterations = p_iterations;190191_iterations_changed();192}193194void JoltJoint3D::set_solver_position_iterations(int p_iterations) {195if (position_iterations == p_iterations) {196return;197}198199position_iterations = p_iterations;200201_iterations_changed();202}203204void JoltJoint3D::set_collision_disabled(bool p_disabled) {205collision_disabled = p_disabled;206207if (body_a == nullptr || body_b == nullptr) {208return;209}210211PhysicsServer3D *physics_server = PhysicsServer3D::get_singleton();212213if (collision_disabled) {214physics_server->body_add_collision_exception(body_a->get_rid(), body_b->get_rid());215physics_server->body_add_collision_exception(body_b->get_rid(), body_a->get_rid());216} else {217physics_server->body_remove_collision_exception(body_a->get_rid(), body_b->get_rid());218physics_server->body_remove_collision_exception(body_b->get_rid(), body_a->get_rid());219}220}221222void JoltJoint3D::destroy() {223if (jolt_ref == nullptr) {224return;225}226227JoltSpace3D *space = get_space();228229if (space != nullptr) {230space->remove_joint(this);231}232233jolt_ref = nullptr;234}235236237