Fix parameter type in Raycaster::intersectObject(s)
Why
#130 added generic typing to the Intersection type, so that we could get back the same type that we passed in to the intersect methods. That pr missed the Raycaster::intersectObject(s)'s 'object' & 'objects' parameters. This problem causes the following:
const raycaster: Raycaster = null;
const mesh: Mesh = null;
const meshes: Mesh[] = null;
const result1: Mesh = raycaster.intersectObject(mesh)[0].object;
const result2: Mesh = raycaster.intersectObjects(meshes)[0].object;
This code doesn't compile because the type of result1 is still not a Mesh, it's a Object3D<Event>. This is because according to the current typing we pass in a Object3D and we get back an Object3D. After these changes the given code compiles without any errors.
What
Made the 'object' and 'objects' parameters generic in intersectObject & intersectObjects
Checklist
- [x] Checked the target branch (current goes
master, next goesdev) - [x] Added myself to contributors table
- [ ] Ready to be merged
The test is failing in test/cameras/camera-cinematic.ts. It looks like it calls intersectObjects like this:
const intersects = raycaster.intersectObjects<THREE.Mesh>(scene.children);
scene.children has the type THREE.Object3D<THREE.Event>[], which should give us back a THREE.Object3D<THREE.Event>, not a THREE.Mesh This could be fixed like this:
const intersects = raycaster.intersectObjects(scene.children);
if (intersects.length > 0) {
const targetDistance = intersects[0].distance;
const intersectedObject = intersects[0].object as THREE.Mesh;
camera.focusAt(targetDistance); // using Cinematic camera focusAt method
if (INTERSECTED && INTERSECTED.uuid !== intersectedObject.uuid) {
if (INTERSECTED) {
(INTERSECTED.material as THREE.MeshLambertMaterial).emissive.setHex(INTERSECTED.userData.currentHex);
}
INTERSECTED = intersectedObject;
...
Here we explicitly cast intersects[0].object to a THREE.Mesh object I think this might become a breaking change, because with the previous typing the given example would compile with the wrong passed in object type, because it wasn't validated.
Can you provide a codesandbox of this breaking?
Hi! Sorry, I couldn't figure out how to show the error on codesandbox.io The following code
import { Raycaster, Mesh } from 'three';
const raycaster = new Raycaster();
const meshes: Mesh[] = [ new Mesh() ];
const result: Mesh = raycaster.intersectObjects(meshes)[0]?.object;
Produces this error in vscode: 'Type 'Object3D<Event>' is missing the following properties from type 'Mesh<BufferGeometry, Material | Material[]>'...'
(This basically means that we get back an Object3D
Now if we simplify the code in the tests:
import { Raycaster, Scene, Mesh } from 'three';
const raycaster = new Raycaster();
const scene = new Scene();
const intersects: Mesh = raycaster.intersectObjects<Mesh>(scene.children)[0]?.object;
Here we pass in scene.children which contains Object3D objects, but we get back a Mesh object, because we call raycaster.intersectObjects with an explicit type parameter, which is incorrect after the changes (thus the test failing correctly)