diff options
65 files changed, 605 insertions, 94 deletions
diff --git a/core/error_macros.h b/core/error_macros.h index 76da88287b..cc88686301 100644 --- a/core/error_macros.h +++ b/core/error_macros.h @@ -207,6 +207,11 @@ extern bool _err_error_exists; _err_error_exists=false;\ } \ +#define ERR_PRINTS(m_string) \ + { \ + _err_print_error(FUNCTION_STR,__FILE__,__LINE__,String(m_string).utf8().get_data()); \ + _err_error_exists=false;\ + } \ /** Print a warning string. */ diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 1a0552e8d1..4cd3cd595f 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -905,7 +905,7 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) { error=ERR_FILE_UNRECOGNIZED; ERR_EXPLAIN("Unrecognized binary resource file: "+local_path); - ERR_FAIL_V(); + ERR_FAIL(); } bool big_endian = f->get_32(); diff --git a/core/object.cpp b/core/object.cpp index 3a4c06e7e7..96f0c86832 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -314,6 +314,7 @@ void Object::set(const StringName& p_name, const Variant& p_value, bool *r_valid _edited=true; #endif + if (script_instance) { if (script_instance->set(p_name,p_value)) { @@ -326,9 +327,9 @@ void Object::set(const StringName& p_name, const Variant& p_value, bool *r_valid //try built-in setgetter { - if (ObjectTypeDB::set_property(this,p_name,p_value)) { - if (r_valid) - *r_valid=true; + if (ObjectTypeDB::set_property(this,p_name,p_value,r_valid)) { + //if (r_valid) + // *r_valid=true; return; } } @@ -1694,6 +1695,26 @@ void Object::get_translatable_strings(List<String> *p_strings) const { } +Variant::Type Object::get_static_property_type(const StringName& p_property, bool *r_valid) const { + + bool valid; + Variant::Type t = ObjectTypeDB::get_property_type(get_type_name(),p_property,&valid); + if (valid) { + if (r_valid) + *r_valid=true; + return t; + } + + if (get_script_instance()) { + return get_script_instance()->get_property_type(p_property,r_valid); + } + if (r_valid) + *r_valid=false; + + return Variant::NIL; + +} + bool Object::is_queued_for_deletion() const { return _is_queued_for_deletion; } diff --git a/core/object.h b/core/object.h index 981a83958c..5b6361796f 100644 --- a/core/object.h +++ b/core/object.h @@ -606,6 +606,8 @@ public: void set_block_signals(bool p_block); bool is_blocking_signals() const; + Variant::Type get_static_property_type(const StringName& p_property,bool *r_valid=NULL) const; + virtual void get_translatable_strings(List<String> *p_strings) const; virtual void get_argument_options(const StringName& p_function,int p_idx,List<String>*r_options) const; diff --git a/core/object_type_db.cpp b/core/object_type_db.cpp index a64b3d2715..f8ba0a9b15 100644 --- a/core/object_type_db.cpp +++ b/core/object_type_db.cpp @@ -612,6 +612,7 @@ void ObjectTypeDB::add_property(StringName p_type,const PropertyInfo& p_pinfo, c psg._setptr=mb_set; psg._getptr=mb_get; psg.index=p_index; + psg.type=p_pinfo.type; type->property_setget[p_pinfo.name]=psg; @@ -634,7 +635,7 @@ void ObjectTypeDB::get_property_list(StringName p_type,List<PropertyInfo> *p_lis } } -bool ObjectTypeDB::set_property(Object* p_object,const StringName& p_property, const Variant& p_value) { +bool ObjectTypeDB::set_property(Object* p_object,const StringName& p_property, const Variant& p_value,bool *r_valid) { TypeInfo *type=types.getptr(p_object->get_type_name()); @@ -643,13 +644,17 @@ bool ObjectTypeDB::set_property(Object* p_object,const StringName& p_property, c const PropertySetGet *psg = check->property_setget.getptr(p_property); if (psg) { - if (!psg->setter) + if (!psg->setter) { + if (r_valid) + *r_valid=false; return true; //return true but do nothing + } + + Variant::CallError ce; if (psg->index>=0) { Variant index=psg->index; const Variant* arg[2]={&index,&p_value}; - Variant::CallError ce; // p_object->call(psg->setter,arg,2,ce); if (psg->_setptr) { psg->_setptr->call(p_object,arg,2,ce); @@ -660,13 +665,16 @@ bool ObjectTypeDB::set_property(Object* p_object,const StringName& p_property, c } else { const Variant* arg[1]={&p_value}; - Variant::CallError ce; if (psg->_setptr) { psg->_setptr->call(p_object,arg,1,ce); } else { p_object->call(psg->setter,arg,1,ce); } } + + if (r_valid) + *r_valid=ce.error==Variant::CallError::CALL_OK; + return true; } @@ -718,6 +726,29 @@ bool ObjectTypeDB::get_property(Object* p_object,const StringName& p_property, V return false; } +Variant::Type ObjectTypeDB::get_property_type(const StringName& p_type, const StringName& p_property,bool *r_is_valid) { + + TypeInfo *type=types.getptr(p_type); + TypeInfo *check=type; + while(check) { + const PropertySetGet *psg = check->property_setget.getptr(p_property); + if (psg) { + + if (r_is_valid) + *r_is_valid=true; + + return psg->type; + } + + check=check->inherits_ptr; + } + if (r_is_valid) + *r_is_valid=false; + + return Variant::NIL; + +} + void ObjectTypeDB::set_method_flags(StringName p_type,StringName p_method,int p_flags) { diff --git a/core/object_type_db.h b/core/object_type_db.h index bfa0f921e5..319e3ec02c 100644 --- a/core/object_type_db.h +++ b/core/object_type_db.h @@ -117,6 +117,7 @@ class ObjectTypeDB { StringName getter; MethodBind *_setptr; MethodBind *_getptr; + Variant::Type type; }; struct TypeInfo { @@ -456,8 +457,9 @@ public: static void add_property(StringName p_type,const PropertyInfo& p_pinfo, const StringName& p_setter, const StringName& p_getter, int p_index=-1); static void get_property_list(StringName p_type,List<PropertyInfo> *p_list,bool p_no_inheritance=false); - static bool set_property(Object* p_object,const StringName& p_property, const Variant& p_value); + static bool set_property(Object* p_object, const StringName& p_property, const Variant& p_value, bool *r_valid=NULL); static bool get_property(Object* p_object,const StringName& p_property, Variant& r_value); + static Variant::Type get_property_type(const StringName& p_type, const StringName& p_property,bool *r_is_valid=NULL); diff --git a/core/ring_buffer.h b/core/ring_buffer.h index 3cf9cf9064..5cbd261ec8 100644 --- a/core/ring_buffer.h +++ b/core/ring_buffer.h @@ -155,6 +155,12 @@ public: inline int size() { return data.size(); }; + + inline void clear() { + read_pos = 0; + write_pos = 0; + + } void resize(int p_power) { int old_size = size(); diff --git a/core/script_language.cpp b/core/script_language.cpp index 35c50b1022..b7a0f579f4 100644 --- a/core/script_language.cpp +++ b/core/script_language.cpp @@ -267,6 +267,20 @@ void PlaceHolderScriptInstance::get_property_list(List<PropertyInfo> *p_properti } } +Variant::Type PlaceHolderScriptInstance::get_property_type(const StringName& p_name,bool *r_is_valid) const { + + if (values.has(p_name)) { + if (r_is_valid) + *r_is_valid=true; + return values[p_name].get_type(); + } + if (r_is_valid) + *r_is_valid=false; + + return Variant::NIL; +} + + void PlaceHolderScriptInstance::update(const List<PropertyInfo> &p_properties,const Map<StringName,Variant>& p_values) { diff --git a/core/script_language.h b/core/script_language.h index 5a0f673b94..9660f141c7 100644 --- a/core/script_language.h +++ b/core/script_language.h @@ -82,6 +82,7 @@ public: virtual StringName get_instance_base_type() const=0; // this may not work in all scripts, will return empty if so virtual ScriptInstance* instance_create(Object *p_this)=0; virtual bool instance_has(const Object *p_this) const=0; + virtual bool has_source_code() const=0; virtual String get_source_code() const=0; @@ -109,6 +110,7 @@ public: virtual bool set(const StringName& p_name, const Variant& p_value)=0; virtual bool get(const StringName& p_name, Variant &r_ret) const=0; virtual void get_property_list(List<PropertyInfo> *p_properties) const=0; + virtual Variant::Type get_property_type(const StringName& p_name,bool *r_is_valid=NULL) const=0; virtual void get_method_list(List<MethodInfo> *p_list) const=0; virtual bool has_method(const StringName& p_method) const=0; @@ -208,6 +210,7 @@ public: virtual bool set(const StringName& p_name, const Variant& p_value); virtual bool get(const StringName& p_name, Variant &r_ret) const; virtual void get_property_list(List<PropertyInfo> *p_properties) const; + virtual Variant::Type get_property_type(const StringName& p_name,bool *r_is_valid=NULL) const; virtual void get_method_list(List<MethodInfo> *p_list) const {} virtual bool has_method(const StringName& p_method) const { return false; } diff --git a/core/variant.h b/core/variant.h index 8fd9662c36..e75a2b1c92 100644 --- a/core/variant.h +++ b/core/variant.h @@ -390,7 +390,7 @@ public: Variant call(const StringName& p_method,const Variant** p_args,int p_argcount,CallError &r_error); Variant call(const StringName& p_method,const Variant& p_arg1=Variant(),const Variant& p_arg2=Variant(),const Variant& p_arg3=Variant(),const Variant& p_arg4=Variant(),const Variant& p_arg5=Variant()); - static Variant construct(const Variant::Type,const Variant** p_args,int p_argcount,CallError &r_error); + static Variant construct(const Variant::Type,const Variant** p_args,int p_argcount,CallError &r_error,bool p_strict=true); void get_method_list(List<MethodInfo> *p_list) const; bool has_method(const StringName& p_method) const; diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 48c38f05f9..2d10cf4d44 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -858,6 +858,11 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var r_ret=Transform(p_args[0]->operator Matrix3(),p_args[1]->operator Vector3()); } + static void Image_init1(Variant& r_ret, const Variant** p_args) { + + r_ret=Image(*p_args[0],*p_args[1],*p_args[2],Image::Format(p_args[3]->operator int())); + } + static void add_constructor(VariantConstructFunc p_func,const Variant::Type p_type, const String& p_name1="", const Variant::Type p_type1=Variant::NIL, const String& p_name2="", const Variant::Type p_type2=Variant::NIL, @@ -959,7 +964,7 @@ Variant Variant::call(const StringName& p_method,const Variant** p_args,int p_ar #define VCALL(m_type,m_method) _VariantCall::_call_##m_type##_##m_method -Variant Variant::construct(const Variant::Type p_type,const Variant** p_args,int p_argcount,CallError &r_error) { +Variant Variant::construct(const Variant::Type p_type, const Variant** p_args, int p_argcount, CallError &r_error, bool p_strict) { r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; ERR_FAIL_INDEX_V(p_type,VARIANT_MAX,Variant()); @@ -1035,7 +1040,7 @@ Variant Variant::construct(const Variant::Type p_type,const Variant** p_args,int } else if (p_argcount==1 && p_args[0]->type==p_type) { return *p_args[0]; //copy construct - } else if (p_argcount==1 && Variant::can_convert(p_args[0]->type,p_type)) { + } else if (p_argcount==1 && (!p_strict || Variant::can_convert(p_args[0]->type,p_type))) { //near match construct switch(p_type) { @@ -1583,6 +1588,8 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl _VariantCall::add_constructor(_VariantCall::Transform_init1,Variant::TRANSFORM,"x_axis",Variant::VECTOR3,"y_axis",Variant::VECTOR3,"z_axis",Variant::VECTOR3,"origin",Variant::VECTOR3); _VariantCall::add_constructor(_VariantCall::Transform_init2,Variant::TRANSFORM,"basis",Variant::MATRIX3,"origin",Variant::VECTOR3); + _VariantCall::add_constructor(_VariantCall::Image_init1,Variant::IMAGE,"width",Variant::INT,"height",Variant::INT,"mipmaps",Variant::BOOL,"format",Variant::INT); + /* REGISTER CONSTANTS */ _VariantCall::constant_data[Variant::VECTOR3].value["AXIS_X"]=Vector3::AXIS_X; diff --git a/doc/base/classes.xml b/doc/base/classes.xml index fd5df945ba..ab1320908e 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -13147,6 +13147,21 @@ returns:= "username=user&password=pass" <description> </description> </method> + <method name="Image"> + <return type="Image"> + </return> + <argument index="0" name="width" type="int"> + </argument> + <argument index="1" name="height" type="int"> + </argument> + <argument index="2" name="mipmaps" type="bool"> + </argument> + <argument index="3" name="format" type="int"> + </argument> + <description> + Create an empty image of a specific size and format. + </description> + </method> </methods> <constants> <constant name="COMPRESS_BC" value="0"> diff --git a/drivers/theora/video_stream_theora.cpp b/drivers/theora/video_stream_theora.cpp index f301bd7515..fe248bc911 100644 --- a/drivers/theora/video_stream_theora.cpp +++ b/drivers/theora/video_stream_theora.cpp @@ -7,11 +7,34 @@ int VideoStreamPlaybackTheora:: buffer_data() { - char *buffer=ogg_sync_buffer(&oy,4096); - int bytes=file->get_buffer((uint8_t*)buffer, 4096); - ogg_sync_wrote(&oy,bytes); - return(bytes); + char *buffer=ogg_sync_buffer(&oy,4096); + +#ifdef THEORA_USE_THREAD_STREAMING + + int read; + + do { + thread_sem->post(); + read = MIN(ring_buffer.data_left(),4096); + if (read) { + ring_buffer.read((uint8_t*)buffer,read); + ogg_sync_wrote(&oy,read); + } else { + OS::get_singleton()->delay_usec(100); + } + + } while(read==0); + + return read; + +#else + + int bytes=file->get_buffer((uint8_t*)buffer, 4096); + ogg_sync_wrote(&oy,bytes); + return(bytes); + +#endif } int VideoStreamPlaybackTheora::queue_page(ogg_page *page){ @@ -200,6 +223,14 @@ void VideoStreamPlaybackTheora::clear() { } ogg_sync_clear(&oy); +#ifdef THEORA_USE_THREAD_STREAMING + thread_exit=true; + thread_sem->post(); //just in case + Thread::wait_to_finish(thread); + memdelete(thread); + thread=NULL; + ring_buffer.clear(); +#endif //file_name = ""; theora_p = 0; @@ -217,6 +248,7 @@ void VideoStreamPlaybackTheora::clear() { void VideoStreamPlaybackTheora::set_file(const String& p_file) { + ERR_FAIL_COND(playing); ogg_packet op; th_setup_info *ts = NULL; @@ -227,7 +259,17 @@ void VideoStreamPlaybackTheora::set_file(const String& p_file) { file = FileAccess::open(p_file, FileAccess::READ); ERR_FAIL_COND(!file); +#ifdef THEORA_USE_THREAD_STREAMING + thread_exit=false; + thread_eof=false; + //pre-fill buffer + int to_read = ring_buffer.space_left(); + int read = file->get_buffer(read_buffer.ptr(),to_read); + ring_buffer.write(read_buffer.ptr(),read); + thread=Thread::create(_streaming_thread,this); + +#endif ogg_sync_init(&oy); @@ -369,6 +411,7 @@ void VideoStreamPlaybackTheora::set_file(const String& p_file) { th_decode_ctl(td,TH_DECCTL_GET_PPLEVEL_MAX,&pp_level_max, sizeof(pp_level_max)); pp_level=pp_level_max; + pp_level=0; th_decode_ctl(td,TH_DECCTL_SET_PPLEVEL,&pp_level,sizeof(pp_level)); pp_inc=0; @@ -415,6 +458,8 @@ void VideoStreamPlaybackTheora::set_file(const String& p_file) { buffering=true; time=0; audio_frames_wrote=0; + + }; float VideoStreamPlaybackTheora::get_time() const { @@ -436,13 +481,16 @@ void VideoStreamPlaybackTheora::update(float p_delta) { return; }; +#ifdef THEORA_USE_THREAD_STREAMING + thread_sem->post(); +#endif + //double ctime =AudioServer::get_singleton()->get_mix_time(); //print_line("play "+rtos(p_delta)); time+=p_delta; if (videobuf_time>get_time()) { - return; //no new frames need to be produced } @@ -573,21 +621,22 @@ void VideoStreamPlaybackTheora::update(float p_delta) { if(videobuf_time>=get_time()) { frame_done=true; - print_line("frame!"); } else{ /*If we are too slow, reduce the pp level.*/ pp_inc=pp_level>0?-1:0; - print_line("skip!"); } } } else { - print_line("no packet.."); + break; } } - +#ifdef THEORA_USE_THREAD_STREAMING + if (file && thread_eof && ring_buffer.data_left()==0) { +#else if (file && /*!videobuf_ready && */ file->eof_reached()) { +#endif printf("video done, stopping\n"); stop(); return; @@ -633,6 +682,7 @@ void VideoStreamPlaybackTheora::update(float p_delta) { else if(tdiff<ti.fps_denominator*0.05/ti.fps_numerator){ pp_inc=pp_level>0?-1:0; } + } video_write(); @@ -644,15 +694,21 @@ void VideoStreamPlaybackTheora::play() { if (!playing) time=0; + else { + stop(); + } + playing = true; delay_compensation=Globals::get_singleton()->get("audio/video_delay_compensation_ms"); delay_compensation/=1000.0; + }; void VideoStreamPlaybackTheora::stop() { if (playing) { + clear(); set_file(file_name); //reset } @@ -730,7 +786,33 @@ int VideoStreamPlaybackTheora::get_mix_rate() const{ return vi.rate; } +#ifdef THEORA_USE_THREAD_STREAMING + + +void VideoStreamPlaybackTheora::_streaming_thread(void *ud) { + + VideoStreamPlaybackTheora *vs=(VideoStreamPlaybackTheora*)ud; + + while(!vs->thread_exit) { + + //just fill back the buffer + if (!vs->thread_eof) { + + int to_read = vs->ring_buffer.space_left(); + if (to_read) { + int read = vs->file->get_buffer(vs->read_buffer.ptr(),to_read); + vs->ring_buffer.write(vs->read_buffer.ptr(),read); + vs->thread_eof=vs->file->eof_reached(); + } + + + } + + vs->thread_sem->wait(); + } +} +#endif VideoStreamPlaybackTheora::VideoStreamPlaybackTheora() { @@ -749,14 +831,31 @@ VideoStreamPlaybackTheora::VideoStreamPlaybackTheora() { audio_track=0; delay_compensation=0; audio_frames_wrote=0; + +#ifdef THEORA_USE_THREAD_STREAMING + int rb_power = nearest_shift(RB_SIZE_KB*1024); + ring_buffer.resize(rb_power); + read_buffer.resize(RB_SIZE_KB*1024); + thread_sem=Semaphore::create(); + thread=NULL; + thread_exit=false; + thread_eof=false; + +#endif }; VideoStreamPlaybackTheora::~VideoStreamPlaybackTheora() { +#ifdef THEORA_USE_THREAD_STREAMING + + memdelete(thread_sem); +#endif clear(); if (file) memdelete(file); + + }; diff --git a/drivers/theora/video_stream_theora.h b/drivers/theora/video_stream_theora.h index 5540f050f9..c15ef31cfc 100644 --- a/drivers/theora/video_stream_theora.h +++ b/drivers/theora/video_stream_theora.h @@ -6,9 +6,13 @@ #include "theora/theoradec.h" #include "vorbis/codec.h" #include "os/file_access.h" - +#include "ring_buffer.h" #include "io/resource_loader.h" #include "scene/resources/video_stream.h" +#include "os/thread.h" +#include "os/semaphore.h" + +//#define THEORA_USE_THREAD_STREAMING class VideoStreamPlaybackTheora : public VideoStreamPlayback { @@ -66,7 +70,25 @@ class VideoStreamPlaybackTheora : public VideoStreamPlayback { AudioMixCallback mix_callback; void* mix_udata; - int audio_track; +#ifdef THEORA_USE_THREAD_STREAMING + + enum { + RB_SIZE_KB=1024 + }; + + RingBuffer<uint8_t> ring_buffer; + Vector<uint8_t> read_buffer; + bool thread_eof; + Semaphore *thread_sem; + Thread *thread; + volatile bool thread_exit; + + static void _streaming_thread(void *ud); + +#endif + + + int audio_track; protected: @@ -116,20 +138,20 @@ class VideoStreamTheora : public VideoStream { OBJ_TYPE(VideoStreamTheora,VideoStream); String file; - int audio_track; + int audio_track; public: Ref<VideoStreamPlayback> instance_playback() { Ref<VideoStreamPlaybackTheora> pb = memnew( VideoStreamPlaybackTheora ); - pb->set_audio_track(audio_track); + pb->set_audio_track(audio_track); pb->set_file(file); return pb; } void set_file(const String& p_file) { file=p_file; } - void set_audio_track(int p_track) { audio_track=p_track; } + void set_audio_track(int p_track) { audio_track=p_track; } VideoStreamTheora() { audio_track=0; } diff --git a/drivers/webp/dec/alpha.c b/drivers/webp/dec/alpha.c index 52216fc4d6..1d029b0e6a 100644 --- a/drivers/webp/dec/alpha.c +++ b/drivers/webp/dec/alpha.c @@ -18,7 +18,7 @@ #include "../dsp/dsp.h" #include "../utils/quant_levels_dec.h" #include "../utils/utils.h" -#include "../webp/format_constants.h" +#include "webp/format_constants.h" //------------------------------------------------------------------------------ // ALPHDecoder object. diff --git a/drivers/webp/dec/decode_vp8.h b/drivers/webp/dec/decode_vp8.h index b9337bbec0..2bf1bdbbf5 100644 --- a/drivers/webp/dec/decode_vp8.h +++ b/drivers/webp/dec/decode_vp8.h @@ -14,7 +14,7 @@ #ifndef WEBP_WEBP_DECODE_VP8_H_ #define WEBP_WEBP_DECODE_VP8_H_ -#include "../webp/decode.h" +#include "webp/decode.h" #ifdef __cplusplus extern "C" { diff --git a/drivers/webp/dec/webp.c b/drivers/webp/dec/webp.c index 952178fa89..93a113a48d 100644 --- a/drivers/webp/dec/webp.c +++ b/drivers/webp/dec/webp.c @@ -17,7 +17,7 @@ #include "./vp8li.h" #include "./webpi.h" #include "../utils/utils.h" -#include "../webp/mux_types.h" // ALPHA_FLAG +#include "webp/mux_types.h" // ALPHA_FLAG //------------------------------------------------------------------------------ // RIFF layout is: diff --git a/drivers/webp/demux/anim_decode.c b/drivers/webp/demux/anim_decode.c index adf84cd193..c81cedfba0 100644 --- a/drivers/webp/demux/anim_decode.c +++ b/drivers/webp/demux/anim_decode.c @@ -11,15 +11,15 @@ // #ifdef HAVE_CONFIG_H -#include "../webp/config.h" +#include "webp/config.h" #endif #include <assert.h> #include <string.h> #include "../utils/utils.h" -#include "../webp/decode.h" -#include "../webp/demux.h" +#include "webp/decode.h" +#include "webp/demux.h" #define NUM_CHANNELS 4 diff --git a/drivers/webp/demux/demux.c b/drivers/webp/demux/demux.c index e8e5418efe..3717e21165 100644 --- a/drivers/webp/demux/demux.c +++ b/drivers/webp/demux/demux.c @@ -11,7 +11,7 @@ // #ifdef HAVE_CONFIG_H -#include "../webp/config.h" +#include "webp/config.h" #endif #include <assert.h> @@ -19,9 +19,9 @@ #include <string.h> #include "../utils/utils.h" -#include "../webp/decode.h" // WebPGetFeatures -#include "../webp/demux.h" -#include "../webp/format_constants.h" +#include "webp/decode.h" // WebPGetFeatures +#include "webp/demux.h" +#include "webp/format_constants.h" #define DMUX_MAJ_VERSION 0 #define DMUX_MIN_VERSION 2 diff --git a/drivers/webp/dsp/dsp.h b/drivers/webp/dsp/dsp.h index 8395df40e4..4613d9c3ff 100644 --- a/drivers/webp/dsp/dsp.h +++ b/drivers/webp/dsp/dsp.h @@ -15,10 +15,10 @@ #define WEBP_DSP_DSP_H_ #ifdef HAVE_CONFIG_H -#include "../webp/config.h" +#include "webp/config.h" #endif -#include "../webp/types.h" +#include "webp/types.h" #ifdef __cplusplus extern "C" { diff --git a/drivers/webp/dsp/lossless.h b/drivers/webp/dsp/lossless.h index ee6771333f..149c6a01d3 100644 --- a/drivers/webp/dsp/lossless.h +++ b/drivers/webp/dsp/lossless.h @@ -15,8 +15,8 @@ #ifndef WEBP_DSP_LOSSLESS_H_ #define WEBP_DSP_LOSSLESS_H_ -#include "../webp/types.h" -#include "../webp/decode.h" +#include "webp/types.h" +#include "webp/decode.h" #include "../enc/histogram.h" #include "../utils/utils.h" diff --git a/drivers/webp/enc/alpha.c b/drivers/webp/enc/alpha.c index fad6346e43..1842b36401 100644 --- a/drivers/webp/enc/alpha.c +++ b/drivers/webp/enc/alpha.c @@ -19,7 +19,7 @@ #include "../utils/filters.h" #include "../utils/quant_levels.h" #include "../utils/utils.h" -#include "../webp/format_constants.h" +#include "webp/format_constants.h" // ----------------------------------------------------------------------------- // Encodes the given alpha data via specified compression method 'method'. diff --git a/drivers/webp/enc/backward_references.h b/drivers/webp/enc/backward_references.h index daa084d846..e410b06f7d 100644 --- a/drivers/webp/enc/backward_references.h +++ b/drivers/webp/enc/backward_references.h @@ -15,8 +15,8 @@ #include <assert.h> #include <stdlib.h> -#include "../webp/types.h" -#include "../webp/format_constants.h" +#include "webp/types.h" +#include "webp/format_constants.h" #ifdef __cplusplus extern "C" { diff --git a/drivers/webp/enc/config.c b/drivers/webp/enc/config.c index f9f7961d58..8fd2276cb5 100644 --- a/drivers/webp/enc/config.c +++ b/drivers/webp/enc/config.c @@ -11,7 +11,7 @@ // // Author: Skal (pascal.massimino@gmail.com) -#include "../webp/encode.h" +#include "webp/encode.h" //------------------------------------------------------------------------------ // WebPConfig diff --git a/drivers/webp/enc/delta_palettization.c b/drivers/webp/enc/delta_palettization.c index 062e588d79..8bd3a3d233 100644 --- a/drivers/webp/enc/delta_palettization.c +++ b/drivers/webp/enc/delta_palettization.c @@ -13,7 +13,7 @@ #include "./delta_palettization.h" #ifdef WEBP_EXPERIMENTAL_FEATURES -#include "../webp/types.h" +#include "webp/types.h" #include "../dsp/lossless.h" #define MK_COL(r, g, b) (((r) << 16) + ((g) << 8) + (b)) diff --git a/drivers/webp/enc/delta_palettization.h b/drivers/webp/enc/delta_palettization.h index e41c0c5ab5..54195d452c 100644 --- a/drivers/webp/enc/delta_palettization.h +++ b/drivers/webp/enc/delta_palettization.h @@ -13,7 +13,7 @@ #ifndef WEBP_ENC_DELTA_PALETTIZATION_H_ #define WEBP_ENC_DELTA_PALETTIZATION_H_ -#include "../webp/encode.h" +#include "webp/encode.h" #include "../enc/vp8li.h" // Replaces enc->argb_[] input by a palettizable approximation of it, diff --git a/drivers/webp/enc/frame.c b/drivers/webp/enc/frame.c index 5b7a40b9ad..65a98ada4d 100644 --- a/drivers/webp/enc/frame.c +++ b/drivers/webp/enc/frame.c @@ -17,7 +17,7 @@ #include "./cost.h" #include "./vp8enci.h" #include "../dsp/dsp.h" -#include "../webp/format_constants.h" // RIFF constants +#include "webp/format_constants.h" // RIFF constants #define SEGMENT_VISU 0 #define DEBUG_SEARCH 0 // useful to track search convergence diff --git a/drivers/webp/enc/histogram.c b/drivers/webp/enc/histogram.c index 62c320d809..68c27fb1db 100644 --- a/drivers/webp/enc/histogram.c +++ b/drivers/webp/enc/histogram.c @@ -10,7 +10,7 @@ // Author: Jyrki Alakuijala (jyrki@google.com) // #ifdef HAVE_CONFIG_H -#include "../webp/config.h" +#include "webp/config.h" #endif #include <math.h> diff --git a/drivers/webp/enc/histogram.h b/drivers/webp/enc/histogram.h index adb16c01ca..72f045793a 100644 --- a/drivers/webp/enc/histogram.h +++ b/drivers/webp/enc/histogram.h @@ -17,8 +17,8 @@ #include <string.h> #include "./backward_references.h" -#include "../webp/format_constants.h" -#include "../webp/types.h" +#include "webp/format_constants.h" +#include "webp/types.h" #ifdef __cplusplus extern "C" { diff --git a/drivers/webp/enc/syntax.c b/drivers/webp/enc/syntax.c index a0e79ef404..2b65f15ca1 100644 --- a/drivers/webp/enc/syntax.c +++ b/drivers/webp/enc/syntax.c @@ -14,8 +14,8 @@ #include <assert.h> #include "../utils/utils.h" -#include "../webp/format_constants.h" // RIFF constants -#include "../webp/mux_types.h" // ALPHA_FLAG +#include "webp/format_constants.h" // RIFF constants +#include "webp/mux_types.h" // ALPHA_FLAG #include "./vp8enci.h" //------------------------------------------------------------------------------ diff --git a/drivers/webp/enc/vp8enci.h b/drivers/webp/enc/vp8enci.h index 1a7ebe5703..0cb2ccc353 100644 --- a/drivers/webp/enc/vp8enci.h +++ b/drivers/webp/enc/vp8enci.h @@ -20,7 +20,7 @@ #include "../utils/bit_writer.h" #include "../utils/thread.h" #include "../utils/utils.h" -#include "../webp/encode.h" +#include "webp/encode.h" #ifdef WEBP_EXPERIMENTAL_FEATURES #include "./vp8li.h" diff --git a/drivers/webp/enc/vp8l.c b/drivers/webp/enc/vp8l.c index 047c9032ac..284995e830 100644 --- a/drivers/webp/enc/vp8l.c +++ b/drivers/webp/enc/vp8l.c @@ -22,7 +22,7 @@ #include "../utils/bit_writer.h" #include "../utils/huffman_encode.h" #include "../utils/utils.h" -#include "../webp/format_constants.h" +#include "webp/format_constants.h" #include "./delta_palettization.h" diff --git a/drivers/webp/enc/vp8li.h b/drivers/webp/enc/vp8li.h index 6b6db127db..4543c3b260 100644 --- a/drivers/webp/enc/vp8li.h +++ b/drivers/webp/enc/vp8li.h @@ -17,8 +17,8 @@ #include "./backward_references.h" #include "./histogram.h" #include "../utils/bit_writer.h" -#include "../webp/encode.h" -#include "../webp/format_constants.h" +#include "webp/encode.h" +#include "webp/format_constants.h" #ifdef __cplusplus extern "C" { diff --git a/drivers/webp/mux/anim_encode.c b/drivers/webp/mux/anim_encode.c index fa86eaac94..bb7c0f50b9 100644 --- a/drivers/webp/mux/anim_encode.c +++ b/drivers/webp/mux/anim_encode.c @@ -15,10 +15,10 @@ #include <stdio.h> #include "../utils/utils.h" -#include "../webp/decode.h" -#include "../webp/encode.h" -#include "../webp/format_constants.h" -#include "../webp/mux.h" +#include "webp/decode.h" +#include "webp/encode.h" +#include "webp/format_constants.h" +#include "webp/mux.h" #if defined(_MSC_VER) && _MSC_VER < 1900 #define snprintf _snprintf diff --git a/drivers/webp/mux/muxi.h b/drivers/webp/mux/muxi.h index 718b2f5d58..8bd5291661 100644 --- a/drivers/webp/mux/muxi.h +++ b/drivers/webp/mux/muxi.h @@ -17,7 +17,7 @@ #include <stdlib.h> #include "../dec/vp8i.h" #include "../dec/vp8li.h" -#include "../webp/mux.h" +#include "webp/mux.h" #ifdef __cplusplus extern "C" { diff --git a/drivers/webp/utils/bit_reader.c b/drivers/webp/utils/bit_reader.c index cd265321bb..5081d5cd4d 100644 --- a/drivers/webp/utils/bit_reader.c +++ b/drivers/webp/utils/bit_reader.c @@ -12,7 +12,7 @@ // Author: Skal (pascal.massimino@gmail.com) #ifdef HAVE_CONFIG_H -#include "../webp/config.h" +#include "webp/config.h" #endif #include "./bit_reader_inl.h" diff --git a/drivers/webp/utils/bit_reader.h b/drivers/webp/utils/bit_reader.h index 0fc62d33b7..7e09653ebc 100644 --- a/drivers/webp/utils/bit_reader.h +++ b/drivers/webp/utils/bit_reader.h @@ -19,7 +19,7 @@ #ifdef _MSC_VER #include <stdlib.h> // _byteswap_ulong #endif -#include "../webp/types.h" +#include "webp/types.h" #ifdef __cplusplus extern "C" { diff --git a/drivers/webp/utils/bit_reader_inl.h b/drivers/webp/utils/bit_reader_inl.h index 37215702d4..20ce5f3cc7 100644 --- a/drivers/webp/utils/bit_reader_inl.h +++ b/drivers/webp/utils/bit_reader_inl.h @@ -17,7 +17,7 @@ #define WEBP_UTILS_BIT_READER_INL_H_ #ifdef HAVE_CONFIG_H -#include "../webp/config.h" +#include "webp/config.h" #endif #ifdef WEBP_FORCE_ALIGNED diff --git a/drivers/webp/utils/bit_writer.h b/drivers/webp/utils/bit_writer.h index ef360d1dc6..867a5ee055 100644 --- a/drivers/webp/utils/bit_writer.h +++ b/drivers/webp/utils/bit_writer.h @@ -14,7 +14,7 @@ #ifndef WEBP_UTILS_BIT_WRITER_H_ #define WEBP_UTILS_BIT_WRITER_H_ -#include "../webp/types.h" +#include "webp/types.h" #ifdef __cplusplus extern "C" { diff --git a/drivers/webp/utils/color_cache.h b/drivers/webp/utils/color_cache.h index a9a9f64270..34299e4c4e 100644 --- a/drivers/webp/utils/color_cache.h +++ b/drivers/webp/utils/color_cache.h @@ -15,7 +15,7 @@ #ifndef WEBP_UTILS_COLOR_CACHE_H_ #define WEBP_UTILS_COLOR_CACHE_H_ -#include "../webp/types.h" +#include "webp/types.h" #ifdef __cplusplus extern "C" { diff --git a/drivers/webp/utils/endian_inl.h b/drivers/webp/utils/endian_inl.h index e11260ff7d..253b7be8ee 100644 --- a/drivers/webp/utils/endian_inl.h +++ b/drivers/webp/utils/endian_inl.h @@ -13,11 +13,11 @@ #define WEBP_UTILS_ENDIAN_INL_H_ #ifdef HAVE_CONFIG_H -#include "../webp/config.h" +#include "webp/config.h" #endif #include "../dsp/dsp.h" -#include "../webp/types.h" +#include "webp/types.h" // some endian fix (e.g.: mips-gcc doesn't define __BIG_ENDIAN__) #if !defined(WORDS_BIGENDIAN) && \ diff --git a/drivers/webp/utils/filters.h b/drivers/webp/utils/filters.h index 088b132fc5..4aba3fd3b7 100644 --- a/drivers/webp/utils/filters.h +++ b/drivers/webp/utils/filters.h @@ -14,7 +14,7 @@ #ifndef WEBP_UTILS_FILTERS_H_ #define WEBP_UTILS_FILTERS_H_ -#include "../webp/types.h" +#include "webp/types.h" #include "../dsp/dsp.h" #ifdef __cplusplus diff --git a/drivers/webp/utils/huffman.c b/drivers/webp/utils/huffman.c index d57376aa6b..e6f482a6a8 100644 --- a/drivers/webp/utils/huffman.c +++ b/drivers/webp/utils/huffman.c @@ -16,7 +16,7 @@ #include <string.h> #include "./huffman.h" #include "../utils/utils.h" -#include "../webp/format_constants.h" +#include "webp/format_constants.h" // Huffman data read via DecodeImageStream is represented in two (red and green) // bytes. diff --git a/drivers/webp/utils/huffman.h b/drivers/webp/utils/huffman.h index c6dd6aaa45..a8cc0da1c3 100644 --- a/drivers/webp/utils/huffman.h +++ b/drivers/webp/utils/huffman.h @@ -15,8 +15,8 @@ #define WEBP_UTILS_HUFFMAN_H_ #include <assert.h> -#include "../webp/format_constants.h" -#include "../webp/types.h" +#include "webp/format_constants.h" +#include "webp/types.h" #ifdef __cplusplus extern "C" { diff --git a/drivers/webp/utils/huffman_encode.c b/drivers/webp/utils/huffman_encode.c index 6421c2beed..d7aad6f56d 100644 --- a/drivers/webp/utils/huffman_encode.c +++ b/drivers/webp/utils/huffman_encode.c @@ -16,7 +16,7 @@ #include <string.h> #include "./huffman_encode.h" #include "../utils/utils.h" -#include "../webp/format_constants.h" +#include "webp/format_constants.h" // ----------------------------------------------------------------------------- // Util function to optimize the symbol map for RLE coding diff --git a/drivers/webp/utils/huffman_encode.h b/drivers/webp/utils/huffman_encode.h index a157165148..93610066f3 100644 --- a/drivers/webp/utils/huffman_encode.h +++ b/drivers/webp/utils/huffman_encode.h @@ -14,7 +14,7 @@ #ifndef WEBP_UTILS_HUFFMAN_ENCODE_H_ #define WEBP_UTILS_HUFFMAN_ENCODE_H_ -#include "../webp/types.h" +#include "webp/types.h" #ifdef __cplusplus extern "C" { diff --git a/drivers/webp/utils/quant_levels.h b/drivers/webp/utils/quant_levels.h index 1cb5a32cae..3916b977ab 100644 --- a/drivers/webp/utils/quant_levels.h +++ b/drivers/webp/utils/quant_levels.h @@ -16,7 +16,7 @@ #include <stdlib.h> -#include "../webp/types.h" +#include "webp/types.h" #ifdef __cplusplus extern "C" { diff --git a/drivers/webp/utils/quant_levels_dec.h b/drivers/webp/utils/quant_levels_dec.h index 9aab068076..29c7e6e205 100644 --- a/drivers/webp/utils/quant_levels_dec.h +++ b/drivers/webp/utils/quant_levels_dec.h @@ -14,7 +14,7 @@ #ifndef WEBP_UTILS_QUANT_LEVELS_DEC_H_ #define WEBP_UTILS_QUANT_LEVELS_DEC_H_ -#include "../webp/types.h" +#include "webp/types.h" #ifdef __cplusplus extern "C" { diff --git a/drivers/webp/utils/random.h b/drivers/webp/utils/random.h index c392a615ca..745f3e2e87 100644 --- a/drivers/webp/utils/random.h +++ b/drivers/webp/utils/random.h @@ -15,7 +15,7 @@ #define WEBP_UTILS_RANDOM_H_ #include <assert.h> -#include "../webp/types.h" +#include "webp/types.h" #ifdef __cplusplus extern "C" { diff --git a/drivers/webp/utils/rescaler.h b/drivers/webp/utils/rescaler.h index 98b01a76d0..868467b4d7 100644 --- a/drivers/webp/utils/rescaler.h +++ b/drivers/webp/utils/rescaler.h @@ -18,7 +18,7 @@ extern "C" { #endif -#include "../webp/types.h" +#include "webp/types.h" #define WEBP_RESCALER_RFIX 32 // fixed-point precision for multiplies #define WEBP_RESCALER_ONE (1ull << WEBP_RESCALER_RFIX) diff --git a/drivers/webp/utils/thread.h b/drivers/webp/utils/thread.h index 8408311855..6008bb7c01 100644 --- a/drivers/webp/utils/thread.h +++ b/drivers/webp/utils/thread.h @@ -15,10 +15,10 @@ #define WEBP_UTILS_THREAD_H_ #ifdef HAVE_CONFIG_H -#include "../webp/config.h" +#include "webp/config.h" #endif -#include "../webp/types.h" +#include "webp/types.h" #ifdef __cplusplus extern "C" { diff --git a/drivers/webp/utils/utils.c b/drivers/webp/utils/utils.c index d8e30930af..35aeae6ab8 100644 --- a/drivers/webp/utils/utils.c +++ b/drivers/webp/utils/utils.c @@ -13,8 +13,8 @@ #include <stdlib.h> #include <string.h> // for memcpy() -#include "../webp/decode.h" -#include "../webp/encode.h" +#include "webp/decode.h" +#include "webp/encode.h" #include "./utils.h" // If PRINT_MEM_INFO is defined, extra info (like total memory used, number of diff --git a/drivers/webp/utils/utils.h b/drivers/webp/utils/utils.h index fcdb7e139b..d0e1cb250a 100644 --- a/drivers/webp/utils/utils.h +++ b/drivers/webp/utils/utils.h @@ -17,7 +17,7 @@ #include <assert.h> -#include "../webp/types.h" +#include "webp/types.h" #ifdef __cplusplus extern "C" { diff --git a/modules/gdscript/gd_script.cpp b/modules/gdscript/gd_script.cpp index 8746f92c9e..c3cc779bce 100644 --- a/modules/gdscript/gd_script.cpp +++ b/modules/gdscript/gd_script.cpp @@ -2274,6 +2274,26 @@ bool GDInstance::get(const StringName& p_name, Variant &r_ret) const { return false; } + +Variant::Type GDInstance::get_property_type(const StringName& p_name,bool *r_is_valid) const { + + + const GDScript *sptr=script.ptr(); + while(sptr) { + + if (sptr->member_info.has(p_name)) { + if (r_is_valid) + *r_is_valid=true; + return sptr->member_info[p_name].type; + } + sptr = sptr->_base; + } + + if (r_is_valid) + *r_is_valid=false; + return Variant::NIL; +} + void GDInstance::get_property_list(List<PropertyInfo> *p_properties) const { // exported members, not doen yet! diff --git a/modules/gdscript/gd_script.h b/modules/gdscript/gd_script.h index 850ffec05f..3d16b59065 100644 --- a/modules/gdscript/gd_script.h +++ b/modules/gdscript/gd_script.h @@ -373,6 +373,8 @@ public: virtual bool set(const StringName& p_name, const Variant& p_value); virtual bool get(const StringName& p_name, Variant &r_ret) const; virtual void get_property_list(List<PropertyInfo> *p_properties) const; + virtual Variant::Type get_property_type(const StringName& p_name,bool *r_is_valid=NULL) const; + virtual void get_method_list(List<MethodInfo> *p_list) const; virtual bool has_method(const StringName& p_method) const; diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 4ec4b054db..3193a2acbb 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -170,7 +170,6 @@ def get_flags(): return [ ('freetype','builtin'), #use builtin freetype ('openssl','builtin'), #use builtin openssl - ('theora','no'), ] def build_res_file( target, source, env ): diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index c2ea1c8bb6..b040e59d16 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -268,6 +268,7 @@ void AnimationPlayer::_generate_node_caches(AnimationData* p_anim) { TrackNodeCacheKey key; key.id=id; key.bone_idx=bone_idx; + if (node_cache_map.has(key)) { @@ -278,6 +279,7 @@ void AnimationPlayer::_generate_node_caches(AnimationData* p_anim) { node_cache_map[key]=TrackNodeCache(); p_anim->node_cache[i]=&node_cache_map[key]; + p_anim->node_cache[i]->path=a->track_get_path(i); p_anim->node_cache[i]->node=child; p_anim->node_cache[i]->resource=resource; p_anim->node_cache[i]->node_2d=child->cast_to<Node2D>(); @@ -320,6 +322,7 @@ void AnimationPlayer::_generate_node_caches(AnimationData* p_anim) { pa.prop=property; pa.object=resource.is_valid()?(Object*)resource.ptr():(Object*)child; pa.special=SP_NONE; + pa.owner=p_anim->node_cache[i]; if (false && p_anim->node_cache[i]->node_2d) { if (pa.prop==SceneStringNames::get_singleton()->transform_pos) @@ -410,7 +413,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData* p_anim,float p TrackNodeCache::PropertyAnim *pa = &E->get(); - if (a->value_track_is_continuous(i) || p_delta==0) { + if (a->value_track_is_continuous(i) || p_delta==0) { //delta == 0 means seek Variant value=a->value_track_interpolate(i,p_time); @@ -436,10 +439,42 @@ void AnimationPlayer::_animation_process_animation(AnimationData* p_anim,float p Variant value=a->track_get_key_value(i,F->get()); switch(pa->special) { - case SP_NONE: pa->object->set(pa->prop,value); break; //you are not speshul - case SP_NODE2D_POS: static_cast<Node2D*>(pa->object)->set_pos(value); break; - case SP_NODE2D_ROT: static_cast<Node2D*>(pa->object)->set_rot(Math::deg2rad(value)); break; - case SP_NODE2D_SCALE: static_cast<Node2D*>(pa->object)->set_scale(value); break; + case SP_NONE: { + bool valid; + pa->object->set(pa->prop,value,&valid); //you are not speshul +#ifdef DEBUG_ENABLED + if (!valid) { + ERR_PRINTS("Failed setting track value '"+String(pa->owner->path)+"'. Check if property exists or the type of key is valid"); + } +#endif + + } break; + case SP_NODE2D_POS: { +#ifdef DEBUG_ENABLED + if (value.get_type()!=Variant::VECTOR2) { + ERR_PRINTS("Position key at time "+rtos(p_time)+" in Animation Track '"+String(pa->owner->path)+"' not of type Vector2()"); + } +#endif + static_cast<Node2D*>(pa->object)->set_pos(value); + } break; + case SP_NODE2D_ROT: { +#ifdef DEBUG_ENABLED + if (value.is_num()) { + ERR_PRINTS("Rotation key at time "+rtos(p_time)+" in Animation Track '"+String(pa->owner->path)+"' not numerical"); + } +#endif + + static_cast<Node2D*>(pa->object)->set_rot(Math::deg2rad(value)); + } break; + case SP_NODE2D_SCALE: { +#ifdef DEBUG_ENABLED + if (value.get_type()!=Variant::VECTOR2) { + ERR_PRINTS("Scale key at time "+rtos(p_time)+" in Animation Track '"+String(pa->owner->path)+"' not of type Vector2()"); + } +#endif + + static_cast<Node2D*>(pa->object)->set_scale(value); + } break; } } @@ -607,13 +642,53 @@ void AnimationPlayer::_animation_update_transforms() { ERR_CONTINUE( pa->accum_pass!=accum_pass ); #if 1 - switch(pa->special) { +/* switch(pa->special) { case SP_NONE: pa->object->set(pa->prop,pa->value_accum); break; //you are not speshul case SP_NODE2D_POS: static_cast<Node2D*>(pa->object)->set_pos(pa->value_accum); break; case SP_NODE2D_ROT: static_cast<Node2D*>(pa->object)->set_rot(Math::deg2rad(pa->value_accum)); break; case SP_NODE2D_SCALE: static_cast<Node2D*>(pa->object)->set_scale(pa->value_accum); break; + }*/ + + switch(pa->special) { + + case SP_NONE: { + bool valid; + pa->object->set(pa->prop,pa->value_accum,&valid); //you are not speshul +#ifdef DEBUG_ENABLED + if (!valid) { + ERR_PRINTS("Failed setting key at time "+rtos(playback.current.pos)+" in Animation '"+get_current_animation()+"', Track '"+String(pa->owner->path)+"'. Check if property exists or the type of key is right for the property"); + } +#endif + + } break; + case SP_NODE2D_POS: { +#ifdef DEBUG_ENABLED + if (pa->value_accum.get_type()!=Variant::VECTOR2) { + ERR_PRINTS("Position key at time "+rtos(playback.current.pos)+" in Animation '"+get_current_animation()+"', Track '"+String(pa->owner->path)+"' not of type Vector2()"); + } +#endif + static_cast<Node2D*>(pa->object)->set_pos(pa->value_accum); + } break; + case SP_NODE2D_ROT: { +#ifdef DEBUG_ENABLED + if (pa->value_accum.is_num()) { + ERR_PRINTS("Rotation key at time "+rtos(playback.current.pos)+" in Animation '"+get_current_animation()+"', Track '"+String(pa->owner->path)+"' not numerical"); + } +#endif + + static_cast<Node2D*>(pa->object)->set_rot(Math::deg2rad(pa->value_accum)); + } break; + case SP_NODE2D_SCALE: { +#ifdef DEBUG_ENABLED + if (pa->value_accum.get_type()!=Variant::VECTOR2) { + ERR_PRINTS("Scale key at time "+rtos(playback.current.pos)+" in Animation '"+get_current_animation()+"', Track '"+String(pa->owner->path)+"' not of type Vector2()"); + } +#endif + + static_cast<Node2D*>(pa->object)->set_scale(pa->value_accum); + } break; } #else diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h index 1e3c37c4d6..18cedee796 100644 --- a/scene/animation/animation_player.h +++ b/scene/animation/animation_player.h @@ -68,6 +68,7 @@ private: struct TrackNodeCache { + NodePath path; uint32_t id; RES resource; Node *node; @@ -84,6 +85,7 @@ private: struct PropertyAnim { + TrackNodeCache *owner; SpecialProperty special; //small optimization StringName prop; Object *object; diff --git a/tools/editor/animation_editor.cpp b/tools/editor/animation_editor.cpp index ace6fda696..4ccb612a39 100644 --- a/tools/editor/animation_editor.cpp +++ b/tools/editor/animation_editor.cpp @@ -34,6 +34,7 @@ #include "pair.h" #include "scene/gui/separator.h" #include "editor_node.h" +#include "tools/editor/plugins/animation_player_editor_plugin.h" /* Missing to fix: *Set @@ -903,6 +904,23 @@ void AnimationKeyEditor::_menu_track(int p_type) { optimize_dialog->popup_centered(Size2(250,180)); } break; + case TRACK_MENU_CLEAN_UP: { + + cleanup_dialog->popup_centered_minsize(Size2(300,0)); + } break; + case TRACK_MENU_CLEAN_UP_CONFIRM: { + + if (cleanup_all->is_pressed()) { + List<StringName> names; + AnimationPlayerEditor::singleton->get_player()->get_animation_list(&names); + for (List<StringName>::Element *E=names.front();E;E=E->next()) { + _cleanup_animation(AnimationPlayerEditor::singleton->get_player()->get_animation(E->get())); + } + } else { + _cleanup_animation(animation); + + } + } break; case CURVE_SET_LINEAR: { curve_edit->force_transition(1.0); @@ -933,6 +951,57 @@ void AnimationKeyEditor::_menu_track(int p_type) { } +void AnimationKeyEditor::_cleanup_animation(Ref<Animation> p_animation) { + + + for(int i=0;i<p_animation->get_track_count();i++) { + + bool prop_exists=false; + Variant::Type valid_type=Variant::NIL; + Object *obj=NULL; + + RES res; + Node *node = root->get_node_and_resource(animation->track_get_path(i),res); + + if (res.is_valid()) { + obj=res.ptr(); + } else if (node) { + obj=node; + } + + if (obj && animation->track_get_type(i)==Animation::TYPE_VALUE) { + valid_type=obj->get_static_property_type(animation->track_get_path(i).get_property(),&prop_exists); + } + + if (!obj && cleanup_tracks->is_pressed()) { + + animation->remove_track(i); + i--; + continue; + } + + if (!prop_exists || animation->track_get_type(i)!=Animation::TYPE_VALUE || cleanup_keys->is_pressed()==false) + continue; + + for(int j=0;j<animation->track_get_key_count(i);j++) { + + Variant v = animation->track_get_key_value(i,j); + + if (!Variant::can_convert(v.get_type(),valid_type)) { + animation->track_remove_key(i,j); + j--; + } + } + + if (animation->track_get_key_count(i)==0 && cleanup_tracks->is_pressed()) { + animation->remove_track(i); + i--; + } + } + + undo_redo->clear_history(); + _update_paths(); +} void AnimationKeyEditor::_animation_optimize() { @@ -1042,6 +1111,7 @@ void AnimationKeyEditor::_track_editor_draw() { timecolor = Color::html("ff4a414f"); Color hover_color = Color(1,1,1,0.05); Color select_color = Color(1,1,1,0.1); + Color invalid_path_color = Color(1,0.6,0.4,0.5); Color track_select_color =Color::html("ffbd8e8e"); Ref<Texture> remove_icon = get_icon("Remove","EditorIcons"); @@ -1068,6 +1138,9 @@ void AnimationKeyEditor::_track_editor_draw() { get_icon("KeyCall","EditorIcons") }; + Ref<Texture> invalid_icon = get_icon("KeyInvalid","EditorIcons"); + Ref<Texture> invalid_icon_hover = get_icon("KeyInvalidHover","EditorIcons"); + Ref<Texture> hsize_icon = get_icon("Hsize","EditorIcons"); Ref<Texture> type_hover=get_icon("KeyHover","EditorIcons"); @@ -1254,6 +1327,23 @@ void AnimationKeyEditor::_track_editor_draw() { break; int y = h+i*h+sep; + bool prop_exists=false; + Variant::Type valid_type=Variant::NIL; + Object *obj=NULL; + + RES res; + Node *node = root->get_node_and_resource(animation->track_get_path(idx),res); + + if (res.is_valid()) { + obj=res.ptr(); + } else if (node) { + obj=node; + } + + if (obj && animation->track_get_type(idx)==Animation::TYPE_VALUE) { + valid_type=obj->get_static_property_type(animation->track_get_path(idx).get_property(),&prop_exists); + } + if (/*mouse_over.over!=MouseOver::OVER_NONE &&*/ idx==mouse_over.track) { Color sepc=hover_color; @@ -1274,6 +1364,8 @@ void AnimationKeyEditor::_track_editor_draw() { ncol=track_select_color; te->draw_string(font,Point2(ofs+Point2(type_icon[0]->get_width()+sep,y+font->get_ascent()+(sep/2))).floor(),np,ncol,name_limit-(type_icon[0]->get_width()+sep)-5); + if (!obj) + te->draw_line(ofs+Point2(0,y+h/2),ofs+Point2(name_limit,y+h/2),invalid_path_color); te->draw_line(ofs+Point2(0,y+h),ofs+Point2(size.width,y+h),sepcolor); @@ -1339,6 +1431,8 @@ void AnimationKeyEditor::_track_editor_draw() { int kc=animation->track_get_key_count(idx); bool first=true; + + for(int i=0;i<kc;i++) { @@ -1386,7 +1480,21 @@ void AnimationKeyEditor::_track_editor_draw() { } - te->draw_texture(tex,ofs+Point2(x,y+key_vofs).floor()); + if (prop_exists && !Variant::can_convert(value.get_type(),valid_type)) { + te->draw_texture(invalid_icon,ofs+Point2(x,y+key_vofs).floor()); + } + + if (prop_exists && !Variant::can_convert(value.get_type(),valid_type)) { + if (tex==type_hover) + te->draw_texture(invalid_icon_hover,ofs+Point2(x,y+key_vofs).floor()); + else + te->draw_texture(invalid_icon,ofs+Point2(x,y+key_vofs).floor()); + } else { + + te->draw_texture(tex,ofs+Point2(x,y+key_vofs).floor()); + } + + first=false; } @@ -2555,6 +2663,8 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { String text; text="time: "+rtos(animation->track_get_key_time(idx,mouse_over.over_key))+"\n"; + + switch(animation->track_get_type(idx)) { case Animation::TYPE_TRANSFORM: { @@ -2569,8 +2679,33 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { } break; case Animation::TYPE_VALUE: { - Variant v = animation->track_get_key_value(idx,mouse_over.over_key); - text+="value: "+String(v)+"\n"; + Variant v = animation->track_get_key_value(idx,mouse_over.over_key);; + //text+="value: "+String(v)+"\n"; + + bool prop_exists=false; + Variant::Type valid_type=Variant::NIL; + Object *obj=NULL; + + RES res; + Node *node = root->get_node_and_resource(animation->track_get_path(idx),res); + + if (res.is_valid()) { + obj=res.ptr(); + } else if (node) { + obj=node; + } + + if (obj) { + valid_type=obj->get_static_property_type(animation->track_get_path(idx).get_property(),&prop_exists); + } + + text+="type: "+Variant::get_type_name(v.get_type())+"\n"; + if (prop_exists && !Variant::can_convert(v.get_type(),valid_type)) { + text+="value: "+String(v)+" (Invalid, expected type: "+Variant::get_type_name(valid_type)+")\n"; + } else { + text+="value: "+String(v)+"\n"; + } + } break; case Animation::TYPE_METHOD: { @@ -2593,6 +2728,9 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { } break; } text+="easing: "+rtos(animation->track_get_key_transition(idx,mouse_over.over_key)); + + + track_editor->set_tooltip(text); return; @@ -2703,6 +2841,7 @@ void AnimationKeyEditor::_notification(int p_what) { //menu_track->get_popup()->add_submenu_item("Set Transitions..","Transitions"); //menu_track->get_popup()->add_separator(); menu_track->get_popup()->add_item("Optimize Animation",TRACK_MENU_OPTIMIZE); + menu_track->get_popup()->add_item("Clean-Up Animation",TRACK_MENU_CLEAN_UP); curve_linear->set_icon(get_icon("CurveLinear","EditorIcons")); curve_in->set_icon(get_icon("CurveIn","EditorIcons")); @@ -3862,6 +4001,32 @@ AnimationKeyEditor::AnimationKeyEditor(UndoRedo *p_undo_redo, EditorHistory *p_h add_child(call_select); call_select->set_title("Call Functions in Which Node?"); + cleanup_dialog = memnew( ConfirmationDialog ); + add_child(cleanup_dialog); + VBoxContainer *cleanup_vb = memnew( VBoxContainer ); + cleanup_dialog->add_child(cleanup_vb); + cleanup_dialog->set_child_rect(cleanup_vb); + cleanup_keys = memnew( CheckButton ); + cleanup_keys->set_text("Remove invalid keys"); + cleanup_keys->set_pressed(true); + cleanup_vb->add_child(cleanup_keys); + + cleanup_tracks = memnew( CheckButton ); + cleanup_tracks->set_text("Remove unresolved and empty tracks"); + cleanup_tracks->set_pressed(true); + cleanup_vb->add_child(cleanup_tracks); + + cleanup_all = memnew( CheckButton ); + cleanup_all->set_text("Clean-Up all animations"); + cleanup_vb->add_child(cleanup_all); + + cleanup_dialog->set_title("Clean up Animation(s) (NO UNDO!)"); + cleanup_dialog->get_ok()->set_text("Clean-Up"); + + cleanup_dialog->connect("confirmed",this,"_menu_track",varray(TRACK_MENU_CLEAN_UP_CONFIRM)); + + + } AnimationKeyEditor::~AnimationKeyEditor() { diff --git a/tools/editor/animation_editor.h b/tools/editor/animation_editor.h index 629377d78e..743242fe94 100644 --- a/tools/editor/animation_editor.h +++ b/tools/editor/animation_editor.h @@ -89,6 +89,8 @@ class AnimationKeyEditor : public VBoxContainer { TRACK_MENU_NEXT_STEP, TRACK_MENU_PREV_STEP, TRACK_MENU_OPTIMIZE, + TRACK_MENU_CLEAN_UP, + TRACK_MENU_CLEAN_UP_CONFIRM, CURVE_SET_LINEAR, CURVE_SET_IN, CURVE_SET_OUT, @@ -190,6 +192,11 @@ class AnimationKeyEditor : public VBoxContainer { SpinBox *optimize_angular_error; SpinBox *optimize_max_angle; + ConfirmationDialog *cleanup_dialog; + CheckButton *cleanup_keys; + CheckButton *cleanup_tracks; + CheckButton *cleanup_all; + SpinBox *step; MenuButton *menu_add_track; @@ -284,6 +291,7 @@ class AnimationKeyEditor : public VBoxContainer { void _animation_changed(); void _animation_optimize(); + void _cleanup_animation(Ref<Animation> p_animation); void _scroll_changed(double); diff --git a/tools/editor/icons/icon_key_invalid.png b/tools/editor/icons/icon_key_invalid.png Binary files differnew file mode 100644 index 0000000000..e8e6c87180 --- /dev/null +++ b/tools/editor/icons/icon_key_invalid.png diff --git a/tools/editor/icons/icon_key_invalid_hover.png b/tools/editor/icons/icon_key_invalid_hover.png Binary files differnew file mode 100644 index 0000000000..6f0396d96a --- /dev/null +++ b/tools/editor/icons/icon_key_invalid_hover.png diff --git a/tools/editor/plugins/animation_player_editor_plugin.cpp b/tools/editor/plugins/animation_player_editor_plugin.cpp index 6542fc8b4a..dc2c241d2f 100644 --- a/tools/editor/plugins/animation_player_editor_plugin.cpp +++ b/tools/editor/plugins/animation_player_editor_plugin.cpp @@ -1250,8 +1250,15 @@ void AnimationPlayerEditor::_bind_methods() { } +AnimationPlayerEditor *AnimationPlayerEditor::singleton=NULL; + +AnimationPlayer *AnimationPlayerEditor::get_player() const { + + return player; +} AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor) { editor=p_editor; + singleton=this; updating=false; diff --git a/tools/editor/plugins/animation_player_editor_plugin.h b/tools/editor/plugins/animation_player_editor_plugin.h index ac4d1ab6ba..839df3ddcc 100644 --- a/tools/editor/plugins/animation_player_editor_plugin.h +++ b/tools/editor/plugins/animation_player_editor_plugin.h @@ -162,6 +162,7 @@ class AnimationPlayerEditor : public VBoxContainer { void _animation_tool_menu(int p_option); void _animation_save_menu(int p_option); + AnimationPlayerEditor(); protected: @@ -171,6 +172,9 @@ protected: static void _bind_methods(); public: + AnimationPlayer *get_player() const; + static AnimationPlayerEditor *singleton; + Dictionary get_state() const; void set_state(const Dictionary& p_state); diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp index 956e7a98a2..4e394f9e3f 100644 --- a/tools/editor/plugins/script_editor_plugin.cpp +++ b/tools/editor/plugins/script_editor_plugin.cpp @@ -1137,12 +1137,14 @@ void ScriptEditor::_menu_option(int p_option) { return; int line = tx->cursor_get_line(); int next_line = line + 1; + int column = tx->cursor_get_column(); - if (line == tx->get_line_count() - 1 || next_line >= tx->get_line_count()) + if (line >= tx->get_line_count() - 1) tx->set_line(line, tx->get_line(line) + "\n"); String line_clone = tx->get_line(line); tx->insert_at(line_clone, next_line); + tx->cursor_set_column(column); tx->update(); } break; |