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:
reduz 2015-09-15 22:07:03 -03:00
parent 4773c19e60
commit 2580ca01e6
25 changed files with 436 additions and 103 deletions

View File

@ -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

View File

@ -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.

View File

@ -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.

File diff suppressed because one or more lines are too long

View File

@ -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;

View File

@ -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();
};

View File

@ -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);
}

View File

@ -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();
};

View File

@ -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;
}

View File

@ -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();
};

View File

@ -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() {

View File

@ -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();

View File

@ -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;

View File

@ -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();
};

View File

@ -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;

View File

@ -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();

View File

@ -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