Unfortunately, three.js’ Ray class currently doesn’t detect intersections with imported Collada objects. Unfortunately, because I heavily rely on imported models and I’m too lazy to do the detection manually.
But, the good new is, the collada objects carry all information needed for the ray caster to work properly; you just need to do some manual tweaking.
[Update:] There’s a super-easy alternative, here’s the post about it and an example implementation.
Step 1: Modifying the Ray Class
The ray class checks whether the passed object is either a THREE.Particle
or a THREE.Mesh
. Usually, when adding a Collada object to the scene, you add it’s scene
property. And this is not a THREE.Mesh
, it’s a THREE.Object3D
. So we modify the check (in src/core/Ray.js, at the time of writing on line 72):
These are the two things the ray caster needs to do it’s work.
Step 2: Modifying the object added to the scene.
Update: Please check the “Update” section further below.
Let’s assume your callback for the Collada loader looks something like this:
This is where we need to add the geometry object needed for the ray caster. The collada object has a dae
property that contains loads of stuff, including animations, images and cameras. And, there is a geometries
property, this is what we are looking for. It contains all geometries that were found in the xml file, but, sadly, as an object. That means, you need to know the name of your mesh. You can look it up in the file or just check the property name in the console:
Expand it further, and you’ll see a mesh
property, containing a geometry3js
property that holds a THREE.Geometry
instance. Bingo! That’s the one we need. In my case:
Now just add that thing to the object that’s going to be added to the scene:
Step 3: Fun (and profit, maybe)
Now the modified Ray class can detect intersections with the Collada object. Of course, you have to look up the mesh id. And you’d better have only one mesh in your Collada. But given the fact that you’ll probably have a limited amount of imported models and that these should ideally contain only one mesh, this should be a doable task. If you still want an automated approach and do not fear assumptions: Iterate over the geometries object, go into the mesh property of the thing you encounter and return the instance stored in geometry3js:
You could even do that in the Collada loader class. But keep in mind that if you have multiple meshes in the original file you have no idea which one is going to end up in the object; I for one prefer doing it manually during the process of adding the Collada to the scene.
Update:
There is another, very convenient way to add the geometry to the object, that also works for Colladas containing multiple meshes. As always, reading the source code just one more time really helps… After loading, the Collada object contains everything that was imported from the XML file in a children
property: Lights, cameras – and the mesh. So what I’m doing now is this:
For large models containing multiple meshes, the results still are a little awkward, but it works reliably for models containing one mesh, and it saves you from looking for the mesh property by hand.
Update 2:
You can also just use the ReusableRay class (I wrote about it here), and don’t have to do anything else. There’s also an example using it to find Collada models by mouse clicks.
unfortunately this don’t work for me.
can you post a little sample source code in which the mousedown event is implemented so i can try it
thanks
A nice example where a mouse down event triggers a ray casting is this one:
https://github.com/mrdoob/three.js/blob/master/examples/webgl_interactive_draggablecubes.html#L191
On line 198 there is a ray being cast into the “direction” of the mouse cursor position. The ray caster successfully detects the objects in the scene, as they are instances of THREE.Mesh (see line 68). Were there any imported Collada objects, the ray caster would ignore them without the above mentioned modifications.