summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
authorRémi Verschelde <remi@verschelde.fr>2016-04-12 13:17:26 +0200
committerRémi Verschelde <remi@verschelde.fr>2016-04-12 13:17:26 +0200
commite07266f6c1177d963f015fa108af40a315305f89 (patch)
treefa11077b94d83f3ce5d677bce45e96a8195ba2c3 /scene
parent29ed58eab698334bcfc06c808406c054b06614a3 (diff)
parentf7c3d6329cdc9c21c205f1522813090313a422d2 (diff)
Merge pull request #4273 from bojidar-bg/add-layers-and-masks-to-3d
Port collision and layer masks to 3D
Diffstat (limited to 'scene')
-rw-r--r--scene/3d/area.cpp70
-rw-r--r--scene/3d/area.h14
-rw-r--r--scene/3d/physics_body.cpp71
-rw-r--r--scene/3d/physics_body.h14
-rw-r--r--scene/3d/ray_cast.cpp32
-rw-r--r--scene/3d/ray_cast.h9
6 files changed, 208 insertions, 2 deletions
diff --git a/scene/3d/area.cpp b/scene/3d/area.cpp
index 7d4235e051..8527c4d60e 100644
--- a/scene/3d/area.cpp
+++ b/scene/3d/area.cpp
@@ -519,6 +519,60 @@ bool Area::overlaps_body(Node* p_body) const{
return E->get().in_tree;
}
+void Area::set_collision_mask(uint32_t p_mask) {
+
+ collision_mask=p_mask;
+ PhysicsServer::get_singleton()->area_set_collision_mask(get_rid(),p_mask);
+}
+
+uint32_t Area::get_collision_mask() const {
+
+ return collision_mask;
+}
+void Area::set_layer_mask(uint32_t p_mask) {
+
+ layer_mask=p_mask;
+ PhysicsServer::get_singleton()->area_set_layer_mask(get_rid(),p_mask);
+}
+
+uint32_t Area::get_layer_mask() const {
+
+ return layer_mask;
+}
+
+void Area::set_collision_mask_bit(int p_bit, bool p_value) {
+
+ uint32_t mask = get_collision_mask();
+ if (p_value)
+ mask|=1<<p_bit;
+ else
+ mask&=~(1<<p_bit);
+ set_collision_mask(mask);
+
+}
+
+bool Area::get_collision_mask_bit(int p_bit) const{
+
+ return get_collision_mask()&(1<<p_bit);
+}
+
+
+void Area::set_layer_mask_bit(int p_bit, bool p_value) {
+
+ uint32_t mask = get_layer_mask();
+ if (p_value)
+ mask|=1<<p_bit;
+ else
+ mask&=~(1<<p_bit);
+ set_layer_mask(mask);
+
+}
+
+bool Area::get_layer_mask_bit(int p_bit) const{
+
+ return get_layer_mask()&(1<<p_bit);
+}
+
void Area::_bind_methods() {
@@ -552,6 +606,18 @@ void Area::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_priority","priority"),&Area::set_priority);
ObjectTypeDB::bind_method(_MD("get_priority"),&Area::get_priority);
+ ObjectTypeDB::bind_method(_MD("set_collision_mask","collision_mask"),&Area::set_collision_mask);
+ ObjectTypeDB::bind_method(_MD("get_collision_mask"),&Area::get_collision_mask);
+
+ ObjectTypeDB::bind_method(_MD("set_layer_mask","layer_mask"),&Area::set_layer_mask);
+ ObjectTypeDB::bind_method(_MD("get_layer_mask"),&Area::get_layer_mask);
+
+ ObjectTypeDB::bind_method(_MD("set_collision_mask_bit","bit","value"),&Area::set_collision_mask_bit);
+ ObjectTypeDB::bind_method(_MD("get_collision_mask_bit","bit"),&Area::get_collision_mask_bit);
+
+ ObjectTypeDB::bind_method(_MD("set_layer_mask_bit","bit","value"),&Area::set_layer_mask_bit);
+ ObjectTypeDB::bind_method(_MD("get_layer_mask_bit","bit"),&Area::get_layer_mask_bit);
+
ObjectTypeDB::bind_method(_MD("set_monitorable","enable"),&Area::set_monitorable);
ObjectTypeDB::bind_method(_MD("is_monitorable"),&Area::is_monitorable);
@@ -589,6 +655,8 @@ void Area::_bind_methods() {
ADD_PROPERTY( PropertyInfo(Variant::INT,"priority",PROPERTY_HINT_RANGE,"0,128,1"),_SCS("set_priority"),_SCS("get_priority"));
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"monitoring"),_SCS("set_enable_monitoring"),_SCS("is_monitoring_enabled"));
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"monitorable"),_SCS("set_monitorable"),_SCS("is_monitorable"));
+ ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
+ ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_mask"),_SCS("get_collision_mask"));
}
@@ -604,6 +672,8 @@ Area::Area() : CollisionObject(PhysicsServer::get_singleton()->area_create(),tru
angular_damp=1;
priority=0;
monitoring=false;
+ collision_mask=1;
+ layer_mask=1;
set_ray_pickable(false);
set_enable_monitoring(true);
set_monitorable(true);
diff --git a/scene/3d/area.h b/scene/3d/area.h
index c250d27fb1..440a7d2030 100644
--- a/scene/3d/area.h
+++ b/scene/3d/area.h
@@ -54,6 +54,8 @@ private:
real_t gravity_distance_scale;
real_t angular_damp;
real_t linear_damp;
+ uint32_t collision_mask;
+ uint32_t layer_mask;
int priority;
bool monitoring;
bool monitorable;
@@ -157,6 +159,18 @@ public:
void set_monitorable(bool p_enable);
bool is_monitorable() const;
+ void set_collision_mask(uint32_t p_mask);
+ uint32_t get_collision_mask() const;
+
+ void set_layer_mask(uint32_t p_mask);
+ uint32_t get_layer_mask() const;
+
+ void set_collision_mask_bit(int p_bit, bool p_value);
+ bool get_collision_mask_bit(int p_bit) const;
+
+ void set_layer_mask_bit(int p_bit, bool p_value);
+ bool get_layer_mask_bit(int p_bit) const;
+
Array get_overlapping_bodies() const;
Array get_overlapping_areas() const; //function for script
diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp
index bc637eed44..243cb31aca 100644
--- a/scene/3d/physics_body.cpp
+++ b/scene/3d/physics_body.cpp
@@ -69,6 +69,50 @@ uint32_t PhysicsBody::get_layer_mask() const {
return layer_mask;
}
+void PhysicsBody::set_collision_mask(uint32_t p_mask) {
+
+ collision_mask=p_mask;
+ PhysicsServer::get_singleton()->body_set_collision_mask(get_rid(),p_mask);
+}
+
+uint32_t PhysicsBody::get_collision_mask() const {
+
+ return collision_mask;
+}
+
+void PhysicsBody::set_collision_mask_bit(int p_bit, bool p_value) {
+
+ uint32_t mask = get_collision_mask();
+ if (p_value)
+ mask|=1<<p_bit;
+ else
+ mask&=~(1<<p_bit);
+ set_collision_mask(mask);
+
+}
+
+bool PhysicsBody::get_collision_mask_bit(int p_bit) const{
+
+ return get_collision_mask()&(1<<p_bit);
+}
+
+
+void PhysicsBody::set_layer_mask_bit(int p_bit, bool p_value) {
+
+ uint32_t mask = get_layer_mask();
+ if (p_value)
+ mask|=1<<p_bit;
+ else
+ mask&=~(1<<p_bit);
+ set_layer_mask(mask);
+
+}
+
+bool PhysicsBody::get_layer_mask_bit(int p_bit) const{
+
+ return get_layer_mask()&(1<<p_bit);
+}
+
void PhysicsBody::add_collision_exception_with(Node* p_node) {
ERR_FAIL_NULL(p_node);
@@ -92,17 +136,42 @@ void PhysicsBody::remove_collision_exception_with(Node* p_node) {
PhysicsServer::get_singleton()->body_remove_collision_exception(get_rid(),physics_body->get_rid());
}
+void PhysicsBody::_set_layers(uint32_t p_mask) {
+ set_layer_mask(p_mask);
+ set_collision_mask(p_mask);
+}
+
+uint32_t PhysicsBody::_get_layers() const{
+
+ return get_layer_mask();
+}
void PhysicsBody::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&PhysicsBody::set_layer_mask);
ObjectTypeDB::bind_method(_MD("get_layer_mask"),&PhysicsBody::get_layer_mask);
- ADD_PROPERTY(PropertyInfo(Variant::INT,"layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
+
+ ObjectTypeDB::bind_method(_MD("set_collision_mask","mask"),&PhysicsBody::set_collision_mask);
+ ObjectTypeDB::bind_method(_MD("get_collision_mask"),&PhysicsBody::get_collision_mask);
+
+ ObjectTypeDB::bind_method(_MD("set_collision_mask_bit","bit","value"),&PhysicsBody::set_collision_mask_bit);
+ ObjectTypeDB::bind_method(_MD("get_collision_mask_bit","bit"),&PhysicsBody::get_collision_mask_bit);
+
+ ObjectTypeDB::bind_method(_MD("set_layer_mask_bit","bit","value"),&PhysicsBody::set_layer_mask_bit);
+ ObjectTypeDB::bind_method(_MD("get_layer_mask_bit","bit"),&PhysicsBody::get_layer_mask_bit);
+
+ ObjectTypeDB::bind_method(_MD("_set_layers","mask"),&PhysicsBody::_set_layers);
+ ObjectTypeDB::bind_method(_MD("_get_layers"),&PhysicsBody::_get_layers);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"layers",PROPERTY_HINT_ALL_FLAGS,"",0),_SCS("_set_layers"),_SCS("_get_layers")); //for backwards compat
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"collision/mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_mask"),_SCS("get_collision_mask"));
}
PhysicsBody::PhysicsBody(PhysicsServer::BodyMode p_mode) : CollisionObject( PhysicsServer::get_singleton()->body_create(p_mode), false) {
layer_mask=1;
+ collision_mask=1;
}
diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h
index da79d63f00..f95b4f017f 100644
--- a/scene/3d/physics_body.h
+++ b/scene/3d/physics_body.h
@@ -39,6 +39,11 @@ class PhysicsBody : public CollisionObject {
OBJ_TYPE(PhysicsBody,CollisionObject);
uint32_t layer_mask;
+ uint32_t collision_mask;
+
+ void _set_layers(uint32_t p_mask);
+ uint32_t _get_layers() const;
+
protected:
static void _bind_methods();
@@ -53,6 +58,15 @@ public:
void set_layer_mask(uint32_t p_mask);
uint32_t get_layer_mask() const;
+ void set_collision_mask(uint32_t p_mask);
+ uint32_t get_collision_mask() const;
+
+ void set_layer_mask_bit(int p_bit, bool p_value);
+ bool get_layer_mask_bit(int p_bit) const;
+
+ void set_collision_mask_bit(int p_bit, bool p_value);
+ bool get_collision_mask_bit(int p_bit) const;
+
void add_collision_exception_with(Node* p_node); //must be physicsbody
void remove_collision_exception_with(Node* p_node);
diff --git a/scene/3d/ray_cast.cpp b/scene/3d/ray_cast.cpp
index 29813597fa..1acda8d1f8 100644
--- a/scene/3d/ray_cast.cpp
+++ b/scene/3d/ray_cast.cpp
@@ -43,6 +43,26 @@ Vector3 RayCast::get_cast_to() const{
return cast_to;
}
+void RayCast::set_layer_mask(uint32_t p_mask) {
+
+ layer_mask=p_mask;
+}
+
+uint32_t RayCast::get_layer_mask() const {
+
+ return layer_mask;
+}
+
+void RayCast::set_type_mask(uint32_t p_mask) {
+
+ type_mask=p_mask;
+}
+
+uint32_t RayCast::get_type_mask() const {
+
+ return type_mask;
+}
+
bool RayCast::is_colliding() const{
return collided;
@@ -130,7 +150,7 @@ void RayCast::_notification(int p_what) {
PhysicsDirectSpaceState::RayResult rr;
- if (dss->intersect_ray(gt.get_origin(),gt.xform(to),rr,exclude)) {
+ if (dss->intersect_ray(gt.get_origin(),gt.xform(to),rr,exclude, layer_mask, type_mask)) {
collided=true;
against=rr.collider_id;
@@ -206,8 +226,16 @@ void RayCast::_bind_methods() {
ObjectTypeDB::bind_method(_MD("clear_exceptions"),&RayCast::clear_exceptions);
+ ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&RayCast::set_layer_mask);
+ ObjectTypeDB::bind_method(_MD("get_layer_mask"),&RayCast::get_layer_mask);
+
+ ObjectTypeDB::bind_method(_MD("set_type_mask","mask"),&RayCast::set_type_mask);
+ ObjectTypeDB::bind_method(_MD("get_type_mask"),&RayCast::get_type_mask);
+
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"enabled"),_SCS("set_enabled"),_SCS("is_enabled"));
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3,"cast_to"),_SCS("set_cast_to"),_SCS("get_cast_to"));
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"layer_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"type_mask",PROPERTY_HINT_FLAGS,"Static,Kinematic,Rigid,Character,Area"),_SCS("set_type_mask"),_SCS("get_type_mask"));
}
RayCast::RayCast() {
@@ -216,5 +244,7 @@ RayCast::RayCast() {
against=0;
collided=false;
against_shape=0;
+ layer_mask=1;
+ type_mask=PhysicsDirectSpaceState::TYPE_MASK_COLLISION;
cast_to=Vector3(0,-1,0);
}
diff --git a/scene/3d/ray_cast.h b/scene/3d/ray_cast.h
index 520b4d5313..4f6514e61b 100644
--- a/scene/3d/ray_cast.h
+++ b/scene/3d/ray_cast.h
@@ -47,6 +47,9 @@ class RayCast : public Spatial {
Set<RID> exclude;
+ uint32_t layer_mask;
+ uint32_t type_mask;
+
protected:
void _notification(int p_what);
@@ -59,6 +62,12 @@ public:
void set_cast_to(const Vector3& p_point);
Vector3 get_cast_to() const;
+ void set_layer_mask(uint32_t p_mask);
+ uint32_t get_layer_mask() const;
+
+ void set_type_mask(uint32_t p_mask);
+ uint32_t get_type_mask() const;
+
bool is_colliding() const;
Object *get_collider() const;
int get_collider_shape() const;