diff options
Diffstat (limited to 'scene')
| -rw-r--r-- | scene/2d/camera_2d.cpp | 31 | ||||
| -rw-r--r-- | scene/2d/camera_2d.h | 2 | ||||
| -rw-r--r-- | scene/2d/tile_map.cpp | 36 | ||||
| -rw-r--r-- | scene/2d/tile_map.h | 3 | ||||
| -rw-r--r-- | scene/animation/animation_tree_player.cpp | 170 | ||||
| -rw-r--r-- | scene/animation/animation_tree_player.h | 5 | ||||
| -rw-r--r-- | scene/gui/rich_text_label.cpp | 30 | ||||
| -rw-r--r-- | scene/gui/rich_text_label.h | 1 | ||||
| -rw-r--r-- | scene/gui/text_edit.cpp | 6 | ||||
| -rw-r--r-- | scene/resources/sample_library.cpp | 19 | ||||
| -rw-r--r-- | scene/resources/sample_library.h | 4 |
11 files changed, 245 insertions, 62 deletions
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index 27e07a35be..f98a50e3e0 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -408,6 +408,35 @@ void Camera2D::force_update_scroll() { _update_scroll(); } +void Camera2D::reset_smoothing() { + + smoothed_camera_pos = camera_pos; + _update_scroll(); +} + +void Camera2D::align() { + + Size2 screen_size = get_viewport_rect().size; + screen_size=get_viewport_rect().size; + Point2 current_camera_pos = get_global_transform().get_origin(); + if (anchor_mode==ANCHOR_MODE_DRAG_CENTER) { + if (h_ofs<0) { + camera_pos.x = current_camera_pos.x + screen_size.x * 0.5 * drag_margin[MARGIN_RIGHT] * h_ofs; + } else { + camera_pos.x = current_camera_pos.x + screen_size.x * 0.5 * drag_margin[MARGIN_LEFT] * h_ofs; + } + if (v_ofs<0) { + camera_pos.y = current_camera_pos.y + screen_size.y * 0.5 * drag_margin[MARGIN_TOP] * v_ofs; + } else { + camera_pos.y = current_camera_pos.y + screen_size.y * 0.5 * drag_margin[MARGIN_BOTTOM] * v_ofs; + } + } else if (anchor_mode==ANCHOR_MODE_FIXED_TOP_LEFT){ + + camera_pos=current_camera_pos; + } + + _update_scroll(); +} void Camera2D::set_follow_smoothing(float p_speed) { @@ -543,6 +572,8 @@ void Camera2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("is_follow_smoothing_enabled"),&Camera2D::is_follow_smoothing_enabled); ObjectTypeDB::bind_method(_MD("force_update_scroll"),&Camera2D::force_update_scroll); + ObjectTypeDB::bind_method(_MD("reset_smoothing"),&Camera2D::reset_smoothing); + ObjectTypeDB::bind_method(_MD("align"),&Camera2D::align); ObjectTypeDB::bind_method(_MD("_set_old_smoothing","follow_smoothing"),&Camera2D::_set_old_smoothing); diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h index 22e5bc382a..b3f55d798d 100644 --- a/scene/2d/camera_2d.h +++ b/scene/2d/camera_2d.h @@ -128,6 +128,8 @@ public: Vector2 get_camera_pos() const; void force_update_scroll(); + void reset_smoothing(); + void align(); Camera2D(); }; diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 1f16b36466..1a4f88c30e 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -222,6 +222,10 @@ void TileMap::_fix_cell_transform(Matrix32& xform,const Cell& p_cell, const Vect Size2 s=p_sc; Vector2 offset = p_offset; + + if (tile_origin==TILE_ORIGIN_BOTTOM_LEFT) + offset.y+=cell_size.y; + if (s.y > s.x) { if ((p_cell.flip_h && (p_cell.flip_v || p_cell.transpose)) || (p_cell.flip_v && !p_cell.transpose)) @@ -240,7 +244,7 @@ void TileMap::_fix_cell_transform(Matrix32& xform,const Cell& p_cell, const Vect if (p_cell.flip_h) { xform.elements[0].x=-xform.elements[0].x; xform.elements[1].x=-xform.elements[1].x; - if (tile_origin==TILE_ORIGIN_TOP_LEFT) + if (tile_origin==TILE_ORIGIN_TOP_LEFT || tile_origin==TILE_ORIGIN_BOTTOM_LEFT) offset.x=s.x-offset.x; } if (p_cell.flip_v) { @@ -248,6 +252,12 @@ void TileMap::_fix_cell_transform(Matrix32& xform,const Cell& p_cell, const Vect xform.elements[1].y=-xform.elements[1].y; if (tile_origin==TILE_ORIGIN_TOP_LEFT) offset.y=s.y-offset.y; + else if (tile_origin==TILE_ORIGIN_BOTTOM_LEFT) { + if(p_cell.transpose) + offset.y+=s.y; + else + offset.y-=s.y; + } } xform.elements[2].x+=offset.x; xform.elements[2].y+=offset.y; @@ -411,6 +421,24 @@ void TileMap::_update_dirty_quadrants() { if (tile_origin==TILE_ORIGIN_TOP_LEFT) { rect.pos+=tile_ofs; + + } else if (tile_origin==TILE_ORIGIN_BOTTOM_LEFT) { + + rect.pos+=tile_ofs; + + if(c.transpose) + { + if(c.flip_h) + rect.pos.x-=cell_size.x; + else + rect.pos.x+=cell_size.x; + } else { + if(c.flip_v) + rect.pos.y-=cell_size.y; + else + rect.pos.y+=cell_size.y; + } + } else if (tile_origin==TILE_ORIGIN_CENTER) { rect.pos+=tcenter; @@ -584,6 +612,9 @@ Map<TileMap::PosKey,TileMap::Quadrant>::Element *TileMap::_create_quadrant(const q.pos+=get_cell_draw_offset(); if (tile_origin==TILE_ORIGIN_CENTER) q.pos+=cell_size/2; + else if (tile_origin==TILE_ORIGIN_BOTTOM_LEFT) + q.pos.y+=cell_size.y; + xform.set_origin( q.pos ); // q.canvas_item = VisualServer::get_singleton()->canvas_item_create(); @@ -1242,7 +1273,7 @@ void TileMap::_bind_methods() { ADD_PROPERTY( PropertyInfo(Variant::INT,"cell/quadrant_size",PROPERTY_HINT_RANGE,"1,128,1"),_SCS("set_quadrant_size"),_SCS("get_quadrant_size")); ADD_PROPERTY( PropertyInfo(Variant::MATRIX32,"cell/custom_transform"),_SCS("set_custom_transform"),_SCS("get_custom_transform")); ADD_PROPERTY( PropertyInfo(Variant::INT,"cell/half_offset",PROPERTY_HINT_ENUM,"Offset X,Offset Y,Disabled"),_SCS("set_half_offset"),_SCS("get_half_offset")); - ADD_PROPERTY( PropertyInfo(Variant::INT,"cell/tile_origin",PROPERTY_HINT_ENUM,"Top Left,Center"),_SCS("set_tile_origin"),_SCS("get_tile_origin")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"cell/tile_origin",PROPERTY_HINT_ENUM,"Top Left,Center,Bottom Left"),_SCS("set_tile_origin"),_SCS("get_tile_origin")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"cell/y_sort"),_SCS("set_y_sort_mode"),_SCS("is_y_sort_mode_enabled")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"collision/use_kinematic",PROPERTY_HINT_NONE,""),_SCS("set_collision_use_kinematic"),_SCS("get_collision_use_kinematic")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"collision/friction",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_collision_friction"),_SCS("get_collision_friction")); @@ -1264,6 +1295,7 @@ void TileMap::_bind_methods() { BIND_CONSTANT( HALF_OFFSET_DISABLED ); BIND_CONSTANT( TILE_ORIGIN_TOP_LEFT ); BIND_CONSTANT( TILE_ORIGIN_CENTER ); + BIND_CONSTANT( TILE_ORIGIN_BOTTOM_LEFT ); } diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index cec5ac0a1b..b48fdde43f 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -54,7 +54,8 @@ public: enum TileOrigin { TILE_ORIGIN_TOP_LEFT, - TILE_ORIGIN_CENTER + TILE_ORIGIN_CENTER, + TILE_ORIGIN_BOTTOM_LEFT }; diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp index 628edf09de..9488ae37a8 100644 --- a/scene/animation/animation_tree_player.cpp +++ b/scene/animation/animation_tree_player.cpp @@ -445,8 +445,44 @@ void AnimationTreePlayer::_notification(int p_what) { } +void AnimationTreePlayer::_compute_weights(float *p_fallback_weight, HashMap<NodePath,float> *p_weights, float p_coeff, const HashMap<NodePath,bool> *p_filter, float p_filtered_coeff) { -float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode **r_prev_anim,float p_weight, float p_time, bool p_seek,const HashMap<NodePath,bool> *p_filter, float p_reverse_weight) { + if (p_filter != NULL) { + + List<NodePath> key_list; + p_filter->get_key_list(&key_list); + + for (List<NodePath>::Element *E = key_list.front();E; E=E->next()) { + + if ((*p_filter)[E->get()]) { + + if (p_weights->has(E->get())) { + (*p_weights)[E->get()] *= p_filtered_coeff; + } else { + p_weights->set(E->get(), *p_fallback_weight * p_filtered_coeff); + } + + } else if (p_weights->has(E->get())) { + (*p_weights)[E->get()] *= p_coeff; + } + } + } + + List<NodePath> key_list; + p_weights->get_key_list(&key_list); + + for (List<NodePath>::Element *E = key_list.front();E;E=E->next()) { + if (p_filter == NULL || !p_filter->has(E->get())) { + (*p_weights)[E->get()] *= p_coeff; + } + } + + *p_fallback_weight *= p_coeff; + +} + + +float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode **r_prev_anim, float p_time, bool p_seek, float p_fallback_weight, HashMap<NodePath,float>* p_weights) { ERR_FAIL_COND_V(!node_map.has(p_node), 0); NodeBase *nb=node_map[p_node]; @@ -458,7 +494,16 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode case NODE_OUTPUT: { NodeOut *on = static_cast<NodeOut*>(nb); - return _process_node(on->inputs[0].node,r_prev_anim,p_weight,p_time,p_seek); + + for(TrackMap::Element *E=track_map.front();E;E=E->next()) { + E->get().total_weight = 0; + } + + HashMap<NodePath, float> weights; + + + + return _process_node(on->inputs[0].node,r_prev_anim,p_time,p_seek, p_fallback_weight, &weights); } break; case NODE_ANIMATION: { @@ -494,15 +539,21 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode } an->skip=true; + for (List<AnimationNode::TrackRef>::Element *E=an->tref.front();E;E=E->next()) { NodePath track_path = an->animation->track_get_path(E->get().local_track); - if (p_filter && p_filter->has(track_path)) { - E->get().weight = MAX(0, p_reverse_weight); - } else if(an->filter.has(track_path)) { + if (an->filter.has(track_path) && an->filter[track_path]) { E->get().weight = 0; - E->get().track->skip = true; + E->get().track->total_weight += p_fallback_weight; } else { - E->get().weight=p_weight; + if (p_weights->has(track_path)) { + float weight = (*p_weights)[track_path]; + E->get().weight = weight; + E->get().track->total_weight += weight; + } else { + E->get().weight = p_fallback_weight; + E->get().track->total_weight += p_fallback_weight; + } } if (E->get().weight>CMP_EPSILON) an->skip=false; @@ -531,7 +582,7 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode if (!osn->active) { //make it as if this node doesn't exist, pass input 0 by. - return _process_node(osn->inputs[0].node,r_prev_anim,p_weight,p_time,p_seek,p_filter,p_reverse_weight); + return _process_node(osn->inputs[0].node,r_prev_anim,p_time,p_seek, p_fallback_weight, p_weights); } float os_seek = p_seek; @@ -563,16 +614,14 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode float main_rem; float os_rem; - float os_reverse_weight = p_reverse_weight; - if (!osn->filter.empty()) { - p_filter = &osn->filter; - p_reverse_weight = p_weight; - os_reverse_weight = -1; - } + HashMap<NodePath, float> os_weights(*p_weights); + float os_fallback_weight = p_fallback_weight; + _compute_weights(&p_fallback_weight, p_weights, osn->mix?1.0 : 1.0 - blend, &osn->filter, 1.0); + _compute_weights(&os_fallback_weight, &os_weights, blend, &osn->filter, 0.0); - main_rem = _process_node(osn->inputs[0].node,r_prev_anim,(osn->mix?p_weight:p_weight*(1.0-blend)),p_time,p_seek,p_filter,p_reverse_weight); - os_rem = _process_node(osn->inputs[1].node,r_prev_anim,p_weight*blend,p_time,os_seek,p_filter,os_reverse_weight); + main_rem = _process_node(osn->inputs[0].node,r_prev_anim,p_time,p_seek, p_fallback_weight, p_weights); + os_rem = _process_node(osn->inputs[1].node,r_prev_anim,p_time,os_seek, os_fallback_weight, &os_weights); if (osn->start) { osn->remaining=os_rem; @@ -591,9 +640,11 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode case NODE_MIX: { MixNode *mn = static_cast<MixNode*>(nb); - - float rem = _process_node(mn->inputs[0].node,r_prev_anim,p_weight,p_time,p_seek,p_filter,p_reverse_weight); - _process_node(mn->inputs[1].node,r_prev_anim,p_weight*mn->amount,p_time,p_seek,p_filter,p_reverse_weight); + HashMap<NodePath, float> mn_weights(*p_weights); + float mn_fallback_weight = p_fallback_weight; + _compute_weights(&mn_fallback_weight, &mn_weights, mn->amount); + float rem = _process_node(mn->inputs[0].node,r_prev_anim, p_time,p_seek,p_fallback_weight,p_weights); + _process_node(mn->inputs[1].node,r_prev_anim,p_time,p_seek,mn_fallback_weight,&mn_weights); return rem; } break; @@ -601,16 +652,12 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode Blend2Node *bn = static_cast<Blend2Node*>(nb); - float rem; - if (!bn->filter.empty()) { - - rem = _process_node(bn->inputs[0].node,r_prev_anim,p_weight*(1.0-bn->value),p_time,p_seek,&bn->filter,p_weight); - _process_node(bn->inputs[1].node,r_prev_anim,p_weight*bn->value,p_time,p_seek,&bn->filter,-1); - - } else { - rem = _process_node(bn->inputs[0].node,r_prev_anim,p_weight*(1.0-bn->value),p_time,p_seek,p_filter,p_reverse_weight*(1.0-bn->value)); - _process_node(bn->inputs[1].node,r_prev_anim,p_weight*bn->value,p_time,p_seek,p_filter,p_reverse_weight*bn->value); - } + HashMap<NodePath, float> bn_weights(*p_weights); + float bn_fallback_weight = p_fallback_weight; + _compute_weights(&p_fallback_weight,p_weights, 1.0 - bn->value, &bn->filter, 1.0); + _compute_weights(&bn_fallback_weight,&bn_weights, bn->value, &bn->filter, 0.0); + float rem = _process_node(bn->inputs[0].node,r_prev_anim,p_time,p_seek,p_fallback_weight,p_weights); + _process_node(bn->inputs[1].node,r_prev_anim,p_time,p_seek,bn_fallback_weight,&bn_weights); return rem; } break; @@ -629,19 +676,39 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode upper_blend = bn->value; } - rem = _process_node(bn->inputs[1].node,r_prev_anim,p_weight*blend,p_time,p_seek,p_filter,p_reverse_weight*blend); - _process_node(bn->inputs[2].node,r_prev_anim,p_weight*upper_blend,p_time,p_seek,p_filter,p_reverse_weight*upper_blend); - _process_node(bn->inputs[0].node,r_prev_anim,p_weight*lower_blend,p_time,p_seek,p_filter,p_reverse_weight*lower_blend); + HashMap<NodePath, float> upper_weights(*p_weights); + float upper_fallback_weight = p_fallback_weight; + HashMap<NodePath, float> lower_weights(*p_weights); + float lower_fallback_weight = p_fallback_weight; + _compute_weights(&upper_fallback_weight,&upper_weights, upper_blend); + _compute_weights(&p_fallback_weight,p_weights, blend); + _compute_weights(&lower_fallback_weight,&lower_weights, lower_blend); + + rem = _process_node(bn->inputs[1].node,r_prev_anim,p_time,p_seek,p_fallback_weight,p_weights); + _process_node(bn->inputs[0].node,r_prev_anim,p_time,p_seek,lower_fallback_weight,&lower_weights); + _process_node(bn->inputs[2].node,r_prev_anim,p_time,p_seek,upper_fallback_weight,&upper_weights); return rem; } break; case NODE_BLEND4: { Blend4Node *bn = static_cast<Blend4Node*>(nb); - float rem = _process_node(bn->inputs[0].node,r_prev_anim,p_weight*(1.0-bn->value.x),p_time,p_seek,p_filter,p_reverse_weight*(1.0-bn->value.x)); - _process_node(bn->inputs[1].node,r_prev_anim,p_weight*bn->value.x,p_time,p_seek,p_filter,p_reverse_weight*bn->value.x); - float rem2 = _process_node(bn->inputs[2].node,r_prev_anim,p_weight*(1.0-bn->value.y),p_time,p_seek,p_filter,p_reverse_weight*(1.0-bn->value.y)); - _process_node(bn->inputs[3].node,r_prev_anim,p_weight*bn->value.y,p_time,p_seek,p_filter,p_reverse_weight*bn->value.y); + HashMap<NodePath, float> weights1(*p_weights); + float fallback_weight1 = p_fallback_weight; + HashMap<NodePath, float> weights2(*p_weights); + float fallback_weight2 = p_fallback_weight; + HashMap<NodePath, float> weights3(*p_weights); + float fallback_weight3 = p_fallback_weight; + + _compute_weights(&p_fallback_weight,p_weights, 1.0-bn->value.x); + _compute_weights(&fallback_weight1,&weights1, bn->value.x); + _compute_weights(&fallback_weight2,&weights2, 1.0-bn->value.y); + _compute_weights(&fallback_weight3,&weights3, bn->value.y); + + float rem = _process_node(bn->inputs[0].node,r_prev_anim,p_time,p_seek,p_fallback_weight,p_weights); + _process_node(bn->inputs[1].node,r_prev_anim,p_time,p_seek,fallback_weight1,&weights1); + float rem2 = _process_node(bn->inputs[2].node,r_prev_anim,p_time,p_seek,fallback_weight2,&weights2); + _process_node(bn->inputs[3].node,r_prev_anim,p_time,p_seek,fallback_weight3,&weights3); return MAX(rem,rem2); @@ -650,9 +717,9 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode TimeScaleNode *tsn = static_cast<TimeScaleNode*>(nb); float rem; if (p_seek) - rem = _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time,true,p_filter,p_reverse_weight); + rem = _process_node(tsn->inputs[0].node,r_prev_anim,p_time,true,p_fallback_weight,p_weights); else - rem = _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time*tsn->scale,false,p_filter,p_reverse_weight); + rem = _process_node(tsn->inputs[0].node,r_prev_anim,p_time*tsn->scale,false,p_fallback_weight,p_weights); if (tsn->scale == 0) return INFINITY; else @@ -669,16 +736,18 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode } tsn->seek_pos=-1; - return _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time,p_seek, p_filter, p_reverse_weight); + return _process_node(tsn->inputs[0].node,r_prev_anim,p_time,p_seek,p_fallback_weight,p_weights); } break; case NODE_TRANSITION: { TransitionNode *tn = static_cast<TransitionNode*>(nb); + HashMap<NodePath, float> prev_weights(*p_weights); + float prev_fallback_weight = p_fallback_weight; if (tn->prev<0) { // process current animation, check for transition - float rem = _process_node(tn->inputs[tn->current].node,r_prev_anim,p_weight,p_time,p_seek,p_filter,p_reverse_weight); + float rem = _process_node(tn->inputs[tn->current].node,r_prev_anim,p_time,p_seek,p_fallback_weight,p_weights); if (p_seek) tn->time=p_time; else @@ -698,22 +767,25 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode float rem; + _compute_weights(&p_fallback_weight,p_weights, 1.0-blend); + _compute_weights(&prev_fallback_weight,&prev_weights, blend); + if (!p_seek && tn->switched) { //just switched, seek to start of current - rem = _process_node(tn->inputs[tn->current].node,r_prev_anim,p_weight*(1.0-blend),0,true,p_filter,p_reverse_weight*(1.0-blend)); + rem = _process_node(tn->inputs[tn->current].node,r_prev_anim,0,true,p_fallback_weight,p_weights); } else { - rem = _process_node(tn->inputs[tn->current].node,r_prev_anim,p_weight*(1.0-blend),p_time,p_seek,p_filter,p_reverse_weight*(1.0-blend)); + rem = _process_node(tn->inputs[tn->current].node,r_prev_anim,p_time,p_seek,p_fallback_weight,p_weights); } tn->switched=false; if (p_seek) { // don't seek prev animation - _process_node(tn->inputs[tn->prev].node,r_prev_anim,p_weight*blend,0,false,p_filter,p_reverse_weight*blend); + _process_node(tn->inputs[tn->prev].node,r_prev_anim,0,false,prev_fallback_weight,&prev_weights); tn->time=p_time; } else { - _process_node(tn->inputs[tn->prev].node,r_prev_anim,p_weight*blend,p_time,false,p_filter,p_reverse_weight*blend); + _process_node(tn->inputs[tn->prev].node,r_prev_anim,p_time,false,prev_fallback_weight,&prev_weights); tn->time+=p_time; tn->prev_xfading-=p_time; if (tn->prev_xfading<0) { @@ -750,10 +822,11 @@ void AnimationTreePlayer::_process_animation(float p_delta) { AnimationNode *prev=NULL; if (reset_request) { - _process_node(out_name,&prev, 1.0, 0, true); + + _process_node(out_name,&prev, 0, true); reset_request=false; } else - _process_node(out_name,&prev, 1.0, p_delta); + _process_node(out_name,&prev, p_delta); if (dirty_caches) { //some animation changed.. ignore this pass @@ -802,7 +875,7 @@ void AnimationTreePlayer::_process_animation(float p_delta) { if (tr.track==NULL || tr.local_track<0 || tr.weight < CMP_EPSILON) continue; - float blend=tr.weight; + float blend=tr.weight / tr.track->total_weight; switch(a->track_get_type(tr.local_track)) { case Animation::TYPE_TRANSFORM: { ///< Transform a node or a bone. @@ -1904,6 +1977,3 @@ AnimationTreePlayer::~AnimationTreePlayer() { node_map.erase( node_map.front() ); } } - - - diff --git a/scene/animation/animation_tree_player.h b/scene/animation/animation_tree_player.h index dae891b5ce..6b5350e9ee 100644 --- a/scene/animation/animation_tree_player.h +++ b/scene/animation/animation_tree_player.h @@ -111,6 +111,7 @@ private: Variant value; bool skip; + float total_weight; }; @@ -273,7 +274,7 @@ private: Map<StringName,NodeBase*> node_map; // return time left to finish animation - float _process_node(const StringName& p_node,AnimationNode **r_prev_anim, float p_weight,float p_step, bool p_seek=false,const HashMap<NodePath,bool> *p_filter=NULL, float p_reverse_weight=0); + float _process_node(const StringName& p_node,AnimationNode **r_prev_anim,float p_step, bool p_seek=false, float p_fallback_weight = 1.0, HashMap<NodePath,float>* p_weights = NULL); void _process_animation(float p_delta); bool reset_request; @@ -283,6 +284,8 @@ private: void _recompute_caches(); void _recompute_caches(const StringName& p_node); DVector<String> _get_node_list(); + + void _compute_weights(float *p_fallback_weight, HashMap<NodePath,float> *p_weights, float p_coeff, const HashMap<NodePath,bool> *p_filter = NULL, float p_filtered_coeff = 0); protected: diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 31cef85aa0..b4fa463cde 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -662,8 +662,7 @@ void RichTextLabel::_notification(int p_what) { } break; case NOTIFICATION_ENTER_TREE: { - if (use_bbcode) - parse_bbcode(bbcode); + set_bbcode(bbcode); main->first_invalid_line=0; //invalidate ALL update(); @@ -1440,7 +1439,6 @@ bool RichTextLabel::is_scroll_following() const { Error RichTextLabel::parse_bbcode(const String& p_bbcode) { - clear(); return append_bbcode(p_bbcode); } @@ -1858,6 +1856,10 @@ void RichTextLabel::set_bbcode(const String& p_bbcode) { bbcode=p_bbcode; if (is_inside_tree() && use_bbcode) parse_bbcode(p_bbcode); + else { // raw text + clear(); + add_text(p_bbcode); + } } String RichTextLabel::get_bbcode() const { @@ -1869,19 +1871,37 @@ void RichTextLabel::set_use_bbcode(bool p_enable) { if (use_bbcode==p_enable) return; use_bbcode=p_enable; - if (is_inside_tree() && use_bbcode) - parse_bbcode(bbcode); + set_bbcode(bbcode); } bool RichTextLabel::is_using_bbcode() const { return use_bbcode; } + +String RichTextLabel::get_text() { + String text = ""; + Item *it = main; + while (it) { + if (it->type == ITEM_TEXT) { + ItemText *t = static_cast<ItemText*>(it); + text += t->text; + } else if (it->type == ITEM_NEWLINE) { + text += "\n"; + } else if (it->type == ITEM_INDENT) { + text += "\t"; + } + it=_get_next_item(it,true); + } + return text; +} + void RichTextLabel::_bind_methods() { ObjectTypeDB::bind_method(_MD("_input_event"),&RichTextLabel::_input_event); ObjectTypeDB::bind_method(_MD("_scroll_changed"),&RichTextLabel::_scroll_changed); + ObjectTypeDB::bind_method(_MD("get_text"),&RichTextLabel::get_text); ObjectTypeDB::bind_method(_MD("add_text","text"),&RichTextLabel::add_text); ObjectTypeDB::bind_method(_MD("add_image","image:Texture"),&RichTextLabel::add_image); ObjectTypeDB::bind_method(_MD("newline"),&RichTextLabel::add_newline); diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index 635fe87ad4..5147905a0e 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -280,6 +280,7 @@ protected: public: + String get_text(); void add_text(const String& p_text); void add_image(const Ref<Texture>& p_image); void add_newline(); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 55e1a2cc52..1315b67ea1 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -965,6 +965,12 @@ void TextEdit::_notification(int p_what) { } bool in_highlighted_word = (j >= highlighted_text_col && j < highlighted_text_col+highlighted_text.length()); + + /* if this is the original highlighted text we don't want to highlight it again */ + if (cursor.line==line && (cursor.column >= highlighted_text_col && cursor.column <= highlighted_text_col+highlighted_text.length())) { + in_highlighted_word = false; + } + if (in_highlighted_word) { VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(Point2i( char_ofs+char_margin, ofs_y ), Size2i(char_w, get_row_height())),cache.word_highlighted_color); } diff --git a/scene/resources/sample_library.cpp b/scene/resources/sample_library.cpp index 73517b180e..67481f267d 100644 --- a/scene/resources/sample_library.cpp +++ b/scene/resources/sample_library.cpp @@ -106,9 +106,9 @@ void SampleLibrary::remove_sample(const StringName& p_name) { sample_map.erase(p_name); } -void SampleLibrary::get_sample_list(List<StringName> *p_samples) { +void SampleLibrary::get_sample_list(List<StringName> *p_samples) const { - for(Map<StringName,SampleData >::Element *E=sample_map.front();E;E=E->next()) { + for(const Map<StringName,SampleData >::Element *E=sample_map.front();E;E=E->next()) { p_samples->push_back(E->key()); } @@ -177,7 +177,20 @@ float SampleLibrary::sample_get_pitch_scale(const StringName& p_name) const{ return sample_map[p_name].pitch_scale; } +Array SampleLibrary::_get_sample_list() const { + List<StringName> snames; + get_sample_list(&snames); + + snames.sort_custom<StringName::AlphCompare>(); + + Array ret; + for (List<StringName>::Element *E=snames.front();E;E=E->next()) { + ret.push_back(E->get()); + } + + return ret; +} void SampleLibrary::_bind_methods() { @@ -186,6 +199,8 @@ void SampleLibrary::_bind_methods() { ObjectTypeDB::bind_method(_MD("has_sample","name"),&SampleLibrary::has_sample ); ObjectTypeDB::bind_method(_MD("remove_sample","name"),&SampleLibrary::remove_sample ); + ObjectTypeDB::bind_method(_MD("get_sample_list"),&SampleLibrary::_get_sample_list ); + ObjectTypeDB::bind_method(_MD("sample_set_volume_db","name","db"),&SampleLibrary::sample_set_volume_db ); ObjectTypeDB::bind_method(_MD("sample_get_volume_db","name"),&SampleLibrary::sample_get_volume_db ); diff --git a/scene/resources/sample_library.h b/scene/resources/sample_library.h index 8377967106..e572aa215a 100644 --- a/scene/resources/sample_library.h +++ b/scene/resources/sample_library.h @@ -47,6 +47,8 @@ class SampleLibrary : public Resource { }; Map<StringName,SampleData > sample_map; + + Array _get_sample_list() const; protected: bool _set(const StringName& p_name, const Variant& p_value); @@ -66,7 +68,7 @@ public: void sample_set_pitch_scale(const StringName& p_name, float p_pitch); float sample_get_pitch_scale(const StringName& p_name) const; Ref<Sample> get_sample(const StringName& p_name) const; - void get_sample_list(List<StringName> *p_samples); + void get_sample_list(List<StringName> *p_samples) const; void remove_sample(const StringName& p_name); StringName get_sample_idx(int p_idx) const; |