summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/audio_stream_player_2d.cpp58
-rw-r--r--scene/2d/physics_body_2d.cpp224
-rw-r--r--scene/2d/physics_body_2d.h52
-rw-r--r--scene/3d/audio_stream_player_3d.cpp156
-rw-r--r--scene/3d/audio_stream_player_3d.h4
-rw-r--r--scene/3d/navigation_mesh.cpp230
-rw-r--r--scene/3d/navigation_mesh.h81
-rw-r--r--scene/3d/physics_body.cpp2
-rw-r--r--scene/audio/audio_player.cpp18
-rw-r--r--scene/gui/dialogs.cpp2
-rw-r--r--scene/gui/slider.cpp10
-rw-r--r--scene/gui/tree.cpp17
-rw-r--r--scene/gui/tree.h4
-rw-r--r--scene/register_scene_types.cpp1
14 files changed, 607 insertions, 252 deletions
diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp
index d2a8e3315a..b6abe90035 100644
--- a/scene/2d/audio_stream_player_2d.cpp
+++ b/scene/2d/audio_stream_player_2d.cpp
@@ -57,52 +57,32 @@ void AudioStreamPlayer2D::_mix_audio() {
AudioFrame vol_inc = (current.vol - prev_outputs[i].vol) / float(buffer_size);
AudioFrame vol = current.vol;
- switch (AudioServer::get_singleton()->get_speaker_mode()) {
+ int cc = AudioServer::get_singleton()->get_channel_count();
- case AudioServer::SPEAKER_MODE_STEREO: {
- AudioFrame *target = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 0);
+ if (cc == 1) {
+ AudioFrame *target = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 0);
- for (int j = 0; j < buffer_size; j++) {
+ for (int j = 0; j < buffer_size; j++) {
- target[j] += buffer[j] * vol;
- vol += vol_inc;
- }
-
- } break;
- case AudioServer::SPEAKER_SURROUND_51: {
-
- AudioFrame *targets[2] = {
- AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 1),
- AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 2),
- };
-
- for (int j = 0; j < buffer_size; j++) {
-
- AudioFrame frame = buffer[j] * vol;
- targets[0][j] += frame;
- targets[1][j] += frame;
- vol += vol_inc;
- }
+ target[j] += buffer[j] * vol;
+ vol += vol_inc;
+ }
- } break;
- case AudioServer::SPEAKER_SURROUND_71: {
+ } else {
+ AudioFrame *targets[4];
- AudioFrame *targets[3] = {
- AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 1),
- AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 2),
- AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 3)
- };
+ for (int k = 0; k < cc; k++) {
+ targets[k] = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, k);
+ }
- for (int j = 0; j < buffer_size; j++) {
+ for (int j = 0; j < buffer_size; j++) {
- AudioFrame frame = buffer[j] * vol;
- targets[0][j] += frame;
- targets[1][j] += frame;
- targets[2][j] += frame;
- vol += vol_inc;
+ AudioFrame frame = buffer[j] * vol;
+ for (int k = 0; k < cc; k++) {
+ targets[k][j] += frame;
}
-
- } break;
+ vol += vol_inc;
+ }
}
prev_outputs[i] = current;
@@ -439,7 +419,7 @@ void AudioStreamPlayer2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_stream", "get_stream");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "volume_db", PROPERTY_HINT_RANGE, "-80,24"), "set_volume_db", "get_volume_db");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "play", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "_is_active");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "is_playing");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autoplay"), "set_autoplay", "is_autoplay_enabled");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_distance", PROPERTY_HINT_RANGE, "1,65536,1"), "set_max_distance", "get_max_distance");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "attenuation", PROPERTY_HINT_EXP_EASING), "set_attenuation", "get_attenuation");
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index b1eb2ba267..c6cd3677cd 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -955,35 +955,25 @@ RigidBody2D::~RigidBody2D() {
//////////////////////////
-Dictionary KinematicBody2D::_move(const Vector2 &p_motion) {
+Ref<KinematicCollision2D> KinematicBody2D::_move(const Vector2 &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;
- d["collider_velocity"] = col.collider_vel;
- if (col.collider) {
- d["collider"] = ObjectDB::get_instance(col.collider);
- } else {
- d["collider"] = Variant();
- }
- d["collider_shape_index"] = col.collider_shape;
- d["collider_metadata"] = col.collider_metadata;
+ if (move_and_collide(p_motion, col)) {
+ if (motion_cache.is_null()) {
+ motion_cache.instance();
+ motion_cache->owner = this;
+ }
- return d;
+ motion_cache->collision = col;
- } else {
- return Dictionary();
+ return motion_cache;
}
+
+ return Ref<KinematicCollision2D>();
}
-bool KinematicBody2D::move(const Vector2 &p_motion, Collision &r_collision) {
+bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, Collision &r_collision) {
Transform2D gt = get_global_transform();
Physics2DServer::MotionResult result;
@@ -1007,7 +997,7 @@ bool KinematicBody2D::move(const Vector2 &p_motion, Collision &r_collision) {
return colliding;
}
-Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction, float p_slope_stop_min_velocity, int p_max_bounces, float p_floor_max_angle) {
+Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction, float p_slope_stop_min_velocity, int p_max_slides, float p_floor_max_angle) {
Vector2 motion = (floor_velocity + p_linear_velocity) * get_fixed_process_delta_time();
Vector2 lv = p_linear_velocity;
@@ -1018,11 +1008,11 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
colliders.clear();
floor_velocity = Vector2();
- while (p_max_bounces) {
+ while (p_max_slides) {
Collision collision;
- bool collided = move(motion, collision);
+ bool collided = move_and_collide(motion, collision);
if (collided) {
@@ -1060,7 +1050,7 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
break;
}
- p_max_bounces--;
+ p_max_slides--;
if (motion == Vector2())
break;
}
@@ -1103,75 +1093,35 @@ float KinematicBody2D::get_safe_margin() const {
return margin;
}
-int KinematicBody2D::get_collision_count() const {
+int KinematicBody2D::get_slide_count() const {
return colliders.size();
}
-Vector2 KinematicBody2D::get_collision_position(int p_collision) const {
-
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector2());
- return colliders[p_collision].collision;
-}
-Vector2 KinematicBody2D::get_collision_normal(int p_collision) const {
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector2());
- return colliders[p_collision].normal;
+KinematicBody2D::Collision KinematicBody2D::get_slide_collision(int p_bounce) const {
+ ERR_FAIL_INDEX_V(p_bounce, colliders.size(), Collision());
+ return colliders[p_bounce];
}
-Vector2 KinematicBody2D::get_collision_travel(int p_collision) const {
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector2());
- return colliders[p_collision].travel;
-}
-Vector2 KinematicBody2D::get_collision_remainder(int p_collision) const {
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector2());
- return colliders[p_collision].remainder;
-}
-Object *KinematicBody2D::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 *KinematicBody2D::get_collision_collider(int p_collision) const {
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), NULL);
+Ref<KinematicCollision2D> KinematicBody2D::_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<KinematicCollision2D>());
+ if (p_bounce >= slide_colliders.size()) {
+ slide_colliders.resize(p_bounce + 1);
}
- return NULL;
-}
-ObjectID KinematicBody2D::get_collision_collider_id(int p_collision) const {
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), 0);
-
- return colliders[p_collision].collider;
-}
-Object *KinematicBody2D::get_collision_collider_shape(int p_collision) const {
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), NULL);
- Object *collider = get_collision_collider(p_collision);
- CollisionObject2D *obj2d = Object::cast_to<CollisionObject2D>(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 KinematicBody2D::get_collision_collider_shape_index(int p_collision) const {
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), -1);
- return colliders[p_collision].collider_shape;
-}
-Vector2 KinematicBody2D::get_collision_collider_velocity(int p_collision) const {
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector2());
- return colliders[p_collision].collider_vel;
-}
-Variant KinematicBody2D::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 KinematicBody2D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("move", "rel_vec"), &KinematicBody2D::_move);
+ ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec"), &KinematicBody2D::_move);
ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "slope_stop_min_velocity", "max_bounces", "floor_max_angle"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(5), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)));
ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec"), &KinematicBody2D::test_move);
@@ -1184,18 +1134,8 @@ void KinematicBody2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &KinematicBody2D::set_safe_margin);
ClassDB::bind_method(D_METHOD("get_safe_margin"), &KinematicBody2D::get_safe_margin);
- ClassDB::bind_method(D_METHOD("get_collision_count"), &KinematicBody2D::get_collision_count);
- ClassDB::bind_method(D_METHOD("get_collision_position", "collision"), &KinematicBody2D::get_collision_position);
- ClassDB::bind_method(D_METHOD("get_collision_normal", "collision"), &KinematicBody2D::get_collision_normal);
- ClassDB::bind_method(D_METHOD("get_collision_travel", "collision"), &KinematicBody2D::get_collision_travel);
- ClassDB::bind_method(D_METHOD("get_collision_remainder", "collision"), &KinematicBody2D::get_collision_remainder);
- ClassDB::bind_method(D_METHOD("get_collision_local_shape", "collision"), &KinematicBody2D::get_collision_local_shape);
- ClassDB::bind_method(D_METHOD("get_collision_collider", "collision"), &KinematicBody2D::get_collision_collider);
- ClassDB::bind_method(D_METHOD("get_collision_collider_id", "collision"), &KinematicBody2D::get_collision_collider_id);
- ClassDB::bind_method(D_METHOD("get_collision_collider_shape", "collision"), &KinematicBody2D::get_collision_collider_shape);
- ClassDB::bind_method(D_METHOD("get_collision_collider_shape_index", "collision"), &KinematicBody2D::get_collision_collider_shape_index);
- ClassDB::bind_method(D_METHOD("get_collision_collider_velocity", "collision"), &KinematicBody2D::get_collision_collider_velocity);
- ClassDB::bind_method(D_METHOD("get_collision_collider_metadata", "collision"), &KinematicBody2D::get_collision_collider_metadata);
+ ClassDB::bind_method(D_METHOD("get_slide_count"), &KinematicBody2D::get_slide_count);
+ ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &KinematicBody2D::_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");
}
@@ -1210,4 +1150,106 @@ KinematicBody2D::KinematicBody2D()
on_wall = false;
}
KinematicBody2D::~KinematicBody2D() {
+ 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;
+ }
+ }
+}
+
+////////////////////////
+
+Vector2 KinematicCollision2D::get_position() const {
+
+ return collision.collision;
+}
+Vector2 KinematicCollision2D::get_normal() const {
+ return collision.normal;
+}
+Vector2 KinematicCollision2D::get_travel() const {
+ return collision.travel;
+}
+Vector2 KinematicCollision2D::get_remainder() const {
+ return collision.remainder;
+}
+Object *KinematicCollision2D::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 *KinematicCollision2D::get_collider() const {
+
+ if (collision.collider) {
+ return ObjectDB::get_instance(collision.collider);
+ }
+
+ return NULL;
+}
+ObjectID KinematicCollision2D::get_collider_id() const {
+
+ return collision.collider;
+}
+Object *KinematicCollision2D::get_collider_shape() const {
+
+ Object *collider = get_collider();
+ if (collider) {
+ CollisionObject2D *obj2d = Object::cast_to<CollisionObject2D>(collider);
+ if (obj2d) {
+ uint32_t ownerid = obj2d->shape_find_owner(collision.collider_shape);
+ return obj2d->shape_owner_get_owner(ownerid);
+ }
+ }
+
+ return NULL;
+}
+int KinematicCollision2D::get_collider_shape_index() const {
+
+ return collision.collider_shape;
+}
+Vector2 KinematicCollision2D::get_collider_velocity() const {
+
+ return collision.collider_vel;
+}
+Variant KinematicCollision2D::get_collider_metadata() const {
+
+ return Variant();
+}
+
+void KinematicCollision2D::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("get_position"), &KinematicCollision2D::get_position);
+ ClassDB::bind_method(D_METHOD("get_normal"), &KinematicCollision2D::get_normal);
+ ClassDB::bind_method(D_METHOD("get_travel"), &KinematicCollision2D::get_travel);
+ ClassDB::bind_method(D_METHOD("get_remainder"), &KinematicCollision2D::get_remainder);
+ ClassDB::bind_method(D_METHOD("get_local_shape"), &KinematicCollision2D::get_local_shape);
+ ClassDB::bind_method(D_METHOD("get_collider"), &KinematicCollision2D::get_collider);
+ ClassDB::bind_method(D_METHOD("get_collider_id"), &KinematicCollision2D::get_collider_id);
+ ClassDB::bind_method(D_METHOD("get_collider_shape"), &KinematicCollision2D::get_collider_shape);
+ ClassDB::bind_method(D_METHOD("get_collider_shape_index"), &KinematicCollision2D::get_collider_shape_index);
+ ClassDB::bind_method(D_METHOD("get_collider_velocity"), &KinematicCollision2D::get_collider_velocity);
+ ClassDB::bind_method(D_METHOD("get_collider_metadata"), &KinematicCollision2D::get_collider_metadata);
+
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position"), "", "get_position");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "normal"), "", "get_normal");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "travel"), "", "get_travel");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "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::VECTOR2, "collider_velocity"), "", "get_collider_velocity");
+ ADD_PROPERTY(PropertyInfo(Variant::NIL, "collider_metadata", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), "", "get_collider_metadata");
+}
+
+KinematicCollision2D::KinematicCollision2D() {
+ collision.collider = 0;
+ collision.collider_shape = 0;
+ collision.local_shape = 0;
+ owner = NULL;
}
diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h
index 1a4b0c0f5c..b82771a8f4 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -34,6 +34,8 @@
#include "servers/physics_2d_server.h"
#include "vset.h"
+class KinematicCollision2D;
+
class PhysicsBody2D : public CollisionObject2D {
GDCLASS(PhysicsBody2D, CollisionObject2D);
@@ -288,42 +290,62 @@ private:
bool on_ceiling;
bool on_wall;
Vector<Collision> colliders;
+ Vector<Ref<KinematicCollision2D> > slide_colliders;
+ Ref<KinematicCollision2D> motion_cache;
_FORCE_INLINE_ bool _ignores_mode(Physics2DServer::BodyMode) const;
- Dictionary _move(const Vector2 &p_motion);
+ Ref<KinematicCollision2D> _move(const Vector2 &p_motion);
+ Ref<KinematicCollision2D> _get_slide_collision(int p_bounce);
protected:
static void _bind_methods();
public:
- bool move(const Vector2 &p_motion, Collision &r_collision);
+ bool move_and_collide(const Vector2 &p_motion, Collision &r_collision);
bool test_move(const Transform2D &p_from, const Vector2 &p_motion);
void set_safe_margin(float p_margin);
float get_safe_margin() const;
- Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction = Vector2(0, 0), float p_slope_stop_min_velocity = 5, int p_max_bounces = 4, float p_floor_max_angle = Math::deg2rad((float)45));
+ Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction = Vector2(0, 0), float p_slope_stop_min_velocity = 5, 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;
Vector2 get_floor_velocity() const;
- int get_collision_count() const;
- Vector2 get_collision_position(int p_collision) const;
- Vector2 get_collision_normal(int p_collision) const;
- Vector2 get_collision_travel(int p_collision) const;
- Vector2 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;
- Vector2 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;
KinematicBody2D();
~KinematicBody2D();
};
+class KinematicCollision2D : public Reference {
+
+ GDCLASS(KinematicCollision2D, Reference);
+
+ KinematicBody2D *owner;
+ friend class KinematicBody2D;
+ KinematicBody2D::Collision collision;
+
+protected:
+ static void _bind_methods();
+
+public:
+ Vector2 get_position() const;
+ Vector2 get_normal() const;
+ Vector2 get_travel() const;
+ Vector2 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;
+ Vector2 get_collider_velocity() const;
+ Variant get_collider_metadata() const;
+
+ KinematicCollision2D();
+};
+
#endif // PHYSICS_BODY_2D_H
diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp
index 2073ebf94e..b8c6a86f55 100644
--- a/scene/3d/audio_stream_player_3d.cpp
+++ b/scene/3d/audio_stream_player_3d.cpp
@@ -72,34 +72,13 @@ void AudioStreamPlayer3D::_mix_audio() {
//mix!
- int buffers = 0;
- int first = 0;
-
- switch (AudioServer::get_singleton()->get_speaker_mode()) {
-
- case AudioServer::SPEAKER_MODE_STEREO: {
- buffers = 1;
- first = 0;
-
- } break;
- case AudioServer::SPEAKER_SURROUND_51: {
- buffers = 2;
- first = 1;
-
- } break;
- case AudioServer::SPEAKER_SURROUND_71: {
-
- buffers = 3;
- first = 1;
-
- } break;
- }
+ int buffers = AudioServer::get_singleton()->get_channel_count();
for (int k = 0; k < buffers; k++) {
AudioFrame vol_inc = (current.vol[k] - prev_outputs[i].vol[k]) / float(buffer_size);
AudioFrame vol = current.vol[k];
- AudioFrame *target = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, first + k);
+ AudioFrame *target = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, k);
current.filter.set_mode(AudioFilterSW::HIGHSHELF);
current.filter.set_sampling_rate(AudioServer::get_singleton()->get_mix_rate());
@@ -146,7 +125,7 @@ void AudioStreamPlayer3D::_mix_audio() {
if (current.reverb_bus_index >= 0) {
- AudioFrame *rtarget = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.reverb_bus_index, first + k);
+ AudioFrame *rtarget = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.reverb_bus_index, k);
if (current.reverb_bus_index == prev_outputs[i].reverb_bus_index) {
AudioFrame rvol_inc = (current.reverb_vol[k] - prev_outputs[i].reverb_vol[k]) / float(buffer_size);
@@ -341,49 +320,57 @@ void AudioStreamPlayer3D::_notification(int p_what) {
flat_pos.y = 0;
flat_pos.normalize();
- switch (AudioServer::get_singleton()->get_speaker_mode()) {
+ unsigned int cc = AudioServer::get_singleton()->get_channel_count();
+ if (cc == 1) {
+ // Stereo pair
+ float c = flat_pos.x * 0.5 + 0.5;
- case AudioServer::SPEAKER_MODE_STEREO: {
-
- float c = flat_pos.x * 0.5 + 0.5;
- output.vol[0].l = 1.0 - c;
- output.vol[0].r = c;
-
- output.vol[0] *= multiplier;
+ output.vol[0].l = 1.0 - c;
+ output.vol[0].r = c;
+ } else {
+ Vector3 camtopos = global_pos - camera->get_global_transform().origin;
+ float c = camtopos.normalized().dot(get_global_transform().basis.get_axis(2).normalized()); //it's z negative
+ float angle = Math::rad2deg(Math::acos(c));
+ float av = angle * (flat_pos.x < 0 ? -1 : 1) / 180.0;
- } break;
- case AudioServer::SPEAKER_SURROUND_51: {
+ if (cc >= 1) {
+ // Stereo pair
+ float fl = Math::abs(1.0 - Math::abs(-0.8 - av));
+ float fr = Math::abs(1.0 - Math::abs(0.8 - av));
- float xl = Vector3(-1, 0, -1).normalized().dot(flat_pos) * 0.5 + 0.5;
- float xr = Vector3(1, 0, -1).normalized().dot(flat_pos) * 0.5 + 0.5;
+ output.vol[0].l = fl;
+ output.vol[0].r = fr;
+ }
- output.vol[0].l = xl;
- output.vol[1].r = 1.0 - xl;
- output.vol[0].r = xr;
- output.vol[1].l = 1.0 - xr;
+ if (cc >= 2) {
+ // Center pair
+ float center = 1.0 - Math::sin(Math::acos(c));
- output.vol[0] *= multiplier;
- output.vol[1] *= multiplier;
- } break;
- case AudioServer::SPEAKER_SURROUND_71: {
+ output.vol[1].l = center;
+ output.vol[1].r = center;
+ }
- float xl = Vector3(-1, 0, -1).normalized().dot(flat_pos) * 0.5 + 0.5;
- float xr = Vector3(1, 0, -1).normalized().dot(flat_pos) * 0.5 + 0.5;
+ if (cc >= 3) {
+ // Side pair
+ float sl = Math::abs(1.0 - Math::abs(-0.4 - av));
+ float sr = Math::abs(1.0 - Math::abs(0.4 - av));
- output.vol[0].l = xl;
- output.vol[1].r = 1.0 - xl;
- output.vol[0].r = xr;
- output.vol[1].l = 1.0 - xr;
+ output.vol[2].l = sl;
+ output.vol[2].r = sr;
+ }
- float c = flat_pos.x * 0.5 + 0.5;
- output.vol[2].l = 1.0 - c;
- output.vol[2].r = c;
+ if (cc >= 4) {
+ // Rear pair
+ float rl = Math::abs(1.0 - Math::abs(-0.2 - av));
+ float rr = Math::abs(1.0 - Math::abs(0.2 - av));
- output.vol[0] *= multiplier;
- output.vol[1] *= multiplier;
- output.vol[2] *= multiplier;
+ output.vol[3].l = rl;
+ output.vol[3].r = rr;
+ }
+ }
- } break;
+ for (int k = 0; k < cc; k++) {
+ output.vol[k] *= multiplier;
}
bool filled_reverb = false;
@@ -422,41 +409,30 @@ void AudioStreamPlayer3D::_notification(int p_what) {
rev_pos.y = 0;
rev_pos.normalize();
- switch (AudioServer::get_singleton()->get_speaker_mode()) {
-
- case AudioServer::SPEAKER_MODE_STEREO: {
-
- float c = rev_pos.x * 0.5 + 0.5;
- output.reverb_vol[0].l = 1.0 - c;
- output.reverb_vol[0].r = c;
-
- } break;
- case AudioServer::SPEAKER_SURROUND_51: {
-
- float xl = Vector3(-1, 0, -1).normalized().dot(rev_pos) * 0.5 + 0.5;
- float xr = Vector3(1, 0, -1).normalized().dot(rev_pos) * 0.5 + 0.5;
-
- output.reverb_vol[0].l = xl;
- output.reverb_vol[1].r = 1.0 - xl;
- output.reverb_vol[0].r = xr;
- output.reverb_vol[1].l = 1.0 - xr;
-
- } break;
- case AudioServer::SPEAKER_SURROUND_71: {
-
- float xl = Vector3(-1, 0, -1).normalized().dot(rev_pos) * 0.5 + 0.5;
- float xr = Vector3(1, 0, -1).normalized().dot(rev_pos) * 0.5 + 0.5;
+ if (cc >= 1) {
+ // Stereo pair
+ float c = rev_pos.x * 0.5 + 0.5;
+ output.reverb_vol[0].l = 1.0 - c;
+ output.reverb_vol[0].r = c;
+ }
- output.reverb_vol[0].l = xl;
- output.reverb_vol[1].r = 1.0 - xl;
- output.reverb_vol[0].r = xr;
- output.reverb_vol[1].l = 1.0 - xr;
+ if (cc >= 3) {
+ // Center pair + Side pair
+ float xl = Vector3(-1, 0, -1).normalized().dot(rev_pos) * 0.5 + 0.5;
+ float xr = Vector3(1, 0, -1).normalized().dot(rev_pos) * 0.5 + 0.5;
- float c = rev_pos.x * 0.5 + 0.5;
- output.reverb_vol[2].l = 1.0 - c;
- output.reverb_vol[2].r = c;
+ output.reverb_vol[1].l = xl;
+ output.reverb_vol[1].r = xr;
+ output.reverb_vol[2].l = 1.0 - xr;
+ output.reverb_vol[2].r = 1.0 - xl;
+ }
- } break;
+ if (cc >= 4) {
+ // Rear pair
+ // FIXME: Not sure what math should be done here
+ float c = rev_pos.x * 0.5 + 0.5;
+ output.reverb_vol[3].l = 1.0 - c;
+ output.reverb_vol[3].r = c;
}
for (int i = 0; i < vol_index_max; i++) {
@@ -879,7 +855,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, "play", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "_is_active");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "is_playing");
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/audio_stream_player_3d.h b/scene/3d/audio_stream_player_3d.h
index 8603cab5a4..b729b55f7e 100644
--- a/scene/3d/audio_stream_player_3d.h
+++ b/scene/3d/audio_stream_player_3d.h
@@ -40,12 +40,12 @@ private:
AudioFilterSW filter;
AudioFilterSW::Processor filter_process[6];
- AudioFrame vol[3];
+ AudioFrame vol[4];
float filter_gain;
float pitch_scale;
int bus_index;
int reverb_bus_index;
- AudioFrame reverb_vol[3];
+ AudioFrame reverb_vol[4];
Viewport *viewport; //pointer only used for reference to previous mix
Output() {
diff --git a/scene/3d/navigation_mesh.cpp b/scene/3d/navigation_mesh.cpp
index 7a55f956e0..40750cdfe8 100644
--- a/scene/3d/navigation_mesh.cpp
+++ b/scene/3d/navigation_mesh.cpp
@@ -63,6 +63,143 @@ void NavigationMesh::create_from_mesh(const Ref<Mesh> &p_mesh) {
}
}
+void NavigationMesh::set_sample_partition_type(int p_value) {
+ ERR_FAIL_COND(p_value >= SAMPLE_PARTITION_MAX);
+ partition_type = static_cast<SamplePartitionType>(p_value);
+}
+
+int NavigationMesh::get_sample_partition_type() const {
+ return static_cast<int>(partition_type);
+}
+
+void NavigationMesh::set_cell_size(float p_value) {
+ cell_size = p_value;
+}
+
+float NavigationMesh::get_cell_size() const {
+ return cell_size;
+}
+
+void NavigationMesh::set_cell_height(float p_value) {
+ cell_height = p_value;
+}
+
+float NavigationMesh::get_cell_height() const {
+ return cell_height;
+}
+
+void NavigationMesh::set_agent_height(float p_value) {
+ agent_height = p_value;
+}
+
+float NavigationMesh::get_agent_height() const {
+ return agent_height;
+}
+
+void NavigationMesh::set_agent_radius(float p_value) {
+ agent_radius = p_value;
+}
+
+float NavigationMesh::get_agent_radius() {
+ return agent_radius;
+}
+
+void NavigationMesh::set_agent_max_climb(float p_value) {
+ agent_max_climb = p_value;
+}
+
+float NavigationMesh::get_agent_max_climb() const {
+ return agent_max_climb;
+}
+
+void NavigationMesh::set_agent_max_slope(float p_value) {
+ agent_max_slope = p_value;
+}
+
+float NavigationMesh::get_agent_max_slope() const {
+ return agent_max_slope;
+}
+
+void NavigationMesh::set_region_min_size(float p_value) {
+ region_min_size = p_value;
+}
+
+float NavigationMesh::get_region_min_size() const {
+ return region_min_size;
+}
+
+void NavigationMesh::set_region_merge_size(float p_value) {
+ region_merge_size = p_value;
+}
+
+float NavigationMesh::get_region_merge_size() const {
+ return region_merge_size;
+}
+
+void NavigationMesh::set_edge_max_length(float p_value) {
+ edge_max_length = p_value;
+}
+
+float NavigationMesh::get_edge_max_length() const {
+ return edge_max_length;
+}
+
+void NavigationMesh::set_edge_max_error(float p_value) {
+ edge_max_error = p_value;
+}
+
+float NavigationMesh::get_edge_max_error() const {
+ return edge_max_error;
+}
+
+void NavigationMesh::set_verts_per_poly(float p_value) {
+ verts_per_poly = p_value;
+}
+
+float NavigationMesh::get_verts_per_poly() const {
+ return verts_per_poly;
+}
+
+void NavigationMesh::set_detail_sample_distance(float p_value) {
+ detail_sample_distance = p_value;
+}
+
+float NavigationMesh::get_detail_sample_distance() const {
+ return detail_sample_distance;
+}
+
+void NavigationMesh::set_detail_sample_max_error(float p_value) {
+ detail_sample_max_error = p_value;
+}
+
+float NavigationMesh::get_detail_sample_max_error() const {
+ return detail_sample_max_error;
+}
+
+void NavigationMesh::set_filter_low_hanging_obstacles(bool p_value) {
+ filter_low_hanging_obstacles = p_value;
+}
+
+bool NavigationMesh::get_filter_low_hanging_obstacles() const {
+ return filter_low_hanging_obstacles;
+}
+
+void NavigationMesh::set_filter_ledge_spans(bool p_value) {
+ filter_ledge_spans = p_value;
+}
+
+bool NavigationMesh::get_filter_ledge_spans() const {
+ return filter_ledge_spans;
+}
+
+void NavigationMesh::set_filter_walkable_low_height_spans(bool p_value) {
+ filter_walkable_low_height_spans = p_value;
+}
+
+bool NavigationMesh::get_filter_walkable_low_height_spans() const {
+ return filter_walkable_low_height_spans;
+}
+
void NavigationMesh::set_vertices(const PoolVector<Vector3> &p_vertices) {
vertices = p_vertices;
@@ -199,6 +336,56 @@ Ref<Mesh> NavigationMesh::get_debug_mesh() {
}
void NavigationMesh::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_sample_partition_type", "sample_partition_type"), &NavigationMesh::set_sample_partition_type);
+ ClassDB::bind_method(D_METHOD("get_sample_partition_type"), &NavigationMesh::get_sample_partition_type);
+
+ ClassDB::bind_method(D_METHOD("set_cell_size", "cell_size"), &NavigationMesh::set_cell_size);
+ ClassDB::bind_method(D_METHOD("get_cell_size"), &NavigationMesh::get_cell_size);
+
+ ClassDB::bind_method(D_METHOD("set_cell_height", "cell_height"), &NavigationMesh::set_cell_height);
+ ClassDB::bind_method(D_METHOD("get_cell_height"), &NavigationMesh::get_cell_height);
+
+ ClassDB::bind_method(D_METHOD("set_agent_height", "agent_height"), &NavigationMesh::set_agent_height);
+ ClassDB::bind_method(D_METHOD("get_agent_height"), &NavigationMesh::get_agent_height);
+
+ ClassDB::bind_method(D_METHOD("set_agent_radius", "agent_radius"), &NavigationMesh::set_agent_radius);
+ ClassDB::bind_method(D_METHOD("get_agent_radius"), &NavigationMesh::get_agent_radius);
+
+ ClassDB::bind_method(D_METHOD("set_agent_max_climb", "agent_max_climb"), &NavigationMesh::set_agent_max_climb);
+ ClassDB::bind_method(D_METHOD("get_agent_max_climb"), &NavigationMesh::get_agent_max_climb);
+
+ ClassDB::bind_method(D_METHOD("set_agent_max_slope", "agent_max_slope"), &NavigationMesh::set_agent_max_slope);
+ ClassDB::bind_method(D_METHOD("get_agent_max_slope"), &NavigationMesh::get_agent_max_slope);
+
+ ClassDB::bind_method(D_METHOD("set_region_min_size", "region_min_size"), &NavigationMesh::set_region_min_size);
+ ClassDB::bind_method(D_METHOD("get_region_min_size"), &NavigationMesh::get_region_min_size);
+
+ ClassDB::bind_method(D_METHOD("set_region_merge_size", "region_merge_size"), &NavigationMesh::set_region_merge_size);
+ ClassDB::bind_method(D_METHOD("get_region_merge_size"), &NavigationMesh::get_region_merge_size);
+
+ ClassDB::bind_method(D_METHOD("set_edge_max_length", "edge_max_length"), &NavigationMesh::set_edge_max_length);
+ ClassDB::bind_method(D_METHOD("get_edge_max_length"), &NavigationMesh::get_edge_max_length);
+
+ ClassDB::bind_method(D_METHOD("set_edge_max_error", "edge_max_error"), &NavigationMesh::set_edge_max_error);
+ ClassDB::bind_method(D_METHOD("get_edge_max_error"), &NavigationMesh::get_edge_max_error);
+
+ ClassDB::bind_method(D_METHOD("set_verts_per_poly", "verts_per_poly"), &NavigationMesh::set_verts_per_poly);
+ ClassDB::bind_method(D_METHOD("get_verts_per_poly"), &NavigationMesh::get_verts_per_poly);
+
+ ClassDB::bind_method(D_METHOD("set_detail_sample_distance", "detail_sample_dist"), &NavigationMesh::set_detail_sample_distance);
+ ClassDB::bind_method(D_METHOD("get_detail_sample_distance"), &NavigationMesh::get_detail_sample_distance);
+
+ ClassDB::bind_method(D_METHOD("set_detail_sample_max_error", "detail_sample_max_error"), &NavigationMesh::set_detail_sample_max_error);
+ ClassDB::bind_method(D_METHOD("get_detail_sample_max_error"), &NavigationMesh::get_detail_sample_max_error);
+
+ ClassDB::bind_method(D_METHOD("set_filter_low_hanging_obstacles", "filter_low_hanging_obstacles"), &NavigationMesh::set_filter_low_hanging_obstacles);
+ ClassDB::bind_method(D_METHOD("get_filter_low_hanging_obstacles"), &NavigationMesh::get_filter_low_hanging_obstacles);
+
+ ClassDB::bind_method(D_METHOD("set_filter_ledge_spans", "filter_ledge_spans"), &NavigationMesh::set_filter_ledge_spans);
+ ClassDB::bind_method(D_METHOD("get_filter_ledge_spans"), &NavigationMesh::get_filter_ledge_spans);
+
+ ClassDB::bind_method(D_METHOD("set_filter_walkable_low_height_spans", "filter_walkable_low_height_spans"), &NavigationMesh::set_filter_walkable_low_height_spans);
+ ClassDB::bind_method(D_METHOD("get_filter_walkable_low_height_spans"), &NavigationMesh::get_filter_walkable_low_height_spans);
ClassDB::bind_method(D_METHOD("set_vertices", "vertices"), &NavigationMesh::set_vertices);
ClassDB::bind_method(D_METHOD("get_vertices"), &NavigationMesh::get_vertices);
@@ -213,11 +400,54 @@ void NavigationMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("_set_polygons", "polygons"), &NavigationMesh::_set_polygons);
ClassDB::bind_method(D_METHOD("_get_polygons"), &NavigationMesh::_get_polygons);
+ BIND_CONSTANT(SAMPLE_PARTITION_WATERSHED);
+ BIND_CONSTANT(SAMPLE_PARTITION_MONOTONE);
+ BIND_CONSTANT(SAMPLE_PARTITION_LAYERS);
+
ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR3_ARRAY, "vertices", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_vertices", "get_vertices");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "polygons", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_polygons", "_get_polygons");
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "sample_partition_type/sample_partition_type", PROPERTY_HINT_ENUM, "Watershed,Monotone,Layers"), "set_sample_partition_type", "get_sample_partition_type");
+
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "cell/size", PROPERTY_HINT_RANGE, "0.1,1.0,0.01"), "set_cell_size", "get_cell_size");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "cell/height", PROPERTY_HINT_RANGE, "0.1,1.0,0.01"), "set_cell_height", "get_cell_height");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "agent/height", PROPERTY_HINT_RANGE, "0.1,5.0,0.01"), "set_agent_height", "get_agent_height");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "agent/radius", PROPERTY_HINT_RANGE, "0.1,5.0,0.01"), "set_agent_radius", "get_agent_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "agent/max_climb", PROPERTY_HINT_RANGE, "0.1,5.0,0.01"), "set_agent_max_climb", "get_agent_max_climb");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "agent/max_slope", PROPERTY_HINT_RANGE, "0.0,90.0,0.1"), "set_agent_max_slope", "get_agent_max_slope");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "region/min_size", PROPERTY_HINT_RANGE, "0.0,150.0,0.01"), "set_region_min_size", "get_region_min_size");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "region/merge_size", PROPERTY_HINT_RANGE, "0.0,150.0,0.01"), "set_region_merge_size", "get_region_merge_size");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "edge/max_length", PROPERTY_HINT_RANGE, "0.0,50.0,0.01"), "set_edge_max_length", "get_edge_max_length");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "edge/max_error", PROPERTY_HINT_RANGE, "0.1,3.0,0.01"), "set_edge_max_error", "get_edge_max_error");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "polygon/verts_per_poly", PROPERTY_HINT_RANGE, "3.0,12.0,1.0"), "set_verts_per_poly", "get_verts_per_poly");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "detail/sample_distance", PROPERTY_HINT_RANGE, "0.0,16.0,0.01"), "set_detail_sample_distance", "get_detail_sample_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "detail/sample_max_error", PROPERTY_HINT_RANGE, "0.0,16.0,0.01"), "set_detail_sample_max_error", "get_detail_sample_max_error");
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter/low_hanging_obstacles"), "set_filter_low_hanging_obstacles", "get_filter_low_hanging_obstacles");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter/ledge_spans"), "set_filter_ledge_spans", "get_filter_ledge_spans");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter/filter_walkable_low_height_spans"), "set_filter_walkable_low_height_spans", "get_filter_walkable_low_height_spans");
}
NavigationMesh::NavigationMesh() {
+ cell_size = 0.3f;
+ cell_height = 0.2f;
+ agent_height = 2.0f;
+ agent_radius = 0.6f;
+ agent_max_climb = 0.9f;
+ agent_max_slope = 45.0f;
+ region_min_size = 8.0f;
+ region_merge_size = 20.0f;
+ edge_max_length = 12.0f;
+ edge_max_error = 1.3f;
+ verts_per_poly = 6.0f;
+ detail_sample_distance = 6.0f;
+ detail_sample_max_error = 1.0f;
+
+ partition_type = SAMPLE_PARTITION_WATERSHED;
+
+ filter_low_hanging_obstacles = false;
+ filter_ledge_spans = false;
+ filter_walkable_low_height_spans = false;
}
void NavigationMeshInstance::set_enabled(bool p_enabled) {
diff --git a/scene/3d/navigation_mesh.h b/scene/3d/navigation_mesh.h
index 36fe3ee34b..dd5ed79500 100644
--- a/scene/3d/navigation_mesh.h
+++ b/scene/3d/navigation_mesh.h
@@ -61,6 +61,87 @@ protected:
Array _get_polygons() const;
public:
+ enum SamplePartitionType {
+ SAMPLE_PARTITION_WATERSHED = 0,
+ SAMPLE_PARTITION_MONOTONE,
+ SAMPLE_PARTITION_LAYERS,
+ SAMPLE_PARTITION_MAX
+ };
+
+protected:
+ float cell_size;
+ float cell_height;
+ float agent_height;
+ float agent_radius;
+ float agent_max_climb;
+ float agent_max_slope;
+ float region_min_size;
+ float region_merge_size;
+ float edge_max_length;
+ float edge_max_error;
+ float verts_per_poly;
+ float detail_sample_distance;
+ float detail_sample_max_error;
+
+ SamplePartitionType partition_type;
+
+ bool filter_low_hanging_obstacles;
+ bool filter_ledge_spans;
+ bool filter_walkable_low_height_spans;
+
+public:
+ // Recast settings
+ void set_sample_partition_type(int p_value);
+ int get_sample_partition_type() const;
+
+ void set_cell_size(float p_value);
+ float get_cell_size() const;
+
+ void set_cell_height(float p_value);
+ float get_cell_height() const;
+
+ void set_agent_height(float p_value);
+ float get_agent_height() const;
+
+ void set_agent_radius(float p_value);
+ float get_agent_radius();
+
+ void set_agent_max_climb(float p_value);
+ float get_agent_max_climb() const;
+
+ void set_agent_max_slope(float p_value);
+ float get_agent_max_slope() const;
+
+ void set_region_min_size(float p_value);
+ float get_region_min_size() const;
+
+ void set_region_merge_size(float p_value);
+ float get_region_merge_size() const;
+
+ void set_edge_max_length(float p_value);
+ float get_edge_max_length() const;
+
+ void set_edge_max_error(float p_value);
+ float get_edge_max_error() const;
+
+ void set_verts_per_poly(float p_value);
+ float get_verts_per_poly() const;
+
+ void set_detail_sample_distance(float p_value);
+ float get_detail_sample_distance() const;
+
+ void set_detail_sample_max_error(float p_value);
+ float get_detail_sample_max_error() const;
+
+ void set_filter_low_hanging_obstacles(bool p_value);
+ bool get_filter_low_hanging_obstacles() const;
+
+ void set_filter_ledge_spans(bool p_value);
+ bool get_filter_ledge_spans() const;
+
+ void set_filter_walkable_low_height_spans(bool p_value);
+ bool get_filter_walkable_low_height_spans() const;
+
void create_from_mesh(const Ref<Mesh> &p_mesh);
void set_vertices(const PoolVector<Vector3> &p_vertices);
diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp
index 6a8226c0e1..7525eb5069 100644
--- a/scene/3d/physics_body.cpp
+++ b/scene/3d/physics_body.cpp
@@ -1061,7 +1061,7 @@ KinematicBody::Collision KinematicBody::get_slide_collision(int p_bounce) const
Ref<KinematicCollision> KinematicBody::_get_slide_collision(int p_bounce) {
ERR_FAIL_INDEX_V(p_bounce, colliders.size(), Ref<KinematicCollision>());
- if (p_bounce > slide_colliders.size()) {
+ if (p_bounce >= slide_colliders.size()) {
slide_colliders.resize(p_bounce + 1);
}
diff --git a/scene/audio/audio_player.cpp b/scene/audio/audio_player.cpp
index 341ae45ce8..6a582c9a3d 100644
--- a/scene/audio/audio_player.cpp
+++ b/scene/audio/audio_player.cpp
@@ -66,29 +66,27 @@ void AudioStreamPlayer::_mix_audio() {
//set volume for next mix
mix_volume_db = volume_db;
- AudioFrame *targets[3] = { NULL, NULL, NULL };
+ AudioFrame *targets[4] = { NULL, NULL, NULL, NULL };
if (AudioServer::get_singleton()->get_speaker_mode() == AudioServer::SPEAKER_MODE_STEREO) {
targets[0] = AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, 0);
} else {
switch (mix_target) {
case MIX_TARGET_STEREO: {
- targets[0] = AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, 1);
+ targets[0] = AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, 0);
} break;
case MIX_TARGET_SURROUND: {
- targets[0] = AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, 1);
- targets[1] = AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, 2);
- if (AudioServer::get_singleton()->get_speaker_mode() == AudioServer::SPEAKER_SURROUND_71) {
- targets[2] = AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, 3);
+ for (int i = 0; i < AudioServer::get_singleton()->get_channel_count(); i++) {
+ targets[i] = AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, i);
}
} break;
case MIX_TARGET_CENTER: {
- targets[0] = AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, 0);
+ targets[0] = AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, 1);
} break;
}
}
- for (int c = 0; c < 3; c++) {
+ for (int c = 0; c < 4; c++) {
if (!targets[c])
break;
for (int i = 0; i < buffer_size; i++) {
@@ -189,7 +187,7 @@ void AudioStreamPlayer::stop() {
bool AudioStreamPlayer::is_playing() const {
if (stream_playback.is_valid()) {
- return active && stream_playback->is_playing();
+ return active; //&& stream_playback->is_playing();
}
return false;
@@ -304,7 +302,7 @@ void AudioStreamPlayer::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_stream", "get_stream");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "volume_db", PROPERTY_HINT_RANGE, "-80,24"), "set_volume_db", "get_volume_db");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "play", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "_is_active");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "is_playing");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autoplay"), "set_autoplay", "is_autoplay_enabled");
ADD_PROPERTY(PropertyInfo(Variant::INT, "mix_target", PROPERTY_HINT_ENUM, "Stereo,Surround,Center"), "set_mix_target", "get_mix_target");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus");
diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp
index 140d002387..d4912339da 100644
--- a/scene/gui/dialogs.cpp
+++ b/scene/gui/dialogs.cpp
@@ -195,7 +195,7 @@ void WindowDialog::_notification(int p_what) {
RID canvas = get_canvas_item();
// Draw the background.
- Ref<StyleBox> panel = get_stylebox("panel", "WindowDialog");
+ Ref<StyleBox> panel = get_stylebox("panel");
Size2 size = get_size();
panel->draw(canvas, Rect2(0, 0, size.x, size.y));
diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp
index 4661f54526..8fda5df53c 100644
--- a/scene/gui/slider.cpp
+++ b/scene/gui/slider.cpp
@@ -162,18 +162,20 @@ void Slider::_notification(int p_what) {
Size2i size = get_size();
Ref<StyleBox> style = get_stylebox("slider");
Ref<StyleBox> focus = get_stylebox("focus");
+ Ref<StyleBox> grabber_area = get_stylebox("grabber_area");
Ref<Texture> grabber = get_icon(editable ? ((mouse_inside || has_focus()) ? "grabber_highlight" : "grabber") : "grabber_disabled");
Ref<Texture> tick = get_icon("tick");
if (orientation == VERTICAL) {
int widget_width = style->get_minimum_size().width + style->get_center_size().width;
+ float areasize = size.height - grabber->get_size().height;
style->draw(ci, Rect2i(Point2i(size.width / 2 - widget_width / 2, 0), Size2i(widget_width, size.height)));
+ grabber_area->draw(ci, Rect2i(Point2i((size.width - widget_width) / 2, size.height - areasize * get_as_ratio() - grabber->get_size().height / 2), Size2i(widget_width, areasize * get_as_ratio() + grabber->get_size().width / 2)));
/*
if (mouse_inside||has_focus())
focus->draw(ci,Rect2i(Point2i(),Size2i(style->get_minimum_size().width+style->get_center_size().width,size.height)));
*/
- float areasize = size.height - grabber->get_size().height;
if (ticks > 1) {
int tickarea = size.height - tick->get_height();
for (int i = 0; i < ticks; i++) {
@@ -186,13 +188,15 @@ void Slider::_notification(int p_what) {
} else {
int widget_height = style->get_minimum_size().height + style->get_center_size().height;
- style->draw(ci, Rect2i(Point2i(0, size.height / 2 - widget_height / 2), Size2i(size.width, widget_height)));
+ float areasize = size.width - grabber->get_size().width;
+
+ style->draw(ci, Rect2i(Point2i(0, (size.height - widget_height) / 2), Size2i(size.width, widget_height)));
+ grabber_area->draw(ci, Rect2i(Point2i(0, (size.height - widget_height) / 2), Size2i(areasize * get_as_ratio() + grabber->get_size().width / 2, widget_height)));
/*
if (mouse_inside||has_focus())
focus->draw(ci,Rect2i(Point2i(),Size2i(size.width,style->get_minimum_size().height+style->get_center_size().height)));
*/
- float areasize = size.width - grabber->get_size().width;
if (ticks > 1) {
int tickarea = size.width - tick->get_width();
for (int i = 0; i < ticks; i++) {
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index db282262ec..4975b66744 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -333,6 +333,15 @@ bool TreeItem::is_collapsed() {
return collapsed;
}
+void TreeItem::set_custom_minimum_height(int p_height) {
+ custom_min_height = p_height;
+ _changed_notify();
+}
+
+int TreeItem::get_custom_minimum_height() const {
+ return custom_min_height;
+}
+
TreeItem *TreeItem::get_next() {
return next;
@@ -703,6 +712,9 @@ void TreeItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_collapsed", "enable"), &TreeItem::set_collapsed);
ClassDB::bind_method(D_METHOD("is_collapsed"), &TreeItem::is_collapsed);
+ ClassDB::bind_method(D_METHOD("set_custom_minimum_height", "height"), &TreeItem::set_custom_minimum_height);
+ ClassDB::bind_method(D_METHOD("get_custom_minimum_height"), &TreeItem::get_custom_minimum_height);
+
ClassDB::bind_method(D_METHOD("get_next"), &TreeItem::get_next);
ClassDB::bind_method(D_METHOD("get_prev"), &TreeItem::get_prev);
ClassDB::bind_method(D_METHOD("get_parent"), &TreeItem::get_parent);
@@ -780,6 +792,7 @@ TreeItem::TreeItem(Tree *p_tree) {
tree = p_tree;
collapsed = false;
disable_folding = false;
+ custom_min_height = 0;
parent = 0; // parent item
next = 0; // next in list
@@ -921,6 +934,9 @@ int Tree::compute_item_height(TreeItem *p_item) const {
default: {}
}
}
+ int item_min_height = p_item->get_custom_minimum_height();
+ if (height < item_min_height)
+ height = item_min_height;
height += cache.vseparation;
@@ -3593,6 +3609,7 @@ void Tree::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_item_area_rect", "item", "column"), &Tree::_get_item_rect, DEFVAL(-1));
ClassDB::bind_method(D_METHOD("get_item_at_pos", "pos"), &Tree::get_item_at_pos);
ClassDB::bind_method(D_METHOD("get_column_at_pos", "pos"), &Tree::get_column_at_pos);
+ ClassDB::bind_method(D_METHOD("get_drop_section_at_pos", "pos"), &Tree::get_drop_section_at_pos);
ClassDB::bind_method(D_METHOD("ensure_cursor_is_visible"), &Tree::ensure_cursor_is_visible);
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index 06d6d3ad5a..5f19558597 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -145,6 +145,7 @@ private:
bool collapsed; // wont show childs
bool disable_folding;
+ int custom_min_height;
TreeItem *parent; // parent item
TreeItem *next; // next in list
@@ -230,6 +231,9 @@ public:
void set_collapsed(bool p_collapsed);
bool is_collapsed();
+ void set_custom_minimum_height(int p_height);
+ int get_custom_minimum_height() const;
+
TreeItem *get_prev();
TreeItem *get_next();
TreeItem *get_parent();
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 9ed3734a36..b9dfbd6bb0 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -430,6 +430,7 @@ void register_scene_types() {
ClassDB::register_class<StaticBody2D>();
ClassDB::register_class<RigidBody2D>();
ClassDB::register_class<KinematicBody2D>();
+ ClassDB::register_class<KinematicCollision2D>();
ClassDB::register_class<Area2D>();
ClassDB::register_class<CollisionShape2D>();
ClassDB::register_class<CollisionPolygon2D>();