summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/3d/area.cpp70
-rw-r--r--scene/3d/area.h14
-rw-r--r--scene/3d/bone_attachment.cpp1
-rw-r--r--scene/3d/physics_body.cpp71
-rw-r--r--scene/3d/physics_body.h14
-rw-r--r--scene/3d/ray_cast.cpp32
-rw-r--r--scene/3d/ray_cast.h9
-rw-r--r--scene/animation/animation_tree_player.cpp158
-rw-r--r--scene/animation/animation_tree_player.h7
-rw-r--r--scene/gui/text_edit.cpp5
-rw-r--r--scene/gui/text_edit.h1
-rw-r--r--scene/resources/curve.cpp3
12 files changed, 295 insertions, 90 deletions
diff --git a/scene/3d/area.cpp b/scene/3d/area.cpp
index 7d4235e051..8527c4d60e 100644
--- a/scene/3d/area.cpp
+++ b/scene/3d/area.cpp
@@ -519,6 +519,60 @@ bool Area::overlaps_body(Node* p_body) const{
return E->get().in_tree;
}
+void Area::set_collision_mask(uint32_t p_mask) {
+
+ collision_mask=p_mask;
+ PhysicsServer::get_singleton()->area_set_collision_mask(get_rid(),p_mask);
+}
+
+uint32_t Area::get_collision_mask() const {
+
+ return collision_mask;
+}
+void Area::set_layer_mask(uint32_t p_mask) {
+
+ layer_mask=p_mask;
+ PhysicsServer::get_singleton()->area_set_layer_mask(get_rid(),p_mask);
+}
+
+uint32_t Area::get_layer_mask() const {
+
+ return layer_mask;
+}
+
+void Area::set_collision_mask_bit(int p_bit, bool p_value) {
+
+ uint32_t mask = get_collision_mask();
+ if (p_value)
+ mask|=1<<p_bit;
+ else
+ mask&=~(1<<p_bit);
+ set_collision_mask(mask);
+
+}
+
+bool Area::get_collision_mask_bit(int p_bit) const{
+
+ return get_collision_mask()&(1<<p_bit);
+}
+
+
+void Area::set_layer_mask_bit(int p_bit, bool p_value) {
+
+ uint32_t mask = get_layer_mask();
+ if (p_value)
+ mask|=1<<p_bit;
+ else
+ mask&=~(1<<p_bit);
+ set_layer_mask(mask);
+
+}
+
+bool Area::get_layer_mask_bit(int p_bit) const{
+
+ return get_layer_mask()&(1<<p_bit);
+}
+
void Area::_bind_methods() {
@@ -552,6 +606,18 @@ void Area::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_priority","priority"),&Area::set_priority);
ObjectTypeDB::bind_method(_MD("get_priority"),&Area::get_priority);
+ ObjectTypeDB::bind_method(_MD("set_collision_mask","collision_mask"),&Area::set_collision_mask);
+ ObjectTypeDB::bind_method(_MD("get_collision_mask"),&Area::get_collision_mask);
+
+ ObjectTypeDB::bind_method(_MD("set_layer_mask","layer_mask"),&Area::set_layer_mask);
+ ObjectTypeDB::bind_method(_MD("get_layer_mask"),&Area::get_layer_mask);
+
+ ObjectTypeDB::bind_method(_MD("set_collision_mask_bit","bit","value"),&Area::set_collision_mask_bit);
+ ObjectTypeDB::bind_method(_MD("get_collision_mask_bit","bit"),&Area::get_collision_mask_bit);
+
+ ObjectTypeDB::bind_method(_MD("set_layer_mask_bit","bit","value"),&Area::set_layer_mask_bit);
+ ObjectTypeDB::bind_method(_MD("get_layer_mask_bit","bit"),&Area::get_layer_mask_bit);
+
ObjectTypeDB::bind_method(_MD("set_monitorable","enable"),&Area::set_monitorable);
ObjectTypeDB::bind_method(_MD("is_monitorable"),&Area::is_monitorable);
@@ -589,6 +655,8 @@ void Area::_bind_methods() {
ADD_PROPERTY( PropertyInfo(Variant::INT,"priority",PROPERTY_HINT_RANGE,"0,128,1"),_SCS("set_priority"),_SCS("get_priority"));
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"monitoring"),_SCS("set_enable_monitoring"),_SCS("is_monitoring_enabled"));
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"monitorable"),_SCS("set_monitorable"),_SCS("is_monitorable"));
+ ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
+ ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_mask"),_SCS("get_collision_mask"));
}
@@ -604,6 +672,8 @@ Area::Area() : CollisionObject(PhysicsServer::get_singleton()->area_create(),tru
angular_damp=1;
priority=0;
monitoring=false;
+ collision_mask=1;
+ layer_mask=1;
set_ray_pickable(false);
set_enable_monitoring(true);
set_monitorable(true);
diff --git a/scene/3d/area.h b/scene/3d/area.h
index c250d27fb1..440a7d2030 100644
--- a/scene/3d/area.h
+++ b/scene/3d/area.h
@@ -54,6 +54,8 @@ private:
real_t gravity_distance_scale;
real_t angular_damp;
real_t linear_damp;
+ uint32_t collision_mask;
+ uint32_t layer_mask;
int priority;
bool monitoring;
bool monitorable;
@@ -157,6 +159,18 @@ public:
void set_monitorable(bool p_enable);
bool is_monitorable() const;
+ void set_collision_mask(uint32_t p_mask);
+ uint32_t get_collision_mask() const;
+
+ void set_layer_mask(uint32_t p_mask);
+ uint32_t get_layer_mask() const;
+
+ void set_collision_mask_bit(int p_bit, bool p_value);
+ bool get_collision_mask_bit(int p_bit) const;
+
+ void set_layer_mask_bit(int p_bit, bool p_value);
+ bool get_layer_mask_bit(int p_bit) const;
+
Array get_overlapping_bodies() const;
Array get_overlapping_areas() const; //function for script
diff --git a/scene/3d/bone_attachment.cpp b/scene/3d/bone_attachment.cpp
index 1628ccc15e..56b61d40e2 100644
--- a/scene/3d/bone_attachment.cpp
+++ b/scene/3d/bone_attachment.cpp
@@ -80,6 +80,7 @@ void BoneAttachment::_check_bind() {
int idx = sk->find_bone(bone_name);
if (idx!=-1) {
sk->bind_child_node_to_bone(idx,this);;
+ set_transform(sk->get_bone_global_pose(idx));
bound=true;
}
}
diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp
index bc637eed44..243cb31aca 100644
--- a/scene/3d/physics_body.cpp
+++ b/scene/3d/physics_body.cpp
@@ -69,6 +69,50 @@ uint32_t PhysicsBody::get_layer_mask() const {
return layer_mask;
}
+void PhysicsBody::set_collision_mask(uint32_t p_mask) {
+
+ collision_mask=p_mask;
+ PhysicsServer::get_singleton()->body_set_collision_mask(get_rid(),p_mask);
+}
+
+uint32_t PhysicsBody::get_collision_mask() const {
+
+ return collision_mask;
+}
+
+void PhysicsBody::set_collision_mask_bit(int p_bit, bool p_value) {
+
+ uint32_t mask = get_collision_mask();
+ if (p_value)
+ mask|=1<<p_bit;
+ else
+ mask&=~(1<<p_bit);
+ set_collision_mask(mask);
+
+}
+
+bool PhysicsBody::get_collision_mask_bit(int p_bit) const{
+
+ return get_collision_mask()&(1<<p_bit);
+}
+
+
+void PhysicsBody::set_layer_mask_bit(int p_bit, bool p_value) {
+
+ uint32_t mask = get_layer_mask();
+ if (p_value)
+ mask|=1<<p_bit;
+ else
+ mask&=~(1<<p_bit);
+ set_layer_mask(mask);
+
+}
+
+bool PhysicsBody::get_layer_mask_bit(int p_bit) const{
+
+ return get_layer_mask()&(1<<p_bit);
+}
+
void PhysicsBody::add_collision_exception_with(Node* p_node) {
ERR_FAIL_NULL(p_node);
@@ -92,17 +136,42 @@ void PhysicsBody::remove_collision_exception_with(Node* p_node) {
PhysicsServer::get_singleton()->body_remove_collision_exception(get_rid(),physics_body->get_rid());
}
+void PhysicsBody::_set_layers(uint32_t p_mask) {
+ set_layer_mask(p_mask);
+ set_collision_mask(p_mask);
+}
+
+uint32_t PhysicsBody::_get_layers() const{
+
+ return get_layer_mask();
+}
void PhysicsBody::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&PhysicsBody::set_layer_mask);
ObjectTypeDB::bind_method(_MD("get_layer_mask"),&PhysicsBody::get_layer_mask);
- ADD_PROPERTY(PropertyInfo(Variant::INT,"layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
+
+ ObjectTypeDB::bind_method(_MD("set_collision_mask","mask"),&PhysicsBody::set_collision_mask);
+ ObjectTypeDB::bind_method(_MD("get_collision_mask"),&PhysicsBody::get_collision_mask);
+
+ ObjectTypeDB::bind_method(_MD("set_collision_mask_bit","bit","value"),&PhysicsBody::set_collision_mask_bit);
+ ObjectTypeDB::bind_method(_MD("get_collision_mask_bit","bit"),&PhysicsBody::get_collision_mask_bit);
+
+ ObjectTypeDB::bind_method(_MD("set_layer_mask_bit","bit","value"),&PhysicsBody::set_layer_mask_bit);
+ ObjectTypeDB::bind_method(_MD("get_layer_mask_bit","bit"),&PhysicsBody::get_layer_mask_bit);
+
+ ObjectTypeDB::bind_method(_MD("_set_layers","mask"),&PhysicsBody::_set_layers);
+ ObjectTypeDB::bind_method(_MD("_get_layers"),&PhysicsBody::_get_layers);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"layers",PROPERTY_HINT_ALL_FLAGS,"",0),_SCS("_set_layers"),_SCS("_get_layers")); //for backwards compat
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"collision/mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_mask"),_SCS("get_collision_mask"));
}
PhysicsBody::PhysicsBody(PhysicsServer::BodyMode p_mode) : CollisionObject( PhysicsServer::get_singleton()->body_create(p_mode), false) {
layer_mask=1;
+ collision_mask=1;
}
diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h
index da79d63f00..f95b4f017f 100644
--- a/scene/3d/physics_body.h
+++ b/scene/3d/physics_body.h
@@ -39,6 +39,11 @@ class PhysicsBody : public CollisionObject {
OBJ_TYPE(PhysicsBody,CollisionObject);
uint32_t layer_mask;
+ uint32_t collision_mask;
+
+ void _set_layers(uint32_t p_mask);
+ uint32_t _get_layers() const;
+
protected:
static void _bind_methods();
@@ -53,6 +58,15 @@ public:
void set_layer_mask(uint32_t p_mask);
uint32_t get_layer_mask() const;
+ void set_collision_mask(uint32_t p_mask);
+ uint32_t get_collision_mask() const;
+
+ void set_layer_mask_bit(int p_bit, bool p_value);
+ bool get_layer_mask_bit(int p_bit) const;
+
+ void set_collision_mask_bit(int p_bit, bool p_value);
+ bool get_collision_mask_bit(int p_bit) const;
+
void add_collision_exception_with(Node* p_node); //must be physicsbody
void remove_collision_exception_with(Node* p_node);
diff --git a/scene/3d/ray_cast.cpp b/scene/3d/ray_cast.cpp
index 29813597fa..1acda8d1f8 100644
--- a/scene/3d/ray_cast.cpp
+++ b/scene/3d/ray_cast.cpp
@@ -43,6 +43,26 @@ Vector3 RayCast::get_cast_to() const{
return cast_to;
}
+void RayCast::set_layer_mask(uint32_t p_mask) {
+
+ layer_mask=p_mask;
+}
+
+uint32_t RayCast::get_layer_mask() const {
+
+ return layer_mask;
+}
+
+void RayCast::set_type_mask(uint32_t p_mask) {
+
+ type_mask=p_mask;
+}
+
+uint32_t RayCast::get_type_mask() const {
+
+ return type_mask;
+}
+
bool RayCast::is_colliding() const{
return collided;
@@ -130,7 +150,7 @@ void RayCast::_notification(int p_what) {
PhysicsDirectSpaceState::RayResult rr;
- if (dss->intersect_ray(gt.get_origin(),gt.xform(to),rr,exclude)) {
+ if (dss->intersect_ray(gt.get_origin(),gt.xform(to),rr,exclude, layer_mask, type_mask)) {
collided=true;
against=rr.collider_id;
@@ -206,8 +226,16 @@ void RayCast::_bind_methods() {
ObjectTypeDB::bind_method(_MD("clear_exceptions"),&RayCast::clear_exceptions);
+ ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&RayCast::set_layer_mask);
+ ObjectTypeDB::bind_method(_MD("get_layer_mask"),&RayCast::get_layer_mask);
+
+ ObjectTypeDB::bind_method(_MD("set_type_mask","mask"),&RayCast::set_type_mask);
+ ObjectTypeDB::bind_method(_MD("get_type_mask"),&RayCast::get_type_mask);
+
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"enabled"),_SCS("set_enabled"),_SCS("is_enabled"));
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3,"cast_to"),_SCS("set_cast_to"),_SCS("get_cast_to"));
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"layer_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"type_mask",PROPERTY_HINT_FLAGS,"Static,Kinematic,Rigid,Character,Area"),_SCS("set_type_mask"),_SCS("get_type_mask"));
}
RayCast::RayCast() {
@@ -216,5 +244,7 @@ RayCast::RayCast() {
against=0;
collided=false;
against_shape=0;
+ layer_mask=1;
+ type_mask=PhysicsDirectSpaceState::TYPE_MASK_COLLISION;
cast_to=Vector3(0,-1,0);
}
diff --git a/scene/3d/ray_cast.h b/scene/3d/ray_cast.h
index 520b4d5313..4f6514e61b 100644
--- a/scene/3d/ray_cast.h
+++ b/scene/3d/ray_cast.h
@@ -47,6 +47,9 @@ class RayCast : public Spatial {
Set<RID> exclude;
+ uint32_t layer_mask;
+ uint32_t type_mask;
+
protected:
void _notification(int p_what);
@@ -59,6 +62,12 @@ public:
void set_cast_to(const Vector3& p_point);
Vector3 get_cast_to() const;
+ void set_layer_mask(uint32_t p_mask);
+ uint32_t get_layer_mask() const;
+
+ void set_type_mask(uint32_t p_mask);
+ uint32_t get_type_mask() const;
+
bool is_colliding() const;
Object *get_collider() const;
int get_collider_shape() const;
diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp
index 9dcad8a533..c732dd54cf 100644
--- a/scene/animation/animation_tree_player.cpp
+++ b/scene/animation/animation_tree_player.cpp
@@ -432,7 +432,7 @@ void AnimationTreePlayer::_notification(int p_what) {
}
-float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode **r_prev_anim,float p_weight, float p_time, bool switched, bool p_seek,const HashMap<NodePath,bool> *p_filter, float p_reverse_weight) {
+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) {
ERR_FAIL_COND_V(!node_map.has(p_node), 0);
NodeBase *nb=node_map[p_node];
@@ -445,7 +445,7 @@ 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,switched,p_seek);
+ return _process_node(on->inputs[0].node,r_prev_anim,p_weight,p_time,p_seek);
} break;
case NODE_ANIMATION: {
@@ -479,9 +479,6 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
an->time=anim_size;
}
- if (switched && an->time >= anim_size) {
- an->time = 0.0;
- }
an->skip=true;
for (List<AnimationNode::TrackRef>::Element *E=an->tref.front();E;E=E->next()) {
@@ -523,13 +520,17 @@ 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,switched,p_seek,p_filter,p_reverse_weight);
+ return _process_node(osn->inputs[0].node,r_prev_anim,p_weight,p_time,p_seek,p_filter,p_reverse_weight);
}
+ float os_seek = p_seek;
+
if (p_seek)
osn->time=p_time;
- if (osn->start)
+ if (osn->start) {
osn->time=0;
+ os_seek = true;
+ }
float blend;
@@ -554,13 +555,13 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
if (!osn->filter.empty()) {
- main_rem = _process_node(osn->inputs[0].node,r_prev_anim,(osn->mix?p_weight:p_weight*(1.0-blend)),p_time,switched,p_seek,&osn->filter,p_weight);
- os_rem = _process_node(osn->inputs[1].node,r_prev_anim,p_weight*blend,p_time,osn->start,p_seek,&osn->filter,-1);
+ main_rem = _process_node(osn->inputs[0].node,r_prev_anim,(osn->mix?p_weight:p_weight*(1.0-blend)),p_time,p_seek,&osn->filter,p_weight);
+ os_rem = _process_node(osn->inputs[1].node,r_prev_anim,p_weight*blend,p_time,os_seek,&osn->filter,-1);
} else {
- main_rem = _process_node(osn->inputs[0].node,r_prev_anim,(osn->mix?p_weight:p_weight*(1.0-blend)),p_time,switched,p_seek);
- os_rem = _process_node(osn->inputs[1].node,r_prev_anim,p_weight*blend,p_time,osn->start,p_seek);
+ main_rem = _process_node(osn->inputs[0].node,r_prev_anim,(osn->mix?p_weight:p_weight*(1.0-blend)),p_time,p_seek);
+ os_rem = _process_node(osn->inputs[1].node,r_prev_anim,p_weight*blend,p_time,os_seek);
}
if (osn->start) {
@@ -570,8 +571,8 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
if (!p_seek) {
osn->time+=p_time;
- osn->remaining-=p_time;
- if (osn->remaining<0)
+ osn->remaining=os_rem;
+ if (osn->remaining<=0)
osn->active=false;
}
@@ -581,8 +582,8 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
MixNode *mn = static_cast<MixNode*>(nb);
- float rem = _process_node(mn->inputs[0].node,r_prev_anim,p_weight,p_time,switched,p_seek,p_filter,p_reverse_weight);
- _process_node(mn->inputs[1].node,r_prev_anim,p_weight*mn->amount,p_time,switched,p_seek,p_filter,p_reverse_weight);
+ 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);
return rem;
} break;
@@ -593,12 +594,12 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
float rem;
if (!bn->filter.empty()) {
- rem = _process_node(bn->inputs[0].node,r_prev_anim,p_weight*(1.0-bn->value),p_time,switched,p_seek,&bn->filter,p_weight);
- _process_node(bn->inputs[1].node,r_prev_anim,p_weight*bn->value,p_time,switched,p_seek,&bn->filter,-1);
+ 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,switched,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,switched,p_seek,p_filter,p_reverse_weight*bn->value);
+ 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);
}
return rem;
@@ -618,19 +619,19 @@ 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,switched,p_seek,p_filter,p_reverse_weight*blend);
- _process_node(bn->inputs[2].node,r_prev_anim,p_weight*upper_blend,p_time,switched,p_seek,p_filter,p_reverse_weight*upper_blend);
- _process_node(bn->inputs[0].node,r_prev_anim,p_weight*lower_blend,p_time,switched,p_seek,p_filter,p_reverse_weight*lower_blend);
+ 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);
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,switched,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,switched,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,switched,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,switched,p_seek,p_filter,p_reverse_weight*bn->value.y);
+ 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);
return MAX(rem,rem2);
@@ -639,9 +640,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,switched,true,p_filter,p_reverse_weight);
+ rem = _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time,true,p_filter,p_reverse_weight);
else
- rem = _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time*tsn->scale,switched,false,p_filter,p_reverse_weight);
+ rem = _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time*tsn->scale,false,p_filter,p_reverse_weight);
if (tsn->scale == 0)
return INFINITY;
else
@@ -651,68 +652,58 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
case NODE_TIMESEEK: {
TimeSeekNode *tsn = static_cast<TimeSeekNode*>(nb);
- if (tsn->seek_pos>=0) {
+ if (tsn->seek_pos>=0 && !p_seek) {
- float res = _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,tsn->seek_pos,switched,true,p_filter,p_reverse_weight);
- tsn->seek_pos=-1;
- return res;
+ p_time = tsn->seek_pos;
+ p_seek = true;
+ }
+ tsn->seek_pos=-1;
- } else
- return _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time,switched,p_seek);
+ return _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time,p_seek);
} break;
case NODE_TRANSITION: {
TransitionNode *tn = static_cast<TransitionNode*>(nb);
- if (tn->prev<0) {
+ 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,switched,p_seek,p_filter,p_reverse_weight);
+ float rem = _process_node(tn->inputs[tn->current].node,r_prev_anim,p_weight,p_time,p_seek,p_filter,p_reverse_weight);
if (p_seek)
tn->time=p_time;
else
tn->time+=p_time;
- if (tn->input_data[tn->current].auto_advance && rem < tn->xfade) {
+ if (tn->input_data[tn->current].auto_advance && rem <= tn->xfade) {
- tn->prev=tn->current;
- tn->current++;
- if (tn->current>=tn->inputs.size())
- tn->current=0;
- tn->prev_xfading=tn->xfade;
- tn->prev_time=tn->time;
- tn->time=0;
- tn->switched=true;
+ tn->set_current((tn->current+1) % tn->inputs.size());
}
return rem;
- } else {
+ } else { // cross-fading from tn->prev to tn->current
float blend = tn->xfade? (tn->prev_xfading/tn->xfade) : 1;
float rem;
- if (!p_seek && tn->switched) { //just switched
+ 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,true,p_filter,p_reverse_weight*(1.0-blend));
+ 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));
} else {
- rem = _process_node(tn->inputs[tn->current].node,r_prev_anim,p_weight*(1.0-blend),p_time,switched,p_seek,p_filter,p_reverse_weight*(1.0-blend));
+ 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));
}
tn->switched=false;
- //if (!p_seek)
-
-
- if (p_seek) {
- _process_node(tn->inputs[tn->prev].node,r_prev_anim,p_weight*blend,0,true,false,p_filter,p_reverse_weight*blend);
+ 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);
tn->time=p_time;
} else {
- _process_node(tn->inputs[tn->prev].node,r_prev_anim,p_weight*blend,p_time,switched,false,p_filter,p_reverse_weight*blend);
+ _process_node(tn->inputs[tn->prev].node,r_prev_anim,p_weight*blend,p_time,false,p_filter,p_reverse_weight*blend);
tn->time+=p_time;
tn->prev_xfading-=p_time;
if (tn->prev_xfading<0) {
@@ -749,10 +740,10 @@ void AnimationTreePlayer::_process_animation(float p_delta) {
AnimationNode *prev=NULL;
if (reset_request) {
- _process_node(out_name,&prev, 1.0, 0, true, true );
+ _process_node(out_name,&prev, 1.0, 0, true);
reset_request=false;
} else
- _process_node(out_name,&prev, 1.0, p_delta, false, false );
+ _process_node(out_name,&prev, 1.0, p_delta);
if (dirty_caches) {
//some animation changed.. ignore this pass
@@ -775,9 +766,8 @@ void AnimationTreePlayer::_process_animation(float p_delta) {
t.scale.y=0;
t.scale.z=0;
- Variant value = t.node->get(t.property);
- value.zero();
- t.node->set(t.property, value);
+ t.value = t.object->get(t.property);
+ t.value.zero();
}
@@ -824,9 +814,9 @@ void AnimationTreePlayer::_process_animation(float p_delta) {
case Animation::TYPE_VALUE: { ///< Set a value in a property, can be interpolated.
if (a->value_track_is_continuous(tr.local_track)) {
- Variant blended, value = a->value_track_interpolate(tr.local_track,anim_list->time);
- Variant::blend(tr.track->node->get(tr.track->property),value,blend,blended);
- tr.track->node->set(tr.track->property,blended);
+ Variant value = a->value_track_interpolate(tr.local_track,anim_list->time);
+ Variant::blend(tr.track->value,value,blend,tr.track->value);
+ tr.track->object->set(tr.track->property,tr.track->value);
} else {
List<int> indices;
@@ -834,7 +824,7 @@ void AnimationTreePlayer::_process_animation(float p_delta) {
for(List<int>::Element *E=indices.front();E;E=E->next()) {
Variant value = a->track_get_key_value(tr.local_track,E->get());
- tr.track->node->set(tr.track->property,value);
+ tr.track->object->set(tr.track->property,value);
}
}
} break;
@@ -847,7 +837,7 @@ void AnimationTreePlayer::_process_animation(float p_delta) {
StringName method = a->method_track_get_name(tr.local_track,E->get());
Vector<Variant> args=a->method_track_get_params(tr.local_track,E->get());
args.resize(VARIANT_ARG_MAX);
- tr.track->node->call(method,args[0],args[1],args[2],args[3],args[4]);
+ tr.track->object->call(method,args[0],args[1],args[2],args[3],args[4]);
}
} break;
}
@@ -864,7 +854,7 @@ void AnimationTreePlayer::_process_animation(float p_delta) {
Track &t = E->get();
- if (!t.node)
+ if (!t.object)
continue;
if(t.property) // value track; was applied in step 2
@@ -1158,21 +1148,24 @@ void AnimationTreePlayer::transition_node_set_xfade_time(const StringName& p_nod
n->xfade=p_time;
}
+void AnimationTreePlayer::TransitionNode::set_current(int p_current) {
+ ERR_FAIL_INDEX(p_current,inputs.size());
-void AnimationTreePlayer::transition_node_set_current(const StringName& p_node, int p_current) {
-
- GET_NODE( NODE_TRANSITION, TransitionNode );
- ERR_FAIL_INDEX(p_current,n->inputs.size());
-
- if (n->current==p_current)
+ if (current==p_current)
return;
- n->prev=n->current;
- n->prev_xfading=n->xfade;
- n->prev_time=n->time;
- n->time=0;
- n->current=p_current;
+ prev=current;
+ prev_xfading=xfade;
+ prev_time=time;
+ time=0;
+ current=p_current;
+ switched=true;
+}
+
+void AnimationTreePlayer::transition_node_set_current(const StringName& p_node, int p_current) {
+ GET_NODE( NODE_TRANSITION, TransitionNode );
+ n->set_current(p_current);
}
@@ -1500,7 +1493,8 @@ AnimationTreePlayer::Track* AnimationTreePlayer::_find_track(const NodePath& p_p
Node *parent=get_node(base_path);
ERR_FAIL_COND_V(!parent,NULL);
- Node *child=parent->get_node(p_path);
+ RES resource;
+ Node *child=parent->get_node_and_resource(p_path,resource);
if (!child) {
String err = "Animation track references unknown Node: '"+String(p_path)+"'.";
WARN_PRINT(err.ascii().get_data());
@@ -1528,7 +1522,7 @@ AnimationTreePlayer::Track* AnimationTreePlayer::_find_track(const NodePath& p_p
Track tr;
tr.id=id;
- tr.node=child;
+ tr.object=resource.is_valid()?(Object*)resource.ptr():(Object*)child;
tr.skeleton=child->cast_to<Skeleton>();
tr.spatial=child->cast_to<Spatial>();
tr.bone_idx=bone_idx;
@@ -1606,6 +1600,7 @@ void AnimationTreePlayer::set_active(bool p_active) {
active = p_active;
processing = active;
+ reset_request = p_active;
_set_process(processing, true);
}
@@ -1623,7 +1618,7 @@ AnimationTreePlayer::ConnectError AnimationTreePlayer::get_last_error() const {
void AnimationTreePlayer::reset() {
- reset_request=false;
+ reset_request=true;
}
@@ -1860,12 +1855,11 @@ AnimationTreePlayer::AnimationTreePlayer() {
out_name="out";
out->pos=Point2(40,40);
node_map.insert( out_name , out);
- AnimationProcessMode animation_process_mode;
animation_process_mode = ANIMATION_PROCESS_IDLE;
processing = false;
active=false;
dirty_caches=true;
- reset_request=false;
+ reset_request=true;
last_error=CONNECT_INCOMPLETE;
base_path=String("..");
}
diff --git a/scene/animation/animation_tree_player.h b/scene/animation/animation_tree_player.h
index 0fec9a9551..2e44d69aa1 100644
--- a/scene/animation/animation_tree_player.h
+++ b/scene/animation/animation_tree_player.h
@@ -99,7 +99,7 @@ private:
struct Track {
uint32_t id;
- Node *node;
+ Object *object;
Spatial* spatial;
Skeleton *skeleton;
int bone_idx;
@@ -109,6 +109,8 @@ private:
Quat rot;
Vector3 scale;
+ Variant value;
+
};
@@ -246,6 +248,7 @@ private:
float xfade;
TransitionNode() { type=NODE_TRANSITION; xfade=0; inputs.resize(1); input_data.resize(1); current=0; prev=-1; prev_time=0; prev_xfading=0; switched=false; }
+ void set_current(int p_current);
};
@@ -267,7 +270,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 switched, 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_weight,float p_step, bool p_seek=false,const HashMap<NodePath,bool> *p_filter=NULL, float p_reverse_weight=0);
void _process_animation(float p_delta);
bool reset_request;
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index a0887ffacd..f7461a736c 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -682,14 +682,12 @@ void TextEdit::_notification(int p_what) {
}
if (cache.line_number_w) {
- Color fcol = cache.font_color;
- fcol.a*=0.4;
String fc = String::num(line+1);
while (fc.length() < line_number_char_count) {
fc="0"+fc;
}
- cache.font->draw(ci,Point2(cache.style_normal->get_margin(MARGIN_LEFT),ofs_y+cache.font->get_ascent()),fc,fcol);
+ cache.font->draw(ci,Point2(cache.style_normal->get_margin(MARGIN_LEFT),ofs_y+cache.font->get_ascent()),fc,cache.line_number_color);
}
const Map<int,Text::ColorRegionInfo>& cri_map=text.get_color_region_info(line);
@@ -3083,6 +3081,7 @@ void TextEdit::_update_caches() {
cache.style_focus=get_stylebox("focus");
cache.font=get_font("font");
cache.caret_color=get_color("caret_color");
+ cache.line_number_color=get_color("line_number_color");
cache.font_color=get_color("font_color");
cache.font_selected_color=get_color("font_selected_color");
cache.keyword_color=get_color("keyword_color");
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index 899ce533c4..09c2a4d729 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -74,6 +74,7 @@ class TextEdit : public Control {
Ref<StyleBox> style_focus;
Ref<Font> font;
Color caret_color;
+ Color line_number_color;
Color font_color;
Color font_selected_color;
Color keyword_color;
diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp
index 7dec4029fc..516156c315 100644
--- a/scene/resources/curve.cpp
+++ b/scene/resources/curve.cpp
@@ -543,7 +543,8 @@ void Curve2D::_bake() const {
Vector2 pos=points[0].pos;
List<Vector2> pointlist;
-
+ pointlist.push_back(pos); //start always from origin
+
for(int i=0;i<points.size()-1;i++) {
float step = 0.1; // at least 10 substeps ought to be enough?