Reputation: 1566
I have a feeling that this approach is entirely wrong as I can't manage to get a proper performance for my website.
Here is the main code that I would like you to see:
onDocumentMouseMove( event ) {
if ( this.isUserInteracting === true ) {
this.lon = ( this.onMouseDownMouseX - event.clientX ) * 0.1 + this.onMouseDownLon;
this.lat = ( event.clientY - this.onMouseDownMouseY ) * 0.1 + this.onMouseDownLat;
}
this.mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
this.mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
if( !this.state.VR ){
this.raycaster.setFromCamera( this.mouse, this.camera );
var intersects = this.raycaster.intersectObjects( this.indicatorHotspotPlane );
if( intersects.length > 0 ) {
this.actualIntersect = intersects[0];
$('html,body').css('cursor', 'pointer');
if(!intersects[ 0 ].object.isAction){
this.marker.material.opacity = 1;
this.marker.lookAt( intersects[ 0 ].face.normal );
this.marker.position.copy( intersects[ 0 ].point );
this.marker.position.y = this.marker.position.y + 30;
if( intersects[ 0 ].point.x >= 0 ){
this.marker.position.x = this.marker.position.x - 30;
}else{
this.marker.position.x = this.marker.position.x + 30;
}
}
} else {
this.actualIntersect = null;
$('html,body').css('cursor', 'move');
this.marker.material.opacity = 0;
}
}
}
I believe that raycaster.intersectObjects is a very expensive operation to run inside this kind of event handler.
If I comment this piece of code, everything runs nicely.
Is there any other way of finding intersections when mouse is moving without having performance problems?
this.indicatorHotspotPlane is an array with maybe 5 objects like this one:
var hotspotPlane = new THREE.Mesh( new THREE.PlaneBufferGeometry( hotpot.width , hotpot.height ) );
And my scene contains these objects and a sphere geometry with a texture on it.
Upvotes: 0
Views: 1472
Reputation: 8866
Take a look at this three.js example.
Whats' happening here:
There is still a cost of doing this: You will incur an extra render every time you need to refresh your render target. Also, if your scene is REALLY BIG (taking a long time to render), it may perform just as poorly as raycasting. Still, the moral of the story is that it is much easier to read a color value from a buffer than it is to perform a raycast.
Another caveat is that this will only work for the nearest shape (the equivalent of intersects[0]
). This is because occluded shapes won't have their colors exposed (their colors are completely covered by other shapes). So if you need to get ALL of the shapes under your mouse, then raycasting is still the best option.
Additional Info:
I overlooked part of your code and jumped straight into solving the raytracing problem. After a deeper review, here is some extra info:
It looks like you're taking whatever object you intersect, and are checking a specific property:
if(!intersects[ 0 ].object.isAction){
Using the method described above, you would check for that property on whatever object you get out of your color map.
To get the intersection point, you WILL need to perform a raycast, but now it will only happen if the object under your mouse passes your test first, rather than every time your mouse moves.
The raycast will occur for every mouse move event while the cursor is over an appropriate object, so you may want to reconsider how often you need to update your marker (maybe every N frames), or perhaps set the marker only the first time you encounter a particular shape. I don't know your use-case, so perhaps this isn't viable.
Upvotes: 1