summaryrefslogtreecommitdiff
path: root/scene/3d
diff options
context:
space:
mode:
Diffstat (limited to 'scene/3d')
-rw-r--r--scene/3d/arvr_nodes.cpp15
-rw-r--r--scene/3d/arvr_nodes.h2
-rw-r--r--scene/3d/audio_stream_player_3d.cpp8
-rw-r--r--scene/3d/bone_attachment.cpp6
-rw-r--r--scene/3d/collision_shape.cpp3
-rw-r--r--scene/3d/gi_probe.cpp34
-rw-r--r--scene/3d/interpolated_camera.cpp4
-rw-r--r--scene/3d/light.cpp20
-rw-r--r--scene/3d/light.h10
-rw-r--r--scene/3d/path.cpp4
-rw-r--r--scene/3d/physics_body.cpp228
-rw-r--r--scene/3d/physics_body.h52
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