From 5f9fb7159fa33bc979e5050d384b6939658049bd Mon Sep 17 00:00:00 2001
From: Sven Göthel
Date: Mon, 22 Jan 2024 06:35:25 +0100
Subject: Bug 1489 - GraphUI Group: Resolve Performance Regression in
Scene.pickShape(): Drop invisible and clipped shapes
After implementing Bug 1487 (Frustum Clipping/Culling) and using thousands of shapes within one Group mostly culled (outside of frustum),
overall mouse Scene.pickShape() caused tremendous lagging.
This is caused by Scene.pickShape() traversing through _all_ shapes,
rendered ones, invisible ones and culled ones.
+++
Solution is to have Scene and Group provide a pre-sorted list
of actually rendered shapes, i.e. isVisible() and not culled.
Scene.pickShape() can now use this reduced and pre-sorted list
reducing the load considerably.
+++
Further
- cleanup TreeTool
- rename Container methods:
-- setFrustumCullingEnabled() -> setPMvCullingEnabled()
-- isFrustumCullingEnabled() -> isPMvCullingEnabled()
- supply Container with
-- isCullingEnabled()
-- List getRenderedShapes()
-- isOutside()
-- isOutside2()
-- forAllRendered()
---
src/graphui/classes/jogamp/graph/ui/TreeTool.java | 103 +++++++++++++++-------
1 file changed, 72 insertions(+), 31 deletions(-)
(limited to 'src/graphui/classes/jogamp')
diff --git a/src/graphui/classes/jogamp/graph/ui/TreeTool.java b/src/graphui/classes/jogamp/graph/ui/TreeTool.java
index c37cd53d8..1a12ff461 100644
--- a/src/graphui/classes/jogamp/graph/ui/TreeTool.java
+++ b/src/graphui/classes/jogamp/graph/ui/TreeTool.java
@@ -36,24 +36,27 @@ import com.jogamp.graph.ui.Scene;
import com.jogamp.graph.ui.Shape;
import com.jogamp.graph.ui.Shape.Visitor1;
import com.jogamp.graph.ui.Shape.Visitor2;
+import com.jogamp.math.Matrix4f;
import com.jogamp.math.util.PMVMatrix4f;
/** Generic static {@link Shape} tree traversal tools, utilized by {@link Scene} and {@link Container} implementations. */
public class TreeTool {
/**
- * Traverses through the graph up until {@code shape} and apply {@code action} on it.
+ * Traverses through the graph up until {@code shape} of {@link Container#getShapes()} and apply {@code action} on it.
* @param pmv
* @param shape
* @param action
* @return true to signal operation complete, i.e. {@code shape} found, otherwise false
*/
- public static boolean forOne(final List shapes, final PMVMatrix4f pmv, final Shape shape, final Runnable action) {
- for(int i=0; i shapes = cont.getShapes();
+ final int shapeCount = shapes.size();
+ for(int i=0; i shapes, final Visitor1 v) {
+ public static boolean forAll(final Container cont, final Visitor1 v) {
+ final List shapes = cont.getShapes();
+ final int shapeCount = shapes.size();
boolean res = false;
- for(int i=0; !res && i shapes, final PMVMatrix4f pmv, final Visitor2 v) {
+ public static boolean forAll(final Container cont, final PMVMatrix4f pmv, final Visitor2 v) {
+ final List shapes = cont.getShapes();
+ final int shapeCount = shapes.size();
boolean res = false;
- for(int i=0; !res && i
* Each {@link Container} level is sorted using {@code sortComp}
+ *
+ * @param cont container of the shapes
* @param sortComp
* @param pmv
* @param v
* @return true to signal operation complete and to stop traversal, i.e. {@link Visitor2#visit(Shape, PMVMatrix4f)} returned true, otherwise false
*/
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public static boolean forSortedAll(final Comparator sortComp, final List shapes, final PMVMatrix4f pmv, final Visitor2 v) {
- final Object[] shapesS = shapes.toArray();
- Arrays.sort(shapesS, (Comparator)sortComp);
+ public static boolean forSortedAll(final Container cont, final Comparator sortComp, final PMVMatrix4f pmv, final Visitor2 v) {
+ final List shapes = cont.getShapes();
+ final int shapeCount = shapes.size();
+ final Shape[] shapesS = shapes.toArray(new Shape[shapeCount]);
+ Arrays.sort(shapesS, sortComp);
+ boolean res = false;
+
+ for(int i=0; !res && i
+ * Each {@link Container} level is sorted using {@code sortComp}
+ *
+ * @param cont container of the shapes
+ * @param pmv
+ * @param v
+ * @return true to signal operation complete and to stop traversal, i.e. {@link Visitor2#visit(Shape, PMVMatrix4f)} returned true, otherwise false
+ */
+ public static boolean forAllRendered(final Container cont, final PMVMatrix4f pmv, final Visitor2 v) {
+ final List shapes = cont.getRenderedShapes();
boolean res = false;
- for(int i=0; !res && i shapes, final Shape s) {
+ public static boolean contains(final Container cont, final Shape s) {
+ final List shapes = cont.getShapes();
if( shapes.contains(s) ) {
return true;
}
for(final Shape shape : shapes) {
if( shape instanceof Container ) {
- if( ((Container)shape).contains(s) ) {
+ if( contains((Container)shape, s) ) {
return true;
}
}
@@ -156,9 +197,9 @@ public class TreeTool {
return false;
}
- public static Shape getShapeByID(final List shapes, final int id) {
+ public static Shape getShapeByID(final Container cont, final int id) {
final Shape[] res = { null };
- forAll(shapes, (final Shape s) -> {
+ forAll(cont, (final Shape s) -> {
if( s.getID() == id ) {
res[0] = s;
return true;
@@ -168,9 +209,9 @@ public class TreeTool {
});
return res[0];
}
- public static Shape getShapeByName(final List shapes, final String name) {
+ public static Shape getShapeByName(final Container cont, final String name) {
final Shape[] res = { null };
- forAll(shapes, (final Shape s) -> {
+ forAll(cont, (final Shape s) -> {
if( s.getName().equals(name) ) {
res[0] = s;
return true;
--
cgit v1.2.3