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? 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 i dont known it work for all SubNodes
and i hope it will work much faster
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