Path: blob/master/modules/godot_physics_2d/godot_area_2d.h
10277 views
/**************************************************************************/1/* godot_area_2d.h */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#pragma once3132#include "godot_collision_object_2d.h"3334#include "core/templates/self_list.h"35#include "servers/physics_server_2d.h"3637class GodotSpace2D;38class GodotBody2D;39class GodotConstraint2D;4041class GodotArea2D : public GodotCollisionObject2D {42PhysicsServer2D::AreaSpaceOverrideMode gravity_override_mode = PhysicsServer2D::AREA_SPACE_OVERRIDE_DISABLED;43PhysicsServer2D::AreaSpaceOverrideMode linear_damping_override_mode = PhysicsServer2D::AREA_SPACE_OVERRIDE_DISABLED;44PhysicsServer2D::AreaSpaceOverrideMode angular_damping_override_mode = PhysicsServer2D::AREA_SPACE_OVERRIDE_DISABLED;4546real_t gravity = 9.80665;47Vector2 gravity_vector = Vector2(0, -1);48bool gravity_is_point = false;49real_t gravity_point_unit_distance = 0.0;50real_t linear_damp = 0.1;51real_t angular_damp = 1.0;52int priority = 0;53bool monitorable = false;5455Callable monitor_callback;5657Callable area_monitor_callback;5859SelfList<GodotArea2D> monitor_query_list;60SelfList<GodotArea2D> moved_list;6162struct BodyKey {63RID rid;64ObjectID instance_id;65uint32_t body_shape = 0;66uint32_t area_shape = 0;6768static uint32_t hash(const BodyKey &p_key) {69uint32_t h = hash_one_uint64(p_key.rid.get_id());70h = hash_murmur3_one_64(p_key.instance_id, h);71h = hash_murmur3_one_32(p_key.area_shape, h);72return hash_fmix32(hash_murmur3_one_32(p_key.body_shape, h));73}7475_FORCE_INLINE_ bool operator==(const BodyKey &p_key) const {76return rid == p_key.rid && instance_id == p_key.instance_id && body_shape == p_key.body_shape && area_shape == p_key.area_shape;77}7879_FORCE_INLINE_ BodyKey() {}80BodyKey(GodotBody2D *p_body, uint32_t p_body_shape, uint32_t p_area_shape);81BodyKey(GodotArea2D *p_body, uint32_t p_body_shape, uint32_t p_area_shape);82};8384struct BodyState {85int state = 0;86_FORCE_INLINE_ void inc() { state++; }87_FORCE_INLINE_ void dec() { state--; }88};8990HashMap<BodyKey, BodyState, BodyKey> monitored_bodies;91HashMap<BodyKey, BodyState, BodyKey> monitored_areas;9293HashSet<GodotConstraint2D *> constraints;9495virtual void _shapes_changed() override;96void _queue_monitor_update();9798void _set_space_override_mode(PhysicsServer2D::AreaSpaceOverrideMode &r_mode, PhysicsServer2D::AreaSpaceOverrideMode p_new_mode);99100public:101void set_monitor_callback(const Callable &p_callback);102_FORCE_INLINE_ bool has_monitor_callback() const { return monitor_callback.is_valid(); }103104void set_area_monitor_callback(const Callable &p_callback);105_FORCE_INLINE_ bool has_area_monitor_callback() const { return area_monitor_callback.is_valid(); }106107_FORCE_INLINE_ void add_body_to_query(GodotBody2D *p_body, uint32_t p_body_shape, uint32_t p_area_shape);108_FORCE_INLINE_ void remove_body_from_query(GodotBody2D *p_body, uint32_t p_body_shape, uint32_t p_area_shape);109110_FORCE_INLINE_ void add_area_to_query(GodotArea2D *p_area, uint32_t p_area_shape, uint32_t p_self_shape);111_FORCE_INLINE_ void remove_area_from_query(GodotArea2D *p_area, uint32_t p_area_shape, uint32_t p_self_shape);112113void set_param(PhysicsServer2D::AreaParameter p_param, const Variant &p_value);114Variant get_param(PhysicsServer2D::AreaParameter p_param) const;115116_FORCE_INLINE_ void set_gravity(real_t p_gravity) { gravity = p_gravity; }117_FORCE_INLINE_ real_t get_gravity() const { return gravity; }118119_FORCE_INLINE_ void set_gravity_vector(const Vector2 &p_gravity) { gravity_vector = p_gravity; }120_FORCE_INLINE_ Vector2 get_gravity_vector() const { return gravity_vector; }121122_FORCE_INLINE_ void set_gravity_as_point(bool p_enable) { gravity_is_point = p_enable; }123_FORCE_INLINE_ bool is_gravity_point() const { return gravity_is_point; }124125_FORCE_INLINE_ void set_gravity_point_unit_distance(real_t scale) { gravity_point_unit_distance = scale; }126_FORCE_INLINE_ real_t get_gravity_point_unit_distance() const { return gravity_point_unit_distance; }127128_FORCE_INLINE_ void set_linear_damp(real_t p_linear_damp) { linear_damp = p_linear_damp; }129_FORCE_INLINE_ real_t get_linear_damp() const { return linear_damp; }130131_FORCE_INLINE_ void set_angular_damp(real_t p_angular_damp) { angular_damp = p_angular_damp; }132_FORCE_INLINE_ real_t get_angular_damp() const { return angular_damp; }133134_FORCE_INLINE_ void set_priority(int p_priority) { priority = p_priority; }135_FORCE_INLINE_ int get_priority() const { return priority; }136137_FORCE_INLINE_ void add_constraint(GodotConstraint2D *p_constraint) { constraints.insert(p_constraint); }138_FORCE_INLINE_ void remove_constraint(GodotConstraint2D *p_constraint) { constraints.erase(p_constraint); }139_FORCE_INLINE_ const HashSet<GodotConstraint2D *> &get_constraints() const { return constraints; }140_FORCE_INLINE_ void clear_constraints() { constraints.clear(); }141142void set_monitorable(bool p_monitorable);143_FORCE_INLINE_ bool is_monitorable() const { return monitorable; }144145void set_transform(const Transform2D &p_transform);146147void set_space(GodotSpace2D *p_space) override;148149void call_queries();150151void compute_gravity(const Vector2 &p_position, Vector2 &r_gravity) const;152153GodotArea2D();154~GodotArea2D();155};156157void GodotArea2D::add_body_to_query(GodotBody2D *p_body, uint32_t p_body_shape, uint32_t p_area_shape) {158BodyKey bk(p_body, p_body_shape, p_area_shape);159monitored_bodies[bk].inc();160if (!monitor_query_list.in_list()) {161_queue_monitor_update();162}163}164165void GodotArea2D::remove_body_from_query(GodotBody2D *p_body, uint32_t p_body_shape, uint32_t p_area_shape) {166BodyKey bk(p_body, p_body_shape, p_area_shape);167monitored_bodies[bk].dec();168if (get_space() && !monitor_query_list.in_list()) {169_queue_monitor_update();170}171}172173void GodotArea2D::add_area_to_query(GodotArea2D *p_area, uint32_t p_area_shape, uint32_t p_self_shape) {174BodyKey bk(p_area, p_area_shape, p_self_shape);175monitored_areas[bk].inc();176if (!monitor_query_list.in_list()) {177_queue_monitor_update();178}179}180181void GodotArea2D::remove_area_from_query(GodotArea2D *p_area, uint32_t p_area_shape, uint32_t p_self_shape) {182BodyKey bk(p_area, p_area_shape, p_self_shape);183monitored_areas[bk].dec();184if (get_space() && !monitor_query_list.in_list()) {185_queue_monitor_update();186}187}188189190