Path: blob/master/modules/godot_physics_3d/godot_area_pair_3d.cpp
10277 views
/**************************************************************************/1/* godot_area_pair_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_area_pair_3d.h"3132#include "godot_collision_solver_3d.h"3334bool GodotAreaPair3D::setup(real_t p_step) {35bool result = false;36if (area->collides_with(body) && GodotCollisionSolver3D::solve_static(body->get_shape(body_shape), body->get_transform() * body->get_shape_transform(body_shape), area->get_shape(area_shape), area->get_transform() * area->get_shape_transform(area_shape), nullptr, this)) {37result = true;38}3940process_collision = false;41has_space_override = false;42if (result != colliding) {43if ((int)area->get_param(PhysicsServer3D::AREA_PARAM_GRAVITY_OVERRIDE_MODE) != PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED) {44has_space_override = true;45} else if ((int)area->get_param(PhysicsServer3D::AREA_PARAM_LINEAR_DAMP_OVERRIDE_MODE) != PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED) {46has_space_override = true;47} else if ((int)area->get_param(PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP_OVERRIDE_MODE) != PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED) {48has_space_override = true;49}50process_collision = has_space_override;5152if (area->has_monitor_callback()) {53process_collision = true;54}5556colliding = result;57}5859return process_collision;60}6162bool GodotAreaPair3D::pre_solve(real_t p_step) {63if (!process_collision) {64return false;65}6667if (colliding) {68if (has_space_override) {69body_has_attached_area = true;70body->add_area(area);71}7273if (area->has_monitor_callback()) {74area->add_body_to_query(body, body_shape, area_shape);75}76} else {77if (has_space_override) {78body_has_attached_area = false;79body->remove_area(area);80}8182if (area->has_monitor_callback()) {83area->remove_body_from_query(body, body_shape, area_shape);84}85}8687return false; // Never do any post solving.88}8990void GodotAreaPair3D::solve(real_t p_step) {91// Nothing to do.92}9394GodotAreaPair3D::GodotAreaPair3D(GodotBody3D *p_body, int p_body_shape, GodotArea3D *p_area, int p_area_shape) {95body = p_body;96area = p_area;97body_shape = p_body_shape;98area_shape = p_area_shape;99body->add_constraint(this, 0);100area->add_constraint(this);101if (p_body->get_mode() == PhysicsServer3D::BODY_MODE_KINEMATIC) {102p_body->set_active(true);103}104}105106GodotAreaPair3D::~GodotAreaPair3D() {107if (colliding) {108if (body_has_attached_area) {109body_has_attached_area = false;110body->remove_area(area);111}112if (area->has_monitor_callback()) {113area->remove_body_from_query(body, body_shape, area_shape);114}115}116body->remove_constraint(this);117area->remove_constraint(this);118}119120////////////////////////////////////////////////////121122bool GodotArea2Pair3D::setup(real_t p_step) {123bool result_a = area_a->collides_with(area_b);124bool result_b = area_b->collides_with(area_a);125if ((result_a || result_b) && !GodotCollisionSolver3D::solve_static(area_a->get_shape(shape_a), area_a->get_transform() * area_a->get_shape_transform(shape_a), area_b->get_shape(shape_b), area_b->get_transform() * area_b->get_shape_transform(shape_b), nullptr, this)) {126result_a = false;127result_b = false;128}129130bool process_collision = false;131132process_collision_a = false;133if (result_a != colliding_a) {134if (area_a->has_area_monitor_callback() && area_b_monitorable) {135process_collision_a = true;136process_collision = true;137}138colliding_a = result_a;139}140141process_collision_b = false;142if (result_b != colliding_b) {143if (area_b->has_area_monitor_callback() && area_a_monitorable) {144process_collision_b = true;145process_collision = true;146}147colliding_b = result_b;148}149150return process_collision;151}152153bool GodotArea2Pair3D::pre_solve(real_t p_step) {154if (process_collision_a) {155if (colliding_a) {156area_a->add_area_to_query(area_b, shape_b, shape_a);157} else {158area_a->remove_area_from_query(area_b, shape_b, shape_a);159}160}161162if (process_collision_b) {163if (colliding_b) {164area_b->add_area_to_query(area_a, shape_a, shape_b);165} else {166area_b->remove_area_from_query(area_a, shape_a, shape_b);167}168}169170return false; // Never do any post solving.171}172173void GodotArea2Pair3D::solve(real_t p_step) {174// Nothing to do.175}176177GodotArea2Pair3D::GodotArea2Pair3D(GodotArea3D *p_area_a, int p_shape_a, GodotArea3D *p_area_b, int p_shape_b) {178area_a = p_area_a;179area_b = p_area_b;180shape_a = p_shape_a;181shape_b = p_shape_b;182area_a_monitorable = area_a->is_monitorable();183area_b_monitorable = area_b->is_monitorable();184area_a->add_constraint(this);185area_b->add_constraint(this);186}187188GodotArea2Pair3D::~GodotArea2Pair3D() {189if (colliding_a) {190if (area_a->has_area_monitor_callback() && area_b_monitorable) {191area_a->remove_area_from_query(area_b, shape_b, shape_a);192}193}194195if (colliding_b) {196if (area_b->has_area_monitor_callback() && area_a_monitorable) {197area_b->remove_area_from_query(area_a, shape_a, shape_b);198}199}200201area_a->remove_constraint(this);202area_b->remove_constraint(this);203}204205////////////////////////////////////////////////////206207bool GodotAreaSoftBodyPair3D::setup(real_t p_step) {208bool result = false;209if (210area->collides_with(soft_body) &&211GodotCollisionSolver3D::solve_static(212soft_body->get_shape(soft_body_shape),213soft_body->get_transform() * soft_body->get_shape_transform(soft_body_shape),214area->get_shape(area_shape),215area->get_transform() * area->get_shape_transform(area_shape),216nullptr,217this)) {218result = true;219}220221process_collision = false;222has_space_override = false;223if (result != colliding) {224if ((int)area->get_param(PhysicsServer3D::AREA_PARAM_GRAVITY_OVERRIDE_MODE) != PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED) {225has_space_override = true;226} else if (area->get_wind_force_magnitude() > CMP_EPSILON) {227has_space_override = true;228}229230if (area->has_monitor_callback()) {231process_collision = true;232}233234colliding = result;235}236237return process_collision;238}239240bool GodotAreaSoftBodyPair3D::pre_solve(real_t p_step) {241if (!process_collision) {242return false;243}244245if (colliding) {246if (has_space_override) {247body_has_attached_area = true;248soft_body->add_area(area);249}250251if (area->has_monitor_callback()) {252area->add_soft_body_to_query(soft_body, soft_body_shape, area_shape);253}254} else {255if (has_space_override) {256body_has_attached_area = false;257soft_body->remove_area(area);258}259260if (area->has_monitor_callback()) {261area->remove_soft_body_from_query(soft_body, soft_body_shape, area_shape);262}263}264265return false; // Never do any post solving.266}267268void GodotAreaSoftBodyPair3D::solve(real_t p_step) {269// Nothing to do.270}271272GodotAreaSoftBodyPair3D::GodotAreaSoftBodyPair3D(GodotSoftBody3D *p_soft_body, int p_soft_body_shape, GodotArea3D *p_area, int p_area_shape) {273soft_body = p_soft_body;274area = p_area;275soft_body_shape = p_soft_body_shape;276area_shape = p_area_shape;277soft_body->add_constraint(this);278area->add_constraint(this);279}280281GodotAreaSoftBodyPair3D::~GodotAreaSoftBodyPair3D() {282if (colliding) {283if (body_has_attached_area) {284body_has_attached_area = false;285soft_body->remove_area(area);286}287if (area->has_monitor_callback()) {288area->remove_soft_body_from_query(soft_body, soft_body_shape, area_shape);289}290}291soft_body->remove_constraint(this);292area->remove_constraint(this);293}294295296