Path: blob/master/modules/godot_physics_3d/godot_physics_server_3d.cpp
10277 views
/**************************************************************************/1/* godot_physics_server_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 "godot_physics_server_3d.h"3132#include "godot_body_direct_state_3d.h"33#include "godot_broad_phase_3d_bvh.h"34#include "joints/godot_cone_twist_joint_3d.h"35#include "joints/godot_generic_6dof_joint_3d.h"36#include "joints/godot_hinge_joint_3d.h"37#include "joints/godot_pin_joint_3d.h"38#include "joints/godot_slider_joint_3d.h"3940#include "core/debugger/engine_debugger.h"41#include "core/os/os.h"4243#define FLUSH_QUERY_CHECK(m_object) \44ERR_FAIL_COND_MSG(m_object->get_space() && flushing_queries, "Can't change this state while flushing queries. Use call_deferred() or set_deferred() to change monitoring state instead.");4546RID GodotPhysicsServer3D::world_boundary_shape_create() {47GodotShape3D *shape = memnew(GodotWorldBoundaryShape3D);48RID rid = shape_owner.make_rid(shape);49shape->set_self(rid);50return rid;51}52RID GodotPhysicsServer3D::separation_ray_shape_create() {53GodotShape3D *shape = memnew(GodotSeparationRayShape3D);54RID rid = shape_owner.make_rid(shape);55shape->set_self(rid);56return rid;57}58RID GodotPhysicsServer3D::sphere_shape_create() {59GodotShape3D *shape = memnew(GodotSphereShape3D);60RID rid = shape_owner.make_rid(shape);61shape->set_self(rid);62return rid;63}64RID GodotPhysicsServer3D::box_shape_create() {65GodotShape3D *shape = memnew(GodotBoxShape3D);66RID rid = shape_owner.make_rid(shape);67shape->set_self(rid);68return rid;69}70RID GodotPhysicsServer3D::capsule_shape_create() {71GodotShape3D *shape = memnew(GodotCapsuleShape3D);72RID rid = shape_owner.make_rid(shape);73shape->set_self(rid);74return rid;75}76RID GodotPhysicsServer3D::cylinder_shape_create() {77GodotShape3D *shape = memnew(GodotCylinderShape3D);78RID rid = shape_owner.make_rid(shape);79shape->set_self(rid);80return rid;81}82RID GodotPhysicsServer3D::convex_polygon_shape_create() {83GodotShape3D *shape = memnew(GodotConvexPolygonShape3D);84RID rid = shape_owner.make_rid(shape);85shape->set_self(rid);86return rid;87}88RID GodotPhysicsServer3D::concave_polygon_shape_create() {89GodotShape3D *shape = memnew(GodotConcavePolygonShape3D);90RID rid = shape_owner.make_rid(shape);91shape->set_self(rid);92return rid;93}94RID GodotPhysicsServer3D::heightmap_shape_create() {95GodotShape3D *shape = memnew(GodotHeightMapShape3D);96RID rid = shape_owner.make_rid(shape);97shape->set_self(rid);98return rid;99}100RID GodotPhysicsServer3D::custom_shape_create() {101ERR_FAIL_V(RID());102}103104void GodotPhysicsServer3D::shape_set_data(RID p_shape, const Variant &p_data) {105GodotShape3D *shape = shape_owner.get_or_null(p_shape);106ERR_FAIL_NULL(shape);107shape->set_data(p_data);108}109110void GodotPhysicsServer3D::shape_set_custom_solver_bias(RID p_shape, real_t p_bias) {111GodotShape3D *shape = shape_owner.get_or_null(p_shape);112ERR_FAIL_NULL(shape);113shape->set_custom_bias(p_bias);114}115116PhysicsServer3D::ShapeType GodotPhysicsServer3D::shape_get_type(RID p_shape) const {117const GodotShape3D *shape = shape_owner.get_or_null(p_shape);118ERR_FAIL_NULL_V(shape, SHAPE_CUSTOM);119return shape->get_type();120}121122Variant GodotPhysicsServer3D::shape_get_data(RID p_shape) const {123const GodotShape3D *shape = shape_owner.get_or_null(p_shape);124ERR_FAIL_NULL_V(shape, Variant());125ERR_FAIL_COND_V(!shape->is_configured(), Variant());126return shape->get_data();127}128129void GodotPhysicsServer3D::shape_set_margin(RID p_shape, real_t p_margin) {130}131132real_t GodotPhysicsServer3D::shape_get_margin(RID p_shape) const {133return 0.0;134}135136real_t GodotPhysicsServer3D::shape_get_custom_solver_bias(RID p_shape) const {137const GodotShape3D *shape = shape_owner.get_or_null(p_shape);138ERR_FAIL_NULL_V(shape, 0);139return shape->get_custom_bias();140}141142RID GodotPhysicsServer3D::space_create() {143GodotSpace3D *space = memnew(GodotSpace3D);144RID id = space_owner.make_rid(space);145space->set_self(id);146RID area_id = area_create();147GodotArea3D *area = area_owner.get_or_null(area_id);148ERR_FAIL_NULL_V(area, RID());149space->set_default_area(area);150area->set_space(space);151area->set_priority(-1);152RID sgb = body_create();153body_set_space(sgb, id);154body_set_mode(sgb, BODY_MODE_STATIC);155space->set_static_global_body(sgb);156157return id;158}159160void GodotPhysicsServer3D::space_set_active(RID p_space, bool p_active) {161GodotSpace3D *space = space_owner.get_or_null(p_space);162ERR_FAIL_NULL(space);163if (p_active) {164active_spaces.insert(space);165} else {166active_spaces.erase(space);167}168}169170bool GodotPhysicsServer3D::space_is_active(RID p_space) const {171GodotSpace3D *space = space_owner.get_or_null(p_space);172ERR_FAIL_NULL_V(space, false);173174return active_spaces.has(space);175}176177void GodotPhysicsServer3D::space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) {178GodotSpace3D *space = space_owner.get_or_null(p_space);179ERR_FAIL_NULL(space);180181space->set_param(p_param, p_value);182}183184real_t GodotPhysicsServer3D::space_get_param(RID p_space, SpaceParameter p_param) const {185const GodotSpace3D *space = space_owner.get_or_null(p_space);186ERR_FAIL_NULL_V(space, 0);187return space->get_param(p_param);188}189190PhysicsDirectSpaceState3D *GodotPhysicsServer3D::space_get_direct_state(RID p_space) {191GodotSpace3D *space = space_owner.get_or_null(p_space);192ERR_FAIL_NULL_V(space, nullptr);193ERR_FAIL_COND_V_MSG((using_threads && !doing_sync) || space->is_locked(), nullptr, "Space state is inaccessible right now, wait for iteration or physics process notification.");194195return space->get_direct_state();196}197198void GodotPhysicsServer3D::space_set_debug_contacts(RID p_space, int p_max_contacts) {199GodotSpace3D *space = space_owner.get_or_null(p_space);200ERR_FAIL_NULL(space);201space->set_debug_contacts(p_max_contacts);202}203204Vector<Vector3> GodotPhysicsServer3D::space_get_contacts(RID p_space) const {205GodotSpace3D *space = space_owner.get_or_null(p_space);206ERR_FAIL_NULL_V(space, Vector<Vector3>());207return space->get_debug_contacts();208}209210int GodotPhysicsServer3D::space_get_contact_count(RID p_space) const {211GodotSpace3D *space = space_owner.get_or_null(p_space);212ERR_FAIL_NULL_V(space, 0);213return space->get_debug_contact_count();214}215216RID GodotPhysicsServer3D::area_create() {217GodotArea3D *area = memnew(GodotArea3D);218RID rid = area_owner.make_rid(area);219area->set_self(rid);220return rid;221}222223void GodotPhysicsServer3D::area_set_space(RID p_area, RID p_space) {224GodotArea3D *area = area_owner.get_or_null(p_area);225ERR_FAIL_NULL(area);226227GodotSpace3D *space = nullptr;228if (p_space.is_valid()) {229space = space_owner.get_or_null(p_space);230ERR_FAIL_NULL(space);231}232233if (area->get_space() == space) {234return; //pointless235}236237area->clear_constraints();238area->set_space(space);239}240241RID GodotPhysicsServer3D::area_get_space(RID p_area) const {242GodotArea3D *area = area_owner.get_or_null(p_area);243ERR_FAIL_NULL_V(area, RID());244245GodotSpace3D *space = area->get_space();246if (!space) {247return RID();248}249return space->get_self();250}251252void GodotPhysicsServer3D::area_add_shape(RID p_area, RID p_shape, const Transform3D &p_transform, bool p_disabled) {253GodotArea3D *area = area_owner.get_or_null(p_area);254ERR_FAIL_NULL(area);255256GodotShape3D *shape = shape_owner.get_or_null(p_shape);257ERR_FAIL_NULL(shape);258259area->add_shape(shape, p_transform, p_disabled);260}261262void GodotPhysicsServer3D::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) {263GodotArea3D *area = area_owner.get_or_null(p_area);264ERR_FAIL_NULL(area);265266GodotShape3D *shape = shape_owner.get_or_null(p_shape);267ERR_FAIL_NULL(shape);268ERR_FAIL_COND(!shape->is_configured());269270area->set_shape(p_shape_idx, shape);271}272273void GodotPhysicsServer3D::area_set_shape_transform(RID p_area, int p_shape_idx, const Transform3D &p_transform) {274GodotArea3D *area = area_owner.get_or_null(p_area);275ERR_FAIL_NULL(area);276277area->set_shape_transform(p_shape_idx, p_transform);278}279280int GodotPhysicsServer3D::area_get_shape_count(RID p_area) const {281GodotArea3D *area = area_owner.get_or_null(p_area);282ERR_FAIL_NULL_V(area, -1);283284return area->get_shape_count();285}286287RID GodotPhysicsServer3D::area_get_shape(RID p_area, int p_shape_idx) const {288GodotArea3D *area = area_owner.get_or_null(p_area);289ERR_FAIL_NULL_V(area, RID());290291GodotShape3D *shape = area->get_shape(p_shape_idx);292ERR_FAIL_NULL_V(shape, RID());293294return shape->get_self();295}296297Transform3D GodotPhysicsServer3D::area_get_shape_transform(RID p_area, int p_shape_idx) const {298GodotArea3D *area = area_owner.get_or_null(p_area);299ERR_FAIL_NULL_V(area, Transform3D());300301return area->get_shape_transform(p_shape_idx);302}303304void GodotPhysicsServer3D::area_remove_shape(RID p_area, int p_shape_idx) {305GodotArea3D *area = area_owner.get_or_null(p_area);306ERR_FAIL_NULL(area);307308area->remove_shape(p_shape_idx);309}310311void GodotPhysicsServer3D::area_clear_shapes(RID p_area) {312GodotArea3D *area = area_owner.get_or_null(p_area);313ERR_FAIL_NULL(area);314315while (area->get_shape_count()) {316area->remove_shape(0);317}318}319320void GodotPhysicsServer3D::area_set_shape_disabled(RID p_area, int p_shape_idx, bool p_disabled) {321GodotArea3D *area = area_owner.get_or_null(p_area);322ERR_FAIL_NULL(area);323ERR_FAIL_INDEX(p_shape_idx, area->get_shape_count());324FLUSH_QUERY_CHECK(area);325area->set_shape_disabled(p_shape_idx, p_disabled);326}327328void GodotPhysicsServer3D::area_attach_object_instance_id(RID p_area, ObjectID p_id) {329if (space_owner.owns(p_area)) {330GodotSpace3D *space = space_owner.get_or_null(p_area);331p_area = space->get_default_area()->get_self();332}333GodotArea3D *area = area_owner.get_or_null(p_area);334ERR_FAIL_NULL(area);335area->set_instance_id(p_id);336}337338ObjectID GodotPhysicsServer3D::area_get_object_instance_id(RID p_area) const {339if (space_owner.owns(p_area)) {340GodotSpace3D *space = space_owner.get_or_null(p_area);341p_area = space->get_default_area()->get_self();342}343GodotArea3D *area = area_owner.get_or_null(p_area);344ERR_FAIL_NULL_V(area, ObjectID());345return area->get_instance_id();346}347348void GodotPhysicsServer3D::area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) {349if (space_owner.owns(p_area)) {350GodotSpace3D *space = space_owner.get_or_null(p_area);351p_area = space->get_default_area()->get_self();352}353GodotArea3D *area = area_owner.get_or_null(p_area);354ERR_FAIL_NULL(area);355area->set_param(p_param, p_value);356}357358void GodotPhysicsServer3D::area_set_transform(RID p_area, const Transform3D &p_transform) {359GodotArea3D *area = area_owner.get_or_null(p_area);360ERR_FAIL_NULL(area);361area->set_transform(p_transform);362}363364Variant GodotPhysicsServer3D::area_get_param(RID p_area, AreaParameter p_param) const {365if (space_owner.owns(p_area)) {366GodotSpace3D *space = space_owner.get_or_null(p_area);367p_area = space->get_default_area()->get_self();368}369GodotArea3D *area = area_owner.get_or_null(p_area);370ERR_FAIL_NULL_V(area, Variant());371372return area->get_param(p_param);373}374375Transform3D GodotPhysicsServer3D::area_get_transform(RID p_area) const {376GodotArea3D *area = area_owner.get_or_null(p_area);377ERR_FAIL_NULL_V(area, Transform3D());378379return area->get_transform();380}381382void GodotPhysicsServer3D::area_set_collision_layer(RID p_area, uint32_t p_layer) {383GodotArea3D *area = area_owner.get_or_null(p_area);384ERR_FAIL_NULL(area);385386area->set_collision_layer(p_layer);387}388389uint32_t GodotPhysicsServer3D::area_get_collision_layer(RID p_area) const {390GodotArea3D *area = area_owner.get_or_null(p_area);391ERR_FAIL_NULL_V(area, 0);392393return area->get_collision_layer();394}395396void GodotPhysicsServer3D::area_set_collision_mask(RID p_area, uint32_t p_mask) {397GodotArea3D *area = area_owner.get_or_null(p_area);398ERR_FAIL_NULL(area);399400area->set_collision_mask(p_mask);401}402403uint32_t GodotPhysicsServer3D::area_get_collision_mask(RID p_area) const {404GodotArea3D *area = area_owner.get_or_null(p_area);405ERR_FAIL_NULL_V(area, 0);406407return area->get_collision_mask();408}409410void GodotPhysicsServer3D::area_set_monitorable(RID p_area, bool p_monitorable) {411GodotArea3D *area = area_owner.get_or_null(p_area);412ERR_FAIL_NULL(area);413FLUSH_QUERY_CHECK(area);414415area->set_monitorable(p_monitorable);416}417418void GodotPhysicsServer3D::area_set_monitor_callback(RID p_area, const Callable &p_callback) {419GodotArea3D *area = area_owner.get_or_null(p_area);420ERR_FAIL_NULL(area);421422area->set_monitor_callback(p_callback.is_valid() ? p_callback : Callable());423}424425void GodotPhysicsServer3D::area_set_ray_pickable(RID p_area, bool p_enable) {426GodotArea3D *area = area_owner.get_or_null(p_area);427ERR_FAIL_NULL(area);428429area->set_ray_pickable(p_enable);430}431432void GodotPhysicsServer3D::area_set_area_monitor_callback(RID p_area, const Callable &p_callback) {433GodotArea3D *area = area_owner.get_or_null(p_area);434ERR_FAIL_NULL(area);435436area->set_area_monitor_callback(p_callback.is_valid() ? p_callback : Callable());437}438439/* BODY API */440441RID GodotPhysicsServer3D::body_create() {442GodotBody3D *body = memnew(GodotBody3D);443RID rid = body_owner.make_rid(body);444body->set_self(rid);445return rid;446}447448void GodotPhysicsServer3D::body_set_space(RID p_body, RID p_space) {449GodotBody3D *body = body_owner.get_or_null(p_body);450ERR_FAIL_NULL(body);451452GodotSpace3D *space = nullptr;453if (p_space.is_valid()) {454space = space_owner.get_or_null(p_space);455ERR_FAIL_NULL(space);456}457458if (body->get_space() == space) {459return; //pointless460}461462body->clear_constraint_map();463body->set_space(space);464}465466RID GodotPhysicsServer3D::body_get_space(RID p_body) const {467GodotBody3D *body = body_owner.get_or_null(p_body);468ERR_FAIL_NULL_V(body, RID());469470GodotSpace3D *space = body->get_space();471if (!space) {472return RID();473}474return space->get_self();475}476477void GodotPhysicsServer3D::body_set_mode(RID p_body, BodyMode p_mode) {478GodotBody3D *body = body_owner.get_or_null(p_body);479ERR_FAIL_NULL(body);480481body->set_mode(p_mode);482}483484PhysicsServer3D::BodyMode GodotPhysicsServer3D::body_get_mode(RID p_body) const {485GodotBody3D *body = body_owner.get_or_null(p_body);486ERR_FAIL_NULL_V(body, BODY_MODE_STATIC);487488return body->get_mode();489}490491void GodotPhysicsServer3D::body_add_shape(RID p_body, RID p_shape, const Transform3D &p_transform, bool p_disabled) {492GodotBody3D *body = body_owner.get_or_null(p_body);493ERR_FAIL_NULL(body);494495GodotShape3D *shape = shape_owner.get_or_null(p_shape);496ERR_FAIL_NULL(shape);497498body->add_shape(shape, p_transform, p_disabled);499}500501void GodotPhysicsServer3D::body_set_shape(RID p_body, int p_shape_idx, RID p_shape) {502GodotBody3D *body = body_owner.get_or_null(p_body);503ERR_FAIL_NULL(body);504505GodotShape3D *shape = shape_owner.get_or_null(p_shape);506ERR_FAIL_NULL(shape);507ERR_FAIL_COND(!shape->is_configured());508509body->set_shape(p_shape_idx, shape);510}511void GodotPhysicsServer3D::body_set_shape_transform(RID p_body, int p_shape_idx, const Transform3D &p_transform) {512GodotBody3D *body = body_owner.get_or_null(p_body);513ERR_FAIL_NULL(body);514515body->set_shape_transform(p_shape_idx, p_transform);516}517518int GodotPhysicsServer3D::body_get_shape_count(RID p_body) const {519GodotBody3D *body = body_owner.get_or_null(p_body);520ERR_FAIL_NULL_V(body, -1);521522return body->get_shape_count();523}524525RID GodotPhysicsServer3D::body_get_shape(RID p_body, int p_shape_idx) const {526GodotBody3D *body = body_owner.get_or_null(p_body);527ERR_FAIL_NULL_V(body, RID());528529GodotShape3D *shape = body->get_shape(p_shape_idx);530ERR_FAIL_NULL_V(shape, RID());531532return shape->get_self();533}534535void GodotPhysicsServer3D::body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) {536GodotBody3D *body = body_owner.get_or_null(p_body);537ERR_FAIL_NULL(body);538ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count());539FLUSH_QUERY_CHECK(body);540541body->set_shape_disabled(p_shape_idx, p_disabled);542}543544Transform3D GodotPhysicsServer3D::body_get_shape_transform(RID p_body, int p_shape_idx) const {545GodotBody3D *body = body_owner.get_or_null(p_body);546ERR_FAIL_NULL_V(body, Transform3D());547548return body->get_shape_transform(p_shape_idx);549}550551void GodotPhysicsServer3D::body_remove_shape(RID p_body, int p_shape_idx) {552GodotBody3D *body = body_owner.get_or_null(p_body);553ERR_FAIL_NULL(body);554555body->remove_shape(p_shape_idx);556}557558void GodotPhysicsServer3D::body_clear_shapes(RID p_body) {559GodotBody3D *body = body_owner.get_or_null(p_body);560ERR_FAIL_NULL(body);561562while (body->get_shape_count()) {563body->remove_shape(0);564}565}566567void GodotPhysicsServer3D::body_set_enable_continuous_collision_detection(RID p_body, bool p_enable) {568GodotBody3D *body = body_owner.get_or_null(p_body);569ERR_FAIL_NULL(body);570571body->set_continuous_collision_detection(p_enable);572}573574bool GodotPhysicsServer3D::body_is_continuous_collision_detection_enabled(RID p_body) const {575GodotBody3D *body = body_owner.get_or_null(p_body);576ERR_FAIL_NULL_V(body, false);577578return body->is_continuous_collision_detection_enabled();579}580581void GodotPhysicsServer3D::body_set_collision_layer(RID p_body, uint32_t p_layer) {582GodotBody3D *body = body_owner.get_or_null(p_body);583ERR_FAIL_NULL(body);584585body->set_collision_layer(p_layer);586}587588uint32_t GodotPhysicsServer3D::body_get_collision_layer(RID p_body) const {589const GodotBody3D *body = body_owner.get_or_null(p_body);590ERR_FAIL_NULL_V(body, 0);591592return body->get_collision_layer();593}594595void GodotPhysicsServer3D::body_set_collision_mask(RID p_body, uint32_t p_mask) {596GodotBody3D *body = body_owner.get_or_null(p_body);597ERR_FAIL_NULL(body);598599body->set_collision_mask(p_mask);600}601602uint32_t GodotPhysicsServer3D::body_get_collision_mask(RID p_body) const {603const GodotBody3D *body = body_owner.get_or_null(p_body);604ERR_FAIL_NULL_V(body, 0);605606return body->get_collision_mask();607}608609void GodotPhysicsServer3D::body_set_collision_priority(RID p_body, real_t p_priority) {610GodotBody3D *body = body_owner.get_or_null(p_body);611ERR_FAIL_NULL(body);612613body->set_collision_priority(p_priority);614}615616real_t GodotPhysicsServer3D::body_get_collision_priority(RID p_body) const {617const GodotBody3D *body = body_owner.get_or_null(p_body);618ERR_FAIL_NULL_V(body, 0);619620return body->get_collision_priority();621}622623void GodotPhysicsServer3D::body_attach_object_instance_id(RID p_body, ObjectID p_id) {624GodotBody3D *body = body_owner.get_or_null(p_body);625if (body) {626body->set_instance_id(p_id);627return;628}629630GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);631if (soft_body) {632soft_body->set_instance_id(p_id);633return;634}635636ERR_FAIL_MSG("Invalid ID.");637}638639ObjectID GodotPhysicsServer3D::body_get_object_instance_id(RID p_body) const {640GodotBody3D *body = body_owner.get_or_null(p_body);641ERR_FAIL_NULL_V(body, ObjectID());642643return body->get_instance_id();644}645646void GodotPhysicsServer3D::body_set_user_flags(RID p_body, uint32_t p_flags) {647GodotBody3D *body = body_owner.get_or_null(p_body);648ERR_FAIL_NULL(body);649}650651uint32_t GodotPhysicsServer3D::body_get_user_flags(RID p_body) const {652GodotBody3D *body = body_owner.get_or_null(p_body);653ERR_FAIL_NULL_V(body, 0);654655return 0;656}657658void GodotPhysicsServer3D::body_set_param(RID p_body, BodyParameter p_param, const Variant &p_value) {659GodotBody3D *body = body_owner.get_or_null(p_body);660ERR_FAIL_NULL(body);661662body->set_param(p_param, p_value);663}664665Variant GodotPhysicsServer3D::body_get_param(RID p_body, BodyParameter p_param) const {666GodotBody3D *body = body_owner.get_or_null(p_body);667ERR_FAIL_NULL_V(body, 0);668669return body->get_param(p_param);670}671672void GodotPhysicsServer3D::body_reset_mass_properties(RID p_body) {673GodotBody3D *body = body_owner.get_or_null(p_body);674ERR_FAIL_NULL(body);675676return body->reset_mass_properties();677}678679void GodotPhysicsServer3D::body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) {680GodotBody3D *body = body_owner.get_or_null(p_body);681ERR_FAIL_NULL(body);682683body->set_state(p_state, p_variant);684}685686Variant GodotPhysicsServer3D::body_get_state(RID p_body, BodyState p_state) const {687GodotBody3D *body = body_owner.get_or_null(p_body);688ERR_FAIL_NULL_V(body, Variant());689690return body->get_state(p_state);691}692693void GodotPhysicsServer3D::body_apply_central_impulse(RID p_body, const Vector3 &p_impulse) {694GodotBody3D *body = body_owner.get_or_null(p_body);695ERR_FAIL_NULL(body);696697_update_shapes();698699body->apply_central_impulse(p_impulse);700body->wakeup();701}702703void GodotPhysicsServer3D::body_apply_impulse(RID p_body, const Vector3 &p_impulse, const Vector3 &p_position) {704GodotBody3D *body = body_owner.get_or_null(p_body);705ERR_FAIL_NULL(body);706707_update_shapes();708709body->apply_impulse(p_impulse, p_position);710body->wakeup();711}712713void GodotPhysicsServer3D::body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse) {714GodotBody3D *body = body_owner.get_or_null(p_body);715ERR_FAIL_NULL(body);716717_update_shapes();718719body->apply_torque_impulse(p_impulse);720body->wakeup();721}722723void GodotPhysicsServer3D::body_apply_central_force(RID p_body, const Vector3 &p_force) {724GodotBody3D *body = body_owner.get_or_null(p_body);725ERR_FAIL_NULL(body);726727body->apply_central_force(p_force);728body->wakeup();729}730731void GodotPhysicsServer3D::body_apply_force(RID p_body, const Vector3 &p_force, const Vector3 &p_position) {732GodotBody3D *body = body_owner.get_or_null(p_body);733ERR_FAIL_NULL(body);734735body->apply_force(p_force, p_position);736body->wakeup();737}738739void GodotPhysicsServer3D::soft_body_apply_point_impulse(RID p_body, int p_point_index, const Vector3 &p_impulse) {740GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);741ERR_FAIL_NULL(soft_body);742743soft_body->apply_node_impulse(p_point_index, p_impulse);744}745746void GodotPhysicsServer3D::soft_body_apply_point_force(RID p_body, int p_point_index, const Vector3 &p_force) {747GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);748ERR_FAIL_NULL(soft_body);749750soft_body->apply_node_force(p_point_index, p_force);751}752753void GodotPhysicsServer3D::soft_body_apply_central_impulse(RID p_body, const Vector3 &p_impulse) {754GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);755ERR_FAIL_NULL(soft_body);756757soft_body->apply_central_impulse(p_impulse);758}759760void GodotPhysicsServer3D::soft_body_apply_central_force(RID p_body, const Vector3 &p_force) {761GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);762ERR_FAIL_NULL(soft_body);763764soft_body->apply_central_force(p_force);765}766767void GodotPhysicsServer3D::body_apply_torque(RID p_body, const Vector3 &p_torque) {768GodotBody3D *body = body_owner.get_or_null(p_body);769ERR_FAIL_NULL(body);770771body->apply_torque(p_torque);772body->wakeup();773}774775void GodotPhysicsServer3D::body_add_constant_central_force(RID p_body, const Vector3 &p_force) {776GodotBody3D *body = body_owner.get_or_null(p_body);777ERR_FAIL_NULL(body);778779body->add_constant_central_force(p_force);780body->wakeup();781}782783void GodotPhysicsServer3D::body_add_constant_force(RID p_body, const Vector3 &p_force, const Vector3 &p_position) {784GodotBody3D *body = body_owner.get_or_null(p_body);785ERR_FAIL_NULL(body);786787body->add_constant_force(p_force, p_position);788body->wakeup();789}790791void GodotPhysicsServer3D::body_add_constant_torque(RID p_body, const Vector3 &p_torque) {792GodotBody3D *body = body_owner.get_or_null(p_body);793ERR_FAIL_NULL(body);794795body->add_constant_torque(p_torque);796body->wakeup();797}798799void GodotPhysicsServer3D::body_set_constant_force(RID p_body, const Vector3 &p_force) {800GodotBody3D *body = body_owner.get_or_null(p_body);801ERR_FAIL_NULL(body);802803body->set_constant_force(p_force);804if (!p_force.is_zero_approx()) {805body->wakeup();806}807}808809Vector3 GodotPhysicsServer3D::body_get_constant_force(RID p_body) const {810GodotBody3D *body = body_owner.get_or_null(p_body);811ERR_FAIL_NULL_V(body, Vector3());812return body->get_constant_force();813}814815void GodotPhysicsServer3D::body_set_constant_torque(RID p_body, const Vector3 &p_torque) {816GodotBody3D *body = body_owner.get_or_null(p_body);817ERR_FAIL_NULL(body);818819body->set_constant_torque(p_torque);820if (!p_torque.is_zero_approx()) {821body->wakeup();822}823}824825Vector3 GodotPhysicsServer3D::body_get_constant_torque(RID p_body) const {826GodotBody3D *body = body_owner.get_or_null(p_body);827ERR_FAIL_NULL_V(body, Vector3());828829return body->get_constant_torque();830}831832void GodotPhysicsServer3D::body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity) {833GodotBody3D *body = body_owner.get_or_null(p_body);834ERR_FAIL_NULL(body);835836_update_shapes();837838Vector3 v = body->get_linear_velocity();839Vector3 axis = p_axis_velocity.normalized();840v -= axis * axis.dot(v);841v += p_axis_velocity;842body->set_linear_velocity(v);843body->wakeup();844}845846void GodotPhysicsServer3D::body_set_axis_lock(RID p_body, BodyAxis p_axis, bool p_lock) {847GodotBody3D *body = body_owner.get_or_null(p_body);848ERR_FAIL_NULL(body);849850body->set_axis_lock(p_axis, p_lock);851body->wakeup();852}853854bool GodotPhysicsServer3D::body_is_axis_locked(RID p_body, BodyAxis p_axis) const {855const GodotBody3D *body = body_owner.get_or_null(p_body);856ERR_FAIL_NULL_V(body, false);857return body->is_axis_locked(p_axis);858}859860void GodotPhysicsServer3D::body_add_collision_exception(RID p_body, RID p_body_b) {861GodotBody3D *body = body_owner.get_or_null(p_body);862ERR_FAIL_NULL(body);863864body->add_exception(p_body_b);865body->wakeup();866}867868void GodotPhysicsServer3D::body_remove_collision_exception(RID p_body, RID p_body_b) {869GodotBody3D *body = body_owner.get_or_null(p_body);870ERR_FAIL_NULL(body);871872body->remove_exception(p_body_b);873body->wakeup();874}875876void GodotPhysicsServer3D::body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) {877GodotBody3D *body = body_owner.get_or_null(p_body);878ERR_FAIL_NULL(body);879880for (int i = 0; i < body->get_exceptions().size(); i++) {881p_exceptions->push_back(body->get_exceptions()[i]);882}883}884885void GodotPhysicsServer3D::body_set_contacts_reported_depth_threshold(RID p_body, real_t p_threshold) {886GodotBody3D *body = body_owner.get_or_null(p_body);887ERR_FAIL_NULL(body);888}889890real_t GodotPhysicsServer3D::body_get_contacts_reported_depth_threshold(RID p_body) const {891GodotBody3D *body = body_owner.get_or_null(p_body);892ERR_FAIL_NULL_V(body, 0);893return 0;894}895896void GodotPhysicsServer3D::body_set_omit_force_integration(RID p_body, bool p_omit) {897GodotBody3D *body = body_owner.get_or_null(p_body);898ERR_FAIL_NULL(body);899900body->set_omit_force_integration(p_omit);901}902903bool GodotPhysicsServer3D::body_is_omitting_force_integration(RID p_body) const {904GodotBody3D *body = body_owner.get_or_null(p_body);905ERR_FAIL_NULL_V(body, false);906return body->get_omit_force_integration();907}908909void GodotPhysicsServer3D::body_set_max_contacts_reported(RID p_body, int p_contacts) {910GodotBody3D *body = body_owner.get_or_null(p_body);911ERR_FAIL_NULL(body);912body->set_max_contacts_reported(p_contacts);913}914915int GodotPhysicsServer3D::body_get_max_contacts_reported(RID p_body) const {916GodotBody3D *body = body_owner.get_or_null(p_body);917ERR_FAIL_NULL_V(body, -1);918return body->get_max_contacts_reported();919}920921void GodotPhysicsServer3D::body_set_state_sync_callback(RID p_body, const Callable &p_callable) {922GodotBody3D *body = body_owner.get_or_null(p_body);923ERR_FAIL_NULL(body);924body->set_state_sync_callback(p_callable);925}926927void GodotPhysicsServer3D::body_set_force_integration_callback(RID p_body, const Callable &p_callable, const Variant &p_udata) {928GodotBody3D *body = body_owner.get_or_null(p_body);929ERR_FAIL_NULL(body);930body->set_force_integration_callback(p_callable, p_udata);931}932933void GodotPhysicsServer3D::body_set_ray_pickable(RID p_body, bool p_enable) {934GodotBody3D *body = body_owner.get_or_null(p_body);935ERR_FAIL_NULL(body);936body->set_ray_pickable(p_enable);937}938939bool GodotPhysicsServer3D::body_test_motion(RID p_body, const MotionParameters &p_parameters, MotionResult *r_result) {940GodotBody3D *body = body_owner.get_or_null(p_body);941ERR_FAIL_NULL_V(body, false);942ERR_FAIL_NULL_V(body->get_space(), false);943ERR_FAIL_COND_V(body->get_space()->is_locked(), false);944945_update_shapes();946947return body->get_space()->test_body_motion(body, p_parameters, r_result);948}949950PhysicsDirectBodyState3D *GodotPhysicsServer3D::body_get_direct_state(RID p_body) {951ERR_FAIL_COND_V_MSG((using_threads && !doing_sync), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification.");952953if (!body_owner.owns(p_body)) {954return nullptr;955}956957GodotBody3D *body = body_owner.get_or_null(p_body);958ERR_FAIL_NULL_V(body, nullptr);959960if (!body->get_space()) {961return nullptr;962}963964ERR_FAIL_COND_V_MSG(body->get_space()->is_locked(), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification.");965966return body->get_direct_state();967}968969/* SOFT BODY */970971RID GodotPhysicsServer3D::soft_body_create() {972GodotSoftBody3D *soft_body = memnew(GodotSoftBody3D);973RID rid = soft_body_owner.make_rid(soft_body);974soft_body->set_self(rid);975return rid;976}977978void GodotPhysicsServer3D::soft_body_update_rendering_server(RID p_body, PhysicsServer3DRenderingServerHandler *p_rendering_server_handler) {979GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);980ERR_FAIL_NULL(soft_body);981982soft_body->update_rendering_server(p_rendering_server_handler);983}984985void GodotPhysicsServer3D::soft_body_set_space(RID p_body, RID p_space) {986GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);987ERR_FAIL_NULL(soft_body);988989GodotSpace3D *space = nullptr;990if (p_space.is_valid()) {991space = space_owner.get_or_null(p_space);992ERR_FAIL_NULL(space);993}994995if (soft_body->get_space() == space) {996return;997}998999soft_body->set_space(space);1000}10011002RID GodotPhysicsServer3D::soft_body_get_space(RID p_body) const {1003GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1004ERR_FAIL_NULL_V(soft_body, RID());10051006GodotSpace3D *space = soft_body->get_space();1007if (!space) {1008return RID();1009}1010return space->get_self();1011}10121013void GodotPhysicsServer3D::soft_body_set_collision_layer(RID p_body, uint32_t p_layer) {1014GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1015ERR_FAIL_NULL(soft_body);10161017soft_body->set_collision_layer(p_layer);1018}10191020uint32_t GodotPhysicsServer3D::soft_body_get_collision_layer(RID p_body) const {1021GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1022ERR_FAIL_NULL_V(soft_body, 0);10231024return soft_body->get_collision_layer();1025}10261027void GodotPhysicsServer3D::soft_body_set_collision_mask(RID p_body, uint32_t p_mask) {1028GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1029ERR_FAIL_NULL(soft_body);10301031soft_body->set_collision_mask(p_mask);1032}10331034uint32_t GodotPhysicsServer3D::soft_body_get_collision_mask(RID p_body) const {1035GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1036ERR_FAIL_NULL_V(soft_body, 0);10371038return soft_body->get_collision_mask();1039}10401041void GodotPhysicsServer3D::soft_body_add_collision_exception(RID p_body, RID p_body_b) {1042GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1043ERR_FAIL_NULL(soft_body);10441045soft_body->add_exception(p_body_b);1046}10471048void GodotPhysicsServer3D::soft_body_remove_collision_exception(RID p_body, RID p_body_b) {1049GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1050ERR_FAIL_NULL(soft_body);10511052soft_body->remove_exception(p_body_b);1053}10541055void GodotPhysicsServer3D::soft_body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) {1056GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1057ERR_FAIL_NULL(soft_body);10581059for (int i = 0; i < soft_body->get_exceptions().size(); i++) {1060p_exceptions->push_back(soft_body->get_exceptions()[i]);1061}1062}10631064void GodotPhysicsServer3D::soft_body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) {1065GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1066ERR_FAIL_NULL(soft_body);10671068soft_body->set_state(p_state, p_variant);1069}10701071Variant GodotPhysicsServer3D::soft_body_get_state(RID p_body, BodyState p_state) const {1072GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1073ERR_FAIL_NULL_V(soft_body, Variant());10741075return soft_body->get_state(p_state);1076}10771078void GodotPhysicsServer3D::soft_body_set_transform(RID p_body, const Transform3D &p_transform) {1079GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1080ERR_FAIL_NULL(soft_body);10811082soft_body->set_state(BODY_STATE_TRANSFORM, p_transform);1083}10841085void GodotPhysicsServer3D::soft_body_set_ray_pickable(RID p_body, bool p_enable) {1086GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1087ERR_FAIL_NULL(soft_body);10881089soft_body->set_ray_pickable(p_enable);1090}10911092void GodotPhysicsServer3D::soft_body_set_simulation_precision(RID p_body, int p_simulation_precision) {1093GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1094ERR_FAIL_NULL(soft_body);10951096soft_body->set_iteration_count(p_simulation_precision);1097}10981099int GodotPhysicsServer3D::soft_body_get_simulation_precision(RID p_body) const {1100GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1101ERR_FAIL_NULL_V(soft_body, 0.f);11021103return soft_body->get_iteration_count();1104}11051106void GodotPhysicsServer3D::soft_body_set_total_mass(RID p_body, real_t p_total_mass) {1107GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1108ERR_FAIL_NULL(soft_body);11091110soft_body->set_total_mass(p_total_mass);1111}11121113real_t GodotPhysicsServer3D::soft_body_get_total_mass(RID p_body) const {1114GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1115ERR_FAIL_NULL_V(soft_body, 0.f);11161117return soft_body->get_total_mass();1118}11191120void GodotPhysicsServer3D::soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) {1121GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1122ERR_FAIL_NULL(soft_body);11231124soft_body->set_linear_stiffness(p_stiffness);1125}11261127real_t GodotPhysicsServer3D::soft_body_get_linear_stiffness(RID p_body) const {1128GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1129ERR_FAIL_NULL_V(soft_body, 0.f);11301131return soft_body->get_linear_stiffness();1132}11331134void GodotPhysicsServer3D::soft_body_set_shrinking_factor(RID p_body, real_t p_shrinking_factor) {1135GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1136ERR_FAIL_NULL(soft_body);11371138soft_body->set_shrinking_factor(p_shrinking_factor);1139}11401141real_t GodotPhysicsServer3D::soft_body_get_shrinking_factor(RID p_body) const {1142GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1143ERR_FAIL_NULL_V(soft_body, 0.f);11441145return soft_body->get_shrinking_factor();1146}11471148void GodotPhysicsServer3D::soft_body_set_pressure_coefficient(RID p_body, real_t p_pressure_coefficient) {1149GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1150ERR_FAIL_NULL(soft_body);11511152soft_body->set_pressure_coefficient(p_pressure_coefficient);1153}11541155real_t GodotPhysicsServer3D::soft_body_get_pressure_coefficient(RID p_body) const {1156GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1157ERR_FAIL_NULL_V(soft_body, 0.f);11581159return soft_body->get_pressure_coefficient();1160}11611162void GodotPhysicsServer3D::soft_body_set_damping_coefficient(RID p_body, real_t p_damping_coefficient) {1163GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1164ERR_FAIL_NULL(soft_body);11651166soft_body->set_damping_coefficient(p_damping_coefficient);1167}11681169real_t GodotPhysicsServer3D::soft_body_get_damping_coefficient(RID p_body) const {1170GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1171ERR_FAIL_NULL_V(soft_body, 0.f);11721173return soft_body->get_damping_coefficient();1174}11751176void GodotPhysicsServer3D::soft_body_set_drag_coefficient(RID p_body, real_t p_drag_coefficient) {1177GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1178ERR_FAIL_NULL(soft_body);11791180soft_body->set_drag_coefficient(p_drag_coefficient);1181}11821183real_t GodotPhysicsServer3D::soft_body_get_drag_coefficient(RID p_body) const {1184GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1185ERR_FAIL_NULL_V(soft_body, 0.f);11861187return soft_body->get_drag_coefficient();1188}11891190void GodotPhysicsServer3D::soft_body_set_mesh(RID p_body, RID p_mesh) {1191GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1192ERR_FAIL_NULL(soft_body);11931194soft_body->set_mesh(p_mesh);1195}11961197AABB GodotPhysicsServer3D::soft_body_get_bounds(RID p_body) const {1198GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1199ERR_FAIL_NULL_V(soft_body, AABB());12001201return soft_body->get_bounds();1202}12031204void GodotPhysicsServer3D::soft_body_move_point(RID p_body, int p_point_index, const Vector3 &p_global_position) {1205GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1206ERR_FAIL_NULL(soft_body);12071208soft_body->set_vertex_position(p_point_index, p_global_position);1209}12101211Vector3 GodotPhysicsServer3D::soft_body_get_point_global_position(RID p_body, int p_point_index) const {1212GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1213ERR_FAIL_NULL_V(soft_body, Vector3());12141215return soft_body->get_vertex_position(p_point_index);1216}12171218void GodotPhysicsServer3D::soft_body_remove_all_pinned_points(RID p_body) {1219GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1220ERR_FAIL_NULL(soft_body);12211222soft_body->unpin_all_vertices();1223}12241225void GodotPhysicsServer3D::soft_body_pin_point(RID p_body, int p_point_index, bool p_pin) {1226GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1227ERR_FAIL_NULL(soft_body);12281229if (p_pin) {1230soft_body->pin_vertex(p_point_index);1231} else {1232soft_body->unpin_vertex(p_point_index);1233}1234}12351236bool GodotPhysicsServer3D::soft_body_is_point_pinned(RID p_body, int p_point_index) const {1237GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1238ERR_FAIL_NULL_V(soft_body, false);12391240return soft_body->is_vertex_pinned(p_point_index);1241}12421243/* JOINT API */12441245RID GodotPhysicsServer3D::joint_create() {1246GodotJoint3D *joint = memnew(GodotJoint3D);1247RID rid = joint_owner.make_rid(joint);1248joint->set_self(rid);1249return rid;1250}12511252void GodotPhysicsServer3D::joint_clear(RID p_joint) {1253GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1254ERR_FAIL_NULL(joint);1255if (joint->get_type() != JOINT_TYPE_MAX) {1256GodotJoint3D *empty_joint = memnew(GodotJoint3D);1257empty_joint->copy_settings_from(joint);12581259joint_owner.replace(p_joint, empty_joint);1260memdelete(joint);1261}1262}12631264void 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) {1265GodotBody3D *body_A = body_owner.get_or_null(p_body_A);1266ERR_FAIL_NULL(body_A);12671268if (!p_body_B.is_valid()) {1269ERR_FAIL_NULL(body_A->get_space());1270p_body_B = body_A->get_space()->get_static_global_body();1271}12721273GodotBody3D *body_B = body_owner.get_or_null(p_body_B);1274ERR_FAIL_NULL(body_B);12751276ERR_FAIL_COND(body_A == body_B);12771278GodotJoint3D *prev_joint = joint_owner.get_or_null(p_joint);1279ERR_FAIL_NULL(prev_joint);12801281GodotJoint3D *joint = memnew(GodotPinJoint3D(body_A, p_local_A, body_B, p_local_B));12821283joint->copy_settings_from(prev_joint);1284joint_owner.replace(p_joint, joint);1285memdelete(prev_joint);1286}12871288void GodotPhysicsServer3D::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) {1289GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1290ERR_FAIL_NULL(joint);1291ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN);1292GodotPinJoint3D *pin_joint = static_cast<GodotPinJoint3D *>(joint);1293pin_joint->set_param(p_param, p_value);1294}12951296real_t GodotPhysicsServer3D::pin_joint_get_param(RID p_joint, PinJointParam p_param) const {1297GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1298ERR_FAIL_NULL_V(joint, 0);1299ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, 0);1300GodotPinJoint3D *pin_joint = static_cast<GodotPinJoint3D *>(joint);1301return pin_joint->get_param(p_param);1302}13031304void GodotPhysicsServer3D::pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) {1305GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1306ERR_FAIL_NULL(joint);1307ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN);1308GodotPinJoint3D *pin_joint = static_cast<GodotPinJoint3D *>(joint);1309pin_joint->set_pos_a(p_A);1310}13111312Vector3 GodotPhysicsServer3D::pin_joint_get_local_a(RID p_joint) const {1313GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1314ERR_FAIL_NULL_V(joint, Vector3());1315ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, Vector3());1316GodotPinJoint3D *pin_joint = static_cast<GodotPinJoint3D *>(joint);1317return pin_joint->get_position_a();1318}13191320void GodotPhysicsServer3D::pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) {1321GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1322ERR_FAIL_NULL(joint);1323ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN);1324GodotPinJoint3D *pin_joint = static_cast<GodotPinJoint3D *>(joint);1325pin_joint->set_pos_b(p_B);1326}13271328Vector3 GodotPhysicsServer3D::pin_joint_get_local_b(RID p_joint) const {1329GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1330ERR_FAIL_NULL_V(joint, Vector3());1331ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, Vector3());1332GodotPinJoint3D *pin_joint = static_cast<GodotPinJoint3D *>(joint);1333return pin_joint->get_position_b();1334}13351336void GodotPhysicsServer3D::joint_make_hinge(RID p_joint, RID p_body_A, const Transform3D &p_frame_A, RID p_body_B, const Transform3D &p_frame_B) {1337GodotBody3D *body_A = body_owner.get_or_null(p_body_A);1338ERR_FAIL_NULL(body_A);13391340if (!p_body_B.is_valid()) {1341ERR_FAIL_NULL(body_A->get_space());1342p_body_B = body_A->get_space()->get_static_global_body();1343}13441345GodotBody3D *body_B = body_owner.get_or_null(p_body_B);1346ERR_FAIL_NULL(body_B);13471348ERR_FAIL_COND(body_A == body_B);13491350GodotJoint3D *prev_joint = joint_owner.get_or_null(p_joint);1351ERR_FAIL_NULL(prev_joint);13521353GodotJoint3D *joint = memnew(GodotHingeJoint3D(body_A, body_B, p_frame_A, p_frame_B));13541355joint->copy_settings_from(prev_joint);1356joint_owner.replace(p_joint, joint);1357memdelete(prev_joint);1358}13591360void GodotPhysicsServer3D::joint_make_hinge_simple(RID p_joint, RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) {1361GodotBody3D *body_A = body_owner.get_or_null(p_body_A);1362ERR_FAIL_NULL(body_A);13631364if (!p_body_B.is_valid()) {1365ERR_FAIL_NULL(body_A->get_space());1366p_body_B = body_A->get_space()->get_static_global_body();1367}13681369GodotBody3D *body_B = body_owner.get_or_null(p_body_B);1370ERR_FAIL_NULL(body_B);13711372ERR_FAIL_COND(body_A == body_B);13731374GodotJoint3D *prev_joint = joint_owner.get_or_null(p_joint);1375ERR_FAIL_NULL(prev_joint);13761377GodotJoint3D *joint = memnew(GodotHingeJoint3D(body_A, body_B, p_pivot_A, p_pivot_B, p_axis_A, p_axis_B));13781379joint->copy_settings_from(prev_joint);1380joint_owner.replace(p_joint, joint);1381memdelete(prev_joint);1382}13831384void GodotPhysicsServer3D::hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) {1385GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1386ERR_FAIL_NULL(joint);1387ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_HINGE);1388GodotHingeJoint3D *hinge_joint = static_cast<GodotHingeJoint3D *>(joint);1389hinge_joint->set_param(p_param, p_value);1390}13911392real_t GodotPhysicsServer3D::hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const {1393GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1394ERR_FAIL_NULL_V(joint, 0);1395ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_HINGE, 0);1396GodotHingeJoint3D *hinge_joint = static_cast<GodotHingeJoint3D *>(joint);1397return hinge_joint->get_param(p_param);1398}13991400void GodotPhysicsServer3D::hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_enabled) {1401GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1402ERR_FAIL_NULL(joint);1403ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_HINGE);1404GodotHingeJoint3D *hinge_joint = static_cast<GodotHingeJoint3D *>(joint);1405hinge_joint->set_flag(p_flag, p_enabled);1406}14071408bool GodotPhysicsServer3D::hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const {1409GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1410ERR_FAIL_NULL_V(joint, false);1411ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_HINGE, false);1412GodotHingeJoint3D *hinge_joint = static_cast<GodotHingeJoint3D *>(joint);1413return hinge_joint->get_flag(p_flag);1414}14151416void GodotPhysicsServer3D::joint_set_solver_priority(RID p_joint, int p_priority) {1417GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1418ERR_FAIL_NULL(joint);1419joint->set_priority(p_priority);1420}14211422int GodotPhysicsServer3D::joint_get_solver_priority(RID p_joint) const {1423GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1424ERR_FAIL_NULL_V(joint, 0);1425return joint->get_priority();1426}14271428void GodotPhysicsServer3D::joint_disable_collisions_between_bodies(RID p_joint, bool p_disable) {1429GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1430ERR_FAIL_NULL(joint);14311432joint->disable_collisions_between_bodies(p_disable);14331434if (2 == joint->get_body_count()) {1435GodotBody3D *body_a = *joint->get_body_ptr();1436GodotBody3D *body_b = *(joint->get_body_ptr() + 1);14371438if (p_disable) {1439body_add_collision_exception(body_a->get_self(), body_b->get_self());1440body_add_collision_exception(body_b->get_self(), body_a->get_self());1441} else {1442body_remove_collision_exception(body_a->get_self(), body_b->get_self());1443body_remove_collision_exception(body_b->get_self(), body_a->get_self());1444}1445}1446}14471448bool GodotPhysicsServer3D::joint_is_disabled_collisions_between_bodies(RID p_joint) const {1449GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1450ERR_FAIL_NULL_V(joint, true);14511452return joint->is_disabled_collisions_between_bodies();1453}14541455GodotPhysicsServer3D::JointType GodotPhysicsServer3D::joint_get_type(RID p_joint) const {1456GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1457ERR_FAIL_NULL_V(joint, JOINT_TYPE_PIN);1458return joint->get_type();1459}14601461void GodotPhysicsServer3D::joint_make_slider(RID p_joint, RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) {1462GodotBody3D *body_A = body_owner.get_or_null(p_body_A);1463ERR_FAIL_NULL(body_A);14641465if (!p_body_B.is_valid()) {1466ERR_FAIL_NULL(body_A->get_space());1467p_body_B = body_A->get_space()->get_static_global_body();1468}14691470GodotBody3D *body_B = body_owner.get_or_null(p_body_B);1471ERR_FAIL_NULL(body_B);14721473ERR_FAIL_COND(body_A == body_B);14741475GodotJoint3D *prev_joint = joint_owner.get_or_null(p_joint);1476ERR_FAIL_NULL(prev_joint);14771478GodotJoint3D *joint = memnew(GodotSliderJoint3D(body_A, body_B, p_local_frame_A, p_local_frame_B));14791480joint->copy_settings_from(prev_joint);1481joint_owner.replace(p_joint, joint);1482memdelete(prev_joint);1483}14841485void GodotPhysicsServer3D::slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) {1486GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1487ERR_FAIL_NULL(joint);1488ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_SLIDER);1489GodotSliderJoint3D *slider_joint = static_cast<GodotSliderJoint3D *>(joint);1490slider_joint->set_param(p_param, p_value);1491}14921493real_t GodotPhysicsServer3D::slider_joint_get_param(RID p_joint, SliderJointParam p_param) const {1494GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1495ERR_FAIL_NULL_V(joint, 0);1496ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_CONE_TWIST, 0);1497GodotSliderJoint3D *slider_joint = static_cast<GodotSliderJoint3D *>(joint);1498return slider_joint->get_param(p_param);1499}15001501void GodotPhysicsServer3D::joint_make_cone_twist(RID p_joint, RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) {1502GodotBody3D *body_A = body_owner.get_or_null(p_body_A);1503ERR_FAIL_NULL(body_A);15041505if (!p_body_B.is_valid()) {1506ERR_FAIL_NULL(body_A->get_space());1507p_body_B = body_A->get_space()->get_static_global_body();1508}15091510GodotBody3D *body_B = body_owner.get_or_null(p_body_B);1511ERR_FAIL_NULL(body_B);15121513ERR_FAIL_COND(body_A == body_B);15141515GodotJoint3D *prev_joint = joint_owner.get_or_null(p_joint);1516ERR_FAIL_NULL(prev_joint);15171518GodotJoint3D *joint = memnew(GodotConeTwistJoint3D(body_A, body_B, p_local_frame_A, p_local_frame_B));15191520joint->copy_settings_from(prev_joint);1521joint_owner.replace(p_joint, joint);1522memdelete(prev_joint);1523}15241525void GodotPhysicsServer3D::cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) {1526GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1527ERR_FAIL_NULL(joint);1528ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_CONE_TWIST);1529GodotConeTwistJoint3D *cone_twist_joint = static_cast<GodotConeTwistJoint3D *>(joint);1530cone_twist_joint->set_param(p_param, p_value);1531}15321533real_t GodotPhysicsServer3D::cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const {1534GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1535ERR_FAIL_NULL_V(joint, 0);1536ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_CONE_TWIST, 0);1537GodotConeTwistJoint3D *cone_twist_joint = static_cast<GodotConeTwistJoint3D *>(joint);1538return cone_twist_joint->get_param(p_param);1539}15401541void GodotPhysicsServer3D::joint_make_generic_6dof(RID p_joint, RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) {1542GodotBody3D *body_A = body_owner.get_or_null(p_body_A);1543ERR_FAIL_NULL(body_A);15441545if (!p_body_B.is_valid()) {1546ERR_FAIL_NULL(body_A->get_space());1547p_body_B = body_A->get_space()->get_static_global_body();1548}15491550GodotBody3D *body_B = body_owner.get_or_null(p_body_B);1551ERR_FAIL_NULL(body_B);15521553ERR_FAIL_COND(body_A == body_B);15541555GodotJoint3D *prev_joint = joint_owner.get_or_null(p_joint);1556ERR_FAIL_NULL(prev_joint);15571558GodotJoint3D *joint = memnew(GodotGeneric6DOFJoint3D(body_A, body_B, p_local_frame_A, p_local_frame_B, true));15591560joint->copy_settings_from(prev_joint);1561joint_owner.replace(p_joint, joint);1562memdelete(prev_joint);1563}15641565void GodotPhysicsServer3D::generic_6dof_joint_set_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param, real_t p_value) {1566GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1567ERR_FAIL_NULL(joint);1568ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_6DOF);1569GodotGeneric6DOFJoint3D *generic_6dof_joint = static_cast<GodotGeneric6DOFJoint3D *>(joint);1570generic_6dof_joint->set_param(p_axis, p_param, p_value);1571}15721573real_t GodotPhysicsServer3D::generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) const {1574GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1575ERR_FAIL_NULL_V(joint, 0);1576ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_6DOF, 0);1577GodotGeneric6DOFJoint3D *generic_6dof_joint = static_cast<GodotGeneric6DOFJoint3D *>(joint);1578return generic_6dof_joint->get_param(p_axis, p_param);1579}15801581void GodotPhysicsServer3D::generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag, bool p_enable) {1582GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1583ERR_FAIL_NULL(joint);1584ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_6DOF);1585GodotGeneric6DOFJoint3D *generic_6dof_joint = static_cast<GodotGeneric6DOFJoint3D *>(joint);1586generic_6dof_joint->set_flag(p_axis, p_flag, p_enable);1587}15881589bool GodotPhysicsServer3D::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag) const {1590GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1591ERR_FAIL_NULL_V(joint, false);1592ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_6DOF, false);1593GodotGeneric6DOFJoint3D *generic_6dof_joint = static_cast<GodotGeneric6DOFJoint3D *>(joint);1594return generic_6dof_joint->get_flag(p_axis, p_flag);1595}15961597void GodotPhysicsServer3D::free(RID p_rid) {1598_update_shapes(); //just in case15991600if (shape_owner.owns(p_rid)) {1601GodotShape3D *shape = shape_owner.get_or_null(p_rid);16021603while (shape->get_owners().size()) {1604GodotShapeOwner3D *so = shape->get_owners().begin()->key;1605so->remove_shape(shape);1606}16071608shape_owner.free(p_rid);1609memdelete(shape);1610} else if (body_owner.owns(p_rid)) {1611GodotBody3D *body = body_owner.get_or_null(p_rid);16121613body->set_space(nullptr);16141615while (body->get_shape_count()) {1616body->remove_shape(0);1617}16181619body_owner.free(p_rid);1620memdelete(body);1621} else if (soft_body_owner.owns(p_rid)) {1622GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_rid);16231624soft_body->set_space(nullptr);16251626soft_body_owner.free(p_rid);1627memdelete(soft_body);1628} else if (area_owner.owns(p_rid)) {1629GodotArea3D *area = area_owner.get_or_null(p_rid);16301631area->set_space(nullptr);16321633while (area->get_shape_count()) {1634area->remove_shape(0);1635}16361637area_owner.free(p_rid);1638memdelete(area);1639} else if (space_owner.owns(p_rid)) {1640GodotSpace3D *space = space_owner.get_or_null(p_rid);16411642while (space->get_objects().size()) {1643GodotCollisionObject3D *co = static_cast<GodotCollisionObject3D *>(*space->get_objects().begin());1644co->set_space(nullptr);1645}16461647active_spaces.erase(space);1648free(space->get_default_area()->get_self());1649free(space->get_static_global_body());16501651space_owner.free(p_rid);1652memdelete(space);1653} else if (joint_owner.owns(p_rid)) {1654GodotJoint3D *joint = joint_owner.get_or_null(p_rid);16551656joint_owner.free(p_rid);1657memdelete(joint);16581659} else {1660ERR_FAIL_MSG("Invalid ID.");1661}1662}16631664void GodotPhysicsServer3D::set_active(bool p_active) {1665active = p_active;1666}16671668void GodotPhysicsServer3D::init() {1669stepper = memnew(GodotStep3D);1670}16711672void GodotPhysicsServer3D::step(real_t p_step) {1673if (!active) {1674return;1675}16761677_update_shapes();16781679island_count = 0;1680active_objects = 0;1681collision_pairs = 0;1682for (GodotSpace3D *E : active_spaces) {1683stepper->step(E, p_step);1684island_count += E->get_island_count();1685active_objects += E->get_active_objects();1686collision_pairs += E->get_collision_pairs();1687}1688}16891690void GodotPhysicsServer3D::sync() {1691doing_sync = true;1692}16931694void GodotPhysicsServer3D::flush_queries() {1695if (!active) {1696return;1697}16981699flushing_queries = true;17001701uint64_t time_beg = OS::get_singleton()->get_ticks_usec();17021703for (GodotSpace3D *E : active_spaces) {1704GodotSpace3D *space = E;1705space->call_queries();1706}17071708flushing_queries = false;17091710if (EngineDebugger::is_profiling("servers")) {1711uint64_t total_time[GodotSpace3D::ELAPSED_TIME_MAX];1712static const char *time_name[GodotSpace3D::ELAPSED_TIME_MAX] = {1713"integrate_forces",1714"generate_islands",1715"setup_constraints",1716"solve_constraints",1717"integrate_velocities"1718};17191720for (int i = 0; i < GodotSpace3D::ELAPSED_TIME_MAX; i++) {1721total_time[i] = 0;1722}17231724for (const GodotSpace3D *E : active_spaces) {1725for (int i = 0; i < GodotSpace3D::ELAPSED_TIME_MAX; i++) {1726total_time[i] += E->get_elapsed_time(GodotSpace3D::ElapsedTime(i));1727}1728}17291730Array values;1731values.resize(GodotSpace3D::ELAPSED_TIME_MAX * 2);1732for (int i = 0; i < GodotSpace3D::ELAPSED_TIME_MAX; i++) {1733values[i * 2 + 0] = time_name[i];1734values[i * 2 + 1] = USEC_TO_SEC(total_time[i]);1735}1736values.push_back("flush_queries");1737values.push_back(USEC_TO_SEC(OS::get_singleton()->get_ticks_usec() - time_beg));17381739values.push_front("physics_3d");1740EngineDebugger::profiler_add_frame_data("servers", values);1741}1742}17431744void GodotPhysicsServer3D::end_sync() {1745doing_sync = false;1746}17471748void GodotPhysicsServer3D::finish() {1749memdelete(stepper);1750}17511752int GodotPhysicsServer3D::get_process_info(ProcessInfo p_info) {1753switch (p_info) {1754case INFO_ACTIVE_OBJECTS: {1755return active_objects;1756} break;1757case INFO_COLLISION_PAIRS: {1758return collision_pairs;1759} break;1760case INFO_ISLAND_COUNT: {1761return island_count;1762} break;1763}17641765return 0;1766}17671768void GodotPhysicsServer3D::_update_shapes() {1769while (pending_shape_update_list.first()) {1770pending_shape_update_list.first()->self()->_shape_changed();1771pending_shape_update_list.remove(pending_shape_update_list.first());1772}1773}17741775void GodotPhysicsServer3D::_shape_col_cbk(const Vector3 &p_point_A, int p_index_A, const Vector3 &p_point_B, int p_index_B, const Vector3 &normal, void *p_userdata) {1776CollCbkData *cbk = static_cast<CollCbkData *>(p_userdata);17771778if (cbk->max == 0) {1779return;1780}17811782if (cbk->amount == cbk->max) {1783//find least deep1784real_t min_depth = 1e20;1785int min_depth_idx = 0;1786for (int i = 0; i < cbk->amount; i++) {1787real_t d = cbk->ptr[i * 2 + 0].distance_squared_to(cbk->ptr[i * 2 + 1]);1788if (d < min_depth) {1789min_depth = d;1790min_depth_idx = i;1791}1792}17931794real_t d = p_point_A.distance_squared_to(p_point_B);1795if (d < min_depth) {1796return;1797}1798cbk->ptr[min_depth_idx * 2 + 0] = p_point_A;1799cbk->ptr[min_depth_idx * 2 + 1] = p_point_B;18001801} else {1802cbk->ptr[cbk->amount * 2 + 0] = p_point_A;1803cbk->ptr[cbk->amount * 2 + 1] = p_point_B;1804cbk->amount++;1805}1806}18071808GodotPhysicsServer3D *GodotPhysicsServer3D::godot_singleton = nullptr;1809GodotPhysicsServer3D::GodotPhysicsServer3D(bool p_using_threads) {1810godot_singleton = this;1811GodotBroadPhase3D::create_func = GodotBroadPhase3DBVH::_create;18121813using_threads = p_using_threads;1814}181518161817