Path: blob/master/modules/godot_physics_2d/godot_physics_server_2d.cpp
10277 views
/**************************************************************************/1/* godot_physics_server_2d.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_2d.h"3132#include "godot_body_direct_state_2d.h"33#include "godot_broad_phase_2d_bvh.h"34#include "godot_collision_solver_2d.h"3536#include "core/config/project_settings.h"37#include "core/debugger/engine_debugger.h"38#include "core/os/os.h"3940#define FLUSH_QUERY_CHECK(m_object) \41ERR_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.");4243RID GodotPhysicsServer2D::_shape_create(ShapeType p_shape) {44GodotShape2D *shape = nullptr;45switch (p_shape) {46case SHAPE_WORLD_BOUNDARY: {47shape = memnew(GodotWorldBoundaryShape2D);48} break;49case SHAPE_SEPARATION_RAY: {50shape = memnew(GodotSeparationRayShape2D);51} break;52case SHAPE_SEGMENT: {53shape = memnew(GodotSegmentShape2D);54} break;55case SHAPE_CIRCLE: {56shape = memnew(GodotCircleShape2D);57} break;58case SHAPE_RECTANGLE: {59shape = memnew(GodotRectangleShape2D);60} break;61case SHAPE_CAPSULE: {62shape = memnew(GodotCapsuleShape2D);63} break;64case SHAPE_CONVEX_POLYGON: {65shape = memnew(GodotConvexPolygonShape2D);66} break;67case SHAPE_CONCAVE_POLYGON: {68shape = memnew(GodotConcavePolygonShape2D);69} break;70case SHAPE_CUSTOM: {71ERR_FAIL_V(RID());7273} break;74}7576RID id = shape_owner.make_rid(shape);77shape->set_self(id);7879return id;80}8182RID GodotPhysicsServer2D::world_boundary_shape_create() {83return _shape_create(SHAPE_WORLD_BOUNDARY);84}8586RID GodotPhysicsServer2D::separation_ray_shape_create() {87return _shape_create(SHAPE_SEPARATION_RAY);88}8990RID GodotPhysicsServer2D::segment_shape_create() {91return _shape_create(SHAPE_SEGMENT);92}9394RID GodotPhysicsServer2D::circle_shape_create() {95return _shape_create(SHAPE_CIRCLE);96}9798RID GodotPhysicsServer2D::rectangle_shape_create() {99return _shape_create(SHAPE_RECTANGLE);100}101102RID GodotPhysicsServer2D::capsule_shape_create() {103return _shape_create(SHAPE_CAPSULE);104}105106RID GodotPhysicsServer2D::convex_polygon_shape_create() {107return _shape_create(SHAPE_CONVEX_POLYGON);108}109110RID GodotPhysicsServer2D::concave_polygon_shape_create() {111return _shape_create(SHAPE_CONCAVE_POLYGON);112}113114void GodotPhysicsServer2D::shape_set_data(RID p_shape, const Variant &p_data) {115GodotShape2D *shape = shape_owner.get_or_null(p_shape);116ERR_FAIL_NULL(shape);117shape->set_data(p_data);118}119120void GodotPhysicsServer2D::shape_set_custom_solver_bias(RID p_shape, real_t p_bias) {121GodotShape2D *shape = shape_owner.get_or_null(p_shape);122ERR_FAIL_NULL(shape);123shape->set_custom_bias(p_bias);124}125126PhysicsServer2D::ShapeType GodotPhysicsServer2D::shape_get_type(RID p_shape) const {127const GodotShape2D *shape = shape_owner.get_or_null(p_shape);128ERR_FAIL_NULL_V(shape, SHAPE_CUSTOM);129return shape->get_type();130}131132Variant GodotPhysicsServer2D::shape_get_data(RID p_shape) const {133const GodotShape2D *shape = shape_owner.get_or_null(p_shape);134ERR_FAIL_NULL_V(shape, Variant());135ERR_FAIL_COND_V(!shape->is_configured(), Variant());136return shape->get_data();137}138139real_t GodotPhysicsServer2D::shape_get_custom_solver_bias(RID p_shape) const {140const GodotShape2D *shape = shape_owner.get_or_null(p_shape);141ERR_FAIL_NULL_V(shape, 0);142return shape->get_custom_bias();143}144145void GodotPhysicsServer2D::_shape_col_cbk(const Vector2 &p_point_A, const Vector2 &p_point_B, void *p_userdata) {146CollCbkData *cbk = static_cast<CollCbkData *>(p_userdata);147148if (cbk->max == 0) {149return;150}151152Vector2 rel_dir = (p_point_A - p_point_B);153real_t rel_length2 = rel_dir.length_squared();154if (cbk->valid_dir != Vector2()) {155if (cbk->valid_depth < 10e20) {156if (rel_length2 > cbk->valid_depth * cbk->valid_depth ||157(rel_length2 > CMP_EPSILON && cbk->valid_dir.dot(rel_dir.normalized()) < CMP_EPSILON)) {158cbk->invalid_by_dir++;159return;160}161} else {162if (rel_length2 > 0 && cbk->valid_dir.dot(rel_dir.normalized()) < CMP_EPSILON) {163return;164}165}166}167168if (cbk->amount == cbk->max) {169//find least deep170real_t min_depth = 1e20;171int min_depth_idx = 0;172for (int i = 0; i < cbk->amount; i++) {173real_t d = cbk->ptr[i * 2 + 0].distance_squared_to(cbk->ptr[i * 2 + 1]);174if (d < min_depth) {175min_depth = d;176min_depth_idx = i;177}178}179180if (rel_length2 < min_depth) {181return;182}183cbk->ptr[min_depth_idx * 2 + 0] = p_point_A;184cbk->ptr[min_depth_idx * 2 + 1] = p_point_B;185cbk->passed++;186187} else {188cbk->ptr[cbk->amount * 2 + 0] = p_point_A;189cbk->ptr[cbk->amount * 2 + 1] = p_point_B;190cbk->amount++;191cbk->passed++;192}193}194195bool GodotPhysicsServer2D::shape_collide(RID p_shape_A, const Transform2D &p_xform_A, const Vector2 &p_motion_A, RID p_shape_B, const Transform2D &p_xform_B, const Vector2 &p_motion_B, Vector2 *r_results, int p_result_max, int &r_result_count) {196GodotShape2D *shape_A = shape_owner.get_or_null(p_shape_A);197ERR_FAIL_NULL_V(shape_A, false);198GodotShape2D *shape_B = shape_owner.get_or_null(p_shape_B);199ERR_FAIL_NULL_V(shape_B, false);200201if (p_result_max == 0) {202return GodotCollisionSolver2D::solve(shape_A, p_xform_A, p_motion_A, shape_B, p_xform_B, p_motion_B, nullptr, nullptr);203}204205CollCbkData cbk;206cbk.max = p_result_max;207cbk.amount = 0;208cbk.passed = 0;209cbk.ptr = r_results;210211bool res = GodotCollisionSolver2D::solve(shape_A, p_xform_A, p_motion_A, shape_B, p_xform_B, p_motion_B, _shape_col_cbk, &cbk);212r_result_count = cbk.amount;213return res;214}215216RID GodotPhysicsServer2D::space_create() {217GodotSpace2D *space = memnew(GodotSpace2D);218RID id = space_owner.make_rid(space);219space->set_self(id);220RID area_id = area_create();221GodotArea2D *area = area_owner.get_or_null(area_id);222ERR_FAIL_NULL_V(area, RID());223space->set_default_area(area);224area->set_space(space);225area->set_priority(-1);226227return id;228}229230void GodotPhysicsServer2D::space_set_active(RID p_space, bool p_active) {231GodotSpace2D *space = space_owner.get_or_null(p_space);232ERR_FAIL_NULL(space);233if (p_active) {234active_spaces.insert(space);235} else {236active_spaces.erase(space);237}238}239240bool GodotPhysicsServer2D::space_is_active(RID p_space) const {241GodotSpace2D *space = space_owner.get_or_null(p_space);242ERR_FAIL_NULL_V(space, false);243244return active_spaces.has(space);245}246247void GodotPhysicsServer2D::space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) {248GodotSpace2D *space = space_owner.get_or_null(p_space);249ERR_FAIL_NULL(space);250251space->set_param(p_param, p_value);252}253254real_t GodotPhysicsServer2D::space_get_param(RID p_space, SpaceParameter p_param) const {255const GodotSpace2D *space = space_owner.get_or_null(p_space);256ERR_FAIL_NULL_V(space, 0);257return space->get_param(p_param);258}259260void GodotPhysicsServer2D::space_set_debug_contacts(RID p_space, int p_max_contacts) {261GodotSpace2D *space = space_owner.get_or_null(p_space);262ERR_FAIL_NULL(space);263space->set_debug_contacts(p_max_contacts);264}265266Vector<Vector2> GodotPhysicsServer2D::space_get_contacts(RID p_space) const {267GodotSpace2D *space = space_owner.get_or_null(p_space);268ERR_FAIL_NULL_V(space, Vector<Vector2>());269return space->get_debug_contacts();270}271272int GodotPhysicsServer2D::space_get_contact_count(RID p_space) const {273GodotSpace2D *space = space_owner.get_or_null(p_space);274ERR_FAIL_NULL_V(space, 0);275return space->get_debug_contact_count();276}277278PhysicsDirectSpaceState2D *GodotPhysicsServer2D::space_get_direct_state(RID p_space) {279GodotSpace2D *space = space_owner.get_or_null(p_space);280ERR_FAIL_NULL_V(space, nullptr);281ERR_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.");282283return space->get_direct_state();284}285286RID GodotPhysicsServer2D::area_create() {287GodotArea2D *area = memnew(GodotArea2D);288RID rid = area_owner.make_rid(area);289area->set_self(rid);290return rid;291}292293void GodotPhysicsServer2D::area_set_space(RID p_area, RID p_space) {294GodotArea2D *area = area_owner.get_or_null(p_area);295ERR_FAIL_NULL(area);296297GodotSpace2D *space = nullptr;298if (p_space.is_valid()) {299space = space_owner.get_or_null(p_space);300ERR_FAIL_NULL(space);301}302303if (area->get_space() == space) {304return; //pointless305}306307area->clear_constraints();308area->set_space(space);309}310311RID GodotPhysicsServer2D::area_get_space(RID p_area) const {312GodotArea2D *area = area_owner.get_or_null(p_area);313ERR_FAIL_NULL_V(area, RID());314315GodotSpace2D *space = area->get_space();316if (!space) {317return RID();318}319return space->get_self();320}321322void GodotPhysicsServer2D::area_add_shape(RID p_area, RID p_shape, const Transform2D &p_transform, bool p_disabled) {323GodotArea2D *area = area_owner.get_or_null(p_area);324ERR_FAIL_NULL(area);325326GodotShape2D *shape = shape_owner.get_or_null(p_shape);327ERR_FAIL_NULL(shape);328329area->add_shape(shape, p_transform, p_disabled);330}331332void GodotPhysicsServer2D::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) {333GodotArea2D *area = area_owner.get_or_null(p_area);334ERR_FAIL_NULL(area);335336GodotShape2D *shape = shape_owner.get_or_null(p_shape);337ERR_FAIL_NULL(shape);338ERR_FAIL_COND(!shape->is_configured());339340area->set_shape(p_shape_idx, shape);341}342343void GodotPhysicsServer2D::area_set_shape_transform(RID p_area, int p_shape_idx, const Transform2D &p_transform) {344GodotArea2D *area = area_owner.get_or_null(p_area);345ERR_FAIL_NULL(area);346347area->set_shape_transform(p_shape_idx, p_transform);348}349350void GodotPhysicsServer2D::area_set_shape_disabled(RID p_area, int p_shape, bool p_disabled) {351GodotArea2D *area = area_owner.get_or_null(p_area);352ERR_FAIL_NULL(area);353ERR_FAIL_INDEX(p_shape, area->get_shape_count());354FLUSH_QUERY_CHECK(area);355356area->set_shape_disabled(p_shape, p_disabled);357}358359int GodotPhysicsServer2D::area_get_shape_count(RID p_area) const {360GodotArea2D *area = area_owner.get_or_null(p_area);361ERR_FAIL_NULL_V(area, -1);362363return area->get_shape_count();364}365366RID GodotPhysicsServer2D::area_get_shape(RID p_area, int p_shape_idx) const {367GodotArea2D *area = area_owner.get_or_null(p_area);368ERR_FAIL_NULL_V(area, RID());369370GodotShape2D *shape = area->get_shape(p_shape_idx);371ERR_FAIL_NULL_V(shape, RID());372373return shape->get_self();374}375376Transform2D GodotPhysicsServer2D::area_get_shape_transform(RID p_area, int p_shape_idx) const {377GodotArea2D *area = area_owner.get_or_null(p_area);378ERR_FAIL_NULL_V(area, Transform2D());379380return area->get_shape_transform(p_shape_idx);381}382383void GodotPhysicsServer2D::area_remove_shape(RID p_area, int p_shape_idx) {384GodotArea2D *area = area_owner.get_or_null(p_area);385ERR_FAIL_NULL(area);386387area->remove_shape(p_shape_idx);388}389390void GodotPhysicsServer2D::area_clear_shapes(RID p_area) {391GodotArea2D *area = area_owner.get_or_null(p_area);392ERR_FAIL_NULL(area);393394while (area->get_shape_count()) {395area->remove_shape(0);396}397}398399void GodotPhysicsServer2D::area_attach_object_instance_id(RID p_area, ObjectID p_id) {400if (space_owner.owns(p_area)) {401GodotSpace2D *space = space_owner.get_or_null(p_area);402p_area = space->get_default_area()->get_self();403}404GodotArea2D *area = area_owner.get_or_null(p_area);405ERR_FAIL_NULL(area);406area->set_instance_id(p_id);407}408409ObjectID GodotPhysicsServer2D::area_get_object_instance_id(RID p_area) const {410if (space_owner.owns(p_area)) {411GodotSpace2D *space = space_owner.get_or_null(p_area);412p_area = space->get_default_area()->get_self();413}414GodotArea2D *area = area_owner.get_or_null(p_area);415ERR_FAIL_NULL_V(area, ObjectID());416return area->get_instance_id();417}418419void GodotPhysicsServer2D::area_attach_canvas_instance_id(RID p_area, ObjectID p_id) {420if (space_owner.owns(p_area)) {421GodotSpace2D *space = space_owner.get_or_null(p_area);422p_area = space->get_default_area()->get_self();423}424GodotArea2D *area = area_owner.get_or_null(p_area);425ERR_FAIL_NULL(area);426area->set_canvas_instance_id(p_id);427}428429ObjectID GodotPhysicsServer2D::area_get_canvas_instance_id(RID p_area) const {430if (space_owner.owns(p_area)) {431GodotSpace2D *space = space_owner.get_or_null(p_area);432p_area = space->get_default_area()->get_self();433}434GodotArea2D *area = area_owner.get_or_null(p_area);435ERR_FAIL_NULL_V(area, ObjectID());436return area->get_canvas_instance_id();437}438439void GodotPhysicsServer2D::area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) {440if (space_owner.owns(p_area)) {441GodotSpace2D *space = space_owner.get_or_null(p_area);442p_area = space->get_default_area()->get_self();443}444GodotArea2D *area = area_owner.get_or_null(p_area);445ERR_FAIL_NULL(area);446area->set_param(p_param, p_value);447}448449void GodotPhysicsServer2D::area_set_transform(RID p_area, const Transform2D &p_transform) {450GodotArea2D *area = area_owner.get_or_null(p_area);451ERR_FAIL_NULL(area);452area->set_transform(p_transform);453}454455Variant GodotPhysicsServer2D::area_get_param(RID p_area, AreaParameter p_param) const {456if (space_owner.owns(p_area)) {457GodotSpace2D *space = space_owner.get_or_null(p_area);458p_area = space->get_default_area()->get_self();459}460GodotArea2D *area = area_owner.get_or_null(p_area);461ERR_FAIL_NULL_V(area, Variant());462463return area->get_param(p_param);464}465466Transform2D GodotPhysicsServer2D::area_get_transform(RID p_area) const {467GodotArea2D *area = area_owner.get_or_null(p_area);468ERR_FAIL_NULL_V(area, Transform2D());469470return area->get_transform();471}472473void GodotPhysicsServer2D::area_set_pickable(RID p_area, bool p_pickable) {474GodotArea2D *area = area_owner.get_or_null(p_area);475ERR_FAIL_NULL(area);476area->set_pickable(p_pickable);477}478479void GodotPhysicsServer2D::area_set_monitorable(RID p_area, bool p_monitorable) {480GodotArea2D *area = area_owner.get_or_null(p_area);481ERR_FAIL_NULL(area);482FLUSH_QUERY_CHECK(area);483484area->set_monitorable(p_monitorable);485}486487void GodotPhysicsServer2D::area_set_collision_layer(RID p_area, uint32_t p_layer) {488GodotArea2D *area = area_owner.get_or_null(p_area);489ERR_FAIL_NULL(area);490491area->set_collision_layer(p_layer);492}493494uint32_t GodotPhysicsServer2D::area_get_collision_layer(RID p_area) const {495GodotArea2D *area = area_owner.get_or_null(p_area);496ERR_FAIL_NULL_V(area, 0);497498return area->get_collision_layer();499}500501void GodotPhysicsServer2D::area_set_collision_mask(RID p_area, uint32_t p_mask) {502GodotArea2D *area = area_owner.get_or_null(p_area);503ERR_FAIL_NULL(area);504505area->set_collision_mask(p_mask);506}507508uint32_t GodotPhysicsServer2D::area_get_collision_mask(RID p_area) const {509GodotArea2D *area = area_owner.get_or_null(p_area);510ERR_FAIL_NULL_V(area, 0);511512return area->get_collision_mask();513}514515void GodotPhysicsServer2D::area_set_monitor_callback(RID p_area, const Callable &p_callback) {516GodotArea2D *area = area_owner.get_or_null(p_area);517ERR_FAIL_NULL(area);518519area->set_monitor_callback(p_callback.is_valid() ? p_callback : Callable());520}521522void GodotPhysicsServer2D::area_set_area_monitor_callback(RID p_area, const Callable &p_callback) {523GodotArea2D *area = area_owner.get_or_null(p_area);524ERR_FAIL_NULL(area);525526area->set_area_monitor_callback(p_callback.is_valid() ? p_callback : Callable());527}528529/* BODY API */530531RID GodotPhysicsServer2D::body_create() {532GodotBody2D *body = memnew(GodotBody2D);533RID rid = body_owner.make_rid(body);534body->set_self(rid);535return rid;536}537538void GodotPhysicsServer2D::body_set_space(RID p_body, RID p_space) {539GodotBody2D *body = body_owner.get_or_null(p_body);540ERR_FAIL_NULL(body);541GodotSpace2D *space = nullptr;542if (p_space.is_valid()) {543space = space_owner.get_or_null(p_space);544ERR_FAIL_NULL(space);545}546547if (body->get_space() == space) {548return; //pointless549}550551body->clear_constraint_list();552body->set_space(space);553}554555RID GodotPhysicsServer2D::body_get_space(RID p_body) const {556GodotBody2D *body = body_owner.get_or_null(p_body);557ERR_FAIL_NULL_V(body, RID());558559GodotSpace2D *space = body->get_space();560if (!space) {561return RID();562}563return space->get_self();564}565566void GodotPhysicsServer2D::body_set_mode(RID p_body, BodyMode p_mode) {567GodotBody2D *body = body_owner.get_or_null(p_body);568ERR_FAIL_NULL(body);569FLUSH_QUERY_CHECK(body);570571body->set_mode(p_mode);572}573574PhysicsServer2D::BodyMode GodotPhysicsServer2D::body_get_mode(RID p_body) const {575GodotBody2D *body = body_owner.get_or_null(p_body);576ERR_FAIL_NULL_V(body, BODY_MODE_STATIC);577578return body->get_mode();579}580581void GodotPhysicsServer2D::body_add_shape(RID p_body, RID p_shape, const Transform2D &p_transform, bool p_disabled) {582GodotBody2D *body = body_owner.get_or_null(p_body);583ERR_FAIL_NULL(body);584585GodotShape2D *shape = shape_owner.get_or_null(p_shape);586ERR_FAIL_NULL(shape);587588body->add_shape(shape, p_transform, p_disabled);589}590591void GodotPhysicsServer2D::body_set_shape(RID p_body, int p_shape_idx, RID p_shape) {592GodotBody2D *body = body_owner.get_or_null(p_body);593ERR_FAIL_NULL(body);594595GodotShape2D *shape = shape_owner.get_or_null(p_shape);596ERR_FAIL_NULL(shape);597ERR_FAIL_COND(!shape->is_configured());598599body->set_shape(p_shape_idx, shape);600}601602void GodotPhysicsServer2D::body_set_shape_transform(RID p_body, int p_shape_idx, const Transform2D &p_transform) {603GodotBody2D *body = body_owner.get_or_null(p_body);604ERR_FAIL_NULL(body);605606body->set_shape_transform(p_shape_idx, p_transform);607}608609int GodotPhysicsServer2D::body_get_shape_count(RID p_body) const {610GodotBody2D *body = body_owner.get_or_null(p_body);611ERR_FAIL_NULL_V(body, -1);612613return body->get_shape_count();614}615616RID GodotPhysicsServer2D::body_get_shape(RID p_body, int p_shape_idx) const {617GodotBody2D *body = body_owner.get_or_null(p_body);618ERR_FAIL_NULL_V(body, RID());619620GodotShape2D *shape = body->get_shape(p_shape_idx);621ERR_FAIL_NULL_V(shape, RID());622623return shape->get_self();624}625626Transform2D GodotPhysicsServer2D::body_get_shape_transform(RID p_body, int p_shape_idx) const {627GodotBody2D *body = body_owner.get_or_null(p_body);628ERR_FAIL_NULL_V(body, Transform2D());629630return body->get_shape_transform(p_shape_idx);631}632633void GodotPhysicsServer2D::body_remove_shape(RID p_body, int p_shape_idx) {634GodotBody2D *body = body_owner.get_or_null(p_body);635ERR_FAIL_NULL(body);636637body->remove_shape(p_shape_idx);638}639640void GodotPhysicsServer2D::body_clear_shapes(RID p_body) {641GodotBody2D *body = body_owner.get_or_null(p_body);642ERR_FAIL_NULL(body);643644while (body->get_shape_count()) {645body->remove_shape(0);646}647}648649void GodotPhysicsServer2D::body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) {650GodotBody2D *body = body_owner.get_or_null(p_body);651ERR_FAIL_NULL(body);652ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count());653FLUSH_QUERY_CHECK(body);654655body->set_shape_disabled(p_shape_idx, p_disabled);656}657658void GodotPhysicsServer2D::body_set_shape_as_one_way_collision(RID p_body, int p_shape_idx, bool p_enable, real_t p_margin) {659GodotBody2D *body = body_owner.get_or_null(p_body);660ERR_FAIL_NULL(body);661ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count());662FLUSH_QUERY_CHECK(body);663664body->set_shape_as_one_way_collision(p_shape_idx, p_enable, p_margin);665}666667void GodotPhysicsServer2D::body_set_continuous_collision_detection_mode(RID p_body, CCDMode p_mode) {668GodotBody2D *body = body_owner.get_or_null(p_body);669ERR_FAIL_NULL(body);670body->set_continuous_collision_detection_mode(p_mode);671}672673GodotPhysicsServer2D::CCDMode GodotPhysicsServer2D::body_get_continuous_collision_detection_mode(RID p_body) const {674const GodotBody2D *body = body_owner.get_or_null(p_body);675ERR_FAIL_NULL_V(body, CCD_MODE_DISABLED);676677return body->get_continuous_collision_detection_mode();678}679680void GodotPhysicsServer2D::body_attach_object_instance_id(RID p_body, ObjectID p_id) {681GodotBody2D *body = body_owner.get_or_null(p_body);682ERR_FAIL_NULL(body);683684body->set_instance_id(p_id);685}686687ObjectID GodotPhysicsServer2D::body_get_object_instance_id(RID p_body) const {688GodotBody2D *body = body_owner.get_or_null(p_body);689ERR_FAIL_NULL_V(body, ObjectID());690691return body->get_instance_id();692}693694void GodotPhysicsServer2D::body_attach_canvas_instance_id(RID p_body, ObjectID p_id) {695GodotBody2D *body = body_owner.get_or_null(p_body);696ERR_FAIL_NULL(body);697698body->set_canvas_instance_id(p_id);699}700701ObjectID GodotPhysicsServer2D::body_get_canvas_instance_id(RID p_body) const {702GodotBody2D *body = body_owner.get_or_null(p_body);703ERR_FAIL_NULL_V(body, ObjectID());704705return body->get_canvas_instance_id();706}707708void GodotPhysicsServer2D::body_set_collision_layer(RID p_body, uint32_t p_layer) {709GodotBody2D *body = body_owner.get_or_null(p_body);710ERR_FAIL_NULL(body);711body->set_collision_layer(p_layer);712}713714uint32_t GodotPhysicsServer2D::body_get_collision_layer(RID p_body) const {715GodotBody2D *body = body_owner.get_or_null(p_body);716ERR_FAIL_NULL_V(body, 0);717718return body->get_collision_layer();719}720721void GodotPhysicsServer2D::body_set_collision_mask(RID p_body, uint32_t p_mask) {722GodotBody2D *body = body_owner.get_or_null(p_body);723ERR_FAIL_NULL(body);724body->set_collision_mask(p_mask);725}726727uint32_t GodotPhysicsServer2D::body_get_collision_mask(RID p_body) const {728GodotBody2D *body = body_owner.get_or_null(p_body);729ERR_FAIL_NULL_V(body, 0);730731return body->get_collision_mask();732}733734void GodotPhysicsServer2D::body_set_collision_priority(RID p_body, real_t p_priority) {735GodotBody2D *body = body_owner.get_or_null(p_body);736ERR_FAIL_NULL(body);737738body->set_collision_priority(p_priority);739}740741real_t GodotPhysicsServer2D::body_get_collision_priority(RID p_body) const {742const GodotBody2D *body = body_owner.get_or_null(p_body);743ERR_FAIL_NULL_V(body, 0);744745return body->get_collision_priority();746}747748void GodotPhysicsServer2D::body_set_param(RID p_body, BodyParameter p_param, const Variant &p_value) {749GodotBody2D *body = body_owner.get_or_null(p_body);750ERR_FAIL_NULL(body);751752body->set_param(p_param, p_value);753}754755Variant GodotPhysicsServer2D::body_get_param(RID p_body, BodyParameter p_param) const {756GodotBody2D *body = body_owner.get_or_null(p_body);757ERR_FAIL_NULL_V(body, 0);758759return body->get_param(p_param);760}761762void GodotPhysicsServer2D::body_reset_mass_properties(RID p_body) {763GodotBody2D *body = body_owner.get_or_null(p_body);764ERR_FAIL_NULL(body);765766return body->reset_mass_properties();767}768769void GodotPhysicsServer2D::body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) {770GodotBody2D *body = body_owner.get_or_null(p_body);771ERR_FAIL_NULL(body);772773body->set_state(p_state, p_variant);774}775776Variant GodotPhysicsServer2D::body_get_state(RID p_body, BodyState p_state) const {777GodotBody2D *body = body_owner.get_or_null(p_body);778ERR_FAIL_NULL_V(body, Variant());779780return body->get_state(p_state);781}782783void GodotPhysicsServer2D::body_apply_central_impulse(RID p_body, const Vector2 &p_impulse) {784GodotBody2D *body = body_owner.get_or_null(p_body);785ERR_FAIL_NULL(body);786787body->apply_central_impulse(p_impulse);788body->wakeup();789}790791void GodotPhysicsServer2D::body_apply_torque_impulse(RID p_body, real_t p_torque) {792GodotBody2D *body = body_owner.get_or_null(p_body);793ERR_FAIL_NULL(body);794795_update_shapes();796797body->apply_torque_impulse(p_torque);798body->wakeup();799}800801void GodotPhysicsServer2D::body_apply_impulse(RID p_body, const Vector2 &p_impulse, const Vector2 &p_position) {802GodotBody2D *body = body_owner.get_or_null(p_body);803ERR_FAIL_NULL(body);804805_update_shapes();806807body->apply_impulse(p_impulse, p_position);808body->wakeup();809}810811void GodotPhysicsServer2D::body_apply_central_force(RID p_body, const Vector2 &p_force) {812GodotBody2D *body = body_owner.get_or_null(p_body);813ERR_FAIL_NULL(body);814815body->apply_central_force(p_force);816body->wakeup();817}818819void GodotPhysicsServer2D::body_apply_force(RID p_body, const Vector2 &p_force, const Vector2 &p_position) {820GodotBody2D *body = body_owner.get_or_null(p_body);821ERR_FAIL_NULL(body);822823body->apply_force(p_force, p_position);824body->wakeup();825}826827void GodotPhysicsServer2D::body_apply_torque(RID p_body, real_t p_torque) {828GodotBody2D *body = body_owner.get_or_null(p_body);829ERR_FAIL_NULL(body);830831body->apply_torque(p_torque);832body->wakeup();833}834835void GodotPhysicsServer2D::body_add_constant_central_force(RID p_body, const Vector2 &p_force) {836GodotBody2D *body = body_owner.get_or_null(p_body);837ERR_FAIL_NULL(body);838839body->add_constant_central_force(p_force);840body->wakeup();841}842843void GodotPhysicsServer2D::body_add_constant_force(RID p_body, const Vector2 &p_force, const Vector2 &p_position) {844GodotBody2D *body = body_owner.get_or_null(p_body);845ERR_FAIL_NULL(body);846847body->add_constant_force(p_force, p_position);848body->wakeup();849}850851void GodotPhysicsServer2D::body_add_constant_torque(RID p_body, real_t p_torque) {852GodotBody2D *body = body_owner.get_or_null(p_body);853ERR_FAIL_NULL(body);854855body->add_constant_torque(p_torque);856body->wakeup();857}858859void GodotPhysicsServer2D::body_set_constant_force(RID p_body, const Vector2 &p_force) {860GodotBody2D *body = body_owner.get_or_null(p_body);861ERR_FAIL_NULL(body);862863body->set_constant_force(p_force);864if (!p_force.is_zero_approx()) {865body->wakeup();866}867}868869Vector2 GodotPhysicsServer2D::body_get_constant_force(RID p_body) const {870GodotBody2D *body = body_owner.get_or_null(p_body);871ERR_FAIL_NULL_V(body, Vector2());872return body->get_constant_force();873}874875void GodotPhysicsServer2D::body_set_constant_torque(RID p_body, real_t p_torque) {876GodotBody2D *body = body_owner.get_or_null(p_body);877ERR_FAIL_NULL(body);878879body->set_constant_torque(p_torque);880if (!Math::is_zero_approx(p_torque)) {881body->wakeup();882}883}884885real_t GodotPhysicsServer2D::body_get_constant_torque(RID p_body) const {886GodotBody2D *body = body_owner.get_or_null(p_body);887ERR_FAIL_NULL_V(body, 0);888889return body->get_constant_torque();890}891892void GodotPhysicsServer2D::body_set_axis_velocity(RID p_body, const Vector2 &p_axis_velocity) {893GodotBody2D *body = body_owner.get_or_null(p_body);894ERR_FAIL_NULL(body);895896_update_shapes();897898Vector2 v = body->get_linear_velocity();899Vector2 axis = p_axis_velocity.normalized();900v -= axis * axis.dot(v);901v += p_axis_velocity;902body->set_linear_velocity(v);903body->wakeup();904}905906void GodotPhysicsServer2D::body_add_collision_exception(RID p_body, RID p_body_b) {907GodotBody2D *body = body_owner.get_or_null(p_body);908ERR_FAIL_NULL(body);909910body->add_exception(p_body_b);911body->wakeup();912}913914void GodotPhysicsServer2D::body_remove_collision_exception(RID p_body, RID p_body_b) {915GodotBody2D *body = body_owner.get_or_null(p_body);916ERR_FAIL_NULL(body);917918body->remove_exception(p_body_b);919body->wakeup();920}921922void GodotPhysicsServer2D::body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) {923GodotBody2D *body = body_owner.get_or_null(p_body);924ERR_FAIL_NULL(body);925926for (int i = 0; i < body->get_exceptions().size(); i++) {927p_exceptions->push_back(body->get_exceptions()[i]);928}929}930931void GodotPhysicsServer2D::body_set_contacts_reported_depth_threshold(RID p_body, real_t p_threshold) {932GodotBody2D *body = body_owner.get_or_null(p_body);933ERR_FAIL_NULL(body);934}935936real_t GodotPhysicsServer2D::body_get_contacts_reported_depth_threshold(RID p_body) const {937GodotBody2D *body = body_owner.get_or_null(p_body);938ERR_FAIL_NULL_V(body, 0);939return 0;940}941942void GodotPhysicsServer2D::body_set_omit_force_integration(RID p_body, bool p_omit) {943GodotBody2D *body = body_owner.get_or_null(p_body);944ERR_FAIL_NULL(body);945946body->set_omit_force_integration(p_omit);947}948949bool GodotPhysicsServer2D::body_is_omitting_force_integration(RID p_body) const {950GodotBody2D *body = body_owner.get_or_null(p_body);951ERR_FAIL_NULL_V(body, false);952return body->get_omit_force_integration();953}954955void GodotPhysicsServer2D::body_set_max_contacts_reported(RID p_body, int p_contacts) {956GodotBody2D *body = body_owner.get_or_null(p_body);957ERR_FAIL_NULL(body);958body->set_max_contacts_reported(p_contacts);959}960961int GodotPhysicsServer2D::body_get_max_contacts_reported(RID p_body) const {962GodotBody2D *body = body_owner.get_or_null(p_body);963ERR_FAIL_NULL_V(body, -1);964return body->get_max_contacts_reported();965}966967void GodotPhysicsServer2D::body_set_state_sync_callback(RID p_body, const Callable &p_callable) {968GodotBody2D *body = body_owner.get_or_null(p_body);969ERR_FAIL_NULL(body);970body->set_state_sync_callback(p_callable);971}972973void GodotPhysicsServer2D::body_set_force_integration_callback(RID p_body, const Callable &p_callable, const Variant &p_udata) {974GodotBody2D *body = body_owner.get_or_null(p_body);975ERR_FAIL_NULL(body);976body->set_force_integration_callback(p_callable, p_udata);977}978979bool GodotPhysicsServer2D::body_collide_shape(RID p_body, int p_body_shape, RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, Vector2 *r_results, int p_result_max, int &r_result_count) {980GodotBody2D *body = body_owner.get_or_null(p_body);981ERR_FAIL_NULL_V(body, false);982ERR_FAIL_INDEX_V(p_body_shape, body->get_shape_count(), false);983984return shape_collide(body->get_shape(p_body_shape)->get_self(), body->get_transform() * body->get_shape_transform(p_body_shape), Vector2(), p_shape, p_shape_xform, p_motion, r_results, p_result_max, r_result_count);985}986987void GodotPhysicsServer2D::body_set_pickable(RID p_body, bool p_pickable) {988GodotBody2D *body = body_owner.get_or_null(p_body);989ERR_FAIL_NULL(body);990body->set_pickable(p_pickable);991}992993bool GodotPhysicsServer2D::body_test_motion(RID p_body, const MotionParameters &p_parameters, MotionResult *r_result) {994GodotBody2D *body = body_owner.get_or_null(p_body);995ERR_FAIL_NULL_V(body, false);996ERR_FAIL_NULL_V(body->get_space(), false);997ERR_FAIL_COND_V(body->get_space()->is_locked(), false);998999_update_shapes();10001001return body->get_space()->test_body_motion(body, p_parameters, r_result);1002}10031004PhysicsDirectBodyState2D *GodotPhysicsServer2D::body_get_direct_state(RID p_body) {1005ERR_FAIL_COND_V_MSG((using_threads && !doing_sync), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification.");10061007if (!body_owner.owns(p_body)) {1008return nullptr;1009}10101011GodotBody2D *body = body_owner.get_or_null(p_body);1012ERR_FAIL_NULL_V(body, nullptr);10131014if (!body->get_space()) {1015return nullptr;1016}10171018ERR_FAIL_COND_V_MSG(body->get_space()->is_locked(), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification.");10191020return body->get_direct_state();1021}10221023/* JOINT API */10241025RID GodotPhysicsServer2D::joint_create() {1026GodotJoint2D *joint = memnew(GodotJoint2D);1027RID joint_rid = joint_owner.make_rid(joint);1028joint->set_self(joint_rid);1029return joint_rid;1030}10311032void GodotPhysicsServer2D::joint_clear(RID p_joint) {1033GodotJoint2D *joint = joint_owner.get_or_null(p_joint);1034ERR_FAIL_NULL(joint);1035if (joint->get_type() != JOINT_TYPE_MAX) {1036GodotJoint2D *empty_joint = memnew(GodotJoint2D);1037empty_joint->copy_settings_from(joint);10381039joint_owner.replace(p_joint, empty_joint);1040memdelete(joint);1041}1042}10431044void GodotPhysicsServer2D::joint_set_param(RID p_joint, JointParam p_param, real_t p_value) {1045GodotJoint2D *joint = joint_owner.get_or_null(p_joint);1046ERR_FAIL_NULL(joint);10471048switch (p_param) {1049case JOINT_PARAM_BIAS:1050joint->set_bias(p_value);1051break;1052case JOINT_PARAM_MAX_BIAS:1053joint->set_max_bias(p_value);1054break;1055case JOINT_PARAM_MAX_FORCE:1056joint->set_max_force(p_value);1057break;1058}1059}10601061real_t GodotPhysicsServer2D::joint_get_param(RID p_joint, JointParam p_param) const {1062const GodotJoint2D *joint = joint_owner.get_or_null(p_joint);1063ERR_FAIL_NULL_V(joint, -1);10641065switch (p_param) {1066case JOINT_PARAM_BIAS:1067return joint->get_bias();1068break;1069case JOINT_PARAM_MAX_BIAS:1070return joint->get_max_bias();1071break;1072case JOINT_PARAM_MAX_FORCE:1073return joint->get_max_force();1074break;1075}10761077return 0;1078}10791080void GodotPhysicsServer2D::joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable) {1081GodotJoint2D *joint = joint_owner.get_or_null(p_joint);1082ERR_FAIL_NULL(joint);10831084joint->disable_collisions_between_bodies(p_disable);10851086if (2 == joint->get_body_count()) {1087GodotBody2D *body_a = *joint->get_body_ptr();1088GodotBody2D *body_b = *(joint->get_body_ptr() + 1);10891090if (p_disable) {1091body_add_collision_exception(body_a->get_self(), body_b->get_self());1092body_add_collision_exception(body_b->get_self(), body_a->get_self());1093} else {1094body_remove_collision_exception(body_a->get_self(), body_b->get_self());1095body_remove_collision_exception(body_b->get_self(), body_a->get_self());1096}1097}1098}10991100bool GodotPhysicsServer2D::joint_is_disabled_collisions_between_bodies(RID p_joint) const {1101const GodotJoint2D *joint = joint_owner.get_or_null(p_joint);1102ERR_FAIL_NULL_V(joint, true);11031104return joint->is_disabled_collisions_between_bodies();1105}11061107void GodotPhysicsServer2D::joint_make_pin(RID p_joint, const Vector2 &p_pos, RID p_body_a, RID p_body_b) {1108GodotBody2D *A = body_owner.get_or_null(p_body_a);1109ERR_FAIL_NULL(A);1110GodotBody2D *B = nullptr;1111if (body_owner.owns(p_body_b)) {1112B = body_owner.get_or_null(p_body_b);1113ERR_FAIL_NULL(B);1114}11151116GodotJoint2D *prev_joint = joint_owner.get_or_null(p_joint);1117ERR_FAIL_NULL(prev_joint);11181119GodotJoint2D *joint = memnew(GodotPinJoint2D(p_pos, A, B));11201121joint_owner.replace(p_joint, joint);1122joint->copy_settings_from(prev_joint);1123memdelete(prev_joint);1124}11251126void GodotPhysicsServer2D::joint_make_groove(RID p_joint, const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, RID p_body_a, RID p_body_b) {1127GodotBody2D *A = body_owner.get_or_null(p_body_a);1128ERR_FAIL_NULL(A);11291130GodotBody2D *B = body_owner.get_or_null(p_body_b);1131ERR_FAIL_NULL(B);11321133GodotJoint2D *prev_joint = joint_owner.get_or_null(p_joint);1134ERR_FAIL_NULL(prev_joint);11351136GodotJoint2D *joint = memnew(GodotGrooveJoint2D(p_a_groove1, p_a_groove2, p_b_anchor, A, B));11371138joint_owner.replace(p_joint, joint);1139joint->copy_settings_from(prev_joint);1140memdelete(prev_joint);1141}11421143void GodotPhysicsServer2D::joint_make_damped_spring(RID p_joint, const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, RID p_body_a, RID p_body_b) {1144GodotBody2D *A = body_owner.get_or_null(p_body_a);1145ERR_FAIL_NULL(A);11461147GodotBody2D *B = body_owner.get_or_null(p_body_b);1148ERR_FAIL_NULL(B);11491150GodotJoint2D *prev_joint = joint_owner.get_or_null(p_joint);1151ERR_FAIL_NULL(prev_joint);11521153GodotJoint2D *joint = memnew(GodotDampedSpringJoint2D(p_anchor_a, p_anchor_b, A, B));11541155joint_owner.replace(p_joint, joint);1156joint->copy_settings_from(prev_joint);1157memdelete(prev_joint);1158}11591160void GodotPhysicsServer2D::pin_joint_set_flag(RID p_joint, PinJointFlag p_flag, bool p_enabled) {1161GodotJoint2D *joint = joint_owner.get_or_null(p_joint);1162ERR_FAIL_NULL(joint);1163ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN);11641165GodotPinJoint2D *pin_joint = static_cast<GodotPinJoint2D *>(joint);1166pin_joint->set_flag(p_flag, p_enabled);1167}11681169bool GodotPhysicsServer2D::pin_joint_get_flag(RID p_joint, PinJointFlag p_flag) const {1170GodotJoint2D *joint = joint_owner.get_or_null(p_joint);1171ERR_FAIL_NULL_V(joint, false);1172ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, false);11731174GodotPinJoint2D *pin_joint = static_cast<GodotPinJoint2D *>(joint);1175return pin_joint->get_flag(p_flag);1176}11771178void GodotPhysicsServer2D::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) {1179GodotJoint2D *joint = joint_owner.get_or_null(p_joint);1180ERR_FAIL_NULL(joint);1181ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN);11821183GodotPinJoint2D *pin_joint = static_cast<GodotPinJoint2D *>(joint);1184pin_joint->set_param(p_param, p_value);1185}11861187real_t GodotPhysicsServer2D::pin_joint_get_param(RID p_joint, PinJointParam p_param) const {1188GodotJoint2D *joint = joint_owner.get_or_null(p_joint);1189ERR_FAIL_NULL_V(joint, 0);1190ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, 0);11911192GodotPinJoint2D *pin_joint = static_cast<GodotPinJoint2D *>(joint);1193return pin_joint->get_param(p_param);1194}11951196void GodotPhysicsServer2D::damped_spring_joint_set_param(RID p_joint, DampedSpringParam p_param, real_t p_value) {1197GodotJoint2D *joint = joint_owner.get_or_null(p_joint);1198ERR_FAIL_NULL(joint);1199ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_DAMPED_SPRING);12001201GodotDampedSpringJoint2D *dsj = static_cast<GodotDampedSpringJoint2D *>(joint);1202dsj->set_param(p_param, p_value);1203}12041205real_t GodotPhysicsServer2D::damped_spring_joint_get_param(RID p_joint, DampedSpringParam p_param) const {1206GodotJoint2D *joint = joint_owner.get_or_null(p_joint);1207ERR_FAIL_NULL_V(joint, 0);1208ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_DAMPED_SPRING, 0);12091210GodotDampedSpringJoint2D *dsj = static_cast<GodotDampedSpringJoint2D *>(joint);1211return dsj->get_param(p_param);1212}12131214PhysicsServer2D::JointType GodotPhysicsServer2D::joint_get_type(RID p_joint) const {1215GodotJoint2D *joint = joint_owner.get_or_null(p_joint);1216ERR_FAIL_NULL_V(joint, JOINT_TYPE_PIN);12171218return joint->get_type();1219}12201221void GodotPhysicsServer2D::free(RID p_rid) {1222_update_shapes(); // just in case12231224if (shape_owner.owns(p_rid)) {1225GodotShape2D *shape = shape_owner.get_or_null(p_rid);12261227while (shape->get_owners().size()) {1228GodotShapeOwner2D *so = shape->get_owners().begin()->key;1229so->remove_shape(shape);1230}12311232shape_owner.free(p_rid);1233memdelete(shape);1234} else if (body_owner.owns(p_rid)) {1235GodotBody2D *body = body_owner.get_or_null(p_rid);12361237body_set_space(p_rid, RID());12381239while (body->get_shape_count()) {1240body->remove_shape(0);1241}12421243body_owner.free(p_rid);1244memdelete(body);12451246} else if (area_owner.owns(p_rid)) {1247GodotArea2D *area = area_owner.get_or_null(p_rid);12481249area->set_space(nullptr);12501251while (area->get_shape_count()) {1252area->remove_shape(0);1253}12541255area_owner.free(p_rid);1256memdelete(area);1257} else if (space_owner.owns(p_rid)) {1258GodotSpace2D *space = space_owner.get_or_null(p_rid);12591260while (space->get_objects().size()) {1261GodotCollisionObject2D *co = static_cast<GodotCollisionObject2D *>(*space->get_objects().begin());1262co->set_space(nullptr);1263}12641265active_spaces.erase(space);1266free(space->get_default_area()->get_self());1267space_owner.free(p_rid);1268memdelete(space);1269} else if (joint_owner.owns(p_rid)) {1270GodotJoint2D *joint = joint_owner.get_or_null(p_rid);12711272joint_owner.free(p_rid);1273memdelete(joint);12741275} else {1276ERR_FAIL_MSG("Invalid ID.");1277}1278}12791280void GodotPhysicsServer2D::set_active(bool p_active) {1281active = p_active;1282}12831284void GodotPhysicsServer2D::init() {1285doing_sync = false;1286stepper = memnew(GodotStep2D);1287}12881289void GodotPhysicsServer2D::step(real_t p_step) {1290if (!active) {1291return;1292}12931294_update_shapes();12951296island_count = 0;1297active_objects = 0;1298collision_pairs = 0;1299for (GodotSpace2D *E : active_spaces) {1300stepper->step(E, p_step);1301island_count += E->get_island_count();1302active_objects += E->get_active_objects();1303collision_pairs += E->get_collision_pairs();1304}1305}13061307void GodotPhysicsServer2D::sync() {1308doing_sync = true;1309}13101311void GodotPhysicsServer2D::flush_queries() {1312if (!active) {1313return;1314}13151316flushing_queries = true;13171318uint64_t time_beg = OS::get_singleton()->get_ticks_usec();13191320for (GodotSpace2D *E : active_spaces) {1321E->call_queries();1322}13231324flushing_queries = false;13251326if (EngineDebugger::is_profiling("servers")) {1327uint64_t total_time[GodotSpace2D::ELAPSED_TIME_MAX];1328static const char *time_name[GodotSpace2D::ELAPSED_TIME_MAX] = {1329"integrate_forces",1330"generate_islands",1331"setup_constraints",1332"solve_constraints",1333"integrate_velocities"1334};13351336for (int i = 0; i < GodotSpace2D::ELAPSED_TIME_MAX; i++) {1337total_time[i] = 0;1338}13391340for (const GodotSpace2D *E : active_spaces) {1341for (int i = 0; i < GodotSpace2D::ELAPSED_TIME_MAX; i++) {1342total_time[i] += E->get_elapsed_time(GodotSpace2D::ElapsedTime(i));1343}1344}13451346Array values;1347values.resize(GodotSpace2D::ELAPSED_TIME_MAX * 2);1348for (int i = 0; i < GodotSpace2D::ELAPSED_TIME_MAX; i++) {1349values[i * 2 + 0] = time_name[i];1350values[i * 2 + 1] = USEC_TO_SEC(total_time[i]);1351}1352values.push_back("flush_queries");1353values.push_back(USEC_TO_SEC(OS::get_singleton()->get_ticks_usec() - time_beg));13541355values.push_front("physics_2d");1356EngineDebugger::profiler_add_frame_data("servers", values);1357}1358}13591360void GodotPhysicsServer2D::end_sync() {1361doing_sync = false;1362}13631364void GodotPhysicsServer2D::finish() {1365memdelete(stepper);1366}13671368void GodotPhysicsServer2D::_update_shapes() {1369while (pending_shape_update_list.first()) {1370pending_shape_update_list.first()->self()->_shape_changed();1371pending_shape_update_list.remove(pending_shape_update_list.first());1372}1373}13741375int GodotPhysicsServer2D::get_process_info(ProcessInfo p_info) {1376switch (p_info) {1377case INFO_ACTIVE_OBJECTS: {1378return active_objects;1379} break;1380case INFO_COLLISION_PAIRS: {1381return collision_pairs;1382} break;1383case INFO_ISLAND_COUNT: {1384return island_count;1385} break;1386}13871388return 0;1389}13901391GodotPhysicsServer2D *GodotPhysicsServer2D::godot_singleton = nullptr;13921393GodotPhysicsServer2D::GodotPhysicsServer2D(bool p_using_threads) {1394godot_singleton = this;1395GodotBroadPhase2D::create_func = GodotBroadPhase2DBVH::_create;13961397using_threads = p_using_threads;1398}139914001401