Path: blob/master/modules/godot_physics_3d/godot_physics_server_3d.cpp
21102 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, RequiredParam<PhysicsServer3DRenderingServerHandler> rp_rendering_server_handler) {979GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);980ERR_FAIL_NULL(soft_body);981EXTRACT_PARAM_OR_FAIL(p_rendering_server_handler, rp_rendering_server_handler);982983soft_body->update_rendering_server(p_rendering_server_handler);984}985986void GodotPhysicsServer3D::soft_body_set_space(RID p_body, RID p_space) {987GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);988ERR_FAIL_NULL(soft_body);989990GodotSpace3D *space = nullptr;991if (p_space.is_valid()) {992space = space_owner.get_or_null(p_space);993ERR_FAIL_NULL(space);994}995996if (soft_body->get_space() == space) {997return;998}9991000soft_body->set_space(space);1001}10021003RID GodotPhysicsServer3D::soft_body_get_space(RID p_body) const {1004GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1005ERR_FAIL_NULL_V(soft_body, RID());10061007GodotSpace3D *space = soft_body->get_space();1008if (!space) {1009return RID();1010}1011return space->get_self();1012}10131014void GodotPhysicsServer3D::soft_body_set_collision_layer(RID p_body, uint32_t p_layer) {1015GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1016ERR_FAIL_NULL(soft_body);10171018soft_body->set_collision_layer(p_layer);1019}10201021uint32_t GodotPhysicsServer3D::soft_body_get_collision_layer(RID p_body) const {1022GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1023ERR_FAIL_NULL_V(soft_body, 0);10241025return soft_body->get_collision_layer();1026}10271028void GodotPhysicsServer3D::soft_body_set_collision_mask(RID p_body, uint32_t p_mask) {1029GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1030ERR_FAIL_NULL(soft_body);10311032soft_body->set_collision_mask(p_mask);1033}10341035uint32_t GodotPhysicsServer3D::soft_body_get_collision_mask(RID p_body) const {1036GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1037ERR_FAIL_NULL_V(soft_body, 0);10381039return soft_body->get_collision_mask();1040}10411042void GodotPhysicsServer3D::soft_body_add_collision_exception(RID p_body, RID p_body_b) {1043GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1044ERR_FAIL_NULL(soft_body);10451046soft_body->add_exception(p_body_b);1047}10481049void GodotPhysicsServer3D::soft_body_remove_collision_exception(RID p_body, RID p_body_b) {1050GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1051ERR_FAIL_NULL(soft_body);10521053soft_body->remove_exception(p_body_b);1054}10551056void GodotPhysicsServer3D::soft_body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) {1057GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1058ERR_FAIL_NULL(soft_body);10591060for (int i = 0; i < soft_body->get_exceptions().size(); i++) {1061p_exceptions->push_back(soft_body->get_exceptions()[i]);1062}1063}10641065void GodotPhysicsServer3D::soft_body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) {1066GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1067ERR_FAIL_NULL(soft_body);10681069soft_body->set_state(p_state, p_variant);1070}10711072Variant GodotPhysicsServer3D::soft_body_get_state(RID p_body, BodyState p_state) const {1073GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1074ERR_FAIL_NULL_V(soft_body, Variant());10751076return soft_body->get_state(p_state);1077}10781079void GodotPhysicsServer3D::soft_body_set_transform(RID p_body, const Transform3D &p_transform) {1080GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1081ERR_FAIL_NULL(soft_body);10821083soft_body->set_state(BODY_STATE_TRANSFORM, p_transform);1084}10851086void GodotPhysicsServer3D::soft_body_set_ray_pickable(RID p_body, bool p_enable) {1087GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1088ERR_FAIL_NULL(soft_body);10891090soft_body->set_ray_pickable(p_enable);1091}10921093void GodotPhysicsServer3D::soft_body_set_simulation_precision(RID p_body, int p_simulation_precision) {1094GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1095ERR_FAIL_NULL(soft_body);10961097soft_body->set_iteration_count(p_simulation_precision);1098}10991100int GodotPhysicsServer3D::soft_body_get_simulation_precision(RID p_body) const {1101GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1102ERR_FAIL_NULL_V(soft_body, 0.f);11031104return soft_body->get_iteration_count();1105}11061107void GodotPhysicsServer3D::soft_body_set_total_mass(RID p_body, real_t p_total_mass) {1108GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1109ERR_FAIL_NULL(soft_body);11101111soft_body->set_total_mass(p_total_mass);1112}11131114real_t GodotPhysicsServer3D::soft_body_get_total_mass(RID p_body) const {1115GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1116ERR_FAIL_NULL_V(soft_body, 0.f);11171118return soft_body->get_total_mass();1119}11201121void GodotPhysicsServer3D::soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) {1122GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1123ERR_FAIL_NULL(soft_body);11241125soft_body->set_linear_stiffness(p_stiffness);1126}11271128real_t GodotPhysicsServer3D::soft_body_get_linear_stiffness(RID p_body) const {1129GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1130ERR_FAIL_NULL_V(soft_body, 0.f);11311132return soft_body->get_linear_stiffness();1133}11341135void GodotPhysicsServer3D::soft_body_set_shrinking_factor(RID p_body, real_t p_shrinking_factor) {1136GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1137ERR_FAIL_NULL(soft_body);11381139soft_body->set_shrinking_factor(p_shrinking_factor);1140}11411142real_t GodotPhysicsServer3D::soft_body_get_shrinking_factor(RID p_body) const {1143GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1144ERR_FAIL_NULL_V(soft_body, 0.f);11451146return soft_body->get_shrinking_factor();1147}11481149void GodotPhysicsServer3D::soft_body_set_pressure_coefficient(RID p_body, real_t p_pressure_coefficient) {1150GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1151ERR_FAIL_NULL(soft_body);11521153soft_body->set_pressure_coefficient(p_pressure_coefficient);1154}11551156real_t GodotPhysicsServer3D::soft_body_get_pressure_coefficient(RID p_body) const {1157GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1158ERR_FAIL_NULL_V(soft_body, 0.f);11591160return soft_body->get_pressure_coefficient();1161}11621163void GodotPhysicsServer3D::soft_body_set_damping_coefficient(RID p_body, real_t p_damping_coefficient) {1164GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1165ERR_FAIL_NULL(soft_body);11661167soft_body->set_damping_coefficient(p_damping_coefficient);1168}11691170real_t GodotPhysicsServer3D::soft_body_get_damping_coefficient(RID p_body) const {1171GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1172ERR_FAIL_NULL_V(soft_body, 0.f);11731174return soft_body->get_damping_coefficient();1175}11761177void GodotPhysicsServer3D::soft_body_set_drag_coefficient(RID p_body, real_t p_drag_coefficient) {1178GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1179ERR_FAIL_NULL(soft_body);11801181soft_body->set_drag_coefficient(p_drag_coefficient);1182}11831184real_t GodotPhysicsServer3D::soft_body_get_drag_coefficient(RID p_body) const {1185GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1186ERR_FAIL_NULL_V(soft_body, 0.f);11871188return soft_body->get_drag_coefficient();1189}11901191void GodotPhysicsServer3D::soft_body_set_mesh(RID p_body, RID p_mesh) {1192GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1193ERR_FAIL_NULL(soft_body);11941195soft_body->set_mesh(p_mesh);1196}11971198AABB GodotPhysicsServer3D::soft_body_get_bounds(RID p_body) const {1199GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1200ERR_FAIL_NULL_V(soft_body, AABB());12011202return soft_body->get_bounds();1203}12041205void GodotPhysicsServer3D::soft_body_move_point(RID p_body, int p_point_index, const Vector3 &p_global_position) {1206GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1207ERR_FAIL_NULL(soft_body);12081209soft_body->set_vertex_position(p_point_index, p_global_position);1210}12111212Vector3 GodotPhysicsServer3D::soft_body_get_point_global_position(RID p_body, int p_point_index) const {1213GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1214ERR_FAIL_NULL_V(soft_body, Vector3());12151216return soft_body->get_vertex_position(p_point_index);1217}12181219void GodotPhysicsServer3D::soft_body_remove_all_pinned_points(RID p_body) {1220GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1221ERR_FAIL_NULL(soft_body);12221223soft_body->unpin_all_vertices();1224}12251226void GodotPhysicsServer3D::soft_body_pin_point(RID p_body, int p_point_index, bool p_pin) {1227GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1228ERR_FAIL_NULL(soft_body);12291230if (p_pin) {1231soft_body->pin_vertex(p_point_index);1232} else {1233soft_body->unpin_vertex(p_point_index);1234}1235}12361237bool GodotPhysicsServer3D::soft_body_is_point_pinned(RID p_body, int p_point_index) const {1238GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);1239ERR_FAIL_NULL_V(soft_body, false);12401241return soft_body->is_vertex_pinned(p_point_index);1242}12431244/* JOINT API */12451246RID GodotPhysicsServer3D::joint_create() {1247GodotJoint3D *joint = memnew(GodotJoint3D);1248RID rid = joint_owner.make_rid(joint);1249joint->set_self(rid);1250return rid;1251}12521253void GodotPhysicsServer3D::joint_clear(RID p_joint) {1254GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1255ERR_FAIL_NULL(joint);1256if (joint->get_type() != JOINT_TYPE_MAX) {1257GodotJoint3D *empty_joint = memnew(GodotJoint3D);1258empty_joint->copy_settings_from(joint);12591260joint_owner.replace(p_joint, empty_joint);1261memdelete(joint);1262}1263}12641265void 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) {1266GodotBody3D *body_A = body_owner.get_or_null(p_body_A);1267ERR_FAIL_NULL(body_A);12681269if (!p_body_B.is_valid()) {1270ERR_FAIL_NULL(body_A->get_space());1271p_body_B = body_A->get_space()->get_static_global_body();1272}12731274GodotBody3D *body_B = body_owner.get_or_null(p_body_B);1275ERR_FAIL_NULL(body_B);12761277ERR_FAIL_COND(body_A == body_B);12781279GodotJoint3D *prev_joint = joint_owner.get_or_null(p_joint);1280ERR_FAIL_NULL(prev_joint);12811282GodotJoint3D *joint = memnew(GodotPinJoint3D(body_A, p_local_A, body_B, p_local_B));12831284joint->copy_settings_from(prev_joint);1285joint_owner.replace(p_joint, joint);1286memdelete(prev_joint);1287}12881289void GodotPhysicsServer3D::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) {1290GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1291ERR_FAIL_NULL(joint);1292ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN);1293GodotPinJoint3D *pin_joint = static_cast<GodotPinJoint3D *>(joint);1294pin_joint->set_param(p_param, p_value);1295}12961297real_t GodotPhysicsServer3D::pin_joint_get_param(RID p_joint, PinJointParam p_param) const {1298GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1299ERR_FAIL_NULL_V(joint, 0);1300ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, 0);1301GodotPinJoint3D *pin_joint = static_cast<GodotPinJoint3D *>(joint);1302return pin_joint->get_param(p_param);1303}13041305void GodotPhysicsServer3D::pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) {1306GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1307ERR_FAIL_NULL(joint);1308ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN);1309GodotPinJoint3D *pin_joint = static_cast<GodotPinJoint3D *>(joint);1310pin_joint->set_pos_a(p_A);1311}13121313Vector3 GodotPhysicsServer3D::pin_joint_get_local_a(RID p_joint) const {1314GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1315ERR_FAIL_NULL_V(joint, Vector3());1316ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, Vector3());1317GodotPinJoint3D *pin_joint = static_cast<GodotPinJoint3D *>(joint);1318return pin_joint->get_position_a();1319}13201321void GodotPhysicsServer3D::pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) {1322GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1323ERR_FAIL_NULL(joint);1324ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN);1325GodotPinJoint3D *pin_joint = static_cast<GodotPinJoint3D *>(joint);1326pin_joint->set_pos_b(p_B);1327}13281329Vector3 GodotPhysicsServer3D::pin_joint_get_local_b(RID p_joint) const {1330GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1331ERR_FAIL_NULL_V(joint, Vector3());1332ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, Vector3());1333GodotPinJoint3D *pin_joint = static_cast<GodotPinJoint3D *>(joint);1334return pin_joint->get_position_b();1335}13361337void 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) {1338GodotBody3D *body_A = body_owner.get_or_null(p_body_A);1339ERR_FAIL_NULL(body_A);13401341if (!p_body_B.is_valid()) {1342ERR_FAIL_NULL(body_A->get_space());1343p_body_B = body_A->get_space()->get_static_global_body();1344}13451346GodotBody3D *body_B = body_owner.get_or_null(p_body_B);1347ERR_FAIL_NULL(body_B);13481349ERR_FAIL_COND(body_A == body_B);13501351GodotJoint3D *prev_joint = joint_owner.get_or_null(p_joint);1352ERR_FAIL_NULL(prev_joint);13531354GodotJoint3D *joint = memnew(GodotHingeJoint3D(body_A, body_B, p_frame_A, p_frame_B));13551356joint->copy_settings_from(prev_joint);1357joint_owner.replace(p_joint, joint);1358memdelete(prev_joint);1359}13601361void 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) {1362GodotBody3D *body_A = body_owner.get_or_null(p_body_A);1363ERR_FAIL_NULL(body_A);13641365if (!p_body_B.is_valid()) {1366ERR_FAIL_NULL(body_A->get_space());1367p_body_B = body_A->get_space()->get_static_global_body();1368}13691370GodotBody3D *body_B = body_owner.get_or_null(p_body_B);1371ERR_FAIL_NULL(body_B);13721373ERR_FAIL_COND(body_A == body_B);13741375GodotJoint3D *prev_joint = joint_owner.get_or_null(p_joint);1376ERR_FAIL_NULL(prev_joint);13771378GodotJoint3D *joint = memnew(GodotHingeJoint3D(body_A, body_B, p_pivot_A, p_pivot_B, p_axis_A, p_axis_B));13791380joint->copy_settings_from(prev_joint);1381joint_owner.replace(p_joint, joint);1382memdelete(prev_joint);1383}13841385void GodotPhysicsServer3D::hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) {1386GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1387ERR_FAIL_NULL(joint);1388ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_HINGE);1389GodotHingeJoint3D *hinge_joint = static_cast<GodotHingeJoint3D *>(joint);1390hinge_joint->set_param(p_param, p_value);1391}13921393real_t GodotPhysicsServer3D::hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const {1394GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1395ERR_FAIL_NULL_V(joint, 0);1396ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_HINGE, 0);1397GodotHingeJoint3D *hinge_joint = static_cast<GodotHingeJoint3D *>(joint);1398return hinge_joint->get_param(p_param);1399}14001401void GodotPhysicsServer3D::hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_enabled) {1402GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1403ERR_FAIL_NULL(joint);1404ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_HINGE);1405GodotHingeJoint3D *hinge_joint = static_cast<GodotHingeJoint3D *>(joint);1406hinge_joint->set_flag(p_flag, p_enabled);1407}14081409bool GodotPhysicsServer3D::hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const {1410GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1411ERR_FAIL_NULL_V(joint, false);1412ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_HINGE, false);1413GodotHingeJoint3D *hinge_joint = static_cast<GodotHingeJoint3D *>(joint);1414return hinge_joint->get_flag(p_flag);1415}14161417void GodotPhysicsServer3D::joint_set_solver_priority(RID p_joint, int p_priority) {1418GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1419ERR_FAIL_NULL(joint);1420joint->set_priority(p_priority);1421}14221423int GodotPhysicsServer3D::joint_get_solver_priority(RID p_joint) const {1424GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1425ERR_FAIL_NULL_V(joint, 0);1426return joint->get_priority();1427}14281429void GodotPhysicsServer3D::joint_disable_collisions_between_bodies(RID p_joint, bool p_disable) {1430GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1431ERR_FAIL_NULL(joint);14321433joint->disable_collisions_between_bodies(p_disable);14341435if (2 == joint->get_body_count()) {1436GodotBody3D *body_a = *joint->get_body_ptr();1437GodotBody3D *body_b = *(joint->get_body_ptr() + 1);14381439if (p_disable) {1440body_add_collision_exception(body_a->get_self(), body_b->get_self());1441body_add_collision_exception(body_b->get_self(), body_a->get_self());1442} else {1443body_remove_collision_exception(body_a->get_self(), body_b->get_self());1444body_remove_collision_exception(body_b->get_self(), body_a->get_self());1445}1446}1447}14481449bool GodotPhysicsServer3D::joint_is_disabled_collisions_between_bodies(RID p_joint) const {1450GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1451ERR_FAIL_NULL_V(joint, true);14521453return joint->is_disabled_collisions_between_bodies();1454}14551456GodotPhysicsServer3D::JointType GodotPhysicsServer3D::joint_get_type(RID p_joint) const {1457GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1458ERR_FAIL_NULL_V(joint, JOINT_TYPE_PIN);1459return joint->get_type();1460}14611462void 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) {1463GodotBody3D *body_A = body_owner.get_or_null(p_body_A);1464ERR_FAIL_NULL(body_A);14651466if (!p_body_B.is_valid()) {1467ERR_FAIL_NULL(body_A->get_space());1468p_body_B = body_A->get_space()->get_static_global_body();1469}14701471GodotBody3D *body_B = body_owner.get_or_null(p_body_B);1472ERR_FAIL_NULL(body_B);14731474ERR_FAIL_COND(body_A == body_B);14751476GodotJoint3D *prev_joint = joint_owner.get_or_null(p_joint);1477ERR_FAIL_NULL(prev_joint);14781479GodotJoint3D *joint = memnew(GodotSliderJoint3D(body_A, body_B, p_local_frame_A, p_local_frame_B));14801481joint->copy_settings_from(prev_joint);1482joint_owner.replace(p_joint, joint);1483memdelete(prev_joint);1484}14851486void GodotPhysicsServer3D::slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) {1487GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1488ERR_FAIL_NULL(joint);1489ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_SLIDER);1490GodotSliderJoint3D *slider_joint = static_cast<GodotSliderJoint3D *>(joint);1491slider_joint->set_param(p_param, p_value);1492}14931494real_t GodotPhysicsServer3D::slider_joint_get_param(RID p_joint, SliderJointParam p_param) const {1495GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1496ERR_FAIL_NULL_V(joint, 0);1497ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_CONE_TWIST, 0);1498GodotSliderJoint3D *slider_joint = static_cast<GodotSliderJoint3D *>(joint);1499return slider_joint->get_param(p_param);1500}15011502void 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) {1503GodotBody3D *body_A = body_owner.get_or_null(p_body_A);1504ERR_FAIL_NULL(body_A);15051506if (!p_body_B.is_valid()) {1507ERR_FAIL_NULL(body_A->get_space());1508p_body_B = body_A->get_space()->get_static_global_body();1509}15101511GodotBody3D *body_B = body_owner.get_or_null(p_body_B);1512ERR_FAIL_NULL(body_B);15131514ERR_FAIL_COND(body_A == body_B);15151516GodotJoint3D *prev_joint = joint_owner.get_or_null(p_joint);1517ERR_FAIL_NULL(prev_joint);15181519GodotJoint3D *joint = memnew(GodotConeTwistJoint3D(body_A, body_B, p_local_frame_A, p_local_frame_B));15201521joint->copy_settings_from(prev_joint);1522joint_owner.replace(p_joint, joint);1523memdelete(prev_joint);1524}15251526void GodotPhysicsServer3D::cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) {1527GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1528ERR_FAIL_NULL(joint);1529ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_CONE_TWIST);1530GodotConeTwistJoint3D *cone_twist_joint = static_cast<GodotConeTwistJoint3D *>(joint);1531cone_twist_joint->set_param(p_param, p_value);1532}15331534real_t GodotPhysicsServer3D::cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const {1535GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1536ERR_FAIL_NULL_V(joint, 0);1537ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_CONE_TWIST, 0);1538GodotConeTwistJoint3D *cone_twist_joint = static_cast<GodotConeTwistJoint3D *>(joint);1539return cone_twist_joint->get_param(p_param);1540}15411542void 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) {1543GodotBody3D *body_A = body_owner.get_or_null(p_body_A);1544ERR_FAIL_NULL(body_A);15451546if (!p_body_B.is_valid()) {1547ERR_FAIL_NULL(body_A->get_space());1548p_body_B = body_A->get_space()->get_static_global_body();1549}15501551GodotBody3D *body_B = body_owner.get_or_null(p_body_B);1552ERR_FAIL_NULL(body_B);15531554ERR_FAIL_COND(body_A == body_B);15551556GodotJoint3D *prev_joint = joint_owner.get_or_null(p_joint);1557ERR_FAIL_NULL(prev_joint);15581559GodotJoint3D *joint = memnew(GodotGeneric6DOFJoint3D(body_A, body_B, p_local_frame_A, p_local_frame_B, true));15601561joint->copy_settings_from(prev_joint);1562joint_owner.replace(p_joint, joint);1563memdelete(prev_joint);1564}15651566void GodotPhysicsServer3D::generic_6dof_joint_set_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param, real_t p_value) {1567GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1568ERR_FAIL_NULL(joint);1569ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_6DOF);1570GodotGeneric6DOFJoint3D *generic_6dof_joint = static_cast<GodotGeneric6DOFJoint3D *>(joint);1571generic_6dof_joint->set_param(p_axis, p_param, p_value);1572}15731574real_t GodotPhysicsServer3D::generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) const {1575GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1576ERR_FAIL_NULL_V(joint, 0);1577ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_6DOF, 0);1578GodotGeneric6DOFJoint3D *generic_6dof_joint = static_cast<GodotGeneric6DOFJoint3D *>(joint);1579return generic_6dof_joint->get_param(p_axis, p_param);1580}15811582void GodotPhysicsServer3D::generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag, bool p_enable) {1583GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1584ERR_FAIL_NULL(joint);1585ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_6DOF);1586GodotGeneric6DOFJoint3D *generic_6dof_joint = static_cast<GodotGeneric6DOFJoint3D *>(joint);1587generic_6dof_joint->set_flag(p_axis, p_flag, p_enable);1588}15891590bool GodotPhysicsServer3D::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag) const {1591GodotJoint3D *joint = joint_owner.get_or_null(p_joint);1592ERR_FAIL_NULL_V(joint, false);1593ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_6DOF, false);1594GodotGeneric6DOFJoint3D *generic_6dof_joint = static_cast<GodotGeneric6DOFJoint3D *>(joint);1595return generic_6dof_joint->get_flag(p_axis, p_flag);1596}15971598void GodotPhysicsServer3D::free_rid(RID p_rid) {1599_update_shapes(); //just in case16001601if (shape_owner.owns(p_rid)) {1602GodotShape3D *shape = shape_owner.get_or_null(p_rid);16031604while (shape->get_owners().size()) {1605GodotShapeOwner3D *so = shape->get_owners().begin()->key;1606so->remove_shape(shape);1607}16081609shape_owner.free(p_rid);1610memdelete(shape);1611} else if (body_owner.owns(p_rid)) {1612GodotBody3D *body = body_owner.get_or_null(p_rid);16131614body->set_space(nullptr);16151616while (body->get_shape_count()) {1617body->remove_shape(0);1618}16191620body_owner.free(p_rid);1621memdelete(body);1622} else if (soft_body_owner.owns(p_rid)) {1623GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_rid);16241625soft_body->set_space(nullptr);16261627soft_body_owner.free(p_rid);1628memdelete(soft_body);1629} else if (area_owner.owns(p_rid)) {1630GodotArea3D *area = area_owner.get_or_null(p_rid);16311632area->set_space(nullptr);16331634while (area->get_shape_count()) {1635area->remove_shape(0);1636}16371638area_owner.free(p_rid);1639memdelete(area);1640} else if (space_owner.owns(p_rid)) {1641GodotSpace3D *space = space_owner.get_or_null(p_rid);16421643while (space->get_objects().size()) {1644GodotCollisionObject3D *co = static_cast<GodotCollisionObject3D *>(*space->get_objects().begin());1645co->set_space(nullptr);1646}16471648active_spaces.erase(space);1649free_rid(space->get_default_area()->get_self());1650free_rid(space->get_static_global_body());16511652space_owner.free(p_rid);1653memdelete(space);1654} else if (joint_owner.owns(p_rid)) {1655GodotJoint3D *joint = joint_owner.get_or_null(p_rid);16561657joint_owner.free(p_rid);1658memdelete(joint);16591660} else {1661ERR_FAIL_MSG("Invalid ID.");1662}1663}16641665void GodotPhysicsServer3D::set_active(bool p_active) {1666active = p_active;1667}16681669void GodotPhysicsServer3D::init() {1670stepper = memnew(GodotStep3D);1671}16721673void GodotPhysicsServer3D::step(real_t p_step) {1674if (!active) {1675return;1676}16771678_update_shapes();16791680island_count = 0;1681active_objects = 0;1682collision_pairs = 0;1683for (GodotSpace3D *E : active_spaces) {1684stepper->step(E, p_step);1685island_count += E->get_island_count();1686active_objects += E->get_active_objects();1687collision_pairs += E->get_collision_pairs();1688}1689}16901691void GodotPhysicsServer3D::sync() {1692doing_sync = true;1693}16941695void GodotPhysicsServer3D::flush_queries() {1696if (!active) {1697return;1698}16991700flushing_queries = true;17011702uint64_t time_beg = OS::get_singleton()->get_ticks_usec();17031704for (GodotSpace3D *E : active_spaces) {1705GodotSpace3D *space = E;1706space->call_queries();1707}17081709flushing_queries = false;17101711if (EngineDebugger::is_profiling("servers")) {1712uint64_t total_time[GodotSpace3D::ELAPSED_TIME_MAX];1713static const char *time_name[GodotSpace3D::ELAPSED_TIME_MAX] = {1714"integrate_forces",1715"generate_islands",1716"setup_constraints",1717"solve_constraints",1718"integrate_velocities"1719};17201721for (int i = 0; i < GodotSpace3D::ELAPSED_TIME_MAX; i++) {1722total_time[i] = 0;1723}17241725for (const GodotSpace3D *E : active_spaces) {1726for (int i = 0; i < GodotSpace3D::ELAPSED_TIME_MAX; i++) {1727total_time[i] += E->get_elapsed_time(GodotSpace3D::ElapsedTime(i));1728}1729}17301731Array values;1732values.resize(GodotSpace3D::ELAPSED_TIME_MAX * 2);1733for (int i = 0; i < GodotSpace3D::ELAPSED_TIME_MAX; i++) {1734values[i * 2 + 0] = time_name[i];1735values[i * 2 + 1] = USEC_TO_SEC(total_time[i]);1736}1737values.push_back("flush_queries");1738values.push_back(USEC_TO_SEC(OS::get_singleton()->get_ticks_usec() - time_beg));17391740values.push_front("physics_3d");1741EngineDebugger::profiler_add_frame_data("servers", values);1742}1743}17441745void GodotPhysicsServer3D::end_sync() {1746doing_sync = false;1747}17481749void GodotPhysicsServer3D::finish() {1750memdelete(stepper);1751}17521753int GodotPhysicsServer3D::get_process_info(ProcessInfo p_info) {1754switch (p_info) {1755case INFO_ACTIVE_OBJECTS: {1756return active_objects;1757} break;1758case INFO_COLLISION_PAIRS: {1759return collision_pairs;1760} break;1761case INFO_ISLAND_COUNT: {1762return island_count;1763} break;1764}17651766return 0;1767}17681769void GodotPhysicsServer3D::_update_shapes() {1770while (pending_shape_update_list.first()) {1771pending_shape_update_list.first()->self()->_shape_changed();1772pending_shape_update_list.remove(pending_shape_update_list.first());1773}1774}17751776void 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) {1777CollCbkData *cbk = static_cast<CollCbkData *>(p_userdata);17781779if (cbk->max == 0) {1780return;1781}17821783if (cbk->amount == cbk->max) {1784//find least deep1785real_t min_depth = 1e20;1786int min_depth_idx = 0;1787for (int i = 0; i < cbk->amount; i++) {1788real_t d = cbk->ptr[i * 2 + 0].distance_squared_to(cbk->ptr[i * 2 + 1]);1789if (d < min_depth) {1790min_depth = d;1791min_depth_idx = i;1792}1793}17941795real_t d = p_point_A.distance_squared_to(p_point_B);1796if (d < min_depth) {1797return;1798}1799cbk->ptr[min_depth_idx * 2 + 0] = p_point_A;1800cbk->ptr[min_depth_idx * 2 + 1] = p_point_B;18011802} else {1803cbk->ptr[cbk->amount * 2 + 0] = p_point_A;1804cbk->ptr[cbk->amount * 2 + 1] = p_point_B;1805cbk->amount++;1806}1807}18081809GodotPhysicsServer3D *GodotPhysicsServer3D::godot_singleton = nullptr;1810GodotPhysicsServer3D::GodotPhysicsServer3D(bool p_using_threads) {1811godot_singleton = this;1812GodotBroadPhase3D::create_func = GodotBroadPhase3DBVH::_create;18131814using_threads = p_using_threads;1815}181618171818