- Enhanced the flush mechanism by flushing only needed thing.
- Flushing Areas before anything else. - Make sure to correctly fetch gravity when the integrate_forces function is used - Lazy reload body when layer and mask changes - Shapes are reloaded just before the physics step starts. - Improved some other parts of the code. - Added override keyword - Using LocalVector
This commit is contained in:
parent
9e34ba4855
commit
8d0d6d6921
|
@ -65,14 +65,11 @@ AreaBullet::~AreaBullet() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AreaBullet::dispatch_callbacks() {
|
void AreaBullet::dispatch_callbacks() {
|
||||||
if (!isScratched) {
|
RigidCollisionObjectBullet::dispatch_callbacks();
|
||||||
return;
|
|
||||||
}
|
|
||||||
isScratched = false;
|
|
||||||
|
|
||||||
// Reverse order because I've to remove EXIT objects
|
// Reverse order because I've to remove EXIT objects
|
||||||
for (int i = overlappingObjects.size() - 1; 0 <= i; --i) {
|
for (int i = overlappingObjects.size() - 1; 0 <= i; --i) {
|
||||||
OverlappingObjectData &otherObj = overlappingObjects.write[i];
|
OverlappingObjectData &otherObj = overlappingObjects[i];
|
||||||
|
|
||||||
switch (otherObj.state) {
|
switch (otherObj.state) {
|
||||||
case OVERLAP_STATE_ENTER:
|
case OVERLAP_STATE_ENTER:
|
||||||
|
@ -112,10 +109,9 @@ void AreaBullet::call_event(CollisionObjectBullet *p_otherObject, PhysicsServer3
|
||||||
}
|
}
|
||||||
|
|
||||||
void AreaBullet::scratch() {
|
void AreaBullet::scratch() {
|
||||||
if (isScratched) {
|
if (space != nullptr) {
|
||||||
return;
|
space->add_to_pre_flush_queue(this);
|
||||||
}
|
}
|
||||||
isScratched = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AreaBullet::clear_overlaps(bool p_notify) {
|
void AreaBullet::clear_overlaps(bool p_notify) {
|
||||||
|
@ -173,9 +169,9 @@ void AreaBullet::do_reload_body() {
|
||||||
|
|
||||||
void AreaBullet::set_space(SpaceBullet *p_space) {
|
void AreaBullet::set_space(SpaceBullet *p_space) {
|
||||||
// Clear the old space if there is one
|
// Clear the old space if there is one
|
||||||
|
|
||||||
if (space) {
|
if (space) {
|
||||||
clear_overlaps(false);
|
clear_overlaps(false);
|
||||||
isScratched = false;
|
|
||||||
|
|
||||||
// Remove this object form the physics world
|
// Remove this object form the physics world
|
||||||
space->unregister_collision_object(this);
|
space->unregister_collision_object(this);
|
||||||
|
@ -187,10 +183,11 @@ void AreaBullet::set_space(SpaceBullet *p_space) {
|
||||||
if (space) {
|
if (space) {
|
||||||
space->register_collision_object(this);
|
space->register_collision_object(this);
|
||||||
reload_body();
|
reload_body();
|
||||||
|
scratch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AreaBullet::on_collision_filters_change() {
|
void AreaBullet::do_reload_collision_filters() {
|
||||||
if (space) {
|
if (space) {
|
||||||
space->reload_collision_filters(this);
|
space->reload_collision_filters(this);
|
||||||
}
|
}
|
||||||
|
@ -204,13 +201,13 @@ void AreaBullet::add_overlap(CollisionObjectBullet *p_otherObject) {
|
||||||
|
|
||||||
void AreaBullet::put_overlap_as_exit(int p_index) {
|
void AreaBullet::put_overlap_as_exit(int p_index) {
|
||||||
scratch();
|
scratch();
|
||||||
overlappingObjects.write[p_index].state = OVERLAP_STATE_EXIT;
|
overlappingObjects[p_index].state = OVERLAP_STATE_EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AreaBullet::put_overlap_as_inside(int p_index) {
|
void AreaBullet::put_overlap_as_inside(int p_index) {
|
||||||
// This check is required to be sure this body was inside
|
// This check is required to be sure this body was inside
|
||||||
if (OVERLAP_STATE_DIRTY == overlappingObjects[p_index].state) {
|
if (OVERLAP_STATE_DIRTY == overlappingObjects[p_index].state) {
|
||||||
overlappingObjects.write[p_index].state = OVERLAP_STATE_INSIDE;
|
overlappingObjects[p_index].state = OVERLAP_STATE_INSIDE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#define AREABULLET_H
|
#define AREABULLET_H
|
||||||
|
|
||||||
#include "collision_object_bullet.h"
|
#include "collision_object_bullet.h"
|
||||||
#include "core/vector.h"
|
#include "core/local_vector.h"
|
||||||
#include "servers/physics_server_3d.h"
|
#include "servers/physics_server_3d.h"
|
||||||
#include "space_bullet.h"
|
#include "space_bullet.h"
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ private:
|
||||||
Variant *call_event_res_ptr[5];
|
Variant *call_event_res_ptr[5];
|
||||||
|
|
||||||
btGhostObject *btGhost;
|
btGhostObject *btGhost;
|
||||||
Vector<OverlappingObjectData> overlappingObjects;
|
LocalVector<OverlappingObjectData> overlappingObjects;
|
||||||
bool monitorable = true;
|
bool monitorable = true;
|
||||||
|
|
||||||
PhysicsServer3D::AreaSpaceOverrideMode spOv_mode = PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED;
|
PhysicsServer3D::AreaSpaceOverrideMode spOv_mode = PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED;
|
||||||
|
@ -96,8 +96,6 @@ private:
|
||||||
real_t spOv_angularDump = 0.1;
|
real_t spOv_angularDump = 0.1;
|
||||||
int spOv_priority = 0;
|
int spOv_priority = 0;
|
||||||
|
|
||||||
bool isScratched = false;
|
|
||||||
|
|
||||||
InOutEventCallback eventsCallbacks[2];
|
InOutEventCallback eventsCallbacks[2];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -139,11 +137,11 @@ public:
|
||||||
_FORCE_INLINE_ void set_spOv_priority(int p_priority) { spOv_priority = p_priority; }
|
_FORCE_INLINE_ void set_spOv_priority(int p_priority) { spOv_priority = p_priority; }
|
||||||
_FORCE_INLINE_ int get_spOv_priority() { return spOv_priority; }
|
_FORCE_INLINE_ int get_spOv_priority() { return spOv_priority; }
|
||||||
|
|
||||||
virtual void main_shape_changed();
|
virtual void main_shape_changed() override;
|
||||||
virtual void do_reload_body();
|
virtual void do_reload_body() override;
|
||||||
virtual void set_space(SpaceBullet *p_space);
|
virtual void set_space(SpaceBullet *p_space) override;
|
||||||
|
|
||||||
virtual void dispatch_callbacks();
|
virtual void dispatch_callbacks() override;
|
||||||
void call_event(CollisionObjectBullet *p_otherObject, PhysicsServer3D::AreaBodyStatus p_status);
|
void call_event(CollisionObjectBullet *p_otherObject, PhysicsServer3D::AreaBodyStatus p_status);
|
||||||
void set_on_state_change(ObjectID p_id, const StringName &p_method, const Variant &p_udata = Variant());
|
void set_on_state_change(ObjectID p_id, const StringName &p_method, const Variant &p_udata = Variant());
|
||||||
void scratch();
|
void scratch();
|
||||||
|
@ -152,9 +150,9 @@ public:
|
||||||
// Dispatch the callbacks and removes from overlapping list
|
// Dispatch the callbacks and removes from overlapping list
|
||||||
void remove_overlap(CollisionObjectBullet *p_object, bool p_notify);
|
void remove_overlap(CollisionObjectBullet *p_object, bool p_notify);
|
||||||
|
|
||||||
virtual void on_collision_filters_change();
|
virtual void do_reload_collision_filters() override;
|
||||||
virtual void on_collision_checker_start() {}
|
virtual void on_collision_checker_start() override {}
|
||||||
virtual void on_collision_checker_end() { isTransformChanged = false; }
|
virtual void on_collision_checker_end() override { isTransformChanged = false; }
|
||||||
|
|
||||||
void add_overlap(CollisionObjectBullet *p_otherObject);
|
void add_overlap(CollisionObjectBullet *p_otherObject);
|
||||||
void put_overlap_as_exit(int p_index);
|
void put_overlap_as_exit(int p_index);
|
||||||
|
@ -166,8 +164,8 @@ public:
|
||||||
void set_event_callback(Type p_callbackObjectType, ObjectID p_id, const StringName &p_method);
|
void set_event_callback(Type p_callbackObjectType, ObjectID p_id, const StringName &p_method);
|
||||||
bool has_event_callback(Type p_callbackObjectType);
|
bool has_event_callback(Type p_callbackObjectType);
|
||||||
|
|
||||||
virtual void on_enter_area(AreaBullet *p_area);
|
virtual void on_enter_area(AreaBullet *p_area) override;
|
||||||
virtual void on_exit_area(AreaBullet *p_area);
|
virtual void on_exit_area(AreaBullet *p_area) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -52,7 +52,7 @@ class BulletPhysicsServer3D : public PhysicsServer3D {
|
||||||
|
|
||||||
bool active = true;
|
bool active = true;
|
||||||
char active_spaces_count = 0;
|
char active_spaces_count = 0;
|
||||||
Vector<SpaceBullet *> active_spaces;
|
LocalVector<SpaceBullet *> active_spaces;
|
||||||
|
|
||||||
mutable RID_PtrOwner<SpaceBullet> space_owner;
|
mutable RID_PtrOwner<SpaceBullet> space_owner;
|
||||||
mutable RID_PtrOwner<ShapeBullet> shape_owner;
|
mutable RID_PtrOwner<ShapeBullet> shape_owner;
|
||||||
|
|
|
@ -165,11 +165,20 @@ bool CollisionObjectBullet::has_collision_exception(const CollisionObjectBullet
|
||||||
return !bt_collision_object->checkCollideWith(p_otherCollisionObject->bt_collision_object);
|
return !bt_collision_object->checkCollideWith(p_otherCollisionObject->bt_collision_object);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CollisionObjectBullet::prepare_object_for_dispatch() {
|
void CollisionObjectBullet::reload_body() {
|
||||||
if (need_body_reload) {
|
needs_body_reload = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CollisionObjectBullet::dispatch_callbacks() {}
|
||||||
|
|
||||||
|
void CollisionObjectBullet::pre_process() {
|
||||||
|
if (needs_body_reload) {
|
||||||
do_reload_body();
|
do_reload_body();
|
||||||
need_body_reload = false;
|
} else if (needs_collision_filters_reload) {
|
||||||
|
do_reload_collision_filters();
|
||||||
}
|
}
|
||||||
|
needs_body_reload = false;
|
||||||
|
needs_collision_filters_reload = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CollisionObjectBullet::set_collision_enabled(bool p_enabled) {
|
void CollisionObjectBullet::set_collision_enabled(bool p_enabled) {
|
||||||
|
@ -245,7 +254,7 @@ void RigidCollisionObjectBullet::add_shape(ShapeBullet *p_shape, const Transform
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidCollisionObjectBullet::set_shape(int p_index, ShapeBullet *p_shape) {
|
void RigidCollisionObjectBullet::set_shape(int p_index, ShapeBullet *p_shape) {
|
||||||
ShapeWrapper &shp = shapes.write[p_index];
|
ShapeWrapper &shp = shapes[p_index];
|
||||||
shp.shape->remove_owner(this);
|
shp.shape->remove_owner(this);
|
||||||
p_shape->add_owner(this);
|
p_shape->add_owner(this);
|
||||||
shp.shape = p_shape;
|
shp.shape = p_shape;
|
||||||
|
@ -307,7 +316,7 @@ void RigidCollisionObjectBullet::remove_all_shapes(bool p_permanentlyFromThisBod
|
||||||
void RigidCollisionObjectBullet::set_shape_transform(int p_index, const Transform &p_transform) {
|
void RigidCollisionObjectBullet::set_shape_transform(int p_index, const Transform &p_transform) {
|
||||||
ERR_FAIL_INDEX(p_index, get_shape_count());
|
ERR_FAIL_INDEX(p_index, get_shape_count());
|
||||||
|
|
||||||
shapes.write[p_index].set_transform(p_transform);
|
shapes[p_index].set_transform(p_transform);
|
||||||
shape_changed(p_index);
|
shape_changed(p_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,7 +334,7 @@ void RigidCollisionObjectBullet::set_shape_disabled(int p_index, bool p_disabled
|
||||||
if (shapes[p_index].active != p_disabled) {
|
if (shapes[p_index].active != p_disabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
shapes.write[p_index].active = !p_disabled;
|
shapes[p_index].active = !p_disabled;
|
||||||
shape_changed(p_index);
|
shape_changed(p_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,16 +342,16 @@ bool RigidCollisionObjectBullet::is_shape_disabled(int p_index) {
|
||||||
return !shapes[p_index].active;
|
return !shapes[p_index].active;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidCollisionObjectBullet::prepare_object_for_dispatch() {
|
void RigidCollisionObjectBullet::pre_process() {
|
||||||
if (need_shape_reload) {
|
if (need_shape_reload) {
|
||||||
do_reload_shapes();
|
do_reload_shapes();
|
||||||
need_shape_reload = false;
|
need_shape_reload = false;
|
||||||
}
|
}
|
||||||
CollisionObjectBullet::prepare_object_for_dispatch();
|
CollisionObjectBullet::pre_process();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidCollisionObjectBullet::shape_changed(int p_shape_index) {
|
void RigidCollisionObjectBullet::shape_changed(int p_shape_index) {
|
||||||
ShapeWrapper &shp = shapes.write[p_shape_index];
|
ShapeWrapper &shp = shapes[p_shape_index];
|
||||||
if (shp.bt_shape == mainShape) {
|
if (shp.bt_shape == mainShape) {
|
||||||
mainShape = nullptr;
|
mainShape = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -363,12 +372,11 @@ void RigidCollisionObjectBullet::do_reload_shapes() {
|
||||||
mainShape = nullptr;
|
mainShape = nullptr;
|
||||||
|
|
||||||
const int shape_count = shapes.size();
|
const int shape_count = shapes.size();
|
||||||
ShapeWrapper *shapes_ptr = shapes.ptrw();
|
|
||||||
|
|
||||||
// Reset all shapes if required
|
// Reset all shapes if required
|
||||||
if (force_shape_reset) {
|
if (force_shape_reset) {
|
||||||
for (int i(0); i < shape_count; ++i) {
|
for (int i(0); i < shape_count; ++i) {
|
||||||
shapes_ptr[i].release_bt_shape();
|
shapes[i].release_bt_shape();
|
||||||
}
|
}
|
||||||
force_shape_reset = false;
|
force_shape_reset = false;
|
||||||
}
|
}
|
||||||
|
@ -377,10 +385,10 @@ void RigidCollisionObjectBullet::do_reload_shapes() {
|
||||||
|
|
||||||
if (1 == shape_count) {
|
if (1 == shape_count) {
|
||||||
// Is it possible to optimize by not using compound?
|
// Is it possible to optimize by not using compound?
|
||||||
btTransform transform = shapes_ptr[0].get_adjusted_transform();
|
btTransform transform = shapes[0].get_adjusted_transform();
|
||||||
if (transform.getOrigin().isZero() && transform.getBasis() == transform.getBasis().getIdentity()) {
|
if (transform.getOrigin().isZero() && transform.getBasis() == transform.getBasis().getIdentity()) {
|
||||||
shapes_ptr[0].claim_bt_shape(body_scale);
|
shapes[0].claim_bt_shape(body_scale);
|
||||||
mainShape = shapes_ptr[0].bt_shape;
|
mainShape = shapes[0].bt_shape;
|
||||||
main_shape_changed();
|
main_shape_changed();
|
||||||
// Nothing more to do
|
// Nothing more to do
|
||||||
return;
|
return;
|
||||||
|
@ -391,10 +399,10 @@ void RigidCollisionObjectBullet::do_reload_shapes() {
|
||||||
btCompoundShape *compoundShape = bulletnew(btCompoundShape(enableDynamicAabbTree, shape_count));
|
btCompoundShape *compoundShape = bulletnew(btCompoundShape(enableDynamicAabbTree, shape_count));
|
||||||
|
|
||||||
for (int i(0); i < shape_count; ++i) {
|
for (int i(0); i < shape_count; ++i) {
|
||||||
shapes_ptr[i].claim_bt_shape(body_scale);
|
shapes[i].claim_bt_shape(body_scale);
|
||||||
btTransform scaled_shape_transform(shapes_ptr[i].get_adjusted_transform());
|
btTransform scaled_shape_transform(shapes[i].get_adjusted_transform());
|
||||||
scaled_shape_transform.getOrigin() *= body_scale;
|
scaled_shape_transform.getOrigin() *= body_scale;
|
||||||
compoundShape->addChildShape(scaled_shape_transform, shapes_ptr[i].bt_shape);
|
compoundShape->addChildShape(scaled_shape_transform, shapes[i].bt_shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
compoundShape->recalculateLocalAabb();
|
compoundShape->recalculateLocalAabb();
|
||||||
|
@ -408,7 +416,7 @@ void RigidCollisionObjectBullet::body_scale_changed() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidCollisionObjectBullet::internal_shape_destroy(int p_index, bool p_permanentlyFromThisBody) {
|
void RigidCollisionObjectBullet::internal_shape_destroy(int p_index, bool p_permanentlyFromThisBody) {
|
||||||
ShapeWrapper &shp = shapes.write[p_index];
|
ShapeWrapper &shp = shapes[p_index];
|
||||||
shp.shape->remove_owner(this, p_permanentlyFromThisBody);
|
shp.shape->remove_owner(this, p_permanentlyFromThisBody);
|
||||||
if (shp.bt_shape == mainShape) {
|
if (shp.bt_shape == mainShape) {
|
||||||
mainShape = nullptr;
|
mainShape = nullptr;
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#ifndef COLLISION_OBJECT_BULLET_H
|
#ifndef COLLISION_OBJECT_BULLET_H
|
||||||
#define COLLISION_OBJECT_BULLET_H
|
#define COLLISION_OBJECT_BULLET_H
|
||||||
|
|
||||||
|
#include "core/local_vector.h"
|
||||||
#include "core/math/transform.h"
|
#include "core/math/transform.h"
|
||||||
#include "core/math/vector3.h"
|
#include "core/math/vector3.h"
|
||||||
#include "core/object.h"
|
#include "core/object.h"
|
||||||
|
@ -126,16 +127,18 @@ protected:
|
||||||
|
|
||||||
VSet<RID> exceptions;
|
VSet<RID> exceptions;
|
||||||
|
|
||||||
bool need_body_reload = true;
|
bool needs_body_reload = true;
|
||||||
|
bool needs_collision_filters_reload = true;
|
||||||
|
|
||||||
/// This array is used to know all areas where this Object is overlapped in
|
/// This array is used to know all areas where this Object is overlapped in
|
||||||
/// New area is added when overlap with new area (AreaBullet::addOverlap), then is removed when it exit (CollisionObjectBullet::onExitArea)
|
/// New area is added when overlap with new area (AreaBullet::addOverlap), then is removed when it exit (CollisionObjectBullet::onExitArea)
|
||||||
/// This array is used mainly to know which area hold the pointer of this object
|
/// This array is used mainly to know which area hold the pointer of this object
|
||||||
Vector<AreaBullet *> areasOverlapped;
|
LocalVector<AreaBullet *> areasOverlapped;
|
||||||
bool isTransformChanged = false;
|
bool isTransformChanged = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool is_in_world = false;
|
bool is_in_world = false;
|
||||||
|
bool is_in_flush_queue = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CollisionObjectBullet(Type p_type);
|
CollisionObjectBullet(Type p_type);
|
||||||
|
@ -171,7 +174,7 @@ public:
|
||||||
_FORCE_INLINE_ void set_collision_layer(uint32_t p_layer) {
|
_FORCE_INLINE_ void set_collision_layer(uint32_t p_layer) {
|
||||||
if (collisionLayer != p_layer) {
|
if (collisionLayer != p_layer) {
|
||||||
collisionLayer = p_layer;
|
collisionLayer = p_layer;
|
||||||
on_collision_filters_change();
|
needs_collision_filters_reload = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_FORCE_INLINE_ uint32_t get_collision_layer() const { return collisionLayer; }
|
_FORCE_INLINE_ uint32_t get_collision_layer() const { return collisionLayer; }
|
||||||
|
@ -179,24 +182,23 @@ public:
|
||||||
_FORCE_INLINE_ void set_collision_mask(uint32_t p_mask) {
|
_FORCE_INLINE_ void set_collision_mask(uint32_t p_mask) {
|
||||||
if (collisionMask != p_mask) {
|
if (collisionMask != p_mask) {
|
||||||
collisionMask = p_mask;
|
collisionMask = p_mask;
|
||||||
on_collision_filters_change();
|
needs_collision_filters_reload = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_FORCE_INLINE_ uint32_t get_collision_mask() const { return collisionMask; }
|
_FORCE_INLINE_ uint32_t get_collision_mask() const { return collisionMask; }
|
||||||
|
|
||||||
virtual void on_collision_filters_change() = 0;
|
virtual void do_reload_collision_filters() = 0;
|
||||||
|
|
||||||
_FORCE_INLINE_ bool test_collision_mask(CollisionObjectBullet *p_other) const {
|
_FORCE_INLINE_ bool test_collision_mask(CollisionObjectBullet *p_other) const {
|
||||||
return collisionLayer & p_other->collisionMask || p_other->collisionLayer & collisionMask;
|
return collisionLayer & p_other->collisionMask || p_other->collisionLayer & collisionMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool need_reload_body() const {
|
bool need_reload_body() const {
|
||||||
return need_body_reload;
|
return needs_body_reload;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reload_body() {
|
void reload_body();
|
||||||
need_body_reload = true;
|
|
||||||
}
|
|
||||||
virtual void do_reload_body() = 0;
|
virtual void do_reload_body() = 0;
|
||||||
virtual void set_space(SpaceBullet *p_space) = 0;
|
virtual void set_space(SpaceBullet *p_space) = 0;
|
||||||
_FORCE_INLINE_ SpaceBullet *get_space() const { return space; }
|
_FORCE_INLINE_ SpaceBullet *get_space() const { return space; }
|
||||||
|
@ -204,8 +206,8 @@ public:
|
||||||
virtual void on_collision_checker_start() = 0;
|
virtual void on_collision_checker_start() = 0;
|
||||||
virtual void on_collision_checker_end() = 0;
|
virtual void on_collision_checker_end() = 0;
|
||||||
|
|
||||||
virtual void prepare_object_for_dispatch();
|
virtual void dispatch_callbacks();
|
||||||
virtual void dispatch_callbacks() = 0;
|
virtual void pre_process();
|
||||||
|
|
||||||
void set_collision_enabled(bool p_enabled);
|
void set_collision_enabled(bool p_enabled);
|
||||||
bool is_collisions_response_enabled();
|
bool is_collisions_response_enabled();
|
||||||
|
@ -229,7 +231,7 @@ public:
|
||||||
class RigidCollisionObjectBullet : public CollisionObjectBullet, public ShapeOwnerBullet {
|
class RigidCollisionObjectBullet : public CollisionObjectBullet, public ShapeOwnerBullet {
|
||||||
protected:
|
protected:
|
||||||
btCollisionShape *mainShape = nullptr;
|
btCollisionShape *mainShape = nullptr;
|
||||||
Vector<ShapeWrapper> shapes;
|
LocalVector<ShapeWrapper> shapes;
|
||||||
bool need_shape_reload = true;
|
bool need_shape_reload = true;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -237,7 +239,7 @@ public:
|
||||||
CollisionObjectBullet(p_type) {}
|
CollisionObjectBullet(p_type) {}
|
||||||
~RigidCollisionObjectBullet();
|
~RigidCollisionObjectBullet();
|
||||||
|
|
||||||
_FORCE_INLINE_ const Vector<ShapeWrapper> &get_shapes_wrappers() const { return shapes; }
|
_FORCE_INLINE_ const LocalVector<ShapeWrapper> &get_shapes_wrappers() const { return shapes; }
|
||||||
|
|
||||||
_FORCE_INLINE_ btCollisionShape *get_main_shape() const { return mainShape; }
|
_FORCE_INLINE_ btCollisionShape *get_main_shape() const { return mainShape; }
|
||||||
|
|
||||||
|
@ -248,9 +250,9 @@ public:
|
||||||
ShapeBullet *get_shape(int p_index) const;
|
ShapeBullet *get_shape(int p_index) const;
|
||||||
btCollisionShape *get_bt_shape(int p_index) const;
|
btCollisionShape *get_bt_shape(int p_index) const;
|
||||||
|
|
||||||
int find_shape(ShapeBullet *p_shape) const;
|
virtual int find_shape(ShapeBullet *p_shape) const override;
|
||||||
|
|
||||||
virtual void remove_shape_full(ShapeBullet *p_shape);
|
virtual void remove_shape_full(ShapeBullet *p_shape) override;
|
||||||
void remove_shape_full(int p_index);
|
void remove_shape_full(int p_index);
|
||||||
void remove_all_shapes(bool p_permanentlyFromThisBody = false, bool p_force_not_reload = false);
|
void remove_all_shapes(bool p_permanentlyFromThisBody = false, bool p_force_not_reload = false);
|
||||||
|
|
||||||
|
@ -262,15 +264,15 @@ public:
|
||||||
void set_shape_disabled(int p_index, bool p_disabled);
|
void set_shape_disabled(int p_index, bool p_disabled);
|
||||||
bool is_shape_disabled(int p_index);
|
bool is_shape_disabled(int p_index);
|
||||||
|
|
||||||
virtual void prepare_object_for_dispatch();
|
virtual void pre_process() override;
|
||||||
|
|
||||||
virtual void shape_changed(int p_shape_index);
|
virtual void shape_changed(int p_shape_index) override;
|
||||||
void reload_shapes();
|
virtual void reload_shapes() override;
|
||||||
bool need_reload_shapes() const { return need_shape_reload; }
|
bool need_reload_shapes() const { return need_shape_reload; }
|
||||||
virtual void do_reload_shapes();
|
virtual void do_reload_shapes();
|
||||||
|
|
||||||
virtual void main_shape_changed() = 0;
|
virtual void main_shape_changed() = 0;
|
||||||
virtual void body_scale_changed();
|
virtual void body_scale_changed() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void internal_shape_destroy(int p_index, bool p_permanentlyFromThisBody = false);
|
void internal_shape_destroy(int p_index, bool p_permanentlyFromThisBody = false);
|
||||||
|
|
|
@ -51,9 +51,7 @@
|
||||||
BulletPhysicsDirectBodyState3D *BulletPhysicsDirectBodyState3D::singleton = nullptr;
|
BulletPhysicsDirectBodyState3D *BulletPhysicsDirectBodyState3D::singleton = nullptr;
|
||||||
|
|
||||||
Vector3 BulletPhysicsDirectBodyState3D::get_total_gravity() const {
|
Vector3 BulletPhysicsDirectBodyState3D::get_total_gravity() const {
|
||||||
Vector3 gVec;
|
return body->total_gravity;
|
||||||
B_TO_G(body->btBody->getGravity(), gVec);
|
|
||||||
return gVec;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float BulletPhysicsDirectBodyState3D::get_total_angular_damp() const {
|
float BulletPhysicsDirectBodyState3D::get_total_angular_damp() const {
|
||||||
|
@ -183,7 +181,7 @@ int BulletPhysicsDirectBodyState3D::get_contact_collider_shape(int p_contact_idx
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 BulletPhysicsDirectBodyState3D::get_contact_collider_velocity_at_position(int p_contact_idx) const {
|
Vector3 BulletPhysicsDirectBodyState3D::get_contact_collider_velocity_at_position(int p_contact_idx) const {
|
||||||
RigidBodyBullet::CollisionData &colDat = body->collisions.write[p_contact_idx];
|
RigidBodyBullet::CollisionData &colDat = body->collisions[p_contact_idx];
|
||||||
|
|
||||||
btVector3 hitLocation;
|
btVector3 hitLocation;
|
||||||
G_TO_B(colDat.hitLocalLocation, hitLocation);
|
G_TO_B(colDat.hitLocalLocation, hitLocation);
|
||||||
|
@ -213,7 +211,7 @@ void RigidBodyBullet::KinematicUtilities::setSafeMargin(btScalar p_margin) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBodyBullet::KinematicUtilities::copyAllOwnerShapes() {
|
void RigidBodyBullet::KinematicUtilities::copyAllOwnerShapes() {
|
||||||
const Vector<CollisionObjectBullet::ShapeWrapper> &shapes_wrappers(owner->get_shapes_wrappers());
|
const LocalVector<CollisionObjectBullet::ShapeWrapper> &shapes_wrappers(owner->get_shapes_wrappers());
|
||||||
const int shapes_count = shapes_wrappers.size();
|
const int shapes_count = shapes_wrappers.size();
|
||||||
|
|
||||||
just_delete_shapes(shapes_count);
|
just_delete_shapes(shapes_count);
|
||||||
|
@ -228,8 +226,8 @@ void RigidBodyBullet::KinematicUtilities::copyAllOwnerShapes() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
shapes.write[i].transform = shape_wrapper->transform;
|
shapes[i].transform = shape_wrapper->transform;
|
||||||
shapes.write[i].transform.getOrigin() *= owner_scale;
|
shapes[i].transform.getOrigin() *= owner_scale;
|
||||||
switch (shape_wrapper->shape->get_type()) {
|
switch (shape_wrapper->shape->get_type()) {
|
||||||
case PhysicsServer3D::SHAPE_SPHERE:
|
case PhysicsServer3D::SHAPE_SPHERE:
|
||||||
case PhysicsServer3D::SHAPE_BOX:
|
case PhysicsServer3D::SHAPE_BOX:
|
||||||
|
@ -237,11 +235,11 @@ void RigidBodyBullet::KinematicUtilities::copyAllOwnerShapes() {
|
||||||
case PhysicsServer3D::SHAPE_CYLINDER:
|
case PhysicsServer3D::SHAPE_CYLINDER:
|
||||||
case PhysicsServer3D::SHAPE_CONVEX_POLYGON:
|
case PhysicsServer3D::SHAPE_CONVEX_POLYGON:
|
||||||
case PhysicsServer3D::SHAPE_RAY: {
|
case PhysicsServer3D::SHAPE_RAY: {
|
||||||
shapes.write[i].shape = static_cast<btConvexShape *>(shape_wrapper->shape->internal_create_bt_shape(owner_scale * shape_wrapper->scale, safe_margin));
|
shapes[i].shape = static_cast<btConvexShape *>(shape_wrapper->shape->internal_create_bt_shape(owner_scale * shape_wrapper->scale, safe_margin));
|
||||||
} break;
|
} break;
|
||||||
default:
|
default:
|
||||||
WARN_PRINT("This shape is not supported for kinematic collision.");
|
WARN_PRINT("This shape is not supported for kinematic collision.");
|
||||||
shapes.write[i].shape = nullptr;
|
shapes[i].shape = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -249,7 +247,7 @@ void RigidBodyBullet::KinematicUtilities::copyAllOwnerShapes() {
|
||||||
void RigidBodyBullet::KinematicUtilities::just_delete_shapes(int new_size) {
|
void RigidBodyBullet::KinematicUtilities::just_delete_shapes(int new_size) {
|
||||||
for (int i = shapes.size() - 1; 0 <= i; --i) {
|
for (int i = shapes.size() - 1; 0 <= i; --i) {
|
||||||
if (shapes[i].shape) {
|
if (shapes[i].shape) {
|
||||||
bulletdelete(shapes.write[i].shape);
|
bulletdelete(shapes[i].shape);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
shapes.resize(new_size);
|
shapes.resize(new_size);
|
||||||
|
@ -271,8 +269,8 @@ RigidBodyBullet::RigidBodyBullet() :
|
||||||
reload_axis_lock();
|
reload_axis_lock();
|
||||||
|
|
||||||
areasWhereIam.resize(maxAreasWhereIam);
|
areasWhereIam.resize(maxAreasWhereIam);
|
||||||
for (int i = areasWhereIam.size() - 1; 0 <= i; --i) {
|
for (uint32_t i = 0; i < areasWhereIam.size(); i += 1) {
|
||||||
areasWhereIam.write[i] = nullptr;
|
areasWhereIam[i] = nullptr;
|
||||||
}
|
}
|
||||||
btBody->setSleepingThresholds(0.2, 0.2);
|
btBody->setSleepingThresholds(0.2, 0.2);
|
||||||
|
|
||||||
|
@ -335,16 +333,15 @@ void RigidBodyBullet::set_space(SpaceBullet *p_space) {
|
||||||
if (space) {
|
if (space) {
|
||||||
space->register_collision_object(this);
|
space->register_collision_object(this);
|
||||||
reload_body();
|
reload_body();
|
||||||
|
space->add_to_flush_queue(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBodyBullet::dispatch_callbacks() {
|
void RigidBodyBullet::dispatch_callbacks() {
|
||||||
|
RigidCollisionObjectBullet::dispatch_callbacks();
|
||||||
|
|
||||||
/// The check isFirstTransformChanged is necessary in order to call integrated forces only when the first transform is sent
|
/// The check isFirstTransformChanged is necessary in order to call integrated forces only when the first transform is sent
|
||||||
if ((btBody->isKinematicObject() || btBody->isActive() || previousActiveState != btBody->isActive()) && force_integration_callback && can_integrate_forces) {
|
if ((btBody->isKinematicObject() || btBody->isActive() || previousActiveState != btBody->isActive()) && force_integration_callback && can_integrate_forces) {
|
||||||
if (omit_forces_integration) {
|
|
||||||
btBody->clearForces();
|
|
||||||
}
|
|
||||||
|
|
||||||
BulletPhysicsDirectBodyState3D *bodyDirect = BulletPhysicsDirectBodyState3D::get_singleton(this);
|
BulletPhysicsDirectBodyState3D *bodyDirect = BulletPhysicsDirectBodyState3D::get_singleton(this);
|
||||||
|
|
||||||
Variant variantBodyDirect = bodyDirect;
|
Variant variantBodyDirect = bodyDirect;
|
||||||
|
@ -362,16 +359,22 @@ void RigidBodyBullet::dispatch_callbacks() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
previousActiveState = btBody->isActive();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RigidBodyBullet::pre_process() {
|
||||||
|
RigidCollisionObjectBullet::pre_process();
|
||||||
|
|
||||||
if (isScratchedSpaceOverrideModificator || 0 < countGravityPointSpaces) {
|
if (isScratchedSpaceOverrideModificator || 0 < countGravityPointSpaces) {
|
||||||
isScratchedSpaceOverrideModificator = false;
|
isScratchedSpaceOverrideModificator = false;
|
||||||
reload_space_override_modificator();
|
reload_space_override_modificator();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Lock axis
|
if (is_active()) {
|
||||||
btBody->setLinearVelocity(btBody->getLinearVelocity() * btBody->getLinearFactor());
|
/// Lock axis
|
||||||
btBody->setAngularVelocity(btBody->getAngularVelocity() * btBody->getAngularFactor());
|
btBody->setLinearVelocity(btBody->getLinearVelocity() * btBody->getLinearFactor());
|
||||||
|
btBody->setAngularVelocity(btBody->getAngularVelocity() * btBody->getAngularFactor());
|
||||||
previousActiveState = btBody->isActive();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBodyBullet::set_force_integration_callback(ObjectID p_id, const StringName &p_method, const Variant &p_udata) {
|
void RigidBodyBullet::set_force_integration_callback(ObjectID p_id, const StringName &p_method, const Variant &p_udata) {
|
||||||
|
@ -392,7 +395,7 @@ void RigidBodyBullet::scratch_space_override_modificator() {
|
||||||
isScratchedSpaceOverrideModificator = true;
|
isScratchedSpaceOverrideModificator = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBodyBullet::on_collision_filters_change() {
|
void RigidBodyBullet::do_reload_collision_filters() {
|
||||||
if (space) {
|
if (space) {
|
||||||
space->reload_collision_filters(this);
|
space->reload_collision_filters(this);
|
||||||
}
|
}
|
||||||
|
@ -405,14 +408,15 @@ void RigidBodyBullet::on_collision_checker_start() {
|
||||||
collisionsCount = 0;
|
collisionsCount = 0;
|
||||||
|
|
||||||
// Swap array
|
// Swap array
|
||||||
Vector<RigidBodyBullet *> *s = prev_collision_traces;
|
SWAP(prev_collision_traces, curr_collision_traces);
|
||||||
prev_collision_traces = curr_collision_traces;
|
|
||||||
curr_collision_traces = s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBodyBullet::on_collision_checker_end() {
|
void RigidBodyBullet::on_collision_checker_end() {
|
||||||
// Always true if active and not a static or kinematic body
|
// Always true if active and not a static or kinematic body
|
||||||
isTransformChanged = btBody->isActive() && !btBody->isStaticOrKinematicObject();
|
isTransformChanged = btBody->isActive() && !btBody->isStaticOrKinematicObject();
|
||||||
|
if (isTransformChanged && space != nullptr) {
|
||||||
|
space->add_to_flush_queue(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RigidBodyBullet::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 RigidBodyBullet::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) {
|
||||||
|
@ -420,7 +424,7 @@ bool RigidBodyBullet::add_collision_object(RigidBodyBullet *p_otherObject, const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CollisionData &cd = collisions.write[collisionsCount];
|
CollisionData &cd = collisions[collisionsCount];
|
||||||
cd.hitLocalLocation = p_hitLocalLocation;
|
cd.hitLocalLocation = p_hitLocalLocation;
|
||||||
cd.otherObject = p_otherObject;
|
cd.otherObject = p_otherObject;
|
||||||
cd.hitWorldLocation = p_hitWorldLocation;
|
cd.hitWorldLocation = p_hitWorldLocation;
|
||||||
|
@ -429,7 +433,7 @@ bool RigidBodyBullet::add_collision_object(RigidBodyBullet *p_otherObject, const
|
||||||
cd.other_object_shape = p_other_shape_index;
|
cd.other_object_shape = p_other_shape_index;
|
||||||
cd.local_shape = p_local_shape_index;
|
cd.local_shape = p_local_shape_index;
|
||||||
|
|
||||||
curr_collision_traces->write[collisionsCount] = p_otherObject;
|
(*curr_collision_traces)[collisionsCount] = p_otherObject;
|
||||||
|
|
||||||
++collisionsCount;
|
++collisionsCount;
|
||||||
return true;
|
return true;
|
||||||
|
@ -464,6 +468,7 @@ bool RigidBodyBullet::is_active() const {
|
||||||
|
|
||||||
void RigidBodyBullet::set_omit_forces_integration(bool p_omit) {
|
void RigidBodyBullet::set_omit_forces_integration(bool p_omit) {
|
||||||
omit_forces_integration = p_omit;
|
omit_forces_integration = p_omit;
|
||||||
|
scratch_space_override_modificator();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBodyBullet::set_param(PhysicsServer3D::BodyParameter p_param, real_t p_value) {
|
void RigidBodyBullet::set_param(PhysicsServer3D::BodyParameter p_param, real_t p_value) {
|
||||||
|
@ -839,15 +844,15 @@ void RigidBodyBullet::on_enter_area(AreaBullet *p_area) {
|
||||||
for (int i = 0; i < areaWhereIamCount; ++i) {
|
for (int i = 0; i < areaWhereIamCount; ++i) {
|
||||||
if (nullptr == areasWhereIam[i]) {
|
if (nullptr == areasWhereIam[i]) {
|
||||||
// This area has the highest priority
|
// This area has the highest priority
|
||||||
areasWhereIam.write[i] = p_area;
|
areasWhereIam[i] = p_area;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
if (areasWhereIam[i]->get_spOv_priority() > p_area->get_spOv_priority()) {
|
if (areasWhereIam[i]->get_spOv_priority() > p_area->get_spOv_priority()) {
|
||||||
// The position was found, just shift all elements
|
// The position was found, just shift all elements
|
||||||
for (int j = i; j < areaWhereIamCount; ++j) {
|
for (int j = i; j < areaWhereIamCount; ++j) {
|
||||||
areasWhereIam.write[j + 1] = areasWhereIam[j];
|
areasWhereIam[j + 1] = areasWhereIam[j];
|
||||||
}
|
}
|
||||||
areasWhereIam.write[i] = p_area;
|
areasWhereIam[i] = p_area;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -871,7 +876,7 @@ void RigidBodyBullet::on_exit_area(AreaBullet *p_area) {
|
||||||
if (p_area == areasWhereIam[i]) {
|
if (p_area == areasWhereIam[i]) {
|
||||||
// The area was found, just shift down all elements
|
// The area was found, just shift down all elements
|
||||||
for (int j = i; j < areaWhereIamCount; ++j) {
|
for (int j = i; j < areaWhereIamCount; ++j) {
|
||||||
areasWhereIam.write[j] = areasWhereIam[j + 1];
|
areasWhereIam[j] = areasWhereIam[j + 1];
|
||||||
}
|
}
|
||||||
wasTheAreaFound = true;
|
wasTheAreaFound = true;
|
||||||
break;
|
break;
|
||||||
|
@ -884,7 +889,7 @@ void RigidBodyBullet::on_exit_area(AreaBullet *p_area) {
|
||||||
}
|
}
|
||||||
|
|
||||||
--areaWhereIamCount;
|
--areaWhereIamCount;
|
||||||
areasWhereIam.write[areaWhereIamCount] = nullptr; // Even if this is not required, I clear the last element to be safe
|
areasWhereIam[areaWhereIamCount] = nullptr; // Even if this is not required, I clear the last element to be safe
|
||||||
if (PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED != p_area->get_spOv_mode()) {
|
if (PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED != p_area->get_spOv_mode()) {
|
||||||
scratch_space_override_modificator();
|
scratch_space_override_modificator();
|
||||||
}
|
}
|
||||||
|
@ -897,36 +902,31 @@ void RigidBodyBullet::reload_space_override_modificator() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 newGravity(0.0, 0.0, 0.0);
|
Vector3 newGravity;
|
||||||
real_t newLinearDamp = MAX(0.0, linearDamp);
|
real_t newLinearDamp = MAX(0.0, linearDamp);
|
||||||
real_t newAngularDamp = MAX(0.0, angularDamp);
|
real_t newAngularDamp = MAX(0.0, angularDamp);
|
||||||
|
|
||||||
AreaBullet *currentArea;
|
|
||||||
// Variable used to calculate new gravity for gravity point areas, it is pointed by currentGravity pointer
|
|
||||||
Vector3 support_gravity(0, 0, 0);
|
|
||||||
|
|
||||||
bool stopped = false;
|
bool stopped = false;
|
||||||
for (int i = areaWhereIamCount - 1; (0 <= i) && !stopped; --i) {
|
for (int i = 0; i < areaWhereIamCount && !stopped; i += 1) {
|
||||||
currentArea = areasWhereIam[i];
|
AreaBullet *currentArea = areasWhereIam[i];
|
||||||
|
|
||||||
if (!currentArea || PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED == currentArea->get_spOv_mode()) {
|
if (!currentArea || PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED == currentArea->get_spOv_mode()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector3 support_gravity;
|
||||||
|
|
||||||
/// Here is calculated the gravity
|
/// Here is calculated the gravity
|
||||||
if (currentArea->is_spOv_gravityPoint()) {
|
if (currentArea->is_spOv_gravityPoint()) {
|
||||||
/// It calculates the direction of new gravity
|
/// It calculates the direction of new gravity
|
||||||
support_gravity = currentArea->get_transform().xform(currentArea->get_spOv_gravityVec()) - get_transform().get_origin();
|
support_gravity = currentArea->get_transform().xform(currentArea->get_spOv_gravityVec()) - get_transform().get_origin();
|
||||||
real_t distanceMag = support_gravity.length();
|
|
||||||
|
const real_t distanceMag = support_gravity.length();
|
||||||
// Normalized in this way to avoid the double call of function "length()"
|
// Normalized in this way to avoid the double call of function "length()"
|
||||||
if (distanceMag == 0) {
|
if (distanceMag == 0) {
|
||||||
support_gravity.x = 0;
|
support_gravity = Vector3();
|
||||||
support_gravity.y = 0;
|
|
||||||
support_gravity.z = 0;
|
|
||||||
} else {
|
} else {
|
||||||
support_gravity.x /= distanceMag;
|
support_gravity /= distanceMag;
|
||||||
support_gravity.y /= distanceMag;
|
|
||||||
support_gravity.z /= distanceMag;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Here is calculated the final gravity
|
/// Here is calculated the final gravity
|
||||||
|
@ -988,10 +988,17 @@ void RigidBodyBullet::reload_space_override_modificator() {
|
||||||
newAngularDamp += space->get_angular_damp();
|
newAngularDamp += space->get_angular_damp();
|
||||||
}
|
}
|
||||||
|
|
||||||
btVector3 newBtGravity;
|
total_gravity = newGravity;
|
||||||
G_TO_B(newGravity * gravity_scale, newBtGravity);
|
|
||||||
|
if (omit_forces_integration) {
|
||||||
|
// Custom behaviour.
|
||||||
|
btBody->setGravity(btVector3(0, 0, 0));
|
||||||
|
} else {
|
||||||
|
btVector3 newBtGravity;
|
||||||
|
G_TO_B(newGravity * gravity_scale, newBtGravity);
|
||||||
|
btBody->setGravity(newBtGravity);
|
||||||
|
}
|
||||||
|
|
||||||
btBody->setGravity(newBtGravity);
|
|
||||||
btBody->setDamping(newLinearDamp, newAngularDamp);
|
btBody->setDamping(newLinearDamp, newAngularDamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -171,7 +171,7 @@ public:
|
||||||
struct KinematicUtilities {
|
struct KinematicUtilities {
|
||||||
RigidBodyBullet *owner;
|
RigidBodyBullet *owner;
|
||||||
btScalar safe_margin;
|
btScalar safe_margin;
|
||||||
Vector<KinematicShape> shapes;
|
LocalVector<KinematicShape> shapes;
|
||||||
|
|
||||||
KinematicUtilities(RigidBodyBullet *p_owner);
|
KinematicUtilities(RigidBodyBullet *p_owner);
|
||||||
~KinematicUtilities();
|
~KinematicUtilities();
|
||||||
|
@ -193,6 +193,7 @@ private:
|
||||||
PhysicsServer3D::BodyMode mode;
|
PhysicsServer3D::BodyMode mode;
|
||||||
GodotMotionState *godotMotionState;
|
GodotMotionState *godotMotionState;
|
||||||
btRigidBody *btBody;
|
btRigidBody *btBody;
|
||||||
|
Vector3 total_gravity;
|
||||||
uint16_t locked_axis = 0;
|
uint16_t locked_axis = 0;
|
||||||
real_t mass = 1;
|
real_t mass = 1;
|
||||||
real_t gravity_scale = 1;
|
real_t gravity_scale = 1;
|
||||||
|
@ -202,18 +203,18 @@ private:
|
||||||
bool omit_forces_integration = false;
|
bool omit_forces_integration = false;
|
||||||
bool can_integrate_forces = false;
|
bool can_integrate_forces = false;
|
||||||
|
|
||||||
Vector<CollisionData> collisions;
|
LocalVector<CollisionData> collisions;
|
||||||
Vector<RigidBodyBullet *> collision_traces_1;
|
LocalVector<RigidBodyBullet *> collision_traces_1;
|
||||||
Vector<RigidBodyBullet *> collision_traces_2;
|
LocalVector<RigidBodyBullet *> collision_traces_2;
|
||||||
Vector<RigidBodyBullet *> *prev_collision_traces;
|
LocalVector<RigidBodyBullet *> *prev_collision_traces;
|
||||||
Vector<RigidBodyBullet *> *curr_collision_traces;
|
LocalVector<RigidBodyBullet *> *curr_collision_traces;
|
||||||
|
|
||||||
// these parameters are used to avoid vector resize
|
// these parameters are used to avoid vector resize
|
||||||
int maxCollisionsDetection = 0;
|
uint32_t maxCollisionsDetection = 0;
|
||||||
int collisionsCount = 0;
|
uint32_t collisionsCount = 0;
|
||||||
int prev_collision_count = 0;
|
uint32_t prev_collision_count = 0;
|
||||||
|
|
||||||
Vector<AreaBullet *> areasWhereIam;
|
LocalVector<AreaBullet *> areasWhereIam;
|
||||||
// these parameters are used to avoid vector resize
|
// these parameters are used to avoid vector resize
|
||||||
int maxAreasWhereIam = 10;
|
int maxAreasWhereIam = 10;
|
||||||
int areaWhereIamCount = 0;
|
int areaWhereIamCount = 0;
|
||||||
|
@ -235,21 +236,20 @@ public:
|
||||||
|
|
||||||
_FORCE_INLINE_ btRigidBody *get_bt_rigid_body() { return btBody; }
|
_FORCE_INLINE_ btRigidBody *get_bt_rigid_body() { return btBody; }
|
||||||
|
|
||||||
virtual void main_shape_changed();
|
virtual void main_shape_changed() override;
|
||||||
virtual void do_reload_body();
|
virtual void do_reload_body() override;
|
||||||
virtual void set_space(SpaceBullet *p_space);
|
virtual void set_space(SpaceBullet *p_space) override;
|
||||||
|
|
||||||
virtual void dispatch_callbacks();
|
virtual void dispatch_callbacks() override;
|
||||||
|
virtual void pre_process() override;
|
||||||
void set_force_integration_callback(ObjectID p_id, const StringName &p_method, const Variant &p_udata = Variant());
|
void set_force_integration_callback(ObjectID p_id, const StringName &p_method, const Variant &p_udata = Variant());
|
||||||
void scratch_space_override_modificator();
|
void scratch_space_override_modificator();
|
||||||
|
|
||||||
virtual void on_collision_filters_change();
|
virtual void do_reload_collision_filters() override;
|
||||||
virtual void on_collision_checker_start();
|
virtual void on_collision_checker_start() override;
|
||||||
virtual void on_collision_checker_end();
|
virtual void on_collision_checker_end() override;
|
||||||
|
|
||||||
void set_max_collisions_detection(int p_maxCollisionsDetection) {
|
|
||||||
ERR_FAIL_COND(0 > p_maxCollisionsDetection);
|
|
||||||
|
|
||||||
|
void set_max_collisions_detection(uint32_t p_maxCollisionsDetection) {
|
||||||
maxCollisionsDetection = p_maxCollisionsDetection;
|
maxCollisionsDetection = p_maxCollisionsDetection;
|
||||||
|
|
||||||
collisions.resize(p_maxCollisionsDetection);
|
collisions.resize(p_maxCollisionsDetection);
|
||||||
|
@ -312,19 +312,19 @@ public:
|
||||||
void set_angular_velocity(const Vector3 &p_velocity);
|
void set_angular_velocity(const Vector3 &p_velocity);
|
||||||
Vector3 get_angular_velocity() const;
|
Vector3 get_angular_velocity() const;
|
||||||
|
|
||||||
virtual void set_transform__bullet(const btTransform &p_global_transform);
|
virtual void set_transform__bullet(const btTransform &p_global_transform) override;
|
||||||
virtual const btTransform &get_transform__bullet() const;
|
virtual const btTransform &get_transform__bullet() const override;
|
||||||
|
|
||||||
virtual void do_reload_shapes();
|
virtual void do_reload_shapes() override;
|
||||||
|
|
||||||
virtual void on_enter_area(AreaBullet *p_area);
|
virtual void on_enter_area(AreaBullet *p_area) override;
|
||||||
virtual void on_exit_area(AreaBullet *p_area);
|
virtual void on_exit_area(AreaBullet *p_area) override;
|
||||||
void reload_space_override_modificator();
|
void reload_space_override_modificator();
|
||||||
|
|
||||||
/// Kinematic
|
/// Kinematic
|
||||||
void reload_kinematic_shapes();
|
void reload_kinematic_shapes();
|
||||||
|
|
||||||
virtual void notify_transform_changed();
|
virtual void notify_transform_changed() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _internal_set_mass(real_t p_mass);
|
void _internal_set_mass(real_t p_mass);
|
||||||
|
|
|
@ -346,14 +346,14 @@ void SoftBodyBullet::set_trimesh_body_shape(Vector<int> p_indices, Vector<Vector
|
||||||
indices_table.push_back(Vector<int>());
|
indices_table.push_back(Vector<int>());
|
||||||
}
|
}
|
||||||
|
|
||||||
indices_table.write[vertex_id].push_back(vs_vertex_index);
|
indices_table[vertex_id].push_back(vs_vertex_index);
|
||||||
vs_indices_to_physics_table.push_back(vertex_id);
|
vs_indices_to_physics_table.push_back(vertex_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const int indices_map_size(indices_table.size());
|
const int indices_map_size(indices_table.size());
|
||||||
|
|
||||||
Vector<btScalar> bt_vertices;
|
LocalVector<btScalar> bt_vertices;
|
||||||
|
|
||||||
{ // Parse vertices to bullet
|
{ // Parse vertices to bullet
|
||||||
|
|
||||||
|
@ -361,13 +361,13 @@ void SoftBodyBullet::set_trimesh_body_shape(Vector<int> p_indices, Vector<Vector
|
||||||
const Vector3 *p_vertices_read = p_vertices.ptr();
|
const Vector3 *p_vertices_read = p_vertices.ptr();
|
||||||
|
|
||||||
for (int i = 0; i < indices_map_size; ++i) {
|
for (int i = 0; i < indices_map_size; ++i) {
|
||||||
bt_vertices.write[3 * i + 0] = p_vertices_read[indices_table[i][0]].x;
|
bt_vertices[3 * i + 0] = p_vertices_read[indices_table[i][0]].x;
|
||||||
bt_vertices.write[3 * i + 1] = p_vertices_read[indices_table[i][0]].y;
|
bt_vertices[3 * i + 1] = p_vertices_read[indices_table[i][0]].y;
|
||||||
bt_vertices.write[3 * i + 2] = p_vertices_read[indices_table[i][0]].z;
|
bt_vertices[3 * i + 2] = p_vertices_read[indices_table[i][0]].z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<int> bt_triangles;
|
LocalVector<int> bt_triangles;
|
||||||
const int triangles_size(p_indices.size() / 3);
|
const int triangles_size(p_indices.size() / 3);
|
||||||
|
|
||||||
{ // Parse indices
|
{ // Parse indices
|
||||||
|
@ -377,9 +377,9 @@ void SoftBodyBullet::set_trimesh_body_shape(Vector<int> p_indices, Vector<Vector
|
||||||
const int *p_indices_read = p_indices.ptr();
|
const int *p_indices_read = p_indices.ptr();
|
||||||
|
|
||||||
for (int i = 0; i < triangles_size; ++i) {
|
for (int i = 0; i < triangles_size; ++i) {
|
||||||
bt_triangles.write[3 * i + 0] = vs_indices_to_physics_table[p_indices_read[3 * i + 2]];
|
bt_triangles[3 * i + 0] = vs_indices_to_physics_table[p_indices_read[3 * i + 2]];
|
||||||
bt_triangles.write[3 * i + 1] = vs_indices_to_physics_table[p_indices_read[3 * i + 1]];
|
bt_triangles[3 * i + 1] = vs_indices_to_physics_table[p_indices_read[3 * i + 1]];
|
||||||
bt_triangles.write[3 * i + 2] = vs_indices_to_physics_table[p_indices_read[3 * i + 0]];
|
bt_triangles[3 * i + 2] = vs_indices_to_physics_table[p_indices_read[3 * i + 0]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#define SOFT_BODY_BULLET_H
|
#define SOFT_BODY_BULLET_H
|
||||||
|
|
||||||
#include "collision_object_bullet.h"
|
#include "collision_object_bullet.h"
|
||||||
#include "scene/resources/material.h" // TODO remove this please
|
|
||||||
|
|
||||||
#ifdef None
|
#ifdef None
|
||||||
/// This is required to remove the macro None defined by x11 compiler because this word "None" is used internally by Bullet
|
/// This is required to remove the macro None defined by x11 compiler because this word "None" is used internally by Bullet
|
||||||
|
@ -58,7 +57,7 @@
|
||||||
class SoftBodyBullet : public CollisionObjectBullet {
|
class SoftBodyBullet : public CollisionObjectBullet {
|
||||||
private:
|
private:
|
||||||
btSoftBody *bt_soft_body = nullptr;
|
btSoftBody *bt_soft_body = nullptr;
|
||||||
Vector<Vector<int>> indices_table;
|
LocalVector<Vector<int>> indices_table;
|
||||||
btSoftBody::Material *mat0; // This is just a copy of pointer managed by btSoftBody
|
btSoftBody::Material *mat0; // This is just a copy of pointer managed by btSoftBody
|
||||||
bool isScratched = false;
|
bool isScratched = false;
|
||||||
|
|
||||||
|
@ -73,7 +72,7 @@ private:
|
||||||
real_t pose_matching_coefficient = 0.; // [0,1]
|
real_t pose_matching_coefficient = 0.; // [0,1]
|
||||||
real_t damping_coefficient = 0.01; // [0,1]
|
real_t damping_coefficient = 0.01; // [0,1]
|
||||||
real_t drag_coefficient = 0.; // [0,1]
|
real_t drag_coefficient = 0.; // [0,1]
|
||||||
Vector<int> pinned_nodes;
|
LocalVector<int> pinned_nodes;
|
||||||
|
|
||||||
// Other property to add
|
// Other property to add
|
||||||
//btScalar kVC; // Volume conversation coefficient [0,+inf]
|
//btScalar kVC; // Volume conversation coefficient [0,+inf]
|
||||||
|
@ -87,15 +86,14 @@ public:
|
||||||
SoftBodyBullet();
|
SoftBodyBullet();
|
||||||
~SoftBodyBullet();
|
~SoftBodyBullet();
|
||||||
|
|
||||||
virtual void do_reload_body();
|
virtual void do_reload_body() override;
|
||||||
virtual void set_space(SpaceBullet *p_space);
|
virtual void set_space(SpaceBullet *p_space) override;
|
||||||
|
|
||||||
virtual void dispatch_callbacks() {}
|
virtual void do_reload_collision_filters() override {}
|
||||||
virtual void on_collision_filters_change() {}
|
virtual void on_collision_checker_start() override {}
|
||||||
virtual void on_collision_checker_start() {}
|
virtual void on_collision_checker_end() override {}
|
||||||
virtual void on_collision_checker_end() {}
|
virtual void on_enter_area(AreaBullet *p_area) override;
|
||||||
virtual void on_enter_area(AreaBullet *p_area);
|
virtual void on_exit_area(AreaBullet *p_area) override;
|
||||||
virtual void on_exit_area(AreaBullet *p_area);
|
|
||||||
|
|
||||||
_FORCE_INLINE_ btSoftBody *get_bt_soft_body() const { return bt_soft_body; }
|
_FORCE_INLINE_ btSoftBody *get_bt_soft_body() const { return bt_soft_body; }
|
||||||
|
|
||||||
|
|
|
@ -348,16 +348,46 @@ SpaceBullet::~SpaceBullet() {
|
||||||
destroy_world();
|
destroy_world();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpaceBullet::flush_queries() {
|
void SpaceBullet::add_to_pre_flush_queue(CollisionObjectBullet *p_co) {
|
||||||
const int size = collision_objects.size();
|
if (p_co->is_in_flush_queue == false) {
|
||||||
CollisionObjectBullet **objects = collision_objects.ptrw();
|
p_co->is_in_flush_queue = true;
|
||||||
for (int i = 0; i < size; i += 1) {
|
queue_pre_flush.push_back(p_co);
|
||||||
objects[i]->prepare_object_for_dispatch();
|
|
||||||
objects[i]->dispatch_callbacks();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SpaceBullet::add_to_flush_queue(CollisionObjectBullet *p_co) {
|
||||||
|
if (p_co->is_in_flush_queue == false) {
|
||||||
|
p_co->is_in_flush_queue = true;
|
||||||
|
queue_flush.push_back(p_co);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpaceBullet::remove_from_any_queue(CollisionObjectBullet *p_co) {
|
||||||
|
if (p_co->is_in_flush_queue) {
|
||||||
|
p_co->is_in_flush_queue = false;
|
||||||
|
queue_pre_flush.erase(p_co);
|
||||||
|
queue_flush.erase(p_co);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpaceBullet::flush_queries() {
|
||||||
|
for (uint32_t i = 0; i < queue_pre_flush.size(); i += 1) {
|
||||||
|
queue_pre_flush[i]->dispatch_callbacks();
|
||||||
|
queue_pre_flush[i]->is_in_flush_queue = false;
|
||||||
|
}
|
||||||
|
for (uint32_t i = 0; i < queue_flush.size(); i += 1) {
|
||||||
|
queue_flush[i]->dispatch_callbacks();
|
||||||
|
queue_flush[i]->is_in_flush_queue = false;
|
||||||
|
}
|
||||||
|
queue_pre_flush.clear();
|
||||||
|
queue_flush.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void SpaceBullet::step(real_t p_delta_time) {
|
void SpaceBullet::step(real_t p_delta_time) {
|
||||||
|
for (uint32_t i = 0; i < collision_objects.size(); i += 1) {
|
||||||
|
collision_objects[i]->pre_process();
|
||||||
|
}
|
||||||
|
|
||||||
delta_time = p_delta_time;
|
delta_time = p_delta_time;
|
||||||
dynamicsWorld->stepSimulation(p_delta_time, 0, 0);
|
dynamicsWorld->stepSimulation(p_delta_time, 0, 0);
|
||||||
}
|
}
|
||||||
|
@ -488,6 +518,7 @@ void SpaceBullet::register_collision_object(CollisionObjectBullet *p_object) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpaceBullet::unregister_collision_object(CollisionObjectBullet *p_object) {
|
void SpaceBullet::unregister_collision_object(CollisionObjectBullet *p_object) {
|
||||||
|
remove_from_any_queue(p_object);
|
||||||
collision_objects.erase(p_object);
|
collision_objects.erase(p_object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -702,7 +733,7 @@ void SpaceBullet::check_ghost_overlaps() {
|
||||||
|
|
||||||
/// 1. Reset all states
|
/// 1. Reset all states
|
||||||
for (i = area->overlappingObjects.size() - 1; 0 <= i; --i) {
|
for (i = area->overlappingObjects.size() - 1; 0 <= i; --i) {
|
||||||
AreaBullet::OverlappingObjectData &otherObj = area->overlappingObjects.write[i];
|
AreaBullet::OverlappingObjectData &otherObj = area->overlappingObjects[i];
|
||||||
// This check prevent the overwrite of ENTER state
|
// This check prevent the overwrite of ENTER state
|
||||||
// if this function is called more times before dispatchCallbacks
|
// if this function is called more times before dispatchCallbacks
|
||||||
if (otherObj.state != AreaBullet::OVERLAP_STATE_ENTER) {
|
if (otherObj.state != AreaBullet::OVERLAP_STATE_ENTER) {
|
||||||
|
|
|
@ -31,8 +31,8 @@
|
||||||
#ifndef SPACE_BULLET_H
|
#ifndef SPACE_BULLET_H
|
||||||
#define SPACE_BULLET_H
|
#define SPACE_BULLET_H
|
||||||
|
|
||||||
|
#include "core/local_vector.h"
|
||||||
#include "core/variant.h"
|
#include "core/variant.h"
|
||||||
#include "core/vector.h"
|
|
||||||
#include "godot_result_callbacks.h"
|
#include "godot_result_callbacks.h"
|
||||||
#include "rid_bullet.h"
|
#include "rid_bullet.h"
|
||||||
#include "servers/physics_server_3d.h"
|
#include "servers/physics_server_3d.h"
|
||||||
|
@ -110,17 +110,23 @@ class SpaceBullet : public RIDBullet {
|
||||||
real_t linear_damp = 0.0;
|
real_t linear_damp = 0.0;
|
||||||
real_t angular_damp = 0.0;
|
real_t angular_damp = 0.0;
|
||||||
|
|
||||||
Vector<CollisionObjectBullet *> collision_objects;
|
LocalVector<CollisionObjectBullet *> queue_pre_flush;
|
||||||
Vector<AreaBullet *> areas;
|
LocalVector<CollisionObjectBullet *> queue_flush;
|
||||||
|
LocalVector<CollisionObjectBullet *> collision_objects;
|
||||||
|
LocalVector<AreaBullet *> areas;
|
||||||
|
|
||||||
Vector<Vector3> contactDebug;
|
LocalVector<Vector3> contactDebug;
|
||||||
int contactDebugCount = 0;
|
uint32_t contactDebugCount = 0;
|
||||||
real_t delta_time = 0.;
|
real_t delta_time = 0.;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SpaceBullet();
|
SpaceBullet();
|
||||||
virtual ~SpaceBullet();
|
virtual ~SpaceBullet();
|
||||||
|
|
||||||
|
void add_to_flush_queue(CollisionObjectBullet *p_co);
|
||||||
|
void add_to_pre_flush_queue(CollisionObjectBullet *p_co);
|
||||||
|
void remove_from_any_queue(CollisionObjectBullet *p_co);
|
||||||
|
|
||||||
void flush_queries();
|
void flush_queries();
|
||||||
real_t get_delta_time() { return delta_time; }
|
real_t get_delta_time() { return delta_time; }
|
||||||
void step(real_t p_delta_time);
|
void step(real_t p_delta_time);
|
||||||
|
@ -177,7 +183,7 @@ public:
|
||||||
}
|
}
|
||||||
_FORCE_INLINE_ void add_debug_contact(const Vector3 &p_contact) {
|
_FORCE_INLINE_ void add_debug_contact(const Vector3 &p_contact) {
|
||||||
if (contactDebugCount < contactDebug.size()) {
|
if (contactDebugCount < contactDebug.size()) {
|
||||||
contactDebug.write[contactDebugCount++] = p_contact;
|
contactDebug[contactDebugCount++] = p_contact;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_FORCE_INLINE_ Vector<Vector3> get_debug_contacts() { return contactDebug; }
|
_FORCE_INLINE_ Vector<Vector3> get_debug_contacts() { return contactDebug; }
|
||||||
|
|
Loading…
Reference in New Issue