summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/canvas_item.cpp9
-rw-r--r--scene/2d/canvas_item.h7
-rw-r--r--scene/2d/collision_polygon_2d.cpp84
-rw-r--r--scene/2d/collision_polygon_2d.h12
-rw-r--r--scene/2d/collision_shape_2d.cpp64
-rw-r--r--scene/2d/collision_shape_2d.h8
-rw-r--r--scene/3d/body_shape.cpp75
-rw-r--r--scene/3d/body_shape.h14
-rw-r--r--scene/3d/collision_polygon.cpp106
-rw-r--r--scene/3d/collision_polygon.h12
-rw-r--r--scene/3d/spatial.cpp25
-rw-r--r--scene/3d/spatial.h5
-rw-r--r--scene/register_scene_types.cpp10
13 files changed, 373 insertions, 58 deletions
diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp
index 92d5088b81..49229ba500 100644
--- a/scene/2d/canvas_item.cpp
+++ b/scene/2d/canvas_item.cpp
@@ -1172,6 +1172,14 @@ Matrix32 CanvasItem::get_viewport_transform() const {
}
+void CanvasItem::set_notify_local_transform(bool p_enable) {
+ notify_local_transform=p_enable;
+}
+
+bool CanvasItem::is_local_transform_notification_enabled() const {
+ return notify_local_transform;
+}
+
CanvasItem::CanvasItem() : xform_change(this) {
@@ -1191,6 +1199,7 @@ CanvasItem::CanvasItem() : xform_change(this) {
canvas_layer=NULL;
use_parent_material=false;
global_invalid=true;
+ notify_local_transform=false;
light_mask=1;
C=NULL;
diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h
index 6d8308dbe4..4885256c64 100644
--- a/scene/2d/canvas_item.h
+++ b/scene/2d/canvas_item.h
@@ -126,6 +126,7 @@ private:
bool block_transform_notify;
bool behind;
bool use_parent_material;
+ bool notify_local_transform;
Ref<CanvasItemMaterial> material;
@@ -155,7 +156,7 @@ private:
protected:
- _FORCE_INLINE_ void _notify_transform() { if (!is_inside_tree()) return; _notify_transform(this); if (!block_transform_notify) notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED); }
+ _FORCE_INLINE_ void _notify_transform() { if (!is_inside_tree()) return; _notify_transform(this); if (!block_transform_notify && notify_local_transform) notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED); }
void item_rect_changed();
@@ -263,6 +264,10 @@ public:
Vector2 get_global_mouse_pos() const;
Vector2 get_local_mouse_pos() const;
+ void set_notify_local_transform(bool p_enable);
+ bool is_local_transform_notification_enabled() const;
+
+
CanvasItem();
~CanvasItem();
};
diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp
index ceea41d1c8..8a5e2f51d1 100644
--- a/scene/2d/collision_polygon_2d.cpp
+++ b/scene/2d/collision_polygon_2d.cpp
@@ -33,7 +33,7 @@
void CollisionPolygon2D::_add_to_collision_object(Object *p_obj) {
- if (unparenting)
+ if (unparenting || !can_update_body)
return;
CollisionObject2D *co = p_obj->cast_to<CollisionObject2D>();
@@ -49,6 +49,7 @@ void CollisionPolygon2D::_add_to_collision_object(Object *p_obj) {
//here comes the sun, lalalala
//decompose concave into multiple convex polygons and add them
Vector< Vector<Vector2> > decomp = Geometry::decompose_polygon(polygon);
+ shape_from=co->get_shape_count();
for(int i=0;i<decomp.size();i++) {
Ref<ConvexPolygonShape2D> convex = memnew( ConvexPolygonShape2D );
convex->set_points(decomp[i]);
@@ -57,6 +58,11 @@ void CollisionPolygon2D::_add_to_collision_object(Object *p_obj) {
co->set_shape_as_trigger(co->get_shape_count()-1,true);
}
+ shape_to=co->get_shape_count()-1;
+ if (shape_to<shape_from) {
+ shape_from=-1;
+ shape_to=-1;
+ }
} else {
@@ -78,6 +84,9 @@ void CollisionPolygon2D::_add_to_collision_object(Object *p_obj) {
if (trigger)
co->set_shape_as_trigger(co->get_shape_count()-1,true);
+ shape_from=co->get_shape_count()-1;
+ shape_to=co->get_shape_count()-1;
+
}
@@ -86,6 +95,8 @@ void CollisionPolygon2D::_add_to_collision_object(Object *p_obj) {
void CollisionPolygon2D::_update_parent() {
+ if (!can_update_body)
+ return;
Node *parent = get_parent();
if (!parent)
return;
@@ -101,12 +112,24 @@ void CollisionPolygon2D::_notification(int p_what) {
switch(p_what) {
case NOTIFICATION_ENTER_TREE: {
unparenting=false;
+ can_update_body=get_tree()->is_editor_hint();
+ } break;
+ case NOTIFICATION_EXIT_TREE: {
+ can_update_body=false;
} break;
case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
if (!is_inside_tree())
break;
- _update_parent();
+ if (can_update_body) {
+ _update_parent();
+ } else if (shape_from>=0 && shape_to>=0) {
+ CollisionObject2D *co = get_parent()->cast_to<CollisionObject2D>();
+ for(int i=shape_from;i<=shape_to;i++) {
+ co->set_shape_transform(i,get_transform());
+ }
+ }
+
} break;
@@ -141,20 +164,22 @@ void CollisionPolygon2D::set_polygon(const Vector<Point2>& p_polygon) {
polygon=p_polygon;
- for(int i=0;i<polygon.size();i++) {
- if (i==0)
- aabb=Rect2(polygon[i],Size2());
- else
- aabb.expand_to(polygon[i]);
- }
- if (aabb==Rect2()) {
+ if (can_update_body) {
+ for(int i=0;i<polygon.size();i++) {
+ if (i==0)
+ aabb=Rect2(polygon[i],Size2());
+ else
+ aabb.expand_to(polygon[i]);
+ }
+ if (aabb==Rect2()) {
- aabb=Rect2(-10,-10,20,20);
- } else {
- aabb.pos-=aabb.size*0.3;
- aabb.size+=aabb.size*0.6;
+ aabb=Rect2(-10,-10,20,20);
+ } else {
+ aabb.pos-=aabb.size*0.3;
+ aabb.size+=aabb.size*0.6;
+ }
+ _update_parent();
}
- _update_parent();
update();
}
@@ -184,6 +209,13 @@ void CollisionPolygon2D::set_trigger(bool p_trigger) {
trigger=p_trigger;
_update_parent();
+ if (!can_update_body && is_inside_tree() && shape_from>=0 && shape_to>=0) {
+ CollisionObject2D *co = get_parent()->cast_to<CollisionObject2D>();
+ for(int i=shape_from;i<=shape_to;i++) {
+ co->set_shape_as_trigger(i,p_trigger);
+ }
+
+ }
}
bool CollisionPolygon2D::is_trigger() const{
@@ -192,6 +224,17 @@ bool CollisionPolygon2D::is_trigger() const{
}
+void CollisionPolygon2D::_set_shape_range(const Vector2& p_range) {
+
+ shape_from=p_range.x;
+ shape_to=p_range.y;
+}
+
+Vector2 CollisionPolygon2D::_get_shape_range() const {
+
+ return Vector2(shape_from,shape_to);
+}
+
void CollisionPolygon2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_add_to_collision_object"),&CollisionPolygon2D::_add_to_collision_object);
@@ -204,9 +247,17 @@ void CollisionPolygon2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_trigger"),&CollisionPolygon2D::set_trigger);
ObjectTypeDB::bind_method(_MD("is_trigger"),&CollisionPolygon2D::is_trigger);
+ ObjectTypeDB::bind_method(_MD("_set_shape_range","shape_range"),&CollisionPolygon2D::_set_shape_range);
+ ObjectTypeDB::bind_method(_MD("_get_shape_range"),&CollisionPolygon2D::_get_shape_range);
+
+ ObjectTypeDB::bind_method(_MD("get_collision_object_first_shape"),&CollisionPolygon2D::get_collision_object_first_shape);
+ ObjectTypeDB::bind_method(_MD("get_collision_object_last_shape"),&CollisionPolygon2D::get_collision_object_last_shape);
+
ADD_PROPERTY( PropertyInfo(Variant::INT,"build_mode",PROPERTY_HINT_ENUM,"Solids,Segments"),_SCS("set_build_mode"),_SCS("get_build_mode"));
ADD_PROPERTY( PropertyInfo(Variant::VECTOR2_ARRAY,"polygon"),_SCS("set_polygon"),_SCS("get_polygon"));
+ ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"shape_range",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_shape_range"),_SCS("_get_shape_range"));
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"trigger"),_SCS("set_trigger"),_SCS("is_trigger"));
+
}
CollisionPolygon2D::CollisionPolygon2D() {
@@ -215,6 +266,9 @@ CollisionPolygon2D::CollisionPolygon2D() {
build_mode=BUILD_SOLIDS;
trigger=false;
unparenting=false;
-
+ shape_from=-1;
+ shape_to=-1;
+ can_update_body=false;
+ set_notify_local_transform(true);
}
diff --git a/scene/2d/collision_polygon_2d.h b/scene/2d/collision_polygon_2d.h
index 4e78868082..4bc9713c8a 100644
--- a/scene/2d/collision_polygon_2d.h
+++ b/scene/2d/collision_polygon_2d.h
@@ -56,6 +56,14 @@ protected:
void _add_to_collision_object(Object *p_obj);
void _update_parent();
+ bool can_update_body;
+ int shape_from;
+ int shape_to;
+
+ void _set_shape_range(const Vector2& p_range);
+ Vector2 _get_shape_range() const;
+
+
protected:
void _notification(int p_what);
@@ -72,6 +80,10 @@ public:
Vector<Point2> get_polygon() const;
virtual Rect2 get_item_rect() const;
+
+ int get_collision_object_first_shape() const { return shape_from; }
+ int get_collision_object_last_shape() const { return shape_to; }
+
CollisionPolygon2D();
};
diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp
index 5012c54b17..a0a015a99e 100644
--- a/scene/2d/collision_shape_2d.cpp
+++ b/scene/2d/collision_shape_2d.cpp
@@ -44,10 +44,12 @@ void CollisionShape2D::_add_to_collision_object(Object *p_obj) {
CollisionObject2D *co = p_obj->cast_to<CollisionObject2D>();
ERR_FAIL_COND(!co);
+ update_shape_index=co->get_shape_count();
co->add_shape(shape,get_transform());
if (trigger)
co->set_shape_as_trigger(co->get_shape_count()-1,true);
+
}
void CollisionShape2D::_shape_changed() {
@@ -74,12 +76,27 @@ void CollisionShape2D::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
unparenting=false;
+ can_update_body=get_tree()->is_editor_hint();
+
} break;
case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
if (!is_inside_tree())
break;
- _update_parent();
+ if (can_update_body) {
+ _update_parent();
+ } else if (update_shape_index>=0){
+
+ CollisionObject2D *co = get_parent()->cast_to<CollisionObject2D>();
+ if (co) {
+ co->set_shape_transform(update_shape_index,get_transform());
+ }
+
+ }
+
+ } break;
+ case NOTIFICATION_EXIT_TREE: {
+ can_update_body=false;
} break;
/*
@@ -92,6 +109,9 @@ void CollisionShape2D::_notification(int p_what) {
} break;*/
case NOTIFICATION_DRAW: {
+ if (!get_tree()->is_editor_hint())
+ return;
+
rect=Rect2();
Color draw_col=Color(0,0.6,0.7,0.5);
@@ -209,7 +229,14 @@ void CollisionShape2D::set_shape(const Ref<Shape2D>& p_shape) {
shape->disconnect("changed",this,"_shape_changed");
shape=p_shape;
update();
- _update_parent();
+ if (is_inside_tree() && can_update_body)
+ _update_parent();
+ if (is_inside_tree() && !can_update_body && update_shape_index>=0) {
+ CollisionObject2D *co = get_parent()->cast_to<CollisionObject2D>();
+ if (co) {
+ co->set_shape(update_shape_index,p_shape);
+ }
+ }
if (shape.is_valid())
shape->connect("changed",this,"_shape_changed");
@@ -228,7 +255,14 @@ Rect2 CollisionShape2D::get_item_rect() const {
void CollisionShape2D::set_trigger(bool p_trigger) {
trigger=p_trigger;
- _update_parent();
+ if (can_update_body) {
+ _update_parent();
+ } else if (is_inside_tree() && update_shape_index>=0){
+ CollisionObject2D *co = get_parent()->cast_to<CollisionObject2D>();
+ if (co) {
+ co->set_shape_as_trigger(update_shape_index,p_trigger);
+ }
+ }
}
bool CollisionShape2D::is_trigger() const{
@@ -236,6 +270,19 @@ bool CollisionShape2D::is_trigger() const{
return trigger;
}
+
+void CollisionShape2D::_set_update_shape_index(int p_index) {
+
+
+ update_shape_index=p_index;
+}
+
+int CollisionShape2D::_get_update_shape_index() const{
+
+ return update_shape_index;
+}
+
+
void CollisionShape2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_shape","shape"),&CollisionShape2D::set_shape);
@@ -245,14 +292,23 @@ void CollisionShape2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_trigger","enable"),&CollisionShape2D::set_trigger);
ObjectTypeDB::bind_method(_MD("is_trigger"),&CollisionShape2D::is_trigger);
+ ObjectTypeDB::bind_method(_MD("_set_update_shape_index","index"),&CollisionShape2D::_set_update_shape_index);
+ ObjectTypeDB::bind_method(_MD("_get_update_shape_index"),&CollisionShape2D::_get_update_shape_index);
+
+ ObjectTypeDB::bind_method(_MD("get_collision_object_shape_index"),&CollisionShape2D::get_collision_object_shape_index);
+
ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT,"shape",PROPERTY_HINT_RESOURCE_TYPE,"Shape2D"),_SCS("set_shape"),_SCS("get_shape"));
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"trigger"),_SCS("set_trigger"),_SCS("is_trigger"));
+ ADD_PROPERTY( PropertyInfo( Variant::INT, "_update_shape_index", PROPERTY_HINT_NONE, "",PROPERTY_USAGE_NOEDITOR), _SCS("_set_update_shape_index"), _SCS("_get_update_shape_index"));
+
}
CollisionShape2D::CollisionShape2D() {
rect=Rect2(-Point2(10,10),Point2(20,20));
-
+ set_notify_local_transform(true);
trigger=false;
unparenting = false;
+ can_update_body = false;
+ update_shape_index=-1;
}
diff --git a/scene/2d/collision_shape_2d.h b/scene/2d/collision_shape_2d.h
index 507912d31e..82e1137174 100644
--- a/scene/2d/collision_shape_2d.h
+++ b/scene/2d/collision_shape_2d.h
@@ -39,7 +39,13 @@ class CollisionShape2D : public Node2D {
Rect2 rect;
bool trigger;
bool unparenting;
+ bool can_update_body;
void _shape_changed();
+ int update_shape_index;
+
+ void _set_update_shape_index(int p_index);
+ int _get_update_shape_index() const;
+
protected:
void _update_parent();
@@ -55,6 +61,8 @@ public:
void set_trigger(bool p_trigger);
bool is_trigger() const;
+ int get_collision_object_shape_index() const { return _get_update_shape_index(); }
+
CollisionShape2D();
};
diff --git a/scene/3d/body_shape.cpp b/scene/3d/body_shape.cpp
index c49d1b028c..709a79a5f4 100644
--- a/scene/3d/body_shape.cpp
+++ b/scene/3d/body_shape.cpp
@@ -43,7 +43,10 @@
void CollisionShape::_update_body() {
-
+ if (!get_tree() || !can_update_body)
+ return;
+ if (!get_tree()->is_editor_hint())
+ return;
if (get_parent() && get_parent()->cast_to<CollisionObject>())
get_parent()->cast_to<CollisionObject>()->_update_shapes_from_children();
@@ -310,10 +313,13 @@ void CollisionShape::_add_to_collision_object(Object* p_cshape) {
if (shape.is_valid()) {
+ update_shape_index=co->get_shape_count();
co->add_shape(shape,get_transform());
- if (trigger)
- co->set_shape_as_trigger( co->get_shape_count() -1, true );
- }
+ if (trigger)
+ co->set_shape_as_trigger( co->get_shape_count() -1, true );
+ } else {
+ update_shape_index=-1;
+ }
}
void CollisionShape::_notification(int p_what) {
@@ -322,12 +328,14 @@ void CollisionShape::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
unparenting=false;
+ can_update_body=get_tree()->is_editor_hint();
+ set_notify_local_transform(!can_update_body);
//indicator_instance = VisualServer::get_singleton()->instance_create2(indicator,get_world()->get_scenario());
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
// VisualServer::get_singleton()->instance_set_transform(indicator_instance,get_global_transform());
- if (updating_body) {
+ if (can_update_body && updating_body) {
_update_body();
}
} break;
@@ -336,16 +344,30 @@ void CollisionShape::_notification(int p_what) {
VisualServer::get_singleton()->free(indicator_instance);
indicator_instance=RID();
}*/
+ can_update_body=false;
+ set_notify_local_transform(false);
} break;
case NOTIFICATION_UNPARENTED: {
unparenting=true;
- if (updating_body)
+ if (can_update_body && updating_body)
_update_body();
} break;
case NOTIFICATION_PARENTED: {
- if (updating_body)
+ if (can_update_body && updating_body)
_update_body();
} break;
+ case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
+
+ if (!can_update_body && update_shape_index>=0) {
+
+ CollisionObject *co = get_parent()->cast_to<CollisionObject>();
+ if (co) {
+ co->set_shape_transform(update_shape_index,get_transform());
+ }
+ }
+
+ } break;
+
}
}
@@ -357,6 +379,18 @@ void CollisionShape::resource_changed(RES res) {
}
+void CollisionShape::_set_update_shape_index(int p_index) {
+
+
+ update_shape_index=p_index;
+}
+
+int CollisionShape::_get_update_shape_index() const{
+
+ return update_shape_index;
+}
+
+
void CollisionShape::_bind_methods() {
//not sure if this should do anything
@@ -368,10 +402,14 @@ void CollisionShape::_bind_methods() {
ObjectTypeDB::bind_method(_MD("is_trigger"),&CollisionShape::is_trigger);
ObjectTypeDB::bind_method(_MD("make_convex_from_brothers"),&CollisionShape::make_convex_from_brothers);
ObjectTypeDB::set_method_flags("CollisionShape","make_convex_from_brothers",METHOD_FLAGS_DEFAULT|METHOD_FLAG_EDITOR);
+ ObjectTypeDB::bind_method(_MD("_set_update_shape_index","index"),&CollisionShape::_set_update_shape_index);
+ ObjectTypeDB::bind_method(_MD("_get_update_shape_index"),&CollisionShape::_get_update_shape_index);
+ ObjectTypeDB::bind_method(_MD("get_collision_object_shape_index"),&CollisionShape::get_collision_object_shape_index);
ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape"), _SCS("set_shape"), _SCS("get_shape"));
- ADD_PROPERTY(PropertyInfo(Variant::BOOL,"trigger"),_SCS("set_trigger"),_SCS("is_trigger"));
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL,"trigger"),_SCS("set_trigger"),_SCS("is_trigger"));
+ ADD_PROPERTY( PropertyInfo( Variant::INT, "_update_shape_index", PROPERTY_HINT_NONE, "",PROPERTY_USAGE_NOEDITOR), _SCS("_set_update_shape_index"), _SCS("_get_update_shape_index"));
}
@@ -383,8 +421,15 @@ void CollisionShape::set_shape(const Ref<Shape> &p_shape) {
if (!shape.is_null())
shape->register_owner(this);
update_gizmo();
- if (updating_body)
+ if (updating_body) {
_update_body();
+ } else if (can_update_body && update_shape_index>=0 && is_inside_tree()){
+ CollisionObject *co = get_parent()->cast_to<CollisionObject>();
+ if (co) {
+ co->set_shape(update_shape_index,p_shape);
+ }
+
+ }
}
Ref<Shape> CollisionShape::get_shape() const {
@@ -405,8 +450,14 @@ bool CollisionShape::is_updating_body() const {
void CollisionShape::set_trigger(bool p_trigger) {
trigger=p_trigger;
- if (updating_body)
+ if (updating_body) {
_update_body();
+ } else if (can_update_body && update_shape_index>=0 && is_inside_tree()){
+ CollisionObject *co = get_parent()->cast_to<CollisionObject>();
+ if (co) {
+ co->set_shape_as_trigger(update_shape_index,p_trigger);
+ }
+ }
}
bool CollisionShape::is_trigger() const{
@@ -419,7 +470,9 @@ CollisionShape::CollisionShape() {
//indicator = VisualServer::get_singleton()->mesh_create();
updating_body=true;
unparenting=false;
- trigger=false;
+ update_shape_index=-1;
+ trigger=false;
+ can_update_body=false;
}
CollisionShape::~CollisionShape() {
diff --git a/scene/3d/body_shape.h b/scene/3d/body_shape.h
index b3c0006d79..c1ebf806a9 100644
--- a/scene/3d/body_shape.h
+++ b/scene/3d/body_shape.h
@@ -56,8 +56,16 @@ class CollisionShape : public Spatial {
bool unparenting;
bool trigger;
+ bool can_update_body;
+
+ int update_shape_index;
+
void _update_body();
void _add_to_collision_object(Object* p_cshape);
+
+ void _set_update_shape_index(int p_index);
+ int _get_update_shape_index() const;
+
protected:
void _notification(int p_what);
@@ -73,8 +81,10 @@ public:
void set_updating_body(bool p_update);
bool is_updating_body() const;
- void set_trigger(bool p_trigger);
- bool is_trigger() const;
+ void set_trigger(bool p_trigger);
+ bool is_trigger() const;
+
+ int get_collision_object_shape_index() const { return _get_update_shape_index(); }
CollisionShape();
~CollisionShape();
diff --git a/scene/3d/collision_polygon.cpp b/scene/3d/collision_polygon.cpp
index 4ab1a1a1ab..c857b4851a 100644
--- a/scene/3d/collision_polygon.cpp
+++ b/scene/3d/collision_polygon.cpp
@@ -6,6 +6,8 @@
void CollisionPolygon::_add_to_collision_object(Object *p_obj) {
+ if (!can_update_body)
+ return;
CollisionObject *co = p_obj->cast_to<CollisionObject>();
ERR_FAIL_COND(!co);
@@ -23,6 +25,7 @@ void CollisionPolygon::_add_to_collision_object(Object *p_obj) {
//here comes the sun, lalalala
//decompose concave into multiple convex polygons and add them
+ shape_from=co->get_shape_count();
for(int i=0;i<decomp.size();i++) {
Ref<ConvexPolygonShape> convex = memnew( ConvexPolygonShape );
DVector<Vector3> cp;
@@ -43,6 +46,11 @@ void CollisionPolygon::_add_to_collision_object(Object *p_obj) {
co->add_shape(convex,get_transform());
}
+ shape_to=co->get_shape_count()-1;
+ if (shape_to<shape_from) {
+ shape_from=-1;
+ shape_to=-1;
+ }
} else {
#if 0
@@ -71,6 +79,9 @@ void CollisionPolygon::_add_to_collision_object(Object *p_obj) {
void CollisionPolygon::_update_parent() {
+ if (!can_update_body)
+ return;
+
Node *parent = get_parent();
if (!parent)
return;
@@ -80,15 +91,50 @@ void CollisionPolygon::_update_parent() {
co->_update_shapes_from_children();
}
+void CollisionPolygon::_set_shape_range(const Vector2& p_range) {
+
+ shape_from=p_range.x;
+ shape_to=p_range.y;
+}
+
+Vector2 CollisionPolygon::_get_shape_range() const {
+
+ return Vector2(shape_from,shape_to);
+}
+
void CollisionPolygon::_notification(int p_what) {
switch(p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ can_update_body=get_tree()->is_editor_hint();
+ set_notify_local_transform(!can_update_body);
+
+ //indicator_instance = VisualServer::get_singleton()->instance_create2(indicator,get_world()->get_scenario());
+ } break;
+ case NOTIFICATION_EXIT_TREE: {
+ can_update_body=false;
+ set_notify_local_transform(false);
+ } break;
case NOTIFICATION_TRANSFORM_CHANGED: {
if (!is_inside_tree())
break;
- _update_parent();
+ if (can_update_body) {
+ _update_parent();
+ }
+
+ } break;
+ case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
+ if (!can_update_body && shape_from>=0 && shape_from>=0) {
+
+ CollisionObject *co = get_parent()->cast_to<CollisionObject>();
+ if (co) {
+ for(int i=shape_from;i<=shape_to;i++) {
+ co->set_shape_transform(i,get_transform());
+ }
+ }
+ }
} break;
#if 0
@@ -119,29 +165,31 @@ void CollisionPolygon::_notification(int p_what) {
void CollisionPolygon::set_polygon(const Vector<Point2>& p_polygon) {
polygon=p_polygon;
+ if (can_update_body) {
- for(int i=0;i<polygon.size();i++) {
+ for(int i=0;i<polygon.size();i++) {
- Vector3 p1(polygon[i].x,polygon[i].y,depth*0.5);
+ Vector3 p1(polygon[i].x,polygon[i].y,depth*0.5);
- if (i==0)
- aabb=AABB(p1,Vector3());
- else
- aabb.expand_to(p1);
+ if (i==0)
+ aabb=AABB(p1,Vector3());
+ else
+ aabb.expand_to(p1);
- Vector3 p2(polygon[i].x,polygon[i].y,-depth*0.5);
- aabb.expand_to(p2);
+ Vector3 p2(polygon[i].x,polygon[i].y,-depth*0.5);
+ aabb.expand_to(p2);
- }
- if (aabb==AABB()) {
+ }
+ if (aabb==AABB()) {
- aabb=AABB(Vector3(-1,-1,-1),Vector3(2,2,2));
- } else {
- aabb.pos-=aabb.size*0.3;
- aabb.size+=aabb.size*0.6;
+ aabb=AABB(Vector3(-1,-1,-1),Vector3(2,2,2));
+ } else {
+ aabb.pos-=aabb.size*0.3;
+ aabb.size+=aabb.size*0.6;
+ }
+ _update_parent();
}
- _update_parent();
update_gizmo();
}
@@ -154,6 +202,8 @@ void CollisionPolygon::set_build_mode(BuildMode p_mode) {
ERR_FAIL_INDEX(p_mode,2);
build_mode=p_mode;
+ if (!can_update_body)
+ return;
_update_parent();
}
@@ -170,6 +220,8 @@ AABB CollisionPolygon::get_item_rect() const {
void CollisionPolygon::set_depth(float p_depth) {
depth=p_depth;
+ if (!can_update_body)
+ return;
_update_parent();
update_gizmo();
}
@@ -183,22 +235,34 @@ float CollisionPolygon::get_depth() const {
void CollisionPolygon::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_add_to_collision_object"),&CollisionPolygon::_add_to_collision_object);
- ObjectTypeDB::bind_method(_MD("set_polygon","polygon"),&CollisionPolygon::set_polygon);
- ObjectTypeDB::bind_method(_MD("get_polygon"),&CollisionPolygon::get_polygon);
+
+ ObjectTypeDB::bind_method(_MD("set_build_mode"),&CollisionPolygon::set_build_mode);
+ ObjectTypeDB::bind_method(_MD("get_build_mode"),&CollisionPolygon::get_build_mode);
ObjectTypeDB::bind_method(_MD("set_depth","depth"),&CollisionPolygon::set_depth);
ObjectTypeDB::bind_method(_MD("get_depth"),&CollisionPolygon::get_depth);
- ObjectTypeDB::bind_method(_MD("set_build_mode"),&CollisionPolygon::set_build_mode);
- ObjectTypeDB::bind_method(_MD("get_build_mode"),&CollisionPolygon::get_build_mode);
+ ObjectTypeDB::bind_method(_MD("set_polygon","polygon"),&CollisionPolygon::set_polygon);
+ ObjectTypeDB::bind_method(_MD("get_polygon"),&CollisionPolygon::get_polygon);
+
+ ObjectTypeDB::bind_method(_MD("_set_shape_range","shape_range"),&CollisionPolygon::_set_shape_range);
+ ObjectTypeDB::bind_method(_MD("_get_shape_range"),&CollisionPolygon::_get_shape_range);
+
+ ObjectTypeDB::bind_method(_MD("get_collision_object_first_shape"),&CollisionPolygon::get_collision_object_first_shape);
+ ObjectTypeDB::bind_method(_MD("get_collision_object_last_shape"),&CollisionPolygon::get_collision_object_last_shape);
ADD_PROPERTY( PropertyInfo(Variant::INT,"build_mode",PROPERTY_HINT_ENUM,"Solids,Triangles"),_SCS("set_build_mode"),_SCS("get_build_mode"));
- ADD_PROPERTY( PropertyInfo(Variant::VECTOR2_ARRAY,"polygon"),_SCS("set_polygon"),_SCS("get_polygon"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"depth"),_SCS("set_depth"),_SCS("get_depth"));
+ ADD_PROPERTY( PropertyInfo(Variant::VECTOR2_ARRAY,"polygon"),_SCS("set_polygon"),_SCS("get_polygon"));
+ ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"shape_range",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_shape_range"),_SCS("_get_shape_range"));
}
CollisionPolygon::CollisionPolygon() {
+ shape_from=-1;
+ shape_to=-1;
+ can_update_body=false;
+
aabb=AABB(Vector3(-1,-1,-1),Vector3(2,2,2));
build_mode=BUILD_SOLIDS;
depth=1.0;
diff --git a/scene/3d/collision_polygon.h b/scene/3d/collision_polygon.h
index efb3666778..9b9afea34f 100644
--- a/scene/3d/collision_polygon.h
+++ b/scene/3d/collision_polygon.h
@@ -24,9 +24,17 @@ protected:
BuildMode build_mode;
Vector<Point2> polygon;
+
void _add_to_collision_object(Object *p_obj);
void _update_parent();
+ bool can_update_body;
+ int shape_from;
+ int shape_to;
+
+ void _set_shape_range(const Vector2& p_range);
+ Vector2 _get_shape_range() const;
+
protected:
void _notification(int p_what);
@@ -43,6 +51,10 @@ public:
Vector<Point2> get_polygon() const;
virtual AABB get_item_rect() const;
+
+ int get_collision_object_first_shape() const { return shape_from; }
+ int get_collision_object_last_shape() const { return shape_to; }
+
CollisionPolygon();
};
diff --git a/scene/3d/spatial.cpp b/scene/3d/spatial.cpp
index 7117c59176..a65f68ed2c 100644
--- a/scene/3d/spatial.cpp
+++ b/scene/3d/spatial.cpp
@@ -231,6 +231,11 @@ void Spatial::set_transform(const Transform& p_transform) {
_change_notify("transform/rotation");
_change_notify("transform/scale");
_propagate_transform_changed(this);
+ if (data.notify_local_transform) {
+ notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED);
+ }
+
+
}
@@ -335,6 +340,9 @@ void Spatial::set_translation(const Vector3& p_translation) {
data.local_transform.origin=p_translation;
_propagate_transform_changed(this);
+ if (data.notify_local_transform) {
+ notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED);
+ }
}
@@ -348,6 +356,9 @@ void Spatial::set_rotation(const Vector3& p_euler){
data.rotation=p_euler;
data.dirty|=DIRTY_LOCAL;
_propagate_transform_changed(this);
+ if (data.notify_local_transform) {
+ notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED);
+ }
}
void Spatial::set_scale(const Vector3& p_scale){
@@ -360,6 +371,9 @@ void Spatial::set_scale(const Vector3& p_scale){
data.scale=p_scale;
data.dirty|=DIRTY_LOCAL;
_propagate_transform_changed(this);
+ if (data.notify_local_transform) {
+ notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED);
+ }
}
@@ -685,6 +699,13 @@ void Spatial::look_at_from_pos(const Vector3& p_pos,const Vector3& p_target, con
}
+void Spatial::set_notify_local_transform(bool p_enable) {
+ data.notify_local_transform=p_enable;
+}
+
+bool Spatial::is_local_transform_notification_enabled() const {
+ return data.notify_local_transform;
+}
void Spatial::_bind_methods() {
@@ -725,6 +746,9 @@ void Spatial::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_set_visible_"), &Spatial::_set_visible_);
ObjectTypeDB::bind_method(_MD("_is_visible_"), &Spatial::_is_visible_);
+ ObjectTypeDB::bind_method(_MD("set_notify_local_transform","enable"), &Spatial::set_notify_local_transform);
+ ObjectTypeDB::bind_method(_MD("is_local_transform_notification_enabled"), &Spatial::is_local_transform_notification_enabled);
+
void rotate(const Vector3& p_normal,float p_radians);
void rotate_x(float p_radians);
void rotate_y(float p_radians);
@@ -783,6 +807,7 @@ Spatial::Spatial() : xform_change(this)
data.gizmo_disabled=false;
data.gizmo_dirty=false;
#endif
+ data.notify_local_transform=false;
data.parent=NULL;
data.C=NULL;
diff --git a/scene/3d/spatial.h b/scene/3d/spatial.h
index 8b40786fb8..7fa6099d7a 100644
--- a/scene/3d/spatial.h
+++ b/scene/3d/spatial.h
@@ -91,6 +91,7 @@ class Spatial : public Node {
List<Spatial*>::Element *C;
bool ignore_notification;
+ bool notify_local_transform;
bool visible;
@@ -134,6 +135,7 @@ public:
NOTIFICATION_ENTER_WORLD=41,
NOTIFICATION_EXIT_WORLD=42,
NOTIFICATION_VISIBILITY_CHANGED=43,
+ NOTIFICATION_LOCAL_TRANSFORM_CHANGED=44,
};
Spatial *get_parent_spatial() const;
@@ -179,6 +181,9 @@ public:
void look_at(const Vector3& p_target, const Vector3& p_up_normal);
void look_at_from_pos(const Vector3& p_pos,const Vector3& p_target, const Vector3& p_up_normal);
+ void set_notify_local_transform(bool p_enable);
+ bool is_local_transform_notification_enabled() const;
+
void orthonormalize();
void set_identity();
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 3727c2e8ec..851de4a89f 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -458,7 +458,6 @@ void register_scene_types() {
/* disable types by default, only editors should enable them */
- ObjectTypeDB::set_type_enabled("CollisionShape",false);
//ObjectTypeDB::set_type_enabled("BodyVolumeSphere",false);
//ObjectTypeDB::set_type_enabled("BodyVolumeBox",false);
//ObjectTypeDB::set_type_enabled("BodyVolumeCapsule",false);
@@ -492,9 +491,12 @@ void register_scene_types() {
ObjectTypeDB::register_type<OccluderPolygon2D>();
ObjectTypeDB::register_type<YSort>();
ObjectTypeDB::register_type<BackBufferCopy>();
-
- ObjectTypeDB::set_type_enabled("CollisionShape2D",false);
- ObjectTypeDB::set_type_enabled("CollisionPolygon2D",false);
+ if (bool(GLOBAL_DEF("physics/remove_collision_helpers_at_runtime",false))) {
+ ObjectTypeDB::set_type_enabled("CollisionShape2D",false);
+ ObjectTypeDB::set_type_enabled("CollisionPolygon2D",false);
+ ObjectTypeDB::set_type_enabled("CollisionShape",false);
+ ObjectTypeDB::set_type_enabled("CollisionPolygon",false);
+ }
OS::get_singleton()->yield(); //may take time to init