Three.js中Raycaster误检测移动指示器,无法正确识别模型求助
Hey there, let's sort out this raycasting issue where your TransformControls' white lines are being detected instead of your target models. Here are a few actionable solutions to get your selection working as intended:
1. Exclude Transform Controls via Custom Object Markers
The root problem is that your Raycaster is picking up the TransformControls' helper elements because they're part of the scene (or nested in your container) when active. You can easily filter these out by adding a custom identifier to the TransformControls and checking for it during intersections.
Step-by-Step Implementation:
First, add a marker to your TransformControls so you can spot it later:
transformControls = new THREE.TransformControls(camera, renderer.domElement); transformControls.userData.isTransformControl = true; // Add this unique marker
Then, modify your raycast function to filter out any objects linked to the TransformControls:
function raycast(eve, object) { var mouseToRaycaster = new THREE.Vector2( ((eve.offsetX / renderer.domElement.offsetWidth ) * 2) - 1, -(( eve.offsetY / renderer.domElement.offsetHeight ) * 2) + 1 ); raycaster.setFromCamera(mouseToRaycaster, camera); // Get all initial intersections let allIntersects = raycaster.intersectObjects(object.children, true); // Filter out TransformControls and their child elements intersects = allIntersects.filter(intersection => { let currentObj = intersection.object; // Traverse up the hierarchy to check if any parent is the TransformControls while (currentObj) { if (currentObj.userData.isTransformControl) { return false; } currentObj = currentObj.parent; } return true; }); // Rest of your existing logic... if (selectedComponent && intersects.length == 0) { transformControls.detach(); selectedComponent.material = redefineMaterial({ map: selectedComponent.material.map }); scene.remove(transformControls); scene.remove(lineYHelper); selectedComponent = false; } }
2. Raycast Only Against Your Model Collection
Instead of casting rays against all children of your container, use your existing meshes array to target only your loaded models. This guarantees you never accidentally pick up helper objects like TransformControls.
Example Modification:
You already have a meshes array with all your models, so update the raycast call to use this directly:
function raycast(eve, object) { var mouseToRaycaster = new THREE.Vector2( ((eve.offsetX / renderer.domElement.offsetWidth ) * 2) - 1, -(( eve.offsetY / renderer.domElement.offsetHeight ) * 2) + 1 ); raycaster.setFromCamera(mouseToRaycaster, camera); // Cast rays only against your actual models, not all container children intersects = raycaster.intersectObjects(meshes, true); // Rest of your logic... }
3. Disable Raycasting on Transform Controls Entirely
A quick fix is to tell the Raycaster to ignore TransformControls' helper objects by overriding their raycast method. This works because THREE.js uses an object's raycast function to determine intersections.
transformControls = new THREE.TransformControls(camera, renderer.domElement); // Disable ray detection for all child elements of TransformControls transformControls.traverse(child => { child.raycast = null; });
Any of these methods should resolve your issue. The first option is the most flexible if you need to keep TransformControls in your scene hierarchy, while the second is the most straightforward if you have a dedicated list of models to target.
内容的提问来源于stack exchange,提问作者Jonathan Drummond

