123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 |
- /*************************************************************************/
- /* rigid_body_bullet.h */
- /*************************************************************************/
- /* This file is part of: */
- /* GODOT ENGINE */
- /* https://godotengine.org */
- /*************************************************************************/
- /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
- /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
- /* */
- /* Permission is hereby granted, free of charge, to any person obtaining */
- /* a copy of this software and associated documentation files (the */
- /* "Software"), to deal in the Software without restriction, including */
- /* without limitation the rights to use, copy, modify, merge, publish, */
- /* distribute, sublicense, and/or sell copies of the Software, and to */
- /* permit persons to whom the Software is furnished to do so, subject to */
- /* the following conditions: */
- /* */
- /* The above copyright notice and this permission notice shall be */
- /* included in all copies or substantial portions of the Software. */
- /* */
- /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
- /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
- /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
- /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
- /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
- /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
- /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
- /*************************************************************************/
- #ifndef BODYBULLET_H
- #define BODYBULLET_H
- #include "collision_object_bullet.h"
- #include "space_bullet.h"
- #include <BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h>
- #include <LinearMath/btTransform.h>
- /**
- @author AndreaCatania
- */
- class AreaBullet;
- class SpaceBullet;
- class btRigidBody;
- class GodotMotionState;
- class BulletPhysicsDirectBodyState;
- /// This class could be used in multi thread with few changes but currently
- /// is set to be only in one single thread.
- ///
- /// In the system there is only one object at a time that manage all bodies and is
- /// created by BulletPhysicsServer and is held by the "singleton" variable of this class
- /// Each time something require it, the body must be set again.
- class BulletPhysicsDirectBodyState : public PhysicsDirectBodyState {
- GDCLASS(BulletPhysicsDirectBodyState, PhysicsDirectBodyState);
- static BulletPhysicsDirectBodyState *singleton;
- public:
- /// This class avoid the creation of more object of this class
- static void initSingleton() {
- if (!singleton) {
- singleton = memnew(BulletPhysicsDirectBodyState);
- }
- }
- static void destroySingleton() {
- memdelete(singleton);
- singleton = nullptr;
- }
- static void singleton_setDeltaTime(real_t p_deltaTime) {
- singleton->deltaTime = p_deltaTime;
- }
- static BulletPhysicsDirectBodyState *get_singleton(RigidBodyBullet *p_body) {
- singleton->body = p_body;
- return singleton;
- }
- public:
- RigidBodyBullet *body;
- real_t deltaTime;
- private:
- BulletPhysicsDirectBodyState() {}
- public:
- virtual Vector3 get_total_gravity() const;
- virtual float get_total_angular_damp() const;
- virtual float get_total_linear_damp() const;
- virtual Vector3 get_center_of_mass() const;
- virtual Basis get_principal_inertia_axes() const;
- // get the mass
- virtual float get_inverse_mass() const;
- // get density of this body space
- virtual Vector3 get_inverse_inertia() const;
- // get density of this body space
- virtual Basis get_inverse_inertia_tensor() const;
- virtual void set_linear_velocity(const Vector3 &p_velocity);
- virtual Vector3 get_linear_velocity() const;
- virtual void set_angular_velocity(const Vector3 &p_velocity);
- virtual Vector3 get_angular_velocity() const;
- virtual void set_transform(const Transform &p_transform);
- virtual Transform get_transform() const;
- virtual Vector3 get_velocity_at_local_position(const Vector3 &p_position) const;
- virtual void add_central_force(const Vector3 &p_force);
- virtual void add_force(const Vector3 &p_force, const Vector3 &p_pos);
- virtual void add_torque(const Vector3 &p_torque);
- virtual void apply_central_impulse(const Vector3 &p_impulse);
- virtual void apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse);
- virtual void apply_torque_impulse(const Vector3 &p_impulse);
- virtual void set_sleep_state(bool p_enable);
- virtual bool is_sleeping() const;
- virtual int get_contact_count() const;
- virtual Vector3 get_contact_local_position(int p_contact_idx) const;
- virtual Vector3 get_contact_local_normal(int p_contact_idx) const;
- virtual float get_contact_impulse(int p_contact_idx) const;
- virtual int get_contact_local_shape(int p_contact_idx) const;
- virtual RID get_contact_collider(int p_contact_idx) const;
- virtual Vector3 get_contact_collider_position(int p_contact_idx) const;
- virtual ObjectID get_contact_collider_id(int p_contact_idx) const;
- virtual int get_contact_collider_shape(int p_contact_idx) const;
- virtual Vector3 get_contact_collider_velocity_at_position(int p_contact_idx) const;
- virtual real_t get_step() const { return deltaTime; }
- virtual void integrate_forces() {
- // Skip the execution of this function
- }
- virtual PhysicsDirectSpaceState *get_space_state();
- };
- class RigidBodyBullet : public RigidCollisionObjectBullet {
- public:
- struct CollisionData {
- RigidBodyBullet *otherObject;
- int other_object_shape;
- int local_shape;
- Vector3 hitLocalLocation;
- Vector3 hitWorldLocation;
- Vector3 hitNormal;
- float appliedImpulse;
- };
- struct ForceIntegrationCallback {
- ObjectID id;
- StringName method;
- Variant udata;
- };
- /// Used to hold shapes
- struct KinematicShape {
- class btConvexShape *shape;
- btTransform transform;
- KinematicShape() :
- shape(nullptr) {}
- bool is_active() const { return shape; }
- };
- struct KinematicUtilities {
- RigidBodyBullet *owner;
- btScalar safe_margin;
- Vector<KinematicShape> shapes;
- KinematicUtilities(RigidBodyBullet *p_owner);
- ~KinematicUtilities();
- void setSafeMargin(btScalar p_margin);
- /// Used to set the default shape to ghost
- void copyAllOwnerShapes();
- private:
- void just_delete_shapes(int new_size);
- };
- private:
- friend class BulletPhysicsDirectBodyState;
- // This is required only for Kinematic movement
- KinematicUtilities *kinematic_utilities;
- PhysicsServer::BodyMode mode;
- GodotMotionState *godotMotionState;
- btRigidBody *btBody;
- uint16_t locked_axis;
- real_t mass;
- real_t gravity_scale;
- real_t linearDamp;
- real_t angularDamp;
- bool can_sleep;
- bool omit_forces_integration;
- bool can_integrate_forces;
- Vector<CollisionData> collisions;
- Vector<RigidBodyBullet *> collision_traces_1;
- Vector<RigidBodyBullet *> collision_traces_2;
- Vector<RigidBodyBullet *> *prev_collision_traces;
- Vector<RigidBodyBullet *> *curr_collision_traces;
- // these parameters are used to avoid vector resize
- int maxCollisionsDetection;
- int collisionsCount;
- int prev_collision_count;
- Vector<AreaBullet *> areasWhereIam;
- // these parameters are used to avoid vector resize
- int maxAreasWhereIam;
- int areaWhereIamCount;
- // Used to know if the area is used as gravity point
- int countGravityPointSpaces;
- bool isScratchedSpaceOverrideModificator;
- bool previousActiveState; // Last check state
- ForceIntegrationCallback *force_integration_callback;
- public:
- RigidBodyBullet();
- ~RigidBodyBullet();
- void init_kinematic_utilities();
- void destroy_kinematic_utilities();
- _FORCE_INLINE_ KinematicUtilities *get_kinematic_utilities() const { return kinematic_utilities; }
- _FORCE_INLINE_ btRigidBody *get_bt_rigid_body() { return btBody; }
- virtual void main_shape_changed();
- virtual void reload_body();
- virtual void set_space(SpaceBullet *p_space);
- virtual void dispatch_callbacks();
- void set_force_integration_callback(ObjectID p_id, const StringName &p_method, const Variant &p_udata = Variant());
- void scratch_space_override_modificator();
- virtual void on_collision_filters_change();
- virtual void on_collision_checker_start();
- virtual void on_collision_checker_end();
- void set_max_collisions_detection(int p_maxCollisionsDetection) {
- ERR_FAIL_COND(0 > p_maxCollisionsDetection);
- maxCollisionsDetection = p_maxCollisionsDetection;
- collisions.resize(p_maxCollisionsDetection);
- collision_traces_1.resize(p_maxCollisionsDetection);
- collision_traces_2.resize(p_maxCollisionsDetection);
- collisionsCount = 0;
- prev_collision_count = MIN(prev_collision_count, p_maxCollisionsDetection);
- }
- int get_max_collisions_detection() {
- return maxCollisionsDetection;
- }
- bool can_add_collision() { return collisionsCount < maxCollisionsDetection; }
- bool add_collision_object(RigidBodyBullet *p_otherObject, const Vector3 &p_hitWorldLocation, const Vector3 &p_hitLocalLocation, const Vector3 &p_hitNormal, const float &p_appliedImpulse, int p_other_shape_index, int p_local_shape_index);
- bool was_colliding(RigidBodyBullet *p_other_object);
- void set_activation_state(bool p_active);
- bool is_active() const;
- void set_omit_forces_integration(bool p_omit);
- _FORCE_INLINE_ bool get_omit_forces_integration() const { return omit_forces_integration; }
- void set_param(PhysicsServer::BodyParameter p_param, real_t);
- real_t get_param(PhysicsServer::BodyParameter p_param) const;
- void set_mode(PhysicsServer::BodyMode p_mode);
- PhysicsServer::BodyMode get_mode() const;
- void set_state(PhysicsServer::BodyState p_state, const Variant &p_variant);
- Variant get_state(PhysicsServer::BodyState p_state) const;
- void apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse);
- void apply_central_impulse(const Vector3 &p_impulse);
- void apply_torque_impulse(const Vector3 &p_impulse);
- void apply_force(const Vector3 &p_force, const Vector3 &p_pos);
- void apply_central_force(const Vector3 &p_force);
- void apply_torque(const Vector3 &p_torque);
- void set_applied_force(const Vector3 &p_force);
- Vector3 get_applied_force() const;
- void set_applied_torque(const Vector3 &p_torque);
- Vector3 get_applied_torque() const;
- void set_axis_lock(PhysicsServer::BodyAxis p_axis, bool lock);
- bool is_axis_locked(PhysicsServer::BodyAxis p_axis) const;
- void reload_axis_lock();
- /// Doc:
- /// https://web.archive.org/web/20180404091446/http://www.bulletphysics.org/mediawiki-1.5.8/index.php/Anti_tunneling_by_Motion_Clamping
- void set_continuous_collision_detection(bool p_enable);
- bool is_continuous_collision_detection_enabled() const;
- void set_linear_velocity(const Vector3 &p_velocity);
- Vector3 get_linear_velocity() const;
- void set_angular_velocity(const Vector3 &p_velocity);
- Vector3 get_angular_velocity() const;
- virtual void set_transform__bullet(const btTransform &p_global_transform);
- virtual const btTransform &get_transform__bullet() const;
- virtual void reload_shapes();
- virtual void on_enter_area(AreaBullet *p_area);
- virtual void on_exit_area(AreaBullet *p_area);
- void reload_space_override_modificator();
- /// Kinematic
- void reload_kinematic_shapes();
- virtual void notify_transform_changed();
- private:
- void _internal_set_mass(real_t p_mass);
- };
- #endif
|