Ability to keep collisionshapes and collisionpolygons when running the game.
Works for 2D and 3D These are still just helpers in case you want to animate them or access them directly. Modifying the real shapes is still done via CollisionObject and CollisionObject2D APIs But an API was added so you can query which shapes from CollisionObject correspond to which CollisionShape. Have Fun!
This commit is contained in:
parent
4773c19e60
commit
2580ca01e6
|
@ -0,0 +1,21 @@
|
|||
|
||||
extends RigidBody2D
|
||||
|
||||
# member variables here, example:
|
||||
# var a=2
|
||||
# var b="textvar"
|
||||
|
||||
var timeout=5
|
||||
|
||||
func _process(delta):
|
||||
timeout-=delta
|
||||
if (timeout<1):
|
||||
set_opacity(timeout)
|
||||
if (timeout<0):
|
||||
queue_free()
|
||||
func _ready():
|
||||
set_process(true)
|
||||
# Initialization here
|
||||
pass
|
||||
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 321 B |
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 253 B |
Binary file not shown.
After Width: | Height: | Size: 889 B |
|
@ -0,0 +1,23 @@
|
|||
|
||||
extends Node2D
|
||||
|
||||
# member variables here, example:
|
||||
# var a=2
|
||||
# var b="textvar"
|
||||
const EMIT_INTERVAL=0.1
|
||||
var timeout=EMIT_INTERVAL
|
||||
|
||||
func _process(delta):
|
||||
timeout-=delta
|
||||
if (timeout<0):
|
||||
timeout=EMIT_INTERVAL
|
||||
var ball = preload("res://ball.scn").instance()
|
||||
ball.set_pos( Vector2(randf() * get_viewport_rect().size.x, 0) )
|
||||
add_child(ball)
|
||||
|
||||
func _ready():
|
||||
set_process(true)
|
||||
# Initialization here
|
||||
pass
|
||||
|
||||
|
Binary file not shown.
|
@ -0,0 +1,4 @@
|
|||
[application]
|
||||
|
||||
name="Run-Time CollisionShape"
|
||||
main_scene="res://dynamic_colobjs.scn"
|
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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()) {
|
||||
|
||||
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();
|
||||
}
|
||||
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;
|
||||
}
|
||||
_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_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_depth","depth"),&CollisionPolygon::set_depth);
|
||||
ObjectTypeDB::bind_method(_MD("get_depth"),&CollisionPolygon::get_depth);
|
||||
|
||||
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;
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue