Hello. I wonder if there is a simple solution for this problem. I have a grid at 0,0,0 that is 64x64x1 cells big. The camera is looking down the y axis at position (-0.049091205, 48.19402, -1.963456). I want now that the user can drag a rectangle and select every triangle that are under the rectangle.
I already have a mouse listener that draws the rectangle and I can use a ray to select the triangles under the mouse. My problem is that I want to select all triangles that are inside the rectangle.
The rectangle can get bigger and smaller, depending how the user is dragging the mouse. If the rectangle is getting smaller then the triangles must be de-selected that are no longer under the rectangle.
I was using a Box to do that and using rootCam.getWorldCoordinates() with projectionZPos=0 and projectionZPos=1 but the Box gets so big that every triangle is selected.
Currently I just slice the rectangle in 10x10 parts and check every part where it hits the terrain grid using a Ray. But it’s getting slow and slower the bigger the rectangle gets. Also, I don’t really like to slice it up like this. Maybe 10x10 is too big and the user will have trouble selecting the correct triangles. But smaller slices are too slow.
Maybe there is a better solution? I still like to just use a Box, because then I can get the collision between the terrain grid and the box.
private void findSelected(int x, int y) {
TempVars t = TempVars.get();
try {
Vector3f trans = ribbonNode.getLocalTranslation();
Vector2f size = ribbon.getSize();
Vector2f click2d = t.vect2d;
terrainSelectedIndices.clear();
results.clear();
for (float xx = trans.x; xx < trans.x + size.x; xx += 10f) {
for (float yy = trans.y; yy < trans.y + size.y; yy += 10f) {
click2d.x = x;
click2d.y = y;
Vector3f click3d = rootCam.getWorldCoordinates(click2d, 0f, t.vect1);
System.out.println(click3d);
Vector3f dir = rootCam.getWorldCoordinates(click2d, 1f).subtractLocal(click3d).normalizeLocal();
ray.setOrigin(click3d);
ray.setDirection(dir);
terrainNode.collideWith(ray, results);
for (CollisionResult c : results) {
terrainSelectedIndices.add(c.getTriangleIndex());
}
}
}
terrainSelectedIndices.stream().forEach(i -> System.out.print("" + i + ","));
System.out.println();
} finally {
t.release();
}
}
For the Box I had something like this:
w1 = rootCam.getWorldCoordinates(rect.bottomLeft, 0f);
w2 = rootCam.getWorldCoordinates(rect.topRight, 1f);
box.updateGeometry(w1, w2);
boxNode.updateModelBound();
terrainNode.collideWith(ray, results);