MouseEvents Optimization

how to do a proper check of mouseOver and mouseOut Actions when i have many elements to check.



i done a RayCasting method. it is doing every frame and it have big cost(i mean time of executing off course)



[java]

public void checkOvering() {

Vector3f origin = camera.getWorldCoordinates(inputManager.getCursorPosition(), 0.0f);

Vector3f direction = camera.getWorldCoordinates(inputManager.getCursorPosition(), 0.3f);

direction.subtractLocal(origin).normalizeLocal();

Ray mouseRay = new Ray(origin, direction);

Iterator<Spatial> i = rootNode.getChildren().iterator();

while (i.hasNext()) {

Spatial spat = i.next();

if (spat instanceof WorldElement) {

WorldElement worldelement = (WorldElement) spat;

CollisionResults results = new CollisionResults();

worldelement.collideWith(mouseRay, results);

if (results.size() > 0) {

// is over

if (!worldelement.isMouseOver) {

worldelement.over_done = false;

worldelement.isMouseOver = true;

}

} else {

// is out

if (worldelement.isMouseOver) {

worldelement.out_done = false;

worldelement.isMouseOver = false;

}

}

}

}

}

[/java]

its a prototype, time to do it proper!



it dont take so much time(as i good remember: 0.04 sec for my CPU - it gives ~20 fps), but it’s still too many(looking at this work every frame)



is there a better way to do this? :slight_smile: the faster one… or the last chance is to lower execution per fps?

Why do you perform a ray test on each spatial? Just group them in one node and perform the check once on the node…

Edit: The first time you do a ray test a collision graph is generated so in case you measure the time for the first test thats not representative.

1 Like

so it will work like this:


  • raycast rootNode(or other main node)
  • get collisionGraph
  • collect searching nodes from collisionGraph
  • compute what to do with this nodes



    ?



    i will check it, tnx :slight_smile: i dont known it work for all SubNodes



    and i hope it will work much faster :slight_smile:





    edit:

    @normen:



    i cant check it now but i hope this will work:



    i done it fast, and check it later. and i hope this is what you mean

    [java]

    public ArrayList<WorldElement> updateOvering() {

    ArrayList<WorldElement> overedElements = new ArrayList<WorldElement>();

    Vector3f origin = camera.getWorldCoordinates(inputManager.getCursorPosition(), 0.0f);

    Vector3f direction = camera.getWorldCoordinates(inputManager.getCursorPosition(), 0.3f);

    direction.subtractLocal(origin).normalizeLocal();

    Ray mouseRay = new Ray(origin, direction);

    CollisionResults results = new CollisionResults();

    rootNode.collideWith(mouseRay, results);

    if (results.size() > 0) {

    Iterator<CollisionResult> i = results.iterator();

    while (i.hasNext()) {

    CollisionResult collision = i.next();

    Node node = collision.getGeometry().getParent();

    if (node instanceof WorldElement) {

    WorldElement worldelement = (WorldElement) node;

    overedElements.add(worldelement);

    }

    }

    }

    return overedElements;

    }

    [/java]

Yep just like that. You might also want to short circuit the while loop and just take the closest collision.



[java]

CollisionResult closest = results.getClosestCollision();

[/java]

1 Like

ahh yes, its great, but don’t need it here



thank you for good advice and great engine :wink: