summaryrefslogtreecommitdiff
path: root/servers/physics
diff options
context:
space:
mode:
authorBojidar Marinov <bojidar.marinov.bg@gmail.com>2016-04-09 21:54:09 +0300
committerBojidar Marinov <bojidar.marinov.bg@gmail.com>2016-04-09 22:11:12 +0300
commitf7c3d6329cdc9c21c205f1522813090313a422d2 (patch)
treeb4ad305e45bf2d66f5e3a8d35aa36948a2f20c5a /servers/physics
parentd454e64f429affb89de036eed6daa5c6e5278492 (diff)
Port collision and layer masks to 3D, fixes #1759
Raycasts now have type_mask and layer_mask. Areas - collision_mask and layer_mask. PhysicsBodies needed only collision_mask.
Diffstat (limited to 'servers/physics')
-rw-r--r--servers/physics/area_pair_sw.cpp10
-rw-r--r--servers/physics/body_pair_sw.cpp2
-rw-r--r--servers/physics/collision_object_sw.cpp1
-rw-r--r--servers/physics/collision_object_sw.h8
-rw-r--r--servers/physics/physics_server_sw.cpp35
-rw-r--r--servers/physics/physics_server_sw.h6
6 files changed, 61 insertions, 1 deletions
diff --git a/servers/physics/area_pair_sw.cpp b/servers/physics/area_pair_sw.cpp
index c6bf6114a0..24f3b75ca5 100644
--- a/servers/physics/area_pair_sw.cpp
+++ b/servers/physics/area_pair_sw.cpp
@@ -32,6 +32,11 @@
bool AreaPairSW::setup(float p_step) {
+ if (!area->test_collision_mask(body)) {
+ colliding = false;
+ return false;
+ }
+
bool result = CollisionSolverSW::solve_static(body->get_shape(body_shape),body->get_transform() * body->get_shape_transform(body_shape),area->get_shape(area_shape),area->get_transform() * area->get_shape_transform(area_shape),NULL,this);
if (result!=colliding) {
@@ -100,6 +105,11 @@ AreaPairSW::~AreaPairSW() {
bool Area2PairSW::setup(float p_step) {
+ if (!area_a->test_collision_mask(area_b)) {
+ colliding = false;
+ return false;
+ }
+
// bool result = area_a->test_collision_mask(area_b) && CollisionSolverSW::solve(area_a->get_shape(shape_a),area_a->get_transform() * area_a->get_shape_transform(shape_a),Vector2(),area_b->get_shape(shape_b),area_b->get_transform() * area_b->get_shape_transform(shape_b),Vector2(),NULL,this);
bool result = CollisionSolverSW::solve_static(area_a->get_shape(shape_a),area_a->get_transform() * area_a->get_shape_transform(shape_a),area_b->get_shape(shape_b),area_b->get_transform() * area_b->get_shape_transform(shape_b),NULL,this);
diff --git a/servers/physics/body_pair_sw.cpp b/servers/physics/body_pair_sw.cpp
index a971cdaad8..40e906c36c 100644
--- a/servers/physics/body_pair_sw.cpp
+++ b/servers/physics/body_pair_sw.cpp
@@ -221,7 +221,7 @@ bool BodyPairSW::_test_ccd(float p_step,BodySW *p_A, int p_shape_A,const Transfo
bool BodyPairSW::setup(float p_step) {
//cannot collide
- if ((A->get_layer_mask()&B->get_layer_mask())==0 || A->has_exception(B->get_self()) || B->has_exception(A->get_self()) || (A->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC && B->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC && A->get_max_contacts_reported()==0 && B->get_max_contacts_reported()==0)) {
+ if (!A->test_collision_mask(B) || A->has_exception(B->get_self()) || B->has_exception(A->get_self()) || (A->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC && B->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC && A->get_max_contacts_reported()==0 && B->get_max_contacts_reported()==0)) {
collided=false;
return false;
}
diff --git a/servers/physics/collision_object_sw.cpp b/servers/physics/collision_object_sw.cpp
index 55c8c1b955..f2864ee95e 100644
--- a/servers/physics/collision_object_sw.cpp
+++ b/servers/physics/collision_object_sw.cpp
@@ -217,5 +217,6 @@ CollisionObjectSW::CollisionObjectSW(Type p_type) {
space=NULL;
instance_id=0;
layer_mask=1;
+ collision_mask=1;
ray_pickable=true;
}
diff --git a/servers/physics/collision_object_sw.h b/servers/physics/collision_object_sw.h
index 592c84e667..bc71c2709b 100644
--- a/servers/physics/collision_object_sw.h
+++ b/servers/physics/collision_object_sw.h
@@ -53,6 +53,7 @@ private:
RID self;
ObjectID instance_id;
uint32_t layer_mask;
+ uint32_t collision_mask;
struct Shape {
@@ -136,6 +137,13 @@ public:
_FORCE_INLINE_ void set_layer_mask(uint32_t p_mask) { layer_mask=p_mask; }
_FORCE_INLINE_ uint32_t get_layer_mask() const { return layer_mask; }
+ _FORCE_INLINE_ void set_collision_mask(uint32_t p_mask) { collision_mask=p_mask; }
+ _FORCE_INLINE_ uint32_t get_collision_mask() const { return collision_mask; }
+
+ _FORCE_INLINE_ bool test_collision_mask(CollisionObjectSW* p_other) const {
+ return layer_mask&p_other->collision_mask || p_other->layer_mask&collision_mask;
+ }
+
void remove_shape(ShapeSW *p_shape);
void remove_shape(int p_index);
diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp
index 5eb14d80dc..5307f1ce88 100644
--- a/servers/physics/physics_server_sw.cpp
+++ b/servers/physics/physics_server_sw.cpp
@@ -418,6 +418,22 @@ Transform PhysicsServerSW::area_get_transform(RID p_area) const {
return area->get_transform();
};
+void PhysicsServerSW::area_set_layer_mask(RID p_area,uint32_t p_mask) {
+
+ AreaSW *area = area_owner.get(p_area);
+ ERR_FAIL_COND(!area);
+
+ area->set_layer_mask(p_mask);
+}
+
+void PhysicsServerSW::area_set_collision_mask(RID p_area,uint32_t p_mask) {
+
+ AreaSW *area = area_owner.get(p_area);
+ ERR_FAIL_COND(!area);
+
+ area->set_collision_mask(p_mask);
+}
+
void PhysicsServerSW::area_set_monitorable(RID p_area,bool p_monitorable) {
AreaSW *area = area_owner.get(p_area);
@@ -657,6 +673,25 @@ uint32_t PhysicsServerSW::body_get_layer_mask(RID p_body, uint32_t p_mask) const
}
+void PhysicsServerSW::body_set_collision_mask(RID p_body, uint32_t p_mask) {
+
+ BodySW *body = body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->set_collision_mask(p_mask);
+ body->wakeup();
+
+}
+
+uint32_t PhysicsServerSW::body_get_collision_mask(RID p_body, uint32_t p_mask) const{
+
+ const BodySW *body = body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body,0);
+
+ return body->get_collision_mask();
+
+}
+
void PhysicsServerSW::body_attach_object_instance_ID(RID p_body,uint32_t p_ID) {
diff --git a/servers/physics/physics_server_sw.h b/servers/physics/physics_server_sw.h
index 2aadac2216..59eeeb42a7 100644
--- a/servers/physics/physics_server_sw.h
+++ b/servers/physics/physics_server_sw.h
@@ -131,6 +131,9 @@ public:
virtual void area_set_ray_pickable(RID p_area,bool p_enable);
virtual bool area_is_ray_pickable(RID p_area) const;
+ virtual void area_set_collision_mask(RID p_area,uint32_t p_mask);
+ virtual void area_set_layer_mask(RID p_area,uint32_t p_mask);
+
virtual void area_set_monitorable(RID p_area,bool p_monitorable);
virtual void area_set_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method);
@@ -171,6 +174,9 @@ public:
virtual void body_set_layer_mask(RID p_body, uint32_t p_mask);
virtual uint32_t body_get_layer_mask(RID p_body, uint32_t p_mask) const;
+ virtual void body_set_collision_mask(RID p_body, uint32_t p_mask);
+ virtual uint32_t body_get_collision_mask(RID p_body, uint32_t p_mask) const;
+
virtual void body_set_user_flags(RID p_body, uint32_t p_flags);
virtual uint32_t body_get_user_flags(RID p_body, uint32_t p_flags) const;