jeromeetienne / threex.domevents

three.js extension which provide dom events inside your 3d scene.

Home Page:http://jeromeetienne.github.io/threex.domevents/examples/demo.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Several things to think about

SebastianNette opened this issue · comments

So I have played around with THREEx.DomEvents for a while and noticed a few things.

  • When an object is flagged visible=false then the raycaster will still find it. It would be nice if there was a way to stop this behaviour. Right now I solve that by doing this:

    while(intersects.length > 0) {
    var intersect = intersects.shift();
    if(!intersect.object.visible) {
      continue;
    }
    ..
    break;
    }

Ofcourse I could just remove it from the scene instead of setting it invisible but I believe setting visible = false is much faster than calling splice everytime.

  • We test too many intersections. If we have 10.000 spheres on our world, each bound to DomEvents mouseevents, then DomEvents will raycast on each of those objects in just every mousemove. At 60fps, we can easily emit 3 mousemove events per frame.

Maybe we can think of a way to only iterate over the onscreen objects instead of all bound objects for the respective eventhandler. Same thing would then apply to the invisible objects. Let's just not iterate over those. (the intersection function itself does this test, but on each intersection call, we have quite a few of those per frame)

  • The relative mouseposition calcuation is unneccessary. we should only calculate a position factor once everytime the renderer size is set. It doesn't change anymore after that happened.

Or maybe we should just write our own intersection test. What THREE is doing is pushing all possible intersections into an array. Why not stop after we found the first intersection since we only work with var intersect = intersects[ 0 ]; anyway? This would require 2 steps. First: Find out what objects are onscreen in the current rendering loop and Second: How far are those from the camera. If we do this calculation once each rendering session, we will save a lot raycasting.

  • The mouse events as well as click events are called every time those happen. Creating many many tests that might not be needed. We could test the mousemove intersections only every time the renderer renders the scene.
  • There should be an easy way to unbind all handlers for an object. When I want to destroy an object entirely, I don't want it to remain in THREEx.DomEvents._boundObjs. Same thing applies to destroying the THREEx.DomEvents. Upon destroying the class, all boundObjs should be free'd and all references should be removed.

Just a few things to think about. Basically I just want to remove every unnecessary calculation and object creation, which might result into saving us 1 ms here and there, who knows. I will try to realize my suggestions and then make a comparision between the current DomEvents and the hopefully improved one.

Update:
I'm currently testing a few improvements out.
My chrome always runs at 60 fps no matter what I do, so I will use my firefox for testing (interestingly IE 11 performs far better than my firefox when it comes to THREE).

Using the current THREEx.DomEvents my firefox crawls around 36-43 fps. The main issue might be the mousemove handler because that one is called 4-6 times per frame at my framerate.
Using my improved version of THREEx.DomEvents gets my firefox up to 45-46 fps.

In other words, I'm saving a minimum of 33-50ms already. And I'm not done improving it yet. Maybe I can upload my current version tomorrow after I tried out some more changes.

(My IE runs at 67 fps (those guys sure beat chrome in that case) when I use my own implementation of DomEvents. The fps drop to 59/60 when I use the current DomEvents class from this repo) I'm excited to see how fast we can make DomEvents!