summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/audio/audio_player.cpp50
-rw-r--r--scene/audio/audio_player.h1
-rw-r--r--scene/gui/item_list.cpp4
-rw-r--r--scene/gui/scroll_container.cpp5
-rw-r--r--scene/gui/text_edit.cpp9
-rw-r--r--scene/gui/text_edit.h1
-rw-r--r--scene/gui/video_player.cpp144
-rw-r--r--scene/gui/video_player.h22
-rwxr-xr-xscene/main/node.cpp17
-rw-r--r--scene/main/node.h1
-rw-r--r--scene/resources/audio_stream_sample.cpp32
-rw-r--r--scene/resources/dynamic_font_stb.cpp5
-rw-r--r--scene/resources/environment.cpp3
-rw-r--r--scene/resources/mesh.cpp13
-rw-r--r--scene/resources/mesh.h2
-rw-r--r--scene/resources/primitive_meshes.cpp38
-rw-r--r--scene/resources/primitive_meshes.h5
-rw-r--r--scene/resources/video_stream.h4
18 files changed, 279 insertions, 77 deletions
diff --git a/scene/audio/audio_player.cpp b/scene/audio/audio_player.cpp
index 058b162e83..08b01c6a4c 100644
--- a/scene/audio/audio_player.cpp
+++ b/scene/audio/audio_player.cpp
@@ -31,20 +31,7 @@
#include "engine.h"
-void AudioStreamPlayer::_mix_audio() {
-
- if (!stream_playback.is_valid()) {
- return;
- }
-
- if (!active) {
- return;
- }
-
- if (setseek >= 0.0) {
- stream_playback->start(setseek);
- setseek = -1.0; //reset seek
- }
+void AudioStreamPlayer::_mix_internal(bool p_fadeout) {
int bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus);
@@ -52,19 +39,24 @@ void AudioStreamPlayer::_mix_audio() {
AudioFrame *buffer = mix_buffer.ptr();
int buffer_size = mix_buffer.size();
+ if (p_fadeout) {
+ buffer_size = MIN(buffer_size, 16); //short fadeout ramp
+ }
+
//mix
stream_playback->mix(buffer, 1.0, buffer_size);
//multiply volume interpolating to avoid clicks if this changes
+ float target_volume = p_fadeout ? -80.0 : volume_db;
float vol = Math::db2linear(mix_volume_db);
- float vol_inc = (Math::db2linear(volume_db) - vol) / float(buffer_size);
+ float vol_inc = (Math::db2linear(target_volume) - vol) / float(buffer_size);
for (int i = 0; i < buffer_size; i++) {
buffer[i] *= vol;
vol += vol_inc;
}
//set volume for next mix
- mix_volume_db = volume_db;
+ mix_volume_db = target_volume;
AudioFrame *targets[4] = { NULL, NULL, NULL, NULL };
@@ -95,6 +87,30 @@ void AudioStreamPlayer::_mix_audio() {
}
}
+void AudioStreamPlayer::_mix_audio() {
+
+ if (!stream_playback.is_valid()) {
+ return;
+ }
+
+ if (!active) {
+ return;
+ }
+
+ if (setseek >= 0.0) {
+ if (stream_playback->is_playing()) {
+
+ //fade out to avoid pops
+ _mix_internal(true);
+ }
+ stream_playback->start(setseek);
+ setseek = -1.0; //reset seek
+ mix_volume_db = volume_db; //reset ramp
+ }
+
+ _mix_internal(false);
+}
+
void AudioStreamPlayer::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
@@ -163,7 +179,7 @@ float AudioStreamPlayer::get_volume_db() const {
void AudioStreamPlayer::play(float p_from_pos) {
if (stream_playback.is_valid()) {
- mix_volume_db = volume_db; //reset volume ramp
+ //mix_volume_db = volume_db; do not reset volume ramp here, can cause clicks
setseek = p_from_pos;
active = true;
set_process_internal(true);
diff --git a/scene/audio/audio_player.h b/scene/audio/audio_player.h
index 4bfc44730d..6e9d623433 100644
--- a/scene/audio/audio_player.h
+++ b/scene/audio/audio_player.h
@@ -59,6 +59,7 @@ private:
MixTarget mix_target;
+ void _mix_internal(bool p_fadeout);
void _mix_audio();
static void _mix_audios(void *self) { reinterpret_cast<AudioStreamPlayer *>(self)->_mix_audio(); }
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index 623a110263..e9e9dcc859 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -754,7 +754,7 @@ void ItemList::_notification(int p_what) {
int width = size.width - bg->get_minimum_size().width;
if (scroll_bar->is_visible()) {
- width -= mw + bg->get_margin(MARGIN_RIGHT);
+ width -= mw;
}
draw_style_box(bg, Rect2(Point2(), size));
@@ -1107,7 +1107,7 @@ void ItemList::_notification(int p_what) {
}
for (int i = 0; i < separators.size(); i++) {
- draw_line(Vector2(bg->get_margin(MARGIN_LEFT), base_ofs.y + separators[i]), Vector2(size.width - bg->get_margin(MARGIN_RIGHT), base_ofs.y + separators[i]), guide_color);
+ draw_line(Vector2(bg->get_margin(MARGIN_LEFT), base_ofs.y + separators[i]), Vector2(width, base_ofs.y + separators[i]), guide_color);
}
}
}
diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp
index 1ad1e3f638..9022d67a4a 100644
--- a/scene/gui/scroll_container.cpp
+++ b/scene/gui/scroll_container.cpp
@@ -347,12 +347,11 @@ void ScrollContainer::update_scrollbars() {
} else {
v_scroll->show();
+ v_scroll->set_max(min.height);
+ v_scroll->set_page(size.height - hmin.height);
scroll.y = v_scroll->get_value();
}
- v_scroll->set_max(min.height);
- v_scroll->set_page(size.height - hmin.height);
-
if (!scroll_h || min.width <= size.width - vmin.width) {
h_scroll->hide();
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 5d4048f928..5d429f9f91 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -3668,6 +3668,11 @@ void TextEdit::set_readonly(bool p_readonly) {
readonly = p_readonly;
}
+bool TextEdit::is_readonly() const {
+
+ return readonly;
+}
+
void TextEdit::set_wrap(bool p_wrap) {
wrap = p_wrap;
@@ -4919,6 +4924,8 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("cursor_is_block_mode"), &TextEdit::cursor_is_block_mode);
ClassDB::bind_method(D_METHOD("set_readonly", "enable"), &TextEdit::set_readonly);
+ ClassDB::bind_method(D_METHOD("is_readonly"), &TextEdit::is_readonly);
+
ClassDB::bind_method(D_METHOD("set_wrap", "enable"), &TextEdit::set_wrap);
ClassDB::bind_method(D_METHOD("set_max_chars", "amount"), &TextEdit::set_max_chars);
ClassDB::bind_method(D_METHOD("set_context_menu_enabled", "enable"), &TextEdit::set_context_menu_enabled);
@@ -4969,6 +4976,8 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("menu_option", "option"), &TextEdit::menu_option);
ClassDB::bind_method(D_METHOD("get_menu"), &TextEdit::get_menu);
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT), "set_text", "get_text");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "readonly"), "set_readonly", "is_readonly");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "highlight_current_line"), "set_highlight_current_line", "is_highlight_current_line_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "syntax_highlighting"), "set_syntax_coloring", "is_syntax_coloring_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_line_numbers"), "set_show_line_numbers", "is_show_line_numbers_enabled");
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index c81b41c2e3..50f005ed6a 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -448,6 +448,7 @@ public:
bool cursor_is_block_mode() const;
void set_readonly(bool p_readonly);
+ bool is_readonly() const;
void set_max_chars(int p_max_chars);
void set_wrap(bool p_wrap);
diff --git a/scene/gui/video_player.cpp b/scene/gui/video_player.cpp
index 190ccd50d5..1b6bd30b58 100644
--- a/scene/gui/video_player.cpp
+++ b/scene/gui/video_player.cpp
@@ -42,44 +42,127 @@ void VideoPlayer::sp_set_mix_rate(int p_rate) {
server_mix_rate = p_rate;
}
-bool VideoPlayer::sp_mix(int32_t *p_buffer, int p_frames) {
-
- if (resampler.is_ready()) {
+bool VideoPlayer::mix(AudioFrame *p_buffer, int p_frames) {
+
+ // Check the amount resampler can really handle.
+ // If it cannot, wait "wait_resampler_phase_limit" times.
+ // This mechanism contributes to smoother pause/unpause operation.
+ if (p_frames <= resampler.get_num_of_ready_frames() ||
+ wait_resampler_limit <= wait_resampler) {
+ wait_resampler = 0;
return resampler.mix(p_buffer, p_frames);
}
-
+ wait_resampler++;
return false;
}
-int VideoPlayer::_audio_mix_callback(void *p_udata, const int16_t *p_data, int p_frames) {
+// Called from main thread (eg VideoStreamPlaybackWebm::update)
+int VideoPlayer::_audio_mix_callback(void *p_udata, const float *p_data, int p_frames) {
VideoPlayer *vp = (VideoPlayer *)p_udata;
- int todo = MIN(vp->resampler.get_todo(), p_frames);
+ int todo = MIN(vp->resampler.get_writer_space(), p_frames);
- int16_t *wb = vp->resampler.get_write_buffer();
+ float *wb = vp->resampler.get_write_buffer();
int c = vp->resampler.get_channel_count();
for (int i = 0; i < todo * c; i++) {
wb[i] = p_data[i];
}
vp->resampler.write(todo);
+
return todo;
}
+// Called from audio thread
+void VideoPlayer::_mix_audio() {
+
+ if (!stream.is_valid()) {
+ return;
+ }
+ if (!playback.is_valid() || !playback->is_playing() || playback->is_paused()) {
+ return;
+ }
+
+ AudioFrame *buffer = mix_buffer.ptr();
+ int buffer_size = mix_buffer.size();
+
+ // Resample
+ if (!mix(buffer, buffer_size))
+ return;
+
+ AudioFrame vol = AudioFrame(volume, volume);
+
+ // Copy to server's audio buffer
+ switch (AudioServer::get_singleton()->get_speaker_mode()) {
+
+ case AudioServer::SPEAKER_MODE_STEREO: {
+ AudioFrame *target = AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, 0);
+
+ for (int j = 0; j < buffer_size; j++) {
+
+ target[j] += buffer[j] * vol;
+ }
+
+ } break;
+ case AudioServer::SPEAKER_SURROUND_51: {
+
+ AudioFrame *targets[2] = {
+ AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, 1),
+ AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, 2),
+ };
+
+ for (int j = 0; j < buffer_size; j++) {
+
+ AudioFrame frame = buffer[j] * vol;
+ targets[0][j] = frame;
+ targets[1][j] = frame;
+ }
+ } break;
+ case AudioServer::SPEAKER_SURROUND_71: {
+
+ AudioFrame *targets[3] = {
+ AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, 1),
+ AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, 2),
+ AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, 3)
+ };
+
+ 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;
+ }
+
+ } break;
+ }
+}
+
void VideoPlayer::_notification(int p_notification) {
switch (p_notification) {
case NOTIFICATION_ENTER_TREE: {
+ AudioServer::get_singleton()->add_callback(_mix_audios, this);
+
if (stream.is_valid() && autoplay && !Engine::get_singleton()->is_editor_hint()) {
play();
}
+
+ } break;
+
+ case NOTIFICATION_EXIT_TREE: {
+
+ AudioServer::get_singleton()->remove_callback(_mix_audios, this);
+
} break;
case NOTIFICATION_INTERNAL_PROCESS: {
+ bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus);
+
if (stream.is_null())
return;
if (paused)
@@ -87,10 +170,11 @@ void VideoPlayer::_notification(int p_notification) {
if (!playback->is_playing())
return;
- double audio_time = USEC_TO_SEC(OS::get_singleton()->get_ticks_usec()); //AudioServer::get_singleton()->get_mix_time();
+ double audio_time = USEC_TO_SEC(OS::get_singleton()->get_ticks_usec());
double delta = last_audio_time == 0 ? 0 : audio_time - last_audio_time;
last_audio_time = audio_time;
+
if (delta == 0)
return;
@@ -135,6 +219,9 @@ bool VideoPlayer::has_expand() const {
void VideoPlayer::set_stream(const Ref<VideoStream> &p_stream) {
stop();
+ AudioServer::get_singleton()->lock();
+ mix_buffer.resize(AudioServer::get_singleton()->thread_get_mix_buffer_size());
+ AudioServer::get_singleton()->unlock();
stream = p_stream;
if (stream.is_valid()) {
@@ -309,6 +396,40 @@ bool VideoPlayer::has_autoplay() const {
return autoplay;
};
+void VideoPlayer::set_bus(const StringName &p_bus) {
+
+ //if audio is active, must lock this
+ AudioServer::get_singleton()->lock();
+ bus = p_bus;
+ AudioServer::get_singleton()->unlock();
+}
+
+StringName VideoPlayer::get_bus() const {
+
+ for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
+ if (AudioServer::get_singleton()->get_bus_name(i) == bus) {
+ return bus;
+ }
+ }
+ return "Master";
+}
+
+void VideoPlayer::_validate_property(PropertyInfo &property) const {
+
+ if (property.name == "bus") {
+
+ String options;
+ for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
+ if (i > 0)
+ options += ",";
+ String name = AudioServer::get_singleton()->get_bus_name(i);
+ options += name;
+ }
+
+ property.hint_string = options;
+ }
+}
+
void VideoPlayer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_stream", "stream"), &VideoPlayer::set_stream);
@@ -345,6 +466,9 @@ void VideoPlayer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_buffering_msec", "msec"), &VideoPlayer::set_buffering_msec);
ClassDB::bind_method(D_METHOD("get_buffering_msec"), &VideoPlayer::get_buffering_msec);
+ ClassDB::bind_method(D_METHOD("set_bus", "bus"), &VideoPlayer::set_bus);
+ ClassDB::bind_method(D_METHOD("get_bus"), &VideoPlayer::get_bus);
+
ClassDB::bind_method(D_METHOD("get_video_texture"), &VideoPlayer::get_video_texture);
ADD_PROPERTY(PropertyInfo(Variant::INT, "audio_track", PROPERTY_HINT_RANGE, "0,128,1"), "set_audio_track", "get_audio_track");
@@ -354,6 +478,7 @@ void VideoPlayer::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autoplay"), "set_autoplay", "has_autoplay");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "paused"), "set_paused", "is_paused");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "expand"), "set_expand", "has_expand");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus");
}
VideoPlayer::VideoPlayer() {
@@ -372,6 +497,9 @@ VideoPlayer::VideoPlayer() {
// internal_stream.player=this;
// stream_rid=AudioServer::get_singleton()->audio_stream_create(&internal_stream);
last_audio_time = 0;
+
+ wait_resampler = 0;
+ wait_resampler_limit = 2;
};
VideoPlayer::~VideoPlayer() {
diff --git a/scene/gui/video_player.h b/scene/gui/video_player.h
index f04e90365f..74e2f14e58 100644
--- a/scene/gui/video_player.h
+++ b/scene/gui/video_player.h
@@ -33,17 +33,24 @@
#include "scene/gui/control.h"
#include "scene/resources/video_stream.h"
#include "servers/audio/audio_rb_resampler.h"
+#include "servers/audio_server.h"
class VideoPlayer : public Control {
GDCLASS(VideoPlayer, Control);
+ struct Output {
+
+ AudioFrame vol;
+ int bus_index;
+ Viewport *viewport; //pointer only used for reference to previous mix
+ };
Ref<VideoStreamPlayback> playback;
Ref<VideoStream> stream;
int sp_get_channel_count() const;
void sp_set_mix_rate(int p_rate); //notify the stream of the mix rate
- bool sp_mix(int32_t *p_buffer, int p_frames);
+ bool mix(AudioFrame *p_buffer, int p_frames);
RID stream_rid;
@@ -51,6 +58,8 @@ class VideoPlayer : public Control {
Ref<Image> last_frame;
AudioRBResampler resampler;
+ Vector<AudioFrame> mix_buffer;
+ int wait_resampler, wait_resampler_limit;
bool paused;
bool autoplay;
@@ -61,12 +70,18 @@ class VideoPlayer : public Control {
int buffering_ms;
int server_mix_rate;
int audio_track;
+ int bus_index;
+
+ StringName bus;
- static int _audio_mix_callback(void *p_udata, const int16_t *p_data, int p_frames);
+ void _mix_audio();
+ static int _audio_mix_callback(void *p_udata, const float *p_data, int p_frames);
+ static void _mix_audios(void *self) { reinterpret_cast<VideoPlayer *>(self)->_mix_audio(); }
protected:
static void _bind_methods();
void _notification(int p_notification);
+ void _validate_property(PropertyInfo &property) const;
public:
Size2 get_minimum_size() const;
@@ -104,6 +119,9 @@ public:
void set_buffering_msec(int p_msec);
int get_buffering_msec() const;
+ void set_bus(const StringName &p_bus);
+ StringName get_bus() const;
+
VideoPlayer();
~VideoPlayer();
};
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index e6e11de177..d38c688241 100755
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -2067,7 +2067,7 @@ int Node::get_position_in_parent() const {
return data.pos;
}
-Node *Node::_duplicate(int p_flags) const {
+Node *Node::duplicate(int p_flags) const {
Node *node = NULL;
@@ -2170,17 +2170,6 @@ Node *Node::_duplicate(int p_flags) const {
return node;
}
-Node *Node::duplicate(int p_flags) const {
-
- Node *dupe = _duplicate(p_flags);
-
- if (dupe && (p_flags & DUPLICATE_SIGNALS)) {
- _duplicate_signals(this, dupe);
- }
-
- return dupe;
-}
-
void Node::_duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p_reown_map) const {
if (get_owner() != get_parent()->get_owner())
@@ -2422,7 +2411,9 @@ void Node::_replace_connections_target(Node *p_new_target) {
if (c.flags & CONNECT_PERSIST) {
c.source->disconnect(c.signal, this, c.method);
- ERR_CONTINUE(!p_new_target->has_method(c.method));
+ bool valid = p_new_target->has_method(c.method) || p_new_target->get_script().is_null() || Ref<Script>(p_new_target->get_script())->has_method(c.method);
+ ERR_EXPLAIN("Attempt to connect signal \'" + c.source->get_class() + "." + c.signal + "\' to nonexistent method \'" + c.target->get_class() + "." + c.method + "\'");
+ ERR_CONTINUE(!valid);
c.source->connect(c.signal, p_new_target, c.method, c.binds, c.flags);
}
}
diff --git a/scene/main/node.h b/scene/main/node.h
index c43e96063f..e8901f7b6e 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -169,7 +169,6 @@ private:
void _duplicate_signals(const Node *p_original, Node *p_copy) const;
void _duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p_reown_map) const;
- Node *_duplicate(int p_flags) const;
Array _get_children() const;
Array _get_groups() const;
diff --git a/scene/resources/audio_stream_sample.cpp b/scene/resources/audio_stream_sample.cpp
index fdc3b79db6..f81f460521 100644
--- a/scene/resources/audio_stream_sample.cpp
+++ b/scene/resources/audio_stream_sample.cpp
@@ -31,17 +31,23 @@
void AudioStreamPlaybackSample::start(float p_from_pos) {
- for (int i = 0; i < 2; i++) {
- ima_adpcm[i].step_index = 0;
- ima_adpcm[i].predictor = 0;
- ima_adpcm[i].loop_step_index = 0;
- ima_adpcm[i].loop_predictor = 0;
- ima_adpcm[i].last_nibble = -1;
- ima_adpcm[i].loop_pos = 0x7FFFFFFF;
- ima_adpcm[i].window_ofs = 0;
+ if (base->format == AudioStreamSample::FORMAT_IMA_ADPCM) {
+ //no seeking in IMA_ADPCM
+ for (int i = 0; i < 2; i++) {
+ ima_adpcm[i].step_index = 0;
+ ima_adpcm[i].predictor = 0;
+ ima_adpcm[i].loop_step_index = 0;
+ ima_adpcm[i].loop_predictor = 0;
+ ima_adpcm[i].last_nibble = -1;
+ ima_adpcm[i].loop_pos = 0x7FFFFFFF;
+ ima_adpcm[i].window_ofs = 0;
+ }
+
+ offset = 0;
+ } else {
+ seek(p_from_pos);
}
- seek(p_from_pos);
sign = 1;
active = true;
}
@@ -373,6 +379,14 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in
dst_buff += target;
}
+
+ if (todo) {
+ //bit was missing from mix
+ int todo_ofs = p_frames - todo;
+ for (int i = todo_ofs; i < p_frames; i++) {
+ p_buffer[i] = AudioFrame(0, 0);
+ }
+ }
}
float AudioStreamPlaybackSample::get_length() const {
diff --git a/scene/resources/dynamic_font_stb.cpp b/scene/resources/dynamic_font_stb.cpp
index 91263fb125..4aa47cb664 100644
--- a/scene/resources/dynamic_font_stb.cpp
+++ b/scene/resources/dynamic_font_stb.cpp
@@ -333,8 +333,7 @@ void DynamicFontAtSize::_update_char(CharType p_char) {
//blit to image and texture
{
-
- Image img(tex.texture_size, tex.texture_size, 0, Image::FORMAT_LA8, tex.imgdata);
+ Ref<Image> img = memnew(Image(tex.texture_size, tex.texture_size, 0, Image::FORMAT_LA8, tex.imgdata));
if (tex.texture.is_null()) {
tex.texture.instance();
@@ -518,7 +517,7 @@ bool ResourceFormatLoaderDynamicFont::handles_type(const String &p_type) const {
String ResourceFormatLoaderDynamicFont::get_resource_type(const String &p_path) const {
- String el = p_path.extension().to_lower();
+ String el = p_path.get_extension().to_lower();
if (el == "ttf")
return "DynamicFontData";
return "";
diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp
index 232f690074..fe59450f2e 100644
--- a/scene/resources/environment.cpp
+++ b/scene/resources/environment.cpp
@@ -1184,7 +1184,8 @@ Environment::Environment() {
bg_energy = 1.0;
bg_canvas_max_layer = 0;
ambient_energy = 1.0;
- ambient_sky_contribution = 1.0;
+ //ambient_sky_contribution = 1.0;
+ set_ambient_light_sky_contribution(1.0);
tone_mapper = TONE_MAPPER_LINEAR;
tonemap_exposure = 1.0;
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index db5d87d703..26f5deae1d 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -574,7 +574,6 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
ERR_FAIL_COND_V(!d.has("format"), false);
uint32_t format = d["format"];
- ERR_FAIL_COND_V(!d.has("primitive"), false);
uint32_t primitive = d["primitive"];
ERR_FAIL_COND_V(!d.has("vertex_count"), false);
@@ -598,8 +597,8 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
Rect3 aabb = d["aabb"];
Vector<Rect3> bone_aabb;
- if (d.has("bone_aabb")) {
- Array baabb = d["bone_aabb"];
+ if (d.has("skeleton_aabb")) {
+ Array baabb = d["skeleton_aabb"];
bone_aabb.resize(baabb.size());
for (int i = 0; i < baabb.size(); i++) {
@@ -1090,6 +1089,14 @@ void ArrayMesh::_bind_methods() {
BIND_ENUM_CONSTANT(ARRAY_FORMAT_INDEX);
}
+void ArrayMesh::reload_from_file() {
+ for (int i = 0; i < get_surface_count(); i++) {
+ surface_remove(i);
+ }
+ Resource::reload_from_file();
+ String path = get_path();
+}
+
ArrayMesh::ArrayMesh() {
mesh = VisualServer::get_singleton()->mesh_create();
diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h
index f4edb258b6..b11adf50b9 100644
--- a/scene/resources/mesh.h
+++ b/scene/resources/mesh.h
@@ -213,6 +213,8 @@ public:
void center_geometry();
void regen_normalmaps();
+ virtual void reload_from_file();
+
ArrayMesh();
~ArrayMesh();
diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp
index ba356d89b1..8e3899315c 100644
--- a/scene/resources/primitive_meshes.cpp
+++ b/scene/resources/primitive_meshes.cpp
@@ -1299,14 +1299,16 @@ void QuadMesh::_create_mesh_array(Array &p_arr) const {
tangents.resize(4 * 4);
uvs.resize(4);
- for (int i = 0; i < 4; i++) {
+ Vector2 _size = Vector2(size.x / 2.0f, size.y / 2.0f);
- static const Vector3 quad_faces[4] = {
- Vector3(-1, -1, 0),
- Vector3(-1, 1, 0),
- Vector3(1, 1, 0),
- Vector3(1, -1, 0),
- };
+ Vector3 quad_faces[4] = {
+ Vector3(-_size.x, -_size.y, 0),
+ Vector3(-_size.x, _size.y, 0),
+ Vector3(_size.x, _size.y, 0),
+ Vector3(_size.x, -_size.y, 0),
+ };
+
+ for (int i = 0; i < 4; i++) {
faces.set(i, quad_faces[i]);
normals.set(i, Vector3(0, 0, 1));
@@ -1325,18 +1327,30 @@ void QuadMesh::_create_mesh_array(Array &p_arr) const {
uvs.set(i, quad_uv[i]);
}
- p_arr[ARRAY_VERTEX] = faces;
- p_arr[ARRAY_NORMAL] = normals;
- p_arr[ARRAY_TANGENT] = tangents;
- p_arr[ARRAY_TEX_UV] = uvs;
+ p_arr[VS::ARRAY_VERTEX] = faces;
+ p_arr[VS::ARRAY_NORMAL] = normals;
+ p_arr[VS::ARRAY_TANGENT] = tangents;
+ p_arr[VS::ARRAY_TEX_UV] = uvs;
};
void QuadMesh::_bind_methods() {
- // nothing here yet...
+ ClassDB::bind_method(D_METHOD("set_size", "size"), &QuadMesh::set_size);
+ ClassDB::bind_method(D_METHOD("get_size"), &QuadMesh::get_size);
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size");
}
QuadMesh::QuadMesh() {
primitive_type = PRIMITIVE_TRIANGLE_FAN;
+ size = Size2(1.0, 1.0);
+}
+
+void QuadMesh::set_size(const Size2 &p_size) {
+ size = p_size;
+ _request_update();
+}
+
+Size2 QuadMesh::get_size() const {
+ return size;
}
/**
diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h
index 38a5695883..f0c8935261 100644
--- a/scene/resources/primitive_meshes.h
+++ b/scene/resources/primitive_meshes.h
@@ -263,7 +263,7 @@ class QuadMesh : public PrimitiveMesh {
GDCLASS(QuadMesh, PrimitiveMesh)
private:
- // nothing? really? Maybe add size some day atleast... :)
+ Size2 size;
protected:
static void _bind_methods();
@@ -271,6 +271,9 @@ protected:
public:
QuadMesh();
+
+ void set_size(const Size2 &p_size);
+ Size2 get_size() const;
};
/**
diff --git a/scene/resources/video_stream.h b/scene/resources/video_stream.h
index 3f79858056..fbe52909e7 100644
--- a/scene/resources/video_stream.h
+++ b/scene/resources/video_stream.h
@@ -40,7 +40,7 @@ protected:
static void _bind_methods();
public:
- typedef int (*AudioMixCallback)(void *p_udata, const int16_t *p_data, int p_frames);
+ typedef int (*AudioMixCallback)(void *p_udata, const float *p_data, int p_frames);
virtual void stop() = 0;
virtual void play() = 0;
@@ -48,7 +48,7 @@ public:
virtual bool is_playing() const = 0;
virtual void set_paused(bool p_paused) = 0;
- virtual bool is_paused(bool p_paused) const = 0;
+ virtual bool is_paused() const = 0;
virtual void set_loop(bool p_enable) = 0;
virtual bool has_loop() const = 0;