The problem of incorrect selection of objects when clicking with the mouse

question

In a 3D scene, when you select an object by clicking with the mouse, sometimes the upper object is clearly selected, but the program reports that the lower object is selected.

Causes and solutions

To select by clicking the mouse, you must first enable the Camera's object picking (physics_object_picking) function, and cast a ray from the viewport camera to the screen position. If this ray hits an object, the object's CollisionObject._input_event() function will be called. So this question is related to the collision function.
If two collision boxes (CollisionShape) are very close, incorrect penetration of the projected ray may occur, triggering the lower collision box (but not the upper collision box).
The minimum Margin value of the collision box can only be set to 0.001 (1 mm).
After testing, for a collision box with a thickness of 2 mm (Extents.y=0.001), if the center distance of the two collision boxes is less than 0.008, errors may occur.
BoxShape.Margin=0.001
The specific reason requires investigating the source code implementation of the engine.
Find godot\modules\bullet\godot_ray_world_algorithm.cpp:

// Epsilon to account for floating point inaccuracies
#define RAY_PENETRATION_DEPTH_EPSILON 0.01
...
void GodotRayWorldAlgorithm::processCollision(...
...
	const btRayShape *ray_shape;
	btTransform ray_transform;
...
	btTransform to(ray_transform * ray_shape->getSupportPoint());
	btCollisionWorld::ClosestRayResultCallback btResult(ray_transform.getOrigin(), to.getOrigin());
	m_world->rayTestSingleInternal(ray_transform, to, other_co_wrapper, btResult);
	if (btResult.hasHit()) {
		btScalar depth(ray_shape->getScaledLength() * (btResult.m_closestHitFraction - 1));
		if (depth > -RAY_PENETRATION_DEPTH_EPSILON) {
			depth = 0.0;
		}

Depth is the product of two numbers, and is cleared when (depth > -0.01).
The 0.001 fineness in the settings is all a lie, and the 0.01 roughness is the real thing.

If the screen light casting function is used, the minimum length of small objects and the distance between objects should be designed in centimeters.

reference

Godot: 3D raycasting from the screen
Godot: Using InputEvent

Guess you like

Origin blog.csdn.net/feiyunw/article/details/127130445