/** * Simple algorithm to add or remove a quad from the selection Ideas: 1. Use one shape per quad => * easy, but can become very fast too big to fit in memory. => pb: flicker when adding / removing * because the scene is detached 2. Use only one shape, modify geometry TODO: pre-create an empty * shape to avoid initial flicker * * @param on * @param p * @param u * @param v * @param groupIdx2 */ protected void toggleSelectedQuad(boolean on, SelectionQuad sq) { LOGGER.finest("on=" + on + " selectionQuad=" + sq); if (on) { // add the given quad to the list if (selection.contains(sq)) return; // already in selection.add(sq); } else { // remove the given quad from the list if (!selection.contains(sq)) return; // not present selection.remove(sq); if (selection.size() == 0) { QuadArray qa = (QuadArray) selectionShape.getGeometry(); qa.setValidVertexCount(0); return; } } // Use in-memory arrays instead of NIO because selection should not be // too big // => faster QuadArray qa = new QuadArray( selection.size() * 4, GeometryArray.COORDINATES | GeometryArray.COLOR_3 | GeometryArray.BY_REFERENCE); float[] coords = new float[selection.size() * 4 * 3]; float[] colors = new float[selection.size() * 4 * 3]; for (int i = 0; i < coords.length; i += 12) { SelectionQuad quad = selection.get(i / 12); quad.updateCoords(grid, coords, i); quad.updateColors(colors, i); } qa.setCoordRefFloat(coords); qa.setColorRefFloat(colors); qa.setCapability(GeometryArray.ALLOW_COUNT_WRITE); // update selection Shape with the new selection list if (selectionShape == null) { Appearance a = new Appearance(); PolygonAttributes pa = new PolygonAttributes(PolygonAttributes.POLYGON_FILL, PolygonAttributes.CULL_NONE, 0); pa.setPolygonOffset(0.5f); // between faces and edges pa.setPolygonOffsetFactor(0.5f); a.setPolygonAttributes(pa); selectionShape = new Shape3D(qa, a); selectionShape.setUserData(this); selectionShape.setPickable(false); selectionShape.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE); selectionShape.setCapability(Shape3D.ALLOW_GEOMETRY_READ); BranchGroup bg = new BranchGroup(); bg.addChild(selectionShape); addChild(bg); } else selectionShape.setGeometry(qa); }