diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/io/resource_format_binary.cpp | 10 | ||||
-rw-r--r-- | core/io/resource_format_xml.cpp | 5 | ||||
-rw-r--r-- | core/list.h | 56 | ||||
-rw-r--r-- | core/math/camera_matrix.cpp | 19 | ||||
-rw-r--r-- | core/math/math_2d.h | 162 | ||||
-rw-r--r-- | core/object.cpp | 8 | ||||
-rw-r--r-- | core/object.h | 1 | ||||
-rw-r--r-- | core/variant_call.cpp | 4 | ||||
-rw-r--r-- | core/variant_op.cpp | 3 |
9 files changed, 261 insertions, 7 deletions
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index e2371fe24f..ead6984650 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -1778,6 +1778,11 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_ f->store_32(VERSION_MINOR); f->store_32(FORMAT_VERSION); + if (f->get_error()!=OK && f->get_error()!=ERR_FILE_EOF) { + f->close(); + return ERR_CANT_CREATE; + } + //f->store_32(saved_resources.size()+external_resources.size()); // load steps -not needed save_unicode_string(p_resource->get_type()); uint64_t md_at = f->get_pos(); @@ -1910,6 +1915,11 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_ f->store_buffer((const uint8_t*)"RSRC",4); //magic at end + if (f->get_error()!=OK && f->get_error()!=ERR_FILE_EOF) { + f->close(); + return ERR_CANT_CREATE; + } + f->close(); diff --git a/core/io/resource_format_xml.cpp b/core/io/resource_format_xml.cpp index 75384d4ab6..033b4d5e5a 100644 --- a/core/io/resource_format_xml.cpp +++ b/core/io/resource_format_xml.cpp @@ -2592,6 +2592,11 @@ Error ResourceFormatSaverXMLInstance::save(const String &p_path,const RES& p_res } exit_tag("resource_file"); + if (f->get_error()!=OK && f->get_error()!=ERR_FILE_EOF) { + f->close(); + return ERR_CANT_CREATE; + } + f->close(); //memdelete(f); diff --git a/core/list.h b/core/list.h index f581feb735..ef30e43d21 100644 --- a/core/list.h +++ b/core/list.h @@ -30,7 +30,7 @@ #define GLOBALS_LIST_H #include "os/memory.h" - +#include "sort.h" /** * Generic Templatized Linked List Implementation. @@ -551,7 +551,7 @@ public: } template<class C> - void sort_custom() { + void sort_custom_inplace() { if(size()<2) return; @@ -603,6 +603,58 @@ public: _data->last=to; } + template<class C> + struct AuxiliaryComparator { + + C compare; + _FORCE_INLINE_ bool operator()(const Element *a,const Element* b) const { + + return compare(a->value,b->value); + } + }; + + template<class C> + void sort_custom() { + + //this version uses auxiliary memory for speed. + //if you don't want to use auxiliary memory, use the in_place version + + int s = size(); + if(s<2) + return; + + + Element **aux_buffer = memnew_arr(Element*,s); + + int idx=0; + for(Element *E=front();E;E=E->next_ptr) { + + aux_buffer[idx]=E; + idx++; + } + + SortArray<Element*,AuxiliaryComparator<C> > sort; + sort.sort(aux_buffer,s); + + _data->first=aux_buffer[0]; + aux_buffer[0]->prev_ptr=NULL; + aux_buffer[0]->next_ptr=aux_buffer[1]; + + _data->last=aux_buffer[s-1]; + aux_buffer[s-1]->prev_ptr=aux_buffer[s-2]; + aux_buffer[s-1]->next_ptr=NULL; + + for(int i=1;i<s-1;i++) { + + aux_buffer[i]->prev_ptr=aux_buffer[i-1]; + aux_buffer[i]->next_ptr=aux_buffer[i+1]; + + } + + memdelete_arr(aux_buffer); + } + + /** * copy constructor for the list */ diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp index a60dea7379..fbe5f8c741 100644 --- a/core/math/camera_matrix.cpp +++ b/core/math/camera_matrix.cpp @@ -121,7 +121,7 @@ void CameraMatrix::set_orthogonal(float p_size, float p_aspect, float p_znear, f void CameraMatrix::set_frustum(float p_left, float p_right, float p_bottom, float p_top, float p_near, float p_far) { - +#if 0 ///@TODO, give a check to this. I'm not sure if it's working. set_identity(); @@ -133,10 +133,27 @@ void CameraMatrix::set_frustum(float p_left, float p_right, float p_bottom, floa matrix[2][3]=-(2*p_far*p_near) / (p_far-p_near); matrix[3][2]=-1; matrix[3][3]=0; +#else + float *te = &matrix[0][0]; + float x = 2 * p_near / ( p_right - p_left ); + float y = 2 * p_near / ( p_top - p_bottom ); + + float a = ( p_right + p_left ) / ( p_right - p_left ); + float b = ( p_top + p_bottom ) / ( p_top - p_bottom ); + float c = - ( p_far + p_near ) / ( p_far - p_near ); + float d = - 2 * p_far * p_near / ( p_far - p_near ); + + te[0] = x; te[4] = 0; te[8] = a; te[12] = 0; + te[1] = 0; te[5] = y; te[9] = b; te[13] = 0; + te[2] = 0; te[6] = 0; te[10] = c; te[14] = d; + te[3] = 0; te[7] = 0; te[11] = - 1; te[15] = 0; + +#endif } + float CameraMatrix::get_z_far() const { const float * matrix = (const float*)this->matrix; diff --git a/core/math/math_2d.h b/core/math/math_2d.h index fa40d305f5..5bc1b5f0be 100644 --- a/core/math/math_2d.h +++ b/core/math/math_2d.h @@ -159,8 +159,8 @@ struct Vector2 { operator String() const { return String::num(x)+","+String::num(y); } - inline Vector2(float p_x,float p_y) { x=p_x; y=p_y; } - inline Vector2() { x=0; y=0; } + _FORCE_INLINE_ Vector2(float p_x,float p_y) { x=p_x; y=p_y; } + _FORCE_INLINE_ Vector2() { x=0; y=0; } }; _FORCE_INLINE_ Vector2 Vector2::plane_project(real_t p_d, const Vector2& p_vec) const { @@ -198,6 +198,8 @@ Vector2 Vector2::linear_interpolate(const Vector2& p_a, const Vector2& p_b,float typedef Vector2 Size2; typedef Vector2 Point2; +struct Matrix32; + struct Rect2 { @@ -224,6 +226,8 @@ struct Rect2 { return true; } + _FORCE_INLINE_ bool intersects_transformed(const Matrix32& p_xform, const Rect2& p_rect) const; + bool intersects_segment(const Point2& p_from, const Point2& p_to, Point2* r_pos=NULL, Point2* r_normal=NULL) const; inline bool encloses(const Rect2& p_rect) const { @@ -597,6 +601,160 @@ struct Matrix32 { }; +bool Rect2::intersects_transformed(const Matrix32& p_xform, const Rect2& p_rect) const { + + //SAT intersection between local and transformed rect2 + + Vector2 xf_points[4]={ + p_xform.xform(p_rect.pos), + p_xform.xform(Vector2(p_rect.pos.x+p_rect.size.x,p_rect.pos.y)), + p_xform.xform(Vector2(p_rect.pos.x,p_rect.pos.y+p_rect.size.y)), + p_xform.xform(Vector2(p_rect.pos.x+p_rect.size.x,p_rect.pos.y+p_rect.size.y)), + }; + + real_t low_limit; + + //base rect2 first (faster) + + if (xf_points[0].y>pos.y) + goto next1; + if (xf_points[1].y>pos.y) + goto next1; + if (xf_points[2].y>pos.y) + goto next1; + if (xf_points[3].y>pos.y) + goto next1; + + return false; + + next1: + + low_limit=pos.y+size.y; + + if (xf_points[0].y<low_limit) + goto next2; + if (xf_points[1].y<low_limit) + goto next2; + if (xf_points[2].y<low_limit) + goto next2; + if (xf_points[3].y<low_limit) + goto next2; + + return false; + + next2: + + if (xf_points[0].x>pos.x) + goto next3; + if (xf_points[1].x>pos.x) + goto next3; + if (xf_points[2].x>pos.x) + goto next3; + if (xf_points[3].x>pos.x) + goto next3; + + return false; + + next3: + + low_limit=pos.x+size.x; + + if (xf_points[0].x<low_limit) + goto next4; + if (xf_points[1].x<low_limit) + goto next4; + if (xf_points[2].x<low_limit) + goto next4; + if (xf_points[3].x<low_limit) + goto next4; + + return false; + + next4: + + Vector2 xf_points2[4]={ + pos, + Vector2(pos.x+size.x,pos.y), + Vector2(pos.x,pos.y+size.y), + Vector2(pos.x+size.x,pos.y+size.y), + }; + + real_t maxa=p_xform.elements[0].dot(xf_points2[0]); + real_t mina=maxa; + + real_t dp = p_xform.elements[0].dot(xf_points2[1]); + maxa=MAX(dp,maxa); + mina=MIN(dp,mina); + + dp = p_xform.elements[0].dot(xf_points2[2]); + maxa=MAX(dp,maxa); + mina=MIN(dp,mina); + + dp = p_xform.elements[0].dot(xf_points2[3]); + maxa=MAX(dp,maxa); + mina=MIN(dp,mina); + + real_t maxb=p_xform.elements[0].dot(xf_points[0]); + real_t minb=maxb; + + dp = p_xform.elements[0].dot(xf_points[1]); + maxb=MAX(dp,maxb); + minb=MIN(dp,minb); + + dp = p_xform.elements[0].dot(xf_points[2]); + maxb=MAX(dp,maxb); + minb=MIN(dp,minb); + + dp = p_xform.elements[0].dot(xf_points[3]); + maxb=MAX(dp,maxb); + minb=MIN(dp,minb); + + + if ( mina > maxb ) + return false; + if ( minb > maxa ) + return false; + + maxa=p_xform.elements[1].dot(xf_points2[0]); + mina=maxa; + + dp = p_xform.elements[1].dot(xf_points2[1]); + maxa=MAX(dp,maxa); + mina=MIN(dp,mina); + + dp = p_xform.elements[1].dot(xf_points2[2]); + maxa=MAX(dp,maxa); + mina=MIN(dp,mina); + + dp = p_xform.elements[1].dot(xf_points2[3]); + maxa=MAX(dp,maxa); + mina=MIN(dp,mina); + + maxb=p_xform.elements[1].dot(xf_points[0]); + minb=maxb; + + dp = p_xform.elements[1].dot(xf_points[1]); + maxb=MAX(dp,maxb); + minb=MIN(dp,minb); + + dp = p_xform.elements[1].dot(xf_points[2]); + maxb=MAX(dp,maxb); + minb=MIN(dp,minb); + + dp = p_xform.elements[1].dot(xf_points[3]); + maxb=MAX(dp,maxb); + minb=MIN(dp,minb); + + + if ( mina > maxb ) + return false; + if ( minb > maxa ) + return false; + + + return true; + +} Vector2 Matrix32::basis_xform(const Vector2& v) const { diff --git a/core/object.cpp b/core/object.cpp index 82144ab4be..2b83f728d1 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -1033,6 +1033,13 @@ void Object::add_user_signal(const MethodInfo& p_signal) { signal_map[p_signal.name]=s; } +bool Object::_has_user_signal(const StringName& p_name) const { + + if (!signal_map.has(p_name)) + return false; + return signal_map[p_name].user.name.length()>0; +} + struct _ObjectSignalDisconnectData { StringName signal; @@ -1431,6 +1438,7 @@ void Object::_bind_methods() { // ObjectTypeDB::bind_method(_MD("call_deferred","method","arg1","arg2","arg3","arg4"),&Object::_call_deferred_bind,DEFVAL(Variant()),DEFVAL(Variant()),DEFVAL(Variant()),DEFVAL(Variant())); ObjectTypeDB::bind_method(_MD("add_user_signal","signal","arguments"),&Object::_add_user_signal,DEFVAL(Array())); + ObjectTypeDB::bind_method(_MD("has_user_signal","signal"),&Object::_has_user_signal); // ObjectTypeDB::bind_method(_MD("emit_signal","signal","arguments"),&Object::_emit_signal,DEFVAL(Array())); diff --git a/core/object.h b/core/object.h index 97ca50cb1a..eb885f5d20 100644 --- a/core/object.h +++ b/core/object.h @@ -386,6 +386,7 @@ friend void postinitialize_handler(Object*); Dictionary metadata; void _add_user_signal(const String& p_name, const Array& p_pargs=Array()); + bool _has_user_signal(const StringName& p_name) const; Variant _emit_signal(const Variant** p_args, int p_argcount, Variant::CallError& r_error); Array _get_signal_list() const; Array _get_signal_connection_list(const String& p_signal) const; diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 3f2800494d..50a60390e5 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -1263,8 +1263,8 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl ADDFUNC1(VECTOR2,VECTOR2,Vector2,snapped,VECTOR2,"by",varray()); ADDFUNC0(VECTOR2,REAL,Vector2,get_aspect,varray()); ADDFUNC1(VECTOR2,REAL,Vector2,dot,VECTOR2,"with",varray()); - ADDFUNC1(VECTOR2,REAL,Vector2,slide,VECTOR2,"vec",varray()); - ADDFUNC1(VECTOR2,REAL,Vector2,reflect,VECTOR2,"vec",varray()); + ADDFUNC1(VECTOR2,VECTOR2,Vector2,slide,VECTOR2,"vec",varray()); + ADDFUNC1(VECTOR2,VECTOR2,Vector2,reflect,VECTOR2,"vec",varray()); //ADDFUNC1(VECTOR2,REAL,Vector2,cross,VECTOR2,"with",varray()); ADDFUNC0(RECT2,REAL,Rect2,get_area,varray()); diff --git a/core/variant_op.cpp b/core/variant_op.cpp index 21bbc8c7ee..d6129e150c 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -552,6 +552,9 @@ void Variant::evaluate(const Operator& p_op, const Variant& p_a, const Variant& if (p_b.type==MATRIX32) { _RETURN( *p_a._data._matrix32 * *p_b._data._matrix32 ); }; + if (p_b.type==VECTOR2) { + _RETURN( p_a._data._matrix32->xform( *(const Vector2*)p_b._data._mem) ); + }; r_valid=false; return; } break; |