summaryrefslogtreecommitdiff
path: root/modules/bullet/rigid_body_bullet.h
diff options
context:
space:
mode:
Diffstat (limited to 'modules/bullet/rigid_body_bullet.h')
-rw-r--r--modules/bullet/rigid_body_bullet.h302
1 files changed, 302 insertions, 0 deletions
diff --git a/modules/bullet/rigid_body_bullet.h b/modules/bullet/rigid_body_bullet.h
new file mode 100644
index 0000000000..ab3c3e58b2
--- /dev/null
+++ b/modules/bullet/rigid_body_bullet.h
@@ -0,0 +1,302 @@
+/*************************************************************************/
+/* body_bullet.h */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+#include "LinearMath/btTransform.h"
+#include "collision_object_bullet.h"
+#include "space_bullet.h"
+
+class AreaBullet;
+class SpaceBullet;
+class btRigidBody;
+class GodotMotionState;
+class BulletPhysicsDirectBodyState;
+
+/// This class could be used in multi thread with few changes but currently
+/// is setted 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 setted 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 = NULL;
+ }
+
+ 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 void add_force(const Vector3 &p_force, const Vector3 &p_pos);
+ virtual void apply_impulse(const Vector3 &p_pos, const Vector3 &p_j);
+ virtual void apply_torque_impulse(const Vector3 &p_j);
+
+ 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 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;
+ };
+
+ struct ForceIntegrationCallback {
+ ObjectID id;
+ StringName method;
+ Variant udata;
+ };
+
+ /// Used to hold shapes
+ struct KinematicShape {
+ class btConvexShape *shape;
+ btTransform transform;
+
+ KinematicShape()
+ : shape(NULL) {}
+ const 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;
+ PhysicsServer::BodyAxisLock axis_lock;
+ GodotMotionState *godotMotionState;
+ btRigidBody *btBody;
+ real_t mass;
+ real_t gravity_scale;
+ real_t linearDamp;
+ real_t angularDamp;
+ bool can_sleep;
+
+ Vector<CollisionData> collisions;
+ // these parameters are used to avoid vector resize
+ int maxCollisionsDetection;
+ int collisionsCount;
+
+ 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 isTransformChanged;
+
+ ForceIntegrationCallback *force_integration_callback;
+
+public:
+ RigidBodyBullet();
+ ~RigidBodyBullet();
+
+ void init_kinematic_utilities();
+ void destroy_kinematic_utilities();
+ _FORCE_INLINE_ class KinematicUtilities *get_kinematic_utilities() const { return kinematic_utilities; }
+
+ _FORCE_INLINE_ btRigidBody *get_bt_rigid_body() { return btBody; }
+
+ 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();
+ void scratch_space_override_modificator();
+
+ virtual void on_collision_filters_change();
+ virtual void on_collision_checker_start();
+ void set_max_collisions_detection(int p_maxCollisionsDetection) {
+ maxCollisionsDetection = p_maxCollisionsDetection;
+ collisions.resize(p_maxCollisionsDetection);
+ collisionsCount = 0;
+ }
+ 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, int p_other_shape_index, int p_local_shape_index);
+
+ void assert_no_constraints();
+
+ void set_activation_state(bool p_active);
+ bool is_active() const;
+
+ 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_force);
+ 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_force);
+
+ 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::BodyAxisLock p_lock);
+ PhysicsServer::BodyAxisLock get_axis_lock() const;
+
+ /// Doc:
+ /// http://www.bulletphysics.org/mediawiki-1.5.8/index.php?title=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 on_shapes_changed();
+
+ 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();
+
+private:
+ void _internal_set_mass(real_t p_mass);
+};
+
+#endif