Explorar el Código

-improved one-way collision handling in both dynamic and character bodies for 2D, fixes #1854

Juan Linietsky hace 10 años
padre
commit
32b1b472af

+ 12 - 3
servers/physics_2d/body_pair_2d_sw.cpp

@@ -265,7 +265,7 @@ bool BodyPair2DSW::setup(float p_step) {
 	} 
 	//faster to set than to check..
 
-	bool prev_collided=collided;
+	//bool prev_collided=collided;
 
 	collided = CollisionSolver2DSW::solve(shape_A_ptr,xform_A,motion_A,shape_B_ptr,xform_B,motion_B,_add_contact,this,&sep_axis);
 	if (!collided) {
@@ -282,12 +282,18 @@ bool BodyPair2DSW::setup(float p_step) {
 				collided=true;
 		}
 
-		if (!collided)
+		if (!collided) {
+			oneway_disabled=false;
 			return false;
+		}
 
 	}
 
-	if (!prev_collided) {
+	if (oneway_disabled)
+		return false;
+
+	//if (!prev_collided) {
+	{
 
 		if (A->is_using_one_way_collision()) {
 			Vector2 direction = A->get_one_way_collision_direction();
@@ -309,6 +315,7 @@ bool BodyPair2DSW::setup(float p_step) {
 
 			if (!valid) {
 				collided=false;
+				oneway_disabled=true;
 				return false;
 			}
 		}
@@ -333,6 +340,7 @@ bool BodyPair2DSW::setup(float p_step) {
 			}
 			if (!valid) {
 				collided=false;
+				oneway_disabled=true;
 				return false;
 			}
 		}
@@ -525,6 +533,7 @@ BodyPair2DSW::BodyPair2DSW(Body2DSW *p_A, int p_shape_A,Body2DSW *p_B, int p_sha
 	B->add_constraint(this,1);
 	contact_count=0;
 	collided=false;
+	oneway_disabled=false;
 
 }
 

+ 1 - 0
servers/physics_2d/body_pair_2d_sw.h

@@ -76,6 +76,7 @@ class BodyPair2DSW : public Constraint2DSW {
 	Contact contacts[MAX_CONTACTS];
 	int contact_count;
 	bool collided;
+	bool oneway_disabled;
 	int cc;
 
 

+ 6 - 1
servers/physics_2d/space_2d_sw.cpp

@@ -655,7 +655,12 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body,const Vector2&p_motion,float p
 					if (col_obj->get_type()==CollisionObject2DSW::TYPE_BODY) {
 
 						const Body2DSW *body=static_cast<const Body2DSW*>(col_obj);
-						cbk.valid_dir=body->get_one_way_collision_direction();
+
+						Vector2 cdir = body->get_one_way_collision_direction();
+						if (cdir!=Vector2() && p_motion.dot(cdir)<0)
+							continue;
+
+						cbk.valid_dir=cdir;
 						cbk.valid_depth=body->get_one_way_collision_max_depth();
 					} else {
 						cbk.valid_dir=Vector2();