diff options
Diffstat (limited to 'scene/3d')
-rw-r--r-- | scene/3d/arvr_nodes.cpp | 15 | ||||
-rw-r--r-- | scene/3d/arvr_nodes.h | 2 | ||||
-rw-r--r-- | scene/3d/audio_stream_player_3d.cpp | 8 | ||||
-rw-r--r-- | scene/3d/bone_attachment.cpp | 6 | ||||
-rw-r--r-- | scene/3d/collision_shape.cpp | 3 | ||||
-rw-r--r-- | scene/3d/gi_probe.cpp | 34 | ||||
-rw-r--r-- | scene/3d/interpolated_camera.cpp | 4 | ||||
-rw-r--r-- | scene/3d/light.cpp | 20 | ||||
-rw-r--r-- | scene/3d/light.h | 10 | ||||
-rw-r--r-- | scene/3d/path.cpp | 4 | ||||
-rw-r--r-- | scene/3d/physics_body.cpp | 228 | ||||
-rw-r--r-- | scene/3d/physics_body.h | 52 |
12 files changed, 249 insertions, 137 deletions
diff --git a/scene/3d/arvr_nodes.cpp b/scene/3d/arvr_nodes.cpp index caf313190b..966dd88a2c 100644 --- a/scene/3d/arvr_nodes.cpp +++ b/scene/3d/arvr_nodes.cpp @@ -31,7 +31,6 @@ #include "arvr_nodes.h" #include "core/os/input.h" #include "servers/arvr/arvr_interface.h" -#include "servers/arvr/arvr_positional_tracker.h" #include "servers/arvr_server.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -142,6 +141,7 @@ void ARVRController::_bind_methods() { ClassDB::bind_method(D_METHOD("get_joystick_axis", "axis"), &ARVRController::get_joystick_axis); ClassDB::bind_method(D_METHOD("get_is_active"), &ARVRController::get_is_active); + ClassDB::bind_method(D_METHOD("get_hand"), &ARVRController::get_hand); ADD_SIGNAL(MethodInfo("button_pressed", PropertyInfo(Variant::INT, "button"))); ADD_SIGNAL(MethodInfo("button_release", PropertyInfo(Variant::INT, "button"))); @@ -204,6 +204,19 @@ bool ARVRController::get_is_active() const { return is_active; }; +ARVRPositionalTracker::TrackerHand ARVRController::get_hand() const { + // get our ARVRServer + ARVRServer *arvr_server = ARVRServer::get_singleton(); + ERR_FAIL_NULL_V(arvr_server, ARVRPositionalTracker::TRACKER_HAND_UNKNOWN); + + ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, controller_id); + if (tracker == NULL) { + return ARVRPositionalTracker::TRACKER_HAND_UNKNOWN; + }; + + return tracker->get_hand(); +}; + String ARVRController::get_configuration_warning() const { if (!is_visible() || !is_inside_tree()) return String(); diff --git a/scene/3d/arvr_nodes.h b/scene/3d/arvr_nodes.h index 4c14be71b5..5269ec0248 100644 --- a/scene/3d/arvr_nodes.h +++ b/scene/3d/arvr_nodes.h @@ -33,6 +33,7 @@ #include "scene/3d/camera.h" #include "scene/3d/spatial.h" +#include "servers/arvr/arvr_positional_tracker.h" /** @author Bastiaan Olij <mux213@gmail.com> @@ -84,6 +85,7 @@ public: float get_joystick_axis(int p_axis) const; bool get_is_active() const; + ARVRPositionalTracker::TrackerHand get_hand() const; String get_configuration_warning() const; diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index a69bec2fc8..2073ebf94e 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -530,13 +530,15 @@ void AudioStreamPlayer3D::_notification(int p_what) { setseek = setplay; active = true; setplay = -1; - _change_notify("playing"); //update property in editor + //do not update, this makes it easier to animate (will shut off otherise) + ///_change_notify("playing"); //update property in editor } //stop playing if no longer active if (!active) { set_fixed_process_internal(false); - _change_notify("playing"); //update property in editor + //do not update, this makes it easier to animate (will shut off otherise) + //_change_notify("playing"); //update property in editor emit_signal("finished"); } } @@ -877,7 +879,7 @@ void AudioStreamPlayer3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_db", PROPERTY_HINT_RANGE, "-80,80"), "set_unit_db", "get_unit_db"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_size", PROPERTY_HINT_RANGE, "0.1,100,0.1"), "set_unit_size", "get_unit_size"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_db", PROPERTY_HINT_RANGE, "-24,6"), "set_max_db", "get_max_db"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "_is_active"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "play", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "_is_active"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autoplay"), "set_autoplay", "is_autoplay_enabled"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_distance", PROPERTY_HINT_RANGE, "0,65536,1"), "set_max_distance", "get_max_distance"); ADD_PROPERTY(PropertyInfo(Variant::INT, "out_of_range_mode", PROPERTY_HINT_ENUM, "Mix,Pause"), "set_out_of_range_mode", "get_out_of_range_mode"); diff --git a/scene/3d/bone_attachment.cpp b/scene/3d/bone_attachment.cpp index e1a5329fb0..2580b645e2 100644 --- a/scene/3d/bone_attachment.cpp +++ b/scene/3d/bone_attachment.cpp @@ -71,7 +71,8 @@ void BoneAttachment::_get_property_list(List<PropertyInfo> *p_list) const { void BoneAttachment::_check_bind() { - if (Skeleton *sk = Object::cast_to<Skeleton>(get_parent())) { + Skeleton *sk = Object::cast_to<Skeleton>(get_parent()); + if (sk) { int idx = sk->find_bone(bone_name); if (idx != -1) { @@ -86,7 +87,8 @@ void BoneAttachment::_check_unbind() { if (bound) { - if (Skeleton *sk = Object::cast_to<Skeleton>(get_parent())) { + Skeleton *sk = Object::cast_to<Skeleton>(get_parent()); + if (sk) { int idx = sk->find_bone(bone_name); if (idx != -1) { diff --git a/scene/3d/collision_shape.cpp b/scene/3d/collision_shape.cpp index 5f1151f8e9..f49d89122d 100644 --- a/scene/3d/collision_shape.cpp +++ b/scene/3d/collision_shape.cpp @@ -50,7 +50,8 @@ void CollisionShape::make_convex_from_brothers() { for (int i = 0; i < p->get_child_count(); i++) { Node *n = p->get_child(i); - if (MeshInstance *mi = Object::cast_to<MeshInstance>(n)) { + MeshInstance *mi = Object::cast_to<MeshInstance>(n); + if (mi) { Ref<Mesh> m = mi->get_mesh(); if (m.is_valid()) { diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp index bb54a43028..c2b5283b9c 100644 --- a/scene/3d/gi_probe.cpp +++ b/scene/3d/gi_probe.cpp @@ -1092,7 +1092,7 @@ void GIProbe::_plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, Baker *p_b void GIProbe::_find_meshes(Node *p_at_node, Baker *p_baker) { MeshInstance *mi = Object::cast_to<MeshInstance>(p_at_node); - if (mi && mi->get_flag(GeometryInstance::FLAG_USE_BAKED_LIGHT)) { + if (mi && mi->get_flag(GeometryInstance::FLAG_USE_BAKED_LIGHT) && mi->is_visible_in_tree()) { Ref<Mesh> mesh = mi->get_mesh(); if (mesh.is_valid()) { @@ -1113,25 +1113,29 @@ void GIProbe::_find_meshes(Node *p_at_node, Baker *p_baker) { } } - if (Spatial *s = Object::cast_to<Spatial>(p_at_node)) { + Spatial *s = Object::cast_to<Spatial>(p_at_node); + if (s) { - Array meshes = p_at_node->call("get_meshes"); - for (int i = 0; i < meshes.size(); i += 2) { + if (s->is_visible_in_tree()) { - Transform mxf = meshes[i]; - Ref<Mesh> mesh = meshes[i + 1]; - if (!mesh.is_valid()) - continue; + Array meshes = p_at_node->call("get_meshes"); + for (int i = 0; i < meshes.size(); i += 2) { - Rect3 aabb = mesh->get_aabb(); + Transform mxf = meshes[i]; + Ref<Mesh> mesh = meshes[i + 1]; + if (!mesh.is_valid()) + continue; - Transform xf = get_global_transform().affine_inverse() * (s->get_global_transform() * mxf); + Rect3 aabb = mesh->get_aabb(); - if (Rect3(-extents, extents * 2).intersects(xf.xform(aabb))) { - Baker::PlotMesh pm; - pm.local_xform = xf; - pm.mesh = mesh; - p_baker->mesh_list.push_back(pm); + Transform xf = get_global_transform().affine_inverse() * (s->get_global_transform() * mxf); + + if (Rect3(-extents, extents * 2).intersects(xf.xform(aabb))) { + Baker::PlotMesh pm; + pm.local_xform = xf; + pm.mesh = mesh; + p_baker->mesh_list.push_back(pm); + } } } } diff --git a/scene/3d/interpolated_camera.cpp b/scene/3d/interpolated_camera.cpp index 157ae42571..0f281b694d 100644 --- a/scene/3d/interpolated_camera.cpp +++ b/scene/3d/interpolated_camera.cpp @@ -55,8 +55,8 @@ void InterpolatedCamera::_notification(int p_what) { Transform local_transform = get_global_transform(); local_transform = local_transform.interpolate_with(target_xform, delta); set_global_transform(local_transform); - - if (Camera *cam = Object::cast_to<Camera>(node)) { + Camera *cam = Object::cast_to<Camera>(node); + if (cam) { if (cam->get_projection() == get_projection()) { diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp index 09b253b309..096f787873 100644 --- a/scene/3d/light.cpp +++ b/scene/3d/light.cpp @@ -230,7 +230,6 @@ void Light::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::COLOR, "shadow_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_shadow_color", "get_shadow_color"); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "shadow_bias", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_param", "get_param", PARAM_SHADOW_BIAS); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "shadow_contact", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_param", "get_param", PARAM_CONTACT_SHADOW_SIZE); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "shadow_max_distance", PROPERTY_HINT_RANGE, "0,65536,0.1"), "set_param", "get_param", PARAM_SHADOW_MAX_DISTANCE); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_reverse_cull_face"), "set_shadow_reverse_cull_face", "get_shadow_reverse_cull_face"); ADD_GROUP("Editor", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_only"), "set_editor_only", "is_editor_only"); @@ -308,6 +307,16 @@ DirectionalLight::ShadowMode DirectionalLight::get_shadow_mode() const { return shadow_mode; } +void DirectionalLight::set_shadow_depth_range(ShadowDepthRange p_range) { + shadow_depth_range = p_range; + VS::get_singleton()->light_directional_set_shadow_depth_range_mode(light, VS::LightDirectionalShadowDepthRangeMode(p_range)); +} + +DirectionalLight::ShadowDepthRange DirectionalLight::get_shadow_depth_range() const { + + return shadow_depth_range; +} + void DirectionalLight::set_blend_splits(bool p_enable) { blend_splits = p_enable; @@ -324,6 +333,9 @@ void DirectionalLight::_bind_methods() { ClassDB::bind_method(D_METHOD("set_shadow_mode", "mode"), &DirectionalLight::set_shadow_mode); ClassDB::bind_method(D_METHOD("get_shadow_mode"), &DirectionalLight::get_shadow_mode); + ClassDB::bind_method(D_METHOD("set_shadow_depth_range", "mode"), &DirectionalLight::set_shadow_depth_range); + ClassDB::bind_method(D_METHOD("get_shadow_depth_range"), &DirectionalLight::get_shadow_depth_range); + ClassDB::bind_method(D_METHOD("set_blend_splits", "enabled"), &DirectionalLight::set_blend_splits); ClassDB::bind_method(D_METHOD("is_blend_splits_enabled"), &DirectionalLight::is_blend_splits_enabled); @@ -335,10 +347,15 @@ void DirectionalLight::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "directional_shadow_blend_splits"), "set_blend_splits", "is_blend_splits_enabled"); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_normal_bias", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_param", "get_param", PARAM_SHADOW_NORMAL_BIAS); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_bias_split_scale", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SHADOW_BIAS_SPLIT_SCALE); + ADD_PROPERTY(PropertyInfo(Variant::INT, "directional_shadow_depth_range", PROPERTY_HINT_ENUM, "Stable,Optimized"), "set_shadow_depth_range", "get_shadow_depth_range"); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_max_distance", PROPERTY_HINT_RANGE, "0,65536,0.1"), "set_param", "get_param", PARAM_SHADOW_MAX_DISTANCE); BIND_ENUM_CONSTANT(SHADOW_ORTHOGONAL); BIND_ENUM_CONSTANT(SHADOW_PARALLEL_2_SPLITS); BIND_ENUM_CONSTANT(SHADOW_PARALLEL_4_SPLITS); + + BIND_ENUM_CONSTANT(SHADOW_DEPTH_RANGE_STABLE); + BIND_ENUM_CONSTANT(SHADOW_DEPTH_RANGE_OPTIMIZED); } DirectionalLight::DirectionalLight() @@ -349,6 +366,7 @@ DirectionalLight::DirectionalLight() set_param(PARAM_SHADOW_MAX_DISTANCE, 200); set_param(PARAM_SHADOW_BIAS_SPLIT_SCALE, 0.25); set_shadow_mode(SHADOW_PARALLEL_4_SPLITS); + set_shadow_depth_range(SHADOW_DEPTH_RANGE_STABLE); blend_splits = false; } diff --git a/scene/3d/light.h b/scene/3d/light.h index 5d589d33e5..6aa0220265 100644 --- a/scene/3d/light.h +++ b/scene/3d/light.h @@ -133,9 +133,15 @@ public: SHADOW_PARALLEL_4_SPLITS }; + enum ShadowDepthRange { + SHADOW_DEPTH_RANGE_STABLE = VS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE, + SHADOW_DEPTH_RANGE_OPTIMIZED = VS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_OPTIMIZED, + }; + private: bool blend_splits; ShadowMode shadow_mode; + ShadowDepthRange shadow_depth_range; protected: static void _bind_methods(); @@ -144,6 +150,9 @@ public: void set_shadow_mode(ShadowMode p_mode); ShadowMode get_shadow_mode() const; + void set_shadow_depth_range(ShadowDepthRange p_mode); + ShadowDepthRange get_shadow_depth_range() const; + void set_blend_splits(bool p_enable); bool is_blend_splits_enabled() const; @@ -151,6 +160,7 @@ public: }; VARIANT_ENUM_CAST(DirectionalLight::ShadowMode) +VARIANT_ENUM_CAST(DirectionalLight::ShadowDepthRange) class OmniLight : public Light { diff --git a/scene/3d/path.cpp b/scene/3d/path.cpp index ed4d88417c..60245fe6ce 100644 --- a/scene/3d/path.cpp +++ b/scene/3d/path.cpp @@ -155,8 +155,8 @@ void PathFollow::_notification(int p_what) { Node *parent = get_parent(); if (parent) { - - if ((path = Object::cast_to<Path>(parent))) { + path = Object::cast_to<Path>(parent); + if (path) { _update_transform(); } } 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; } diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h index 23d752ad76..f88b3860dc 100644 --- a/scene/3d/physics_body.h +++ b/scene/3d/physics_body.h @@ -261,6 +261,8 @@ public: VARIANT_ENUM_CAST(RigidBody::Mode); VARIANT_ENUM_CAST(RigidBody::AxisLock); +class KinematicCollision; + class KinematicBody : public PhysicsBody { GDCLASS(KinematicBody, PhysicsBody); @@ -286,42 +288,62 @@ private: bool on_ceiling; bool on_wall; Vector<Collision> colliders; + Vector<Ref<KinematicCollision> > slide_colliders; + Ref<KinematicCollision> motion_cache; _FORCE_INLINE_ bool _ignores_mode(PhysicsServer::BodyMode) const; - Dictionary _move(const Vector3 &p_motion); + Ref<KinematicCollision> _move(const Vector3 &p_motion); + Ref<KinematicCollision> _get_slide_collision(int p_bounce); protected: static void _bind_methods(); public: - bool move(const Vector3 &p_motion, Collision &r_collision); + bool move_and_collide(const Vector3 &p_motion, Collision &r_collision); bool test_move(const Transform &p_from, const Vector3 &p_motion); void set_safe_margin(float p_margin); float get_safe_margin() const; - Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction = Vector3(0, 0, 0), float p_slope_stop_min_velocity = 0.05, int p_max_bounces = 4, float p_floor_max_angle = Math::deg2rad((float)45)); + Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction = Vector3(0, 0, 0), float p_slope_stop_min_velocity = 0.05, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45)); bool is_on_floor() const; bool is_on_wall() const; bool is_on_ceiling() const; Vector3 get_floor_velocity() const; - int get_collision_count() const; - Vector3 get_collision_position(int p_collision) const; - Vector3 get_collision_normal(int p_collision) const; - Vector3 get_collision_travel(int p_collision) const; - Vector3 get_collision_remainder(int p_collision) const; - Object *get_collision_local_shape(int p_collision) const; - Object *get_collision_collider(int p_collision) const; - ObjectID get_collision_collider_id(int p_collision) const; - Object *get_collision_collider_shape(int p_collision) const; - int get_collision_collider_shape_index(int p_collision) const; - Vector3 get_collision_collider_velocity(int p_collision) const; - Variant get_collision_collider_metadata(int p_collision) const; + int get_slide_count() const; + Collision get_slide_collision(int p_bounce) const; KinematicBody(); ~KinematicBody(); }; +class KinematicCollision : public Reference { + + GDCLASS(KinematicCollision, Reference); + + KinematicBody *owner; + friend class KinematicBody; + KinematicBody::Collision collision; + +protected: + static void _bind_methods(); + +public: + Vector3 get_position() const; + Vector3 get_normal() const; + Vector3 get_travel() const; + Vector3 get_remainder() const; + Object *get_local_shape() const; + Object *get_collider() const; + ObjectID get_collider_id() const; + Object *get_collider_shape() const; + int get_collider_shape_index() const; + Vector3 get_collider_velocity() const; + Variant get_collider_metadata() const; + + KinematicCollision(); +}; + #endif // PHYSICS_BODY__H |