summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/navigation2d.cpp6
-rw-r--r--scene/3d/navigation.cpp2
-rw-r--r--scene/gui/video_player.cpp197
-rw-r--r--scene/gui/video_player.h34
-rw-r--r--scene/io/resource_format_wav.cpp1
-rw-r--r--scene/resources/packed_scene.h9
-rw-r--r--scene/resources/video_stream.cpp8
-rw-r--r--scene/resources/video_stream.h36
8 files changed, 252 insertions, 41 deletions
diff --git a/scene/2d/navigation2d.cpp b/scene/2d/navigation2d.cpp
index 5db0e0a9fc..b7d51730a0 100644
--- a/scene/2d/navigation2d.cpp
+++ b/scene/2d/navigation2d.cpp
@@ -8,8 +8,6 @@ void Navigation2D::_navpoly_link(int p_id) {
NavMesh &nm=navpoly_map[p_id];
ERR_FAIL_COND(nm.linked);
- print_line("LINK");
-
DVector<Vector2> vertices=nm.navpoly->get_vertices();
int len = vertices.size();
if (len==0)
@@ -48,7 +46,6 @@ void Navigation2D::_navpoly_link(int p_id) {
e.point=_get_point(ep);
p.edges[j]=e;
-
int idxn = indices[(j+1)%plen];
if (idxn<0 || idxn>=len) {
valid=false;
@@ -121,7 +118,7 @@ void Navigation2D::_navpoly_unlink(int p_id) {
NavMesh &nm=navpoly_map[p_id];
ERR_FAIL_COND(!nm.linked);
- print_line("UNLINK");
+ //print_line("UNLINK");
for (List<Polygon>::Element *E=nm.polygons.front();E;E=E->next()) {
@@ -358,7 +355,6 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2& p_start, const Vect
if (!begin_poly || !end_poly) {
- //print_line("No Path Path");
return Vector<Vector2>(); //no path
}
diff --git a/scene/3d/navigation.cpp b/scene/3d/navigation.cpp
index bfa8add09c..ce28350be0 100644
--- a/scene/3d/navigation.cpp
+++ b/scene/3d/navigation.cpp
@@ -295,12 +295,14 @@ Vector<Vector3> Navigation::get_simple_path(const Vector3& p_start, const Vector
}
}
+
if (!begin_poly || !end_poly) {
//print_line("No Path Path");
return Vector<Vector3>(); //no path
}
+
if (begin_poly==end_poly) {
Vector<Vector3> path;
diff --git a/scene/gui/video_player.cpp b/scene/gui/video_player.cpp
index c0b971cb33..f50552b32c 100644
--- a/scene/gui/video_player.cpp
+++ b/scene/gui/video_player.cpp
@@ -28,6 +28,88 @@
/*************************************************************************/
#include "video_player.h"
+
+
+int VideoPlayer::InternalStream::get_channel_count() const {
+
+ return player->sp_get_channel_count();
+}
+void VideoPlayer::InternalStream::set_mix_rate(int p_rate){
+
+ return player->sp_set_mix_rate(p_rate);
+}
+bool VideoPlayer::InternalStream::mix(int32_t *p_buffer,int p_frames){
+
+ return player->sp_mix(p_buffer,p_frames);
+}
+void VideoPlayer::InternalStream::update(){
+
+ player->sp_update();
+}
+
+
+int VideoPlayer::sp_get_channel_count() const {
+
+ return playback->get_channels();
+}
+
+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()) {
+ return resampler.mix(p_buffer,p_frames);
+ }
+
+ return false;
+}
+
+void VideoPlayer::sp_update() {
+#if 0
+ _THREAD_SAFE_METHOD_
+ //update is unused
+ if (!paused && playback.is_valid()) {
+
+ if (!playback->is_playing()) {
+ //stream depleted data, but there's still audio in the ringbuffer
+ //check that all this audio has been flushed before stopping the stream
+ int to_mix = resampler.get_total() - resampler.get_todo();
+ if (to_mix==0) {
+ stop();
+ return;
+ }
+
+ return;
+ }
+
+ int todo =resampler.get_todo();
+ int wrote = playback->mix(resampler.get_write_buffer(),todo);
+ resampler.write(wrote);
+ }
+#endif
+}
+
+int VideoPlayer::_audio_mix_callback(void* p_udata,const int16_t *p_data,int p_frames) {
+
+ VideoPlayer *vp=(VideoPlayer*)p_udata;
+
+ int todo=MIN(vp->resampler.get_todo(),p_frames);
+
+ int16_t *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;
+}
+
+
+
void VideoPlayer::_notification(int p_notification) {
switch (p_notification) {
@@ -45,16 +127,25 @@ void VideoPlayer::_notification(int p_notification) {
return;
if (paused)
return;
- if (!stream->is_playing())
+ if (!playback->is_playing())
return;
- stream->update(get_tree()->get_idle_process_time());
- int prev_width = texture->get_width();
+ double audio_time = AudioServer::get_singleton()->get_mix_time();
+
+ double delta = last_audio_time==0?0:audio_time-last_audio_time;
+ last_audio_time=audio_time;
+ if (delta==0)
+ return;
+
+
+ playback->update(delta);
+
+ /*int prev_width = texture->get_width();
stream->pop_frame(texture);
if (prev_width == 0) {
update();
minimum_size_changed();
- };
+ };*/
} break;
@@ -75,6 +166,9 @@ void VideoPlayer::_notification(int p_notification) {
};
+
+
+
Size2 VideoPlayer::get_minimum_size() const {
if (!expand && !texture.is_null())
@@ -100,15 +194,33 @@ void VideoPlayer::set_stream(const Ref<VideoStream> &p_stream) {
stop();
- texture = Ref<ImageTexture>(memnew(ImageTexture));
-
stream=p_stream;
- if (!stream.is_null()) {
-
- stream->set_loop(loops);
- stream->set_paused(paused);
+ if (stream.is_valid()) {
+ stream->set_audio_track(audio_track);
+ playback=stream->instance_playback();
+ } else {
+ playback=Ref<VideoStreamPlayback>();
+ }
+
+ if (!playback.is_null()) {
+ playback->set_loop(loops);
+ playback->set_paused(paused);
+ texture=playback->get_texture();
+
+ AudioServer::get_singleton()->lock();
+ resampler.setup(playback->get_channels(),playback->get_mix_rate(),server_mix_rate,buffering_ms,0);
+ AudioServer::get_singleton()->unlock();
+ playback->set_mix_callback(_audio_mix_callback,this);
+
+ } else {
+ texture.unref();
+ AudioServer::get_singleton()->lock();
+ resampler.clear();
+ AudioServer::get_singleton()->unlock();
}
+ update();
+
};
Ref<VideoStream> VideoPlayer::get_stream() const {
@@ -119,36 +231,41 @@ Ref<VideoStream> VideoPlayer::get_stream() const {
void VideoPlayer::play() {
ERR_FAIL_COND(!is_inside_tree());
- if (stream.is_null())
+ if (playback.is_null())
return;
- stream->play();
+ playback->stop();
+ playback->play();
set_process(true);
+ AudioServer::get_singleton()->stream_set_active(stream_rid,true);
+ AudioServer::get_singleton()->stream_set_volume_scale(stream_rid,volume);
+ last_audio_time=0;
};
void VideoPlayer::stop() {
if (!is_inside_tree())
return;
- if (stream.is_null())
+ if (playback.is_null())
return;
- stream->stop();
+ playback->stop();
set_process(false);
+ last_audio_time=0;
};
bool VideoPlayer::is_playing() const {
- if (stream.is_null())
+ if (playback.is_null())
return false;
- return stream->is_playing();
+ return playback->is_playing();
};
void VideoPlayer::set_paused(bool p_paused) {
paused=p_paused;
- if (stream.is_valid()) {
- stream->set_paused(p_paused);
+ if (playback.is_valid()) {
+ playback->set_paused(p_paused);
set_process(!p_paused);
};
};
@@ -156,7 +273,27 @@ void VideoPlayer::set_paused(bool p_paused) {
bool VideoPlayer::is_paused() const {
return paused;
-};
+}
+
+void VideoPlayer::set_buffering_msec(int p_msec) {
+
+ buffering_ms=p_msec;
+}
+
+int VideoPlayer::get_buffering_msec() const{
+
+ return buffering_ms;
+}
+
+void VideoPlayer::set_audio_track(int p_track) {
+ audio_track=p_track;
+}
+
+int VideoPlayer::get_audio_track() const {
+
+ return audio_track;
+}
+
void VideoPlayer::set_volume(float p_vol) {
@@ -194,9 +331,9 @@ String VideoPlayer::get_stream_name() const {
float VideoPlayer::get_stream_pos() const {
- if (stream.is_null())
+ if (playback.is_null())
return 0;
- return stream->get_pos();
+ return playback->get_pos();
};
@@ -229,6 +366,9 @@ void VideoPlayer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_volume_db","db"),&VideoPlayer::set_volume_db);
ObjectTypeDB::bind_method(_MD("get_volume_db"),&VideoPlayer::get_volume_db);
+ ObjectTypeDB::bind_method(_MD("set_audio_track","track"),&VideoPlayer::set_audio_track);
+ ObjectTypeDB::bind_method(_MD("get_audio_track"),&VideoPlayer::get_audio_track);
+
ObjectTypeDB::bind_method(_MD("get_stream_name"),&VideoPlayer::get_stream_name);
ObjectTypeDB::bind_method(_MD("get_stream_pos"),&VideoPlayer::get_stream_pos);
@@ -239,13 +379,16 @@ void VideoPlayer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_expand","enable"), &VideoPlayer::set_expand );
ObjectTypeDB::bind_method(_MD("has_expand"), &VideoPlayer::has_expand );
+ ObjectTypeDB::bind_method(_MD("set_buffering_msec","msec"),&VideoPlayer::set_buffering_msec);
+ ObjectTypeDB::bind_method(_MD("get_buffering_msec"),&VideoPlayer::get_buffering_msec);
ADD_PROPERTY( PropertyInfo(Variant::OBJECT, "stream/stream", PROPERTY_HINT_RESOURCE_TYPE,"VideoStream"), _SCS("set_stream"), _SCS("get_stream") );
// ADD_PROPERTY( PropertyInfo(Variant::BOOL, "stream/loop"), _SCS("set_loop"), _SCS("has_loop") );
ADD_PROPERTY( PropertyInfo(Variant::REAL, "stream/volume_db", PROPERTY_HINT_RANGE,"-80,24,0.01"), _SCS("set_volume_db"), _SCS("get_volume_db") );
ADD_PROPERTY( PropertyInfo(Variant::BOOL, "stream/autoplay"), _SCS("set_autoplay"), _SCS("has_autoplay") );
ADD_PROPERTY( PropertyInfo(Variant::BOOL, "stream/paused"), _SCS("set_paused"), _SCS("is_paused") );
- ADD_PROPERTY( PropertyInfo( Variant::BOOL, "expand" ), _SCS("set_expand"),_SCS("has_expand") );
+ ADD_PROPERTY( PropertyInfo(Variant::INT, "stream/audio_track",PROPERTY_HINT_RANGE,"0,128,1"), _SCS("set_audio_track"), _SCS("get_audio_track") );
+ ADD_PROPERTY( PropertyInfo( Variant::BOOL, "expand" ), _SCS("set_expand"),_SCS("has_expand") );
}
@@ -257,6 +400,16 @@ VideoPlayer::VideoPlayer() {
autoplay = false;
expand = true;
loops = false;
+
+ audio_track=0;
+
+ buffering_ms=500;
+ server_mix_rate=44100;
+
+ internal_stream.player=this;
+ stream_rid=AudioServer::get_singleton()->audio_stream_create(&internal_stream);
+ last_audio_time=0;
+
};
VideoPlayer::~VideoPlayer() {
diff --git a/scene/gui/video_player.h b/scene/gui/video_player.h
index 2b850ca509..c485e3d6b6 100644
--- a/scene/gui/video_player.h
+++ b/scene/gui/video_player.h
@@ -31,22 +31,50 @@
#include "scene/resources/video_stream.h"
#include "scene/gui/control.h"
+#include "servers/audio/audio_rb_resampler.h"
class VideoPlayer : public Control {
OBJ_TYPE(VideoPlayer,Control);
+ struct InternalStream : public AudioServer::AudioStream {
+ VideoPlayer *player;
+ virtual int get_channel_count() const;
+ virtual void set_mix_rate(int p_rate); //notify the stream of the mix rate
+ virtual bool mix(int32_t *p_buffer,int p_frames);
+ virtual void update();
+ };
+
+
+ InternalStream internal_stream;
+ 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);
+ void sp_update();
+
+
RID stream_rid;
Ref<ImageTexture> texture;
Image last_frame;
+ AudioRBResampler resampler;
+
bool paused;
bool autoplay;
float volume;
+ double last_audio_time;
bool expand;
bool loops;
+ int buffering_ms;
+ int server_mix_rate;
+ int audio_track;
+
+ static int _audio_mix_callback(void* p_udata,const int16_t *p_data,int p_frames);
+
protected:
@@ -82,6 +110,12 @@ public:
void set_autoplay(bool p_vol);
bool has_autoplay() const;
+ void set_audio_track(int p_track);
+ int get_audio_track() const;
+
+ void set_buffering_msec(int p_msec);
+ int get_buffering_msec() const;
+
VideoPlayer();
~VideoPlayer();
};
diff --git a/scene/io/resource_format_wav.cpp b/scene/io/resource_format_wav.cpp
index 090348c933..00b800b28b 100644
--- a/scene/io/resource_format_wav.cpp
+++ b/scene/io/resource_format_wav.cpp
@@ -252,6 +252,7 @@ RES ResourceFormatLoaderWAV::load(const String &p_path, const String& p_original
if (r_error)
*r_error=OK;
+
return sample;
}
diff --git a/scene/resources/packed_scene.h b/scene/resources/packed_scene.h
index 6c7fa545d4..0546addd3e 100644
--- a/scene/resources/packed_scene.h
+++ b/scene/resources/packed_scene.h
@@ -32,6 +32,15 @@
#include "resource.h"
#include "scene/main/node.h"
+//changes:
+//1-make the InstanceState a reference inside the resource that can be shared
+//2-make the instance "editable" with a flag, save here and load here, no need for property
+//3-properly save modifications in sub-scene
+//4-add scene inheritance
+//5-chain of instance states in editor? (to check what was modified)
+//6-saving will be hell
+
+
class PackedScene : public Resource {
OBJ_TYPE( PackedScene, Resource );
diff --git a/scene/resources/video_stream.cpp b/scene/resources/video_stream.cpp
index b27413bb68..c957fd4c67 100644
--- a/scene/resources/video_stream.cpp
+++ b/scene/resources/video_stream.cpp
@@ -28,16 +28,12 @@
/*************************************************************************/
#include "video_stream.h"
-void VideoStream::_bind_methods() {
+void VideoStreamPlayback::_bind_methods() {
- ObjectTypeDB::bind_method(_MD("get_pending_frame_count"),&VideoStream::get_pending_frame_count);
- ObjectTypeDB::bind_method(_MD("pop_frame"),&VideoStream::pop_frame);
- ObjectTypeDB::bind_method(_MD("peek_frame"),&VideoStream::peek_frame);
- ObjectTypeDB::bind_method(_MD("set_audio_track","idx"),&VideoStream::set_audio_track);
};
-VideoStream::VideoStream() {
+VideoStreamPlayback::VideoStreamPlayback() {
};
diff --git a/scene/resources/video_stream.h b/scene/resources/video_stream.h
index 2ad7457ec4..a23ef0c64f 100644
--- a/scene/resources/video_stream.h
+++ b/scene/resources/video_stream.h
@@ -33,15 +33,17 @@
#include "scene/resources/texture.h"
-class VideoStream : public Resource {
+class VideoStreamPlayback : public Resource {
- OBJ_TYPE(VideoStream,Resource);
+ OBJ_TYPE(VideoStreamPlayback,Resource);
protected:
static void _bind_methods();
public:
+ typedef int (*AudioMixCallback)(void* p_udata,const int16_t *p_data,int p_frames);
+
virtual void stop()=0;
virtual void play()=0;
@@ -58,16 +60,34 @@ public:
virtual float get_pos() const=0;
virtual void seek_pos(float p_time)=0;
- virtual int get_pending_frame_count() const=0;
- virtual void pop_frame(Ref<ImageTexture> p_tex)=0;
- virtual Image peek_frame() const=0;
-
virtual void set_audio_track(int p_idx) =0;
- virtual void update(float p_time)=0;
+ //virtual int mix(int16_t* p_bufer,int p_frames)=0;
+
+ virtual Ref<Texture> get_texture()=0;
+ virtual void update(float p_delta)=0;
- VideoStream();
+ virtual void set_mix_callback(AudioMixCallback p_callback,void *p_userdata)=0;
+ virtual int get_channels() const=0;
+ virtual int get_mix_rate() const=0;
+
+ VideoStreamPlayback();
};
+
+class VideoStream : public Resource {
+
+ OBJ_TYPE( VideoStream, Resource );
+ OBJ_SAVE_TYPE( VideoStream ); //children are all saved as AudioStream, so they can be exchanged
+
+public:
+
+ virtual void set_audio_track(int p_track)=0;
+ virtual Ref<VideoStreamPlayback> instance_playback()=0;
+
+ VideoStream() {}
+};
+
+
#endif