diff options
Diffstat (limited to 'scene/3d/physics_body.cpp')
-rw-r--r-- | scene/3d/physics_body.cpp | 228 |
1 files changed, 133 insertions, 95 deletions
diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp index 9590394211..6a8226c0e1 100644 --- a/scene/3d/physics_body.cpp +++ b/scene/3d/physics_body.cpp @@ -912,35 +912,24 @@ RigidBody::~RigidBody() { ////////////////////////////////////////////////////// ////////////////////////// -Dictionary KinematicBody::_move(const Vector3 &p_motion) { +Ref<KinematicCollision> KinematicBody::_move(const Vector3 &p_motion) { Collision col; - if (move(p_motion, col)) { - Dictionary d; - d["position"] = col.collision; - d["normal"] = col.normal; - d["local_shape"] = col.local_shape; - d["travel"] = col.travel; - d["remainder"] = col.remainder; - d["collider_id"] = col.collider; - if (col.collider) { - d["collider"] = ObjectDB::get_instance(col.collider); - } else { - d["collider"] = Variant(); + if (move_and_collide(p_motion, col)) { + if (motion_cache.is_null()) { + motion_cache.instance(); + motion_cache->owner = this; } - d["collider_velocity"] = col.collider_vel; - d["collider_shape_index"] = col.collider_shape; - d["collider_metadata"] = col.collider_metadata; - - return d; + motion_cache->collision = col; - } else { - return Dictionary(); + return motion_cache; } + + return Ref<KinematicCollision>(); } -bool KinematicBody::move(const Vector3 &p_motion, Collision &r_collision) { +bool KinematicBody::move_and_collide(const Vector3 &p_motion, Collision &r_collision) { Transform gt = get_global_transform(); PhysicsServer::MotionResult result; @@ -964,7 +953,7 @@ bool KinematicBody::move(const Vector3 &p_motion, Collision &r_collision) { return colliding; } -Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction, float p_slope_stop_min_velocity, int p_max_bounces, float p_floor_max_angle) { +Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction, float p_slope_stop_min_velocity, int p_max_slides, float p_floor_max_angle) { Vector3 motion = (floor_velocity + p_linear_velocity) * get_fixed_process_delta_time(); Vector3 lv = p_linear_velocity; @@ -975,11 +964,11 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve colliders.clear(); floor_velocity = Vector3(); - while (p_max_bounces) { + while (p_max_slides) { Collision collision; - bool collided = move(motion, collision); + bool collided = move_and_collide(motion, collision); if (collided) { @@ -1017,7 +1006,7 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve break; } - p_max_bounces--; + p_max_slides--; if (motion == Vector3()) break; } @@ -1059,79 +1048,36 @@ float KinematicBody::get_safe_margin() const { return margin; } - -int KinematicBody::get_collision_count() const { +int KinematicBody::get_slide_count() const { return colliders.size(); } -Vector3 KinematicBody::get_collision_position(int p_collision) const { - - ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector3()); - return colliders[p_collision].collision; -} -Vector3 KinematicBody::get_collision_normal(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector3()); - return colliders[p_collision].normal; +KinematicBody::Collision KinematicBody::get_slide_collision(int p_bounce) const { + ERR_FAIL_INDEX_V(p_bounce, colliders.size(), Collision()); + return colliders[p_bounce]; } -Vector3 KinematicBody::get_collision_travel(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector3()); - return colliders[p_collision].travel; -} -Vector3 KinematicBody::get_collision_remainder(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector3()); - return colliders[p_collision].remainder; -} -Object *KinematicBody::get_collision_local_shape(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), NULL); - uint32_t owner = shape_find_owner(colliders[p_collision].local_shape); - return shape_owner_get_owner(owner); -} -Object *KinematicBody::get_collision_collider(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), NULL); +Ref<KinematicCollision> KinematicBody::_get_slide_collision(int p_bounce) { - if (colliders[p_collision].collider) { - return ObjectDB::get_instance(colliders[p_collision].collider); + ERR_FAIL_INDEX_V(p_bounce, colliders.size(), Ref<KinematicCollision>()); + if (p_bounce > slide_colliders.size()) { + slide_colliders.resize(p_bounce + 1); } - return NULL; -} -ObjectID KinematicBody::get_collision_collider_id(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), 0); - - return colliders[p_collision].collider; -} -Object *KinematicBody::get_collision_collider_shape(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), NULL); - Object *collider = get_collision_collider(p_collision); - if (collider) { - CollisionObject *obj2d = Object::cast_to<CollisionObject>(collider); - if (obj2d) { - uint32_t owner = shape_find_owner(colliders[p_collision].collider_shape); - return obj2d->shape_owner_get_owner(owner); - } + if (slide_colliders[p_bounce].is_null()) { + slide_colliders[p_bounce].instance(); + slide_colliders[p_bounce]->owner = this; } - return NULL; -} -int KinematicBody::get_collision_collider_shape_index(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), -1); - return colliders[p_collision].collider_shape; -} -Vector3 KinematicBody::get_collision_collider_velocity(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector3()); - return colliders[p_collision].collider_vel; -} -Variant KinematicBody::get_collision_collider_metadata(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), Variant()); - return colliders[p_collision].collider_metadata; + slide_colliders[p_bounce]->collision = colliders[p_bounce]; + return slide_colliders[p_bounce]; } void KinematicBody::_bind_methods() { - ClassDB::bind_method(D_METHOD("move", "rel_vec"), &KinematicBody::_move); - ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "slope_stop_min_velocity", "max_bounces", "floor_max_angle"), &KinematicBody::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(0.05), DEFVAL(4), DEFVAL(Math::deg2rad((float)45))); + ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec"), &KinematicBody::_move); + ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "slope_stop_min_velocity", "max_slides", "floor_max_angle"), &KinematicBody::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(0.05), DEFVAL(4), DEFVAL(Math::deg2rad((float)45))); ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec"), &KinematicBody::test_move); @@ -1143,18 +1089,8 @@ void KinematicBody::_bind_methods() { ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &KinematicBody::set_safe_margin); ClassDB::bind_method(D_METHOD("get_safe_margin"), &KinematicBody::get_safe_margin); - ClassDB::bind_method(D_METHOD("get_collision_count"), &KinematicBody::get_collision_count); - ClassDB::bind_method(D_METHOD("get_collision_position", "collision"), &KinematicBody::get_collision_position); - ClassDB::bind_method(D_METHOD("get_collision_normal", "collision"), &KinematicBody::get_collision_normal); - ClassDB::bind_method(D_METHOD("get_collision_travel", "collision"), &KinematicBody::get_collision_travel); - ClassDB::bind_method(D_METHOD("get_collision_remainder", "collision"), &KinematicBody::get_collision_remainder); - ClassDB::bind_method(D_METHOD("get_collision_local_shape", "collision"), &KinematicBody::get_collision_local_shape); - ClassDB::bind_method(D_METHOD("get_collision_collider", "collision"), &KinematicBody::get_collision_collider); - ClassDB::bind_method(D_METHOD("get_collision_collider_id", "collision"), &KinematicBody::get_collision_collider_id); - ClassDB::bind_method(D_METHOD("get_collision_collider_shape", "collision"), &KinematicBody::get_collision_collider_shape); - ClassDB::bind_method(D_METHOD("get_collision_collider_shape_index", "collision"), &KinematicBody::get_collision_collider_shape_index); - ClassDB::bind_method(D_METHOD("get_collision_collider_velocity", "collision"), &KinematicBody::get_collision_collider_velocity); - ClassDB::bind_method(D_METHOD("get_collision_collider_metadata", "collision"), &KinematicBody::get_collision_collider_metadata); + ClassDB::bind_method(D_METHOD("get_slide_count"), &KinematicBody::get_slide_count); + ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &KinematicBody::_get_slide_collision); ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin"); } @@ -1169,4 +1105,106 @@ KinematicBody::KinematicBody() on_wall = false; } KinematicBody::~KinematicBody() { + + if (motion_cache.is_valid()) { + motion_cache->owner = NULL; + } + + for (int i = 0; i < slide_colliders.size(); i++) { + if (slide_colliders[i].is_valid()) { + slide_colliders[i]->owner = NULL; + } + } +} +/////////////////////////////////////// + +Vector3 KinematicCollision::get_position() const { + + return collision.collision; +} +Vector3 KinematicCollision::get_normal() const { + return collision.normal; +} +Vector3 KinematicCollision::get_travel() const { + return collision.travel; +} +Vector3 KinematicCollision::get_remainder() const { + return collision.remainder; +} +Object *KinematicCollision::get_local_shape() const { + ERR_FAIL_COND_V(!owner, NULL); + uint32_t ownerid = owner->shape_find_owner(collision.local_shape); + return owner->shape_owner_get_owner(ownerid); +} + +Object *KinematicCollision::get_collider() const { + + if (collision.collider) { + return ObjectDB::get_instance(collision.collider); + } + + return NULL; +} +ObjectID KinematicCollision::get_collider_id() const { + + return collision.collider; +} +Object *KinematicCollision::get_collider_shape() const { + + Object *collider = get_collider(); + if (collider) { + CollisionObject *obj2d = Object::cast_to<CollisionObject>(collider); + if (obj2d) { + uint32_t ownerid = obj2d->shape_find_owner(collision.collider_shape); + return obj2d->shape_owner_get_owner(ownerid); + } + } + + return NULL; +} +int KinematicCollision::get_collider_shape_index() const { + + return collision.collider_shape; +} +Vector3 KinematicCollision::get_collider_velocity() const { + + return collision.collider_vel; +} +Variant KinematicCollision::get_collider_metadata() const { + + return Variant(); +} + +void KinematicCollision::_bind_methods() { + + ClassDB::bind_method(D_METHOD("get_position"), &KinematicCollision::get_position); + ClassDB::bind_method(D_METHOD("get_normal"), &KinematicCollision::get_normal); + ClassDB::bind_method(D_METHOD("get_travel"), &KinematicCollision::get_travel); + ClassDB::bind_method(D_METHOD("get_remainder"), &KinematicCollision::get_remainder); + ClassDB::bind_method(D_METHOD("get_local_shape"), &KinematicCollision::get_local_shape); + ClassDB::bind_method(D_METHOD("get_collider"), &KinematicCollision::get_collider); + ClassDB::bind_method(D_METHOD("get_collider_id"), &KinematicCollision::get_collider_id); + ClassDB::bind_method(D_METHOD("get_collider_shape"), &KinematicCollision::get_collider_shape); + ClassDB::bind_method(D_METHOD("get_collider_shape_index"), &KinematicCollision::get_collider_shape_index); + ClassDB::bind_method(D_METHOD("get_collider_velocity"), &KinematicCollision::get_collider_velocity); + ClassDB::bind_method(D_METHOD("get_collider_metadata"), &KinematicCollision::get_collider_metadata); + + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "position"), "", "get_position"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "normal"), "", "get_normal"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "travel"), "", "get_travel"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "remainder"), "", "get_remainder"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "local_shape"), "", "get_local_shape"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "collider"), "", "get_collider"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_id"), "", "get_collider_id"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "collider_shape"), "", "get_collider_shape"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_shape_index"), "", "get_collider_shape_index"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "collider_velocity"), "", "get_collider_velocity"); + ADD_PROPERTY(PropertyInfo(Variant::NIL, "collider_metadata", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), "", "get_collider_metadata"); +} + +KinematicCollision::KinematicCollision() { + collision.collider = 0; + collision.collider_shape = 0; + collision.local_shape = 0; + owner = NULL; } |