diff options
| author | Juan Linietsky | 2014-10-03 00:10:51 -0300 |
|---|---|---|
| committer | Juan Linietsky | 2014-10-03 00:10:51 -0300 |
| commit | b24fe3dd206ce391ec4c5f68d32fc2259f275563 (patch) | |
| tree | 5d05b14d21ba1c8a484f9b7f3739a63f42ca082d /servers | |
| parent | 870c075ebf67749b21b6cc0c705088bbe273f1bb (diff) | |
| download | godot-b24fe3dd206ce391ec4c5f68d32fc2259f275563.tar.gz godot-b24fe3dd206ce391ec4c5f68d32fc2259f275563.tar.zst godot-b24fe3dd206ce391ec4c5f68d32fc2259f275563.zip | |
Huge Amount of BugFix
-=-=-=-=-=-=-=-=-=-=-
-Fixes to Collada Exporter (avoid crash situtions)
-Fixed to Collada Importer (Fixed Animation Optimizer Bugs)
-Fixes to RigidBody/RigidBody2D body_enter/body_exit, was buggy
-Fixed ability for RigidBody/RigidBody2D to get contacts reported and bodyin/out in Kinematic mode.
-Added proper trigger support for 3D Physics shapes
-Changed proper value for Z-Offset in OmniLight
-Fixed spot attenuation bug in SpotLight
-Fixed some 3D and 2D spatial soudn bugs related to distance attenuation.
-Fixed bugs in EventPlayer (channels were muted by default)
-Fix in ButtonGroup (get nodes in group are now returned in order)
-Fixed Linear->SRGB Conversion, previous algo sucked, new algo works OK
-Changed SRGB->Linear conversion to use hardware if supported, improves texture quality a lot
-Fixed options for Y-Fov and X-Fov in camera, should be more intuitive.
-Fixed bugs related to viewports and transparency
Huge Amount of New Stuff:
-=-=-=-=-=-=-=-==-=-=-=-
-Ability to manually advance an AnimationPlayer that is inactive (with advance() function)
-More work in WinRT platform
-Added XY normalmap support, imports on this format by default. Reduces normlmap size and enables much nice compression using LATC
-Added Anisotropic filter support to textures, can be specified on import
-Added support for Non-Square, Isometric and Hexagonal tilemaps in TileMap.
-Added Isometric Dungeon demo.
-Added simple hexagonal map demo.
-Added Truck-Town demo. Shows how most types of joints and vehicles are used. Please somebody make a nicer town, this one is too hardcore.
-Added an Object-Picking API to both RigidBody and Area! (and relevant demo)
Diffstat (limited to 'servers')
| -rw-r--r-- | servers/physics/area_pair_sw.cpp | 3 | ||||
| -rw-r--r-- | servers/physics/area_sw.cpp | 6 | ||||
| -rw-r--r-- | servers/physics/area_sw.h | 3 | ||||
| -rw-r--r-- | servers/physics/collision_object_sw.cpp | 1 | ||||
| -rw-r--r-- | servers/physics/collision_object_sw.h | 6 | ||||
| -rw-r--r-- | servers/physics/constraint_sw.h | 6 | ||||
| -rw-r--r-- | servers/physics/physics_server_sw.cpp | 31 | ||||
| -rw-r--r-- | servers/physics/physics_server_sw.h | 6 | ||||
| -rw-r--r-- | servers/physics/space_sw.cpp | 5 | ||||
| -rw-r--r-- | servers/physics/step_sw.cpp | 39 | ||||
| -rw-r--r-- | servers/physics_2d/area_2d_sw.cpp | 1 | ||||
| -rw-r--r-- | servers/physics_2d/area_pair_2d_sw.cpp | 2 | ||||
| -rw-r--r-- | servers/physics_server.cpp | 6 | ||||
| -rw-r--r-- | servers/physics_server.h | 6 | ||||
| -rw-r--r-- | servers/register_server_types.cpp | 1 | ||||
| -rw-r--r-- | servers/spatial_sound/spatial_sound_server_sw.cpp | 13 | ||||
| -rw-r--r-- | servers/spatial_sound_2d/spatial_sound_2d_server_sw.cpp | 2 | ||||
| -rw-r--r-- | servers/visual/visual_server_raster.cpp | 50 | ||||
| -rw-r--r-- | servers/visual/visual_server_raster.h | 15 | ||||
| -rw-r--r-- | servers/visual/visual_server_wrap_mt.h | 2 | ||||
| -rw-r--r-- | servers/visual_server.h | 1 |
21 files changed, 159 insertions, 46 deletions
diff --git a/servers/physics/area_pair_sw.cpp b/servers/physics/area_pair_sw.cpp index 4a303d3fd..5938e716e 100644 --- a/servers/physics/area_pair_sw.cpp +++ b/servers/physics/area_pair_sw.cpp @@ -67,7 +67,6 @@ void AreaPairSW::solve(float p_step) { AreaPairSW::AreaPairSW(BodySW *p_body,int p_body_shape, AreaSW *p_area,int p_area_shape) { - body=p_body; area=p_area; body_shape=p_body_shape; @@ -75,6 +74,8 @@ AreaPairSW::AreaPairSW(BodySW *p_body,int p_body_shape, AreaSW *p_area,int p_are colliding=false; body->add_constraint(this,0); area->add_constraint(this); + if (p_body->get_mode()==PhysicsServer::BODY_MODE_KINEMATIC) + p_body->set_active(true); } diff --git a/servers/physics/area_sw.cpp b/servers/physics/area_sw.cpp index 8192a9840..4c9ac814b 100644 --- a/servers/physics/area_sw.cpp +++ b/servers/physics/area_sw.cpp @@ -148,8 +148,6 @@ void AreaSW::call_queries() { return; } - - for (Map<BodyKey,BodyState>::Element *E=monitored_bodies.front();E;E=E->next()) { if (E->get().state==0) @@ -182,8 +180,8 @@ AreaSW::AreaSW() : CollisionObjectSW(TYPE_AREA), monitor_query_list(this), move point_attenuation=1; density=0.1; priority=0; - ray_pickable=false; - + set_ray_pickable(false); + monitor_callback_id=0; } diff --git a/servers/physics/area_sw.h b/servers/physics/area_sw.h index a864055d1..c0c6e5c2a 100644 --- a/servers/physics/area_sw.h +++ b/servers/physics/area_sw.h @@ -48,7 +48,6 @@ class AreaSW : public CollisionObjectSW{ float point_attenuation; float density; int priority; - bool ray_pickable; ObjectID monitor_callback_id; StringName monitor_callback_method; @@ -139,8 +138,6 @@ public: _FORCE_INLINE_ void remove_constraint( ConstraintSW* p_constraint) { constraints.erase(p_constraint); } _FORCE_INLINE_ const Set<ConstraintSW*>& get_constraints() const { return constraints; } - _FORCE_INLINE_ void set_ray_pickable(bool p_enable) { ray_pickable=p_enable; } - _FORCE_INLINE_ bool is_ray_pickable() const { return ray_pickable; } diff --git a/servers/physics/collision_object_sw.cpp b/servers/physics/collision_object_sw.cpp index f34aa19ca..c8e1fc402 100644 --- a/servers/physics/collision_object_sw.cpp +++ b/servers/physics/collision_object_sw.cpp @@ -217,4 +217,5 @@ CollisionObjectSW::CollisionObjectSW(Type p_type) { space=NULL; instance_id=0; layer_mask=1; + ray_pickable=true; } diff --git a/servers/physics/collision_object_sw.h b/servers/physics/collision_object_sw.h index e717cc257..98d05538a 100644 --- a/servers/physics/collision_object_sw.h +++ b/servers/physics/collision_object_sw.h @@ -94,6 +94,9 @@ protected: virtual void _shapes_changed()=0; void _set_space(SpaceSW *space); + bool ray_pickable; + + CollisionObjectSW(Type p_type); public: @@ -119,6 +122,9 @@ public: _FORCE_INLINE_ Transform get_inv_transform() const { return inv_transform; } _FORCE_INLINE_ SpaceSW* get_space() const { return space; } + _FORCE_INLINE_ void set_ray_pickable(bool p_enable) { ray_pickable=p_enable; } + _FORCE_INLINE_ bool is_ray_pickable() const { return ray_pickable; } + _FORCE_INLINE_ void set_layer_mask(uint32_t p_mask) { layer_mask=p_mask; } _FORCE_INLINE_ uint32_t get_layer_mask() const { return layer_mask; } diff --git a/servers/physics/constraint_sw.h b/servers/physics/constraint_sw.h index 1be96422e..5e79c4b54 100644 --- a/servers/physics/constraint_sw.h +++ b/servers/physics/constraint_sw.h @@ -38,12 +38,13 @@ class ConstraintSW { uint64_t island_step; ConstraintSW *island_next; ConstraintSW *island_list_next; + int priority; RID self; protected: - ConstraintSW(BodySW **p_body_ptr=NULL,int p_body_count=0) { _body_ptr=p_body_ptr; _body_count=p_body_count; island_step=0; } + ConstraintSW(BodySW **p_body_ptr=NULL,int p_body_count=0) { _body_ptr=p_body_ptr; _body_count=p_body_count; island_step=0; priority=1; } public: _FORCE_INLINE_ void set_self(const RID& p_self) { self=p_self; } @@ -62,6 +63,9 @@ public: _FORCE_INLINE_ BodySW **get_body_ptr() const { return _body_ptr; } _FORCE_INLINE_ int get_body_count() const { return _body_count; } + _FORCE_INLINE_ void set_priority(int p_priority) { priority=p_priority; } + _FORCE_INLINE_ int get_priority() const { return priority; } + virtual bool setup(float p_step)=0; virtual void solve(float p_step)=0; diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp index 043d2149f..31c4d8f12 100644 --- a/servers/physics/physics_server_sw.cpp +++ b/servers/physics/physics_server_sw.cpp @@ -836,6 +836,22 @@ void PhysicsServerSW::body_set_force_integration_callback(RID p_body,Object *p_r } +void PhysicsServerSW::body_set_ray_pickable(RID p_body,bool p_enable) { + + BodySW *body = body_owner.get(p_body); + ERR_FAIL_COND(!body); + body->set_ray_pickable(p_enable); + +} + +bool PhysicsServerSW::body_is_ray_pickable(RID p_body) const{ + + BodySW *body = body_owner.get(p_body); + ERR_FAIL_COND_V(!body,false); + return body->is_ray_pickable(); + +} + /* JOINT API */ @@ -1000,6 +1016,21 @@ bool PhysicsServerSW::hinge_joint_get_flag(RID p_joint,HingeJointFlag p_flag) co return hinge_joint->get_flag(p_flag); } +void PhysicsServerSW::joint_set_solver_priority(RID p_joint,int p_priority) { + + JointSW *joint = joint_owner.get(p_joint); + ERR_FAIL_COND(!joint); + joint->set_priority(p_priority); +} + +int PhysicsServerSW::joint_get_solver_priority(RID p_joint) const{ + + JointSW *joint = joint_owner.get(p_joint); + ERR_FAIL_COND_V(!joint,0); + return joint->get_priority(); + +} + PhysicsServerSW::JointType PhysicsServerSW::joint_get_type(RID p_joint) const { JointSW *joint = joint_owner.get(p_joint); diff --git a/servers/physics/physics_server_sw.h b/servers/physics/physics_server_sw.h index 76e5aecf5..6609a7866 100644 --- a/servers/physics/physics_server_sw.h +++ b/servers/physics/physics_server_sw.h @@ -201,6 +201,9 @@ public: virtual void body_set_force_integration_callback(RID p_body,Object *p_receiver,const StringName& p_method,const Variant& p_udata=Variant()); + virtual void body_set_ray_pickable(RID p_body,bool p_enable); + virtual bool body_is_ray_pickable(RID p_body) const; + /* JOINT API */ virtual RID joint_create_pin(RID p_body_A,const Vector3& p_local_A,RID p_body_B,const Vector3& p_local_B); @@ -244,6 +247,9 @@ public: virtual JointType joint_get_type(RID p_joint) const; + virtual void joint_set_solver_priority(RID p_joint,int p_priority); + virtual int joint_get_solver_priority(RID p_joint) const; + #if 0 virtual void joint_set_param(RID p_joint, JointParam p_param, real_t p_value); virtual real_t joint_get_param(RID p_joint,JointParam p_param) const; diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp index 68d6b464a..4e8b60b86 100644 --- a/servers/physics/space_sw.cpp +++ b/servers/physics/space_sw.cpp @@ -71,12 +71,13 @@ bool PhysicsDirectSpaceStateSW::intersect_ray(const Vector3& p_from, const Vecto real_t min_d=1e10;
+
for(int i=0;i<amount;i++) {
if (!_match_object_type_query(space->intersection_query_results[i],p_layer_mask,p_object_type_mask))
continue;
- if (space->intersection_query_results[i]->get_type()==CollisionObjectSW::TYPE_AREA && !(static_cast<AreaSW*>(space->intersection_query_results[i])->is_ray_pickable()))
+ if (!(static_cast<AreaSW*>(space->intersection_query_results[i])->is_ray_pickable()))
continue;
if (p_exclude.has( space->intersection_query_results[i]->get_self()))
@@ -97,6 +98,8 @@ bool PhysicsDirectSpaceStateSW::intersect_ray(const Vector3& p_from, const Vecto if (shape->intersect_segment(local_from,local_to,shape_point,shape_normal)) {
+
+
Transform xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
shape_point=xform.xform(shape_point);
diff --git a/servers/physics/step_sw.cpp b/servers/physics/step_sw.cpp index 6d9580487..b7d06d207 100644 --- a/servers/physics/step_sw.cpp +++ b/servers/physics/step_sw.cpp @@ -27,7 +27,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "step_sw.h" - +#include "joints_sw.h" void StepSW::_populate_island(BodySW* p_body,BodySW** p_island,ConstraintSW **p_constraint_island) { @@ -68,14 +68,41 @@ void StepSW::_setup_island(ConstraintSW *p_island,float p_delta) { void StepSW::_solve_island(ConstraintSW *p_island,int p_iterations,float p_delta){ - for(int i=0;i<p_iterations;i++) { + int at_priority=1; - ConstraintSW *ci=p_island; - while(ci) { - ci->solve(p_delta); - ci=ci->get_island_next(); + while(p_island) { + + for(int i=0;i<p_iterations;i++) { + + ConstraintSW *ci=p_island; + while(ci) { + ci->solve(p_delta); + ci=ci->get_island_next(); + } + } + + at_priority++; + + { + ConstraintSW *ci=p_island; + ConstraintSW *prev=NULL; + while(ci) { + if (ci->get_priority()<at_priority) { + if (prev) { + prev->set_island_next(ci->get_island_next()); //remove + } else { + p_island=ci->get_island_next(); + } + } else { + + prev=ci; + } + + ci=ci->get_island_next(); + } } } + } void StepSW::_check_suspend(BodySW *p_island,float p_delta) { diff --git a/servers/physics_2d/area_2d_sw.cpp b/servers/physics_2d/area_2d_sw.cpp index 58035eb65..8be583c23 100644 --- a/servers/physics_2d/area_2d_sw.cpp +++ b/servers/physics_2d/area_2d_sw.cpp @@ -180,6 +180,7 @@ Area2DSW::Area2DSW() : CollisionObject2DSW(TYPE_AREA), monitor_query_list(this), gravity_vector=Vector2(0,-1); gravity_is_point=false; point_attenuation=1; + density=0.1; priority=0; monitor_callback_id=0; diff --git a/servers/physics_2d/area_pair_2d_sw.cpp b/servers/physics_2d/area_pair_2d_sw.cpp index 35286bdb6..1c7f73db5 100644 --- a/servers/physics_2d/area_pair_2d_sw.cpp +++ b/servers/physics_2d/area_pair_2d_sw.cpp @@ -75,6 +75,8 @@ AreaPair2DSW::AreaPair2DSW(Body2DSW *p_body,int p_body_shape, Area2DSW *p_area,i colliding=false; body->add_constraint(this,0); area->add_constraint(this); + if (p_body->get_mode()==Physics2DServer::BODY_MODE_KINEMATIC) //need to be active to process pair + p_body->set_active(true); } diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp index dc8e4cc29..fbed5779f 100644 --- a/servers/physics_server.cpp +++ b/servers/physics_server.cpp @@ -520,6 +520,9 @@ void PhysicsServer::_bind_methods() { ObjectTypeDB::bind_method(_MD("body_set_force_integration_callback","body","receiver","method","userdata"),&PhysicsServer::body_set_force_integration_callback,DEFVAL(Variant())); + ObjectTypeDB::bind_method(_MD("body_set_ray_pickable","body","enable"),&PhysicsServer::body_set_ray_pickable); + ObjectTypeDB::bind_method(_MD("body_is_ray_pickable","body"),&PhysicsServer::body_is_ray_pickable); + /* JOINT API */ BIND_CONSTANT( JOINT_PIN ); @@ -627,6 +630,9 @@ void PhysicsServer::_bind_methods() { ObjectTypeDB::bind_method(_MD("joint_get_type","joint"),&PhysicsServer::joint_get_type); + ObjectTypeDB::bind_method(_MD("joint_set_solver_priority","joint","priority"),&PhysicsServer::joint_set_solver_priority); + ObjectTypeDB::bind_method(_MD("joint_get_solver_priority","joint"),&PhysicsServer::joint_get_solver_priority); + ObjectTypeDB::bind_method(_MD("joint_create_generic_6dof","body_A","local_ref_A","body_B","local_ref_B"),&PhysicsServer::joint_create_generic_6dof); ObjectTypeDB::bind_method(_MD("generic_6dof_joint_set_param","joint","axis","param","value"),&PhysicsServer::generic_6dof_joint_set_param); diff --git a/servers/physics_server.h b/servers/physics_server.h index 25a89775a..0c2542a66 100644 --- a/servers/physics_server.h +++ b/servers/physics_server.h @@ -450,6 +450,10 @@ public: virtual void body_set_force_integration_callback(RID p_body,Object *p_receiver,const StringName& p_method,const Variant& p_udata=Variant())=0; + virtual void body_set_ray_pickable(RID p_body,bool p_enable)=0; + virtual bool body_is_ray_pickable(RID p_body) const=0; + + /* JOINT API */ enum JointType { @@ -464,6 +468,8 @@ public: virtual JointType joint_get_type(RID p_joint) const=0; + virtual void joint_set_solver_priority(RID p_joint,int p_priority)=0; + virtual int joint_get_solver_priority(RID p_joint) const=0; virtual RID joint_create_pin(RID p_body_A,const Vector3& p_local_A,RID p_body_B,const Vector3& p_local_B)=0; diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index f8d38d15c..a2b1b71f9 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -57,6 +57,7 @@ void register_server_types() { ObjectTypeDB::register_virtual_type<Physics2DShapeQueryResult>(); ObjectTypeDB::register_type<Physics2DShapeQueryParameters>(); + ObjectTypeDB::register_type<PhysicsShapeQueryParameters>(); ObjectTypeDB::register_virtual_type<PhysicsDirectBodyState>(); ObjectTypeDB::register_virtual_type<PhysicsDirectSpaceState>(); ObjectTypeDB::register_virtual_type<PhysicsShapeQueryResult>(); diff --git a/servers/spatial_sound/spatial_sound_server_sw.cpp b/servers/spatial_sound/spatial_sound_server_sw.cpp index 7ec29d32c..d00deb391 100644 --- a/servers/spatial_sound/spatial_sound_server_sw.cpp +++ b/servers/spatial_sound/spatial_sound_server_sw.cpp @@ -879,10 +879,13 @@ void SpatialSoundServerSW::update(float p_delta) { float volume_attenuation = 0.0; float air_absorption_hf_cutoff = 0.0; float air_absorption = 0.0; - float pitch_scale=0.0; + float pitch_scale=1.0; Vector3 panning; + //print_line("listeners: "+itos(space->listeners.size())); + + for(Set<RID>::Element *L=space->listeners.front();L;L=L->next()) { Listener *listener=listener_owner.get(L->get()); @@ -899,9 +902,11 @@ void SpatialSoundServerSW::update(float p_delta) { float attenuation_exp=source->params[SOURCE_PARAM_ATTENUATION_DISTANCE_EXP]; float attenuation=1; + //print_line("DIST MIN: "+rtos(distance_min)); + //print_line("DIST MAX: "+rtos(distance_max)); if (distance_max>0) { distance = CLAMP(distance,distance_min,distance_max); - attenuation = Math::pow(1.0 - ((distance - distance_min)/distance_max),CLAMP(attenuation_exp,0.001,16)); + attenuation = Math::pow(1.0 - ((distance - distance_min)/(distance_max-distance_min)),CLAMP(attenuation_exp,0.001,16)); } float hf_attenuation_cutoff = room->params[ROOM_PARAM_ATTENUATION_HF_CUTOFF]; @@ -945,7 +950,7 @@ void SpatialSoundServerSW::update(float p_delta) { air_absorption+=weight*absorption; air_absorption_hf_cutoff+=weight*hf_attenuation_cutoff; panning+=vpanning*weight; - pitch_scale+=pscale*weight; + //pitch_scale+=pscale*weight; } @@ -991,8 +996,8 @@ void SpatialSoundServerSW::update(float p_delta) { reverb_send*=volume_scale; int mix_rate = v.sample_mix_rate*v.pitch_scale*pitch_scale*source->params[SOURCE_PARAM_PITCH_SCALE]; - if (mix_rate<=0) { + if (mix_rate<=0) { ERR_PRINT("Invalid mix rate for voice (0) check for invalid pitch_scale param."); to_disable.push_back(ActiveVoice(source,voice)); // oh well.. continue; //invalid mix rate, disabling diff --git a/servers/spatial_sound_2d/spatial_sound_2d_server_sw.cpp b/servers/spatial_sound_2d/spatial_sound_2d_server_sw.cpp index e3c8aba75..2aab0e7dc 100644 --- a/servers/spatial_sound_2d/spatial_sound_2d_server_sw.cpp +++ b/servers/spatial_sound_2d/spatial_sound_2d_server_sw.cpp @@ -904,7 +904,7 @@ void SpatialSound2DServerSW::update(float p_delta) { if (distance_max>0) { distance = CLAMP(distance,distance_min,distance_max); - attenuation = Math::pow(1.0 - ((distance - distance_min)/distance_max),CLAMP(attenuation_exp,0.001,16)); + attenuation = Math::pow(1.0 - ((distance - distance_min)/(distance_max-distance_min)),CLAMP(attenuation_exp,0.001,16)); } float hf_attenuation_cutoff = room->params[ROOM_PARAM_ATTENUATION_HF_CUTOFF]; diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index 21ecd4030..6d5627877 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -1202,7 +1202,7 @@ RID VisualServerRaster::camera_create() { } void VisualServerRaster::camera_set_perspective(RID p_camera,float p_fovy_degrees, float p_z_near, float p_z_far) { - VS_CHANGED; + VS_CHANGED Camera *camera = camera_owner.get( p_camera ); ERR_FAIL_COND(!camera); camera->type=Camera::PERSPECTIVE; @@ -1226,7 +1226,7 @@ void VisualServerRaster::camera_set_transform(RID p_camera,const Transform& p_tr VS_CHANGED; Camera *camera = camera_owner.get( p_camera ); ERR_FAIL_COND(!camera); - camera->transform=p_transform; + camera->transform=p_transform.orthonormalized(); } @@ -3531,6 +3531,15 @@ void VisualServerRaster::canvas_item_add_set_blend_mode(RID p_item, MaterialBlen canvas_item->commands.push_back(bm); }; +void VisualServerRaster::canvas_item_set_sort_children_by_y(RID p_item, bool p_enable) { + + VS_CHANGED; + CanvasItem *canvas_item = canvas_item_owner.get( p_item ); + ERR_FAIL_COND(!canvas_item); + canvas_item->sort_y=p_enable; +} + + void VisualServerRaster::canvas_item_add_clip_ignore(RID p_item, bool p_ignore) { VS_CHANGED; @@ -5591,26 +5600,30 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat float opacity = ci->opacity * p_opacity; -#ifndef ONTOP_DISABLED - CanvasItem **child_items = ci->child_items.ptr(); + int child_item_count=ci->child_items.size(); - int top_item_count=0; - CanvasItem **top_items=(CanvasItem**)alloca(child_item_count*sizeof(CanvasItem*)); + CanvasItem **child_items=(CanvasItem**)alloca(child_item_count*sizeof(CanvasItem*)); + copymem(child_items,ci->child_items.ptr(),child_item_count*sizeof(CanvasItem*)); if (ci->clip) { rasterizer->canvas_set_clip(true,global_rect); canvas_clip=global_rect; } + if (ci->sort_y) { + + SortArray<CanvasItem*,CanvasItemPtrSort> sorter; + sorter.sort(child_items,child_item_count); + } + + for(int i=0;i<child_item_count;i++) { if (child_items[i]->ontop) - top_items[top_item_count++]=child_items[i]; - else { - _render_canvas_item(child_items[i],xform,p_clip_rect,opacity); - } + continue; + _render_canvas_item(child_items[i],xform,p_clip_rect,opacity); } -#endif + if (s!=0) { @@ -5746,19 +5759,12 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat rasterizer->canvas_set_clip(true,canvas_clip); } -#ifndef ONTOP_DISABLED - - for(int i=0;i<top_item_count;i++) { - - _render_canvas_item(top_items[i],xform,p_clip_rect,opacity); - } - -#else - for(int i=0;i<p_canvas_item->child_items.size();i++) { + for(int i=0;i<child_item_count;i++) { - _render_canvas_item(p_canvas_item->child_items[i],xform,p_clip_rect,opacity); + if (!child_items[i]->ontop) + continue; + _render_canvas_item(child_items[i],xform,p_clip_rect,opacity); } -#endif if (ci->clip) { diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index 49e7996c5..41ad3aab1 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -328,7 +328,7 @@ class VisualServerRaster : public VisualServer { - + struct CanvasItem { @@ -446,13 +446,14 @@ class VisualServerRaster : public VisualServer { bool clip; bool visible; bool ontop; + bool sort_y; float opacity; float self_opacity; MaterialBlendMode blend_mode; RID viewport; mutable bool custom_rect; - mutable bool rect_dirty; + mutable bool rect_dirty; mutable Rect2 rect; Vector<Command*> commands; @@ -460,11 +461,18 @@ class VisualServerRaster : public VisualServer { const Rect2& get_rect() const; void clear() { for (int i=0;i<commands.size();i++) memdelete( commands[i] ); commands.clear(); clip=false; rect_dirty=true;}; - CanvasItem() { clip=false; E=NULL; opacity=1; self_opacity=1; blend_mode=MATERIAL_BLEND_MODE_MIX; visible=true; rect_dirty=true; custom_rect=false; ontop=true; } + CanvasItem() { clip=false; E=NULL; opacity=1; self_opacity=1; blend_mode=MATERIAL_BLEND_MODE_MIX; visible=true; rect_dirty=true; custom_rect=false; ontop=true; sort_y=false;} ~CanvasItem() { clear(); } }; + struct CanvasItemPtrSort { + + _FORCE_INLINE_ bool operator()(const CanvasItem* p_left,const CanvasItem* p_right) const { + + return p_left->xform.elements[2].y < p_right->xform.elements[2].y; + } + }; struct Canvas { @@ -1135,6 +1143,7 @@ public: virtual void canvas_item_add_set_transform(RID p_item,const Matrix32& p_transform); virtual void canvas_item_add_set_blend_mode(RID p_item, MaterialBlendMode p_blend); virtual void canvas_item_add_clip_ignore(RID p_item, bool p_ignore); + virtual void canvas_item_set_sort_children_by_y(RID p_item, bool p_enable); virtual void canvas_item_clear(RID p_item); virtual void canvas_item_raise(RID p_item); diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index f1ba4c453..73e736f68 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -1107,6 +1107,8 @@ public: FUNC2(canvas_item_add_set_blend_mode,RID, MaterialBlendMode ); FUNC2(canvas_item_add_clip_ignore,RID, bool ); + FUNC2(canvas_item_set_sort_children_by_y,RID,bool); + FUNC1(canvas_item_clear,RID); FUNC1(canvas_item_raise,RID); diff --git a/servers/visual_server.h b/servers/visual_server.h index 8934fa790..166e4907b 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -944,6 +944,7 @@ public: virtual void canvas_item_add_set_transform(RID p_item,const Matrix32& p_transform)=0; virtual void canvas_item_add_set_blend_mode(RID p_item, MaterialBlendMode p_blend)=0; virtual void canvas_item_add_clip_ignore(RID p_item, bool p_ignore)=0; + virtual void canvas_item_set_sort_children_by_y(RID p_item, bool p_enable)=0; virtual void canvas_item_clear(RID p_item)=0; virtual void canvas_item_raise(RID p_item)=0; |
