Browse Source

Check for motion in cast_motion() before doing Bullet convexSweepTest().

Also ensure that default closest_safe and closest_unsafe values are
defined in cast_motion() and before cast_motion() is called.
Marcel Admiraal 5 years ago
parent
commit
8ffe905c45
3 changed files with 16 additions and 10 deletions
  1. 12 6
      modules/bullet/space_bullet.cpp
  2. 3 3
      scene/3d/camera_3d.cpp
  3. 1 1
      servers/physics_server_3d.cpp

+ 12 - 6
modules/bullet/space_bullet.cpp

@@ -152,6 +152,15 @@ int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Tra
 }
 }
 
 
 bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, float p_margin, float &r_closest_safe, float &r_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, ShapeRestInfo *r_info) {
 bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, float p_margin, float &r_closest_safe, float &r_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, ShapeRestInfo *r_info) {
+	r_closest_safe = 0.0f;
+	r_closest_unsafe = 0.0f;
+	btVector3 bt_motion;
+	G_TO_B(p_motion, bt_motion);
+
+	if (bt_motion.fuzzyZero()) {
+		return false;
+	}
+
 	ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->getornull(p_shape);
 	ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->getornull(p_shape);
 
 
 	btCollisionShape *btShape = shape->create_bt_shape(p_xform.basis.get_scale(), p_margin);
 	btCollisionShape *btShape = shape->create_bt_shape(p_xform.basis.get_scale(), p_margin);
@@ -162,9 +171,6 @@ bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transf
 	}
 	}
 	btConvexShape *bt_convex_shape = static_cast<btConvexShape *>(btShape);
 	btConvexShape *bt_convex_shape = static_cast<btConvexShape *>(btShape);
 
 
-	btVector3 bt_motion;
-	G_TO_B(p_motion, bt_motion);
-
 	btTransform bt_xform_from;
 	btTransform bt_xform_from;
 	G_TO_B(p_xform, bt_xform_from);
 	G_TO_B(p_xform, bt_xform_from);
 	UNSCALE_BT_BASIS(bt_xform_from);
 	UNSCALE_BT_BASIS(bt_xform_from);
@@ -178,9 +184,6 @@ bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transf
 
 
 	space->dynamicsWorld->convexSweepTest(bt_convex_shape, bt_xform_from, bt_xform_to, btResult, space->dynamicsWorld->getDispatchInfo().m_allowedCcdPenetration);
 	space->dynamicsWorld->convexSweepTest(bt_convex_shape, bt_xform_from, bt_xform_to, btResult, space->dynamicsWorld->getDispatchInfo().m_allowedCcdPenetration);
 
 
-	r_closest_unsafe = 1.0;
-	r_closest_safe = 1.0;
-
 	if (btResult.hasHit()) {
 	if (btResult.hasHit()) {
 		const btScalar l = bt_motion.length();
 		const btScalar l = bt_motion.length();
 		r_closest_unsafe = btResult.m_closestHitFraction;
 		r_closest_unsafe = btResult.m_closestHitFraction;
@@ -196,6 +199,9 @@ bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transf
 			r_info->collider_id = collision_object->get_instance_id();
 			r_info->collider_id = collision_object->get_instance_id();
 			r_info->shape = btResult.m_shapeId;
 			r_info->shape = btResult.m_shapeId;
 		}
 		}
+	} else {
+		r_closest_safe = 1.0f;
+		r_closest_unsafe = 1.0f;
 	}
 	}
 
 
 	bulletdelete(bt_convex_shape);
 	bulletdelete(bt_convex_shape);

+ 3 - 3
scene/3d/camera_3d.cpp

@@ -754,9 +754,9 @@ void ClippedCamera3D::_notification(int p_what) {
 		xf.origin = ray_from;
 		xf.origin = ray_from;
 		xf.orthonormalize();
 		xf.orthonormalize();
 
 
-		float csafe, cunsafe;
-		if (dspace->cast_motion(pyramid_shape, xf, cam_pos - ray_from, margin, csafe, cunsafe, exclude, collision_mask, clip_to_bodies, clip_to_areas)) {
-			clip_offset = cam_pos.distance_to(ray_from + (cam_pos - ray_from) * csafe);
+		float closest_safe = 1.0f, closest_unsafe = 1.0f;
+		if (dspace->cast_motion(pyramid_shape, xf, cam_pos - ray_from, margin, closest_safe, closest_unsafe, exclude, collision_mask, clip_to_bodies, clip_to_areas)) {
+			clip_offset = cam_pos.distance_to(ray_from + (cam_pos - ray_from) * closest_safe);
 		}
 		}
 
 
 		_update_camera();
 		_update_camera();

+ 1 - 1
servers/physics_server_3d.cpp

@@ -295,7 +295,7 @@ Array PhysicsDirectSpaceState3D::_intersect_shape(const Ref<PhysicsShapeQueryPar
 Array PhysicsDirectSpaceState3D::_cast_motion(const Ref<PhysicsShapeQueryParameters3D> &p_shape_query, const Vector3 &p_motion) {
 Array PhysicsDirectSpaceState3D::_cast_motion(const Ref<PhysicsShapeQueryParameters3D> &p_shape_query, const Vector3 &p_motion) {
 	ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array());
 	ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array());
 
 
-	float closest_safe, closest_unsafe;
+	float closest_safe = 1.0f, closest_unsafe = 1.0f;
 	bool res = cast_motion(p_shape_query->shape, p_shape_query->transform, p_motion, p_shape_query->margin, closest_safe, closest_unsafe, p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas);
 	bool res = cast_motion(p_shape_query->shape, p_shape_query->transform, p_motion, p_shape_query->margin, closest_safe, closest_unsafe, p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas);
 	if (!res) {
 	if (!res) {
 		return Array();
 		return Array();