aboutsummaryrefslogtreecommitdiffstats
path: root/src/classes
diff options
context:
space:
mode:
authorpaulby <[email protected]>2007-04-20 00:54:41 +0000
committerpaulby <[email protected]>2007-04-20 00:54:41 +0000
commite5728c258119acd9f42c2168b67561fb48602f56 (patch)
tree0465faab64b7d1bdbc393da96726c0bdacacb84e /src/classes
parent993cbb3af21cd9d67d5a23eef0f1f08f95c7f682 (diff)
Issue 480. Cache getBounds() results
Issue number: Obtained from: Submitted by: Reviewed by: git-svn-id: https://svn.java.net/svn/j3d-core~svn/trunk@825 ba19aa83-45c5-6ac9-afd3-db810772062c
Diffstat (limited to 'src/classes')
-rw-r--r--src/classes/share/javax/media/j3d/BranchGroupRetained.java1
-rw-r--r--src/classes/share/javax/media/j3d/GeometryArrayRetained.java8
-rw-r--r--src/classes/share/javax/media/j3d/GeometryRetained.java2
-rw-r--r--src/classes/share/javax/media/j3d/GroupRetained.java60
-rw-r--r--src/classes/share/javax/media/j3d/MasterControl.java12
-rw-r--r--src/classes/share/javax/media/j3d/NodeRetained.java22
-rw-r--r--src/classes/share/javax/media/j3d/Shape3DRetained.java110
-rw-r--r--src/classes/share/javax/media/j3d/SharedGroupRetained.java21
-rw-r--r--src/classes/share/javax/media/j3d/SwitchRetained.java91
-rw-r--r--src/classes/share/javax/media/j3d/TransformGroupRetained.java12
10 files changed, 251 insertions, 88 deletions
diff --git a/src/classes/share/javax/media/j3d/BranchGroupRetained.java b/src/classes/share/javax/media/j3d/BranchGroupRetained.java
index 568f04b..7607f5b 100644
--- a/src/classes/share/javax/media/j3d/BranchGroupRetained.java
+++ b/src/classes/share/javax/media/j3d/BranchGroupRetained.java
@@ -55,6 +55,7 @@ class BranchGroupRetained extends GroupRetained {
* Detaches this BranchGroup from its parent.
*/
void detach() {
+ dirtyBoundsCache();
if (universe != null) {
universe.resetWaitMCFlag();
synchronized (universe.sceneGraphLock) {
diff --git a/src/classes/share/javax/media/j3d/GeometryArrayRetained.java b/src/classes/share/javax/media/j3d/GeometryArrayRetained.java
index 005f654..ad543cd 100644
--- a/src/classes/share/javax/media/j3d/GeometryArrayRetained.java
+++ b/src/classes/share/javax/media/j3d/GeometryArrayRetained.java
@@ -414,6 +414,13 @@ abstract class GeometryArrayRetained extends GeometryRetained{
// System.err.println("computeBoundingBox ....");
+ if (boundsDirty && VirtualUniverse.mc.cacheAutoComputedBounds) {
+ for(ArrayList<Shape3DRetained> users : userLists) {
+ for(Shape3DRetained shape : users)
+ shape.dirtyBoundsCache();
+ }
+ }
+
if ((vertexFormat & GeometryArray.BY_REFERENCE) == 0) {
// by copy
computeBoundingBox(initialVertexIndex, vertexData);
@@ -444,6 +451,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
//System.err.println("vertexType & PD");
computeBoundingBox(doubleRefCoords);
}
+
}
diff --git a/src/classes/share/javax/media/j3d/GeometryRetained.java b/src/classes/share/javax/media/j3d/GeometryRetained.java
index 4fc68ee..a57cb22 100644
--- a/src/classes/share/javax/media/j3d/GeometryRetained.java
+++ b/src/classes/share/javax/media/j3d/GeometryRetained.java
@@ -81,7 +81,7 @@ abstract class GeometryRetained extends NodeComponentRetained {
// A list of ArrayLists which contain all the Shape3DRetained objects
// refering to this geometry. Each list corresponds to the universe
// above.
- ArrayList userLists = new ArrayList();
+ ArrayList<ArrayList<Shape3DRetained>> userLists = new ArrayList();
// true if color not specified with alpha channel
boolean noAlpha = false;
diff --git a/src/classes/share/javax/media/j3d/GroupRetained.java b/src/classes/share/javax/media/j3d/GroupRetained.java
index 3e99f79..4caf826 100644
--- a/src/classes/share/javax/media/j3d/GroupRetained.java
+++ b/src/classes/share/javax/media/j3d/GroupRetained.java
@@ -199,6 +199,7 @@ class GroupRetained extends NodeRetained implements BHLeafInterface {
}
}
}
+ dirtyBoundsCache();
}
// The method that does the work once the lock is acquired.
@@ -295,6 +296,7 @@ class GroupRetained extends NodeRetained implements BHLeafInterface {
}
}
}
+ dirtyBoundsCache();
}
// The method that does the work once the lock is acquired.
@@ -345,6 +347,7 @@ class GroupRetained extends NodeRetained implements BHLeafInterface {
}
}
}
+ dirtyBoundsCache();
}
/**
@@ -476,6 +479,7 @@ class GroupRetained extends NodeRetained implements BHLeafInterface {
}
}
}
+ dirtyBoundsCache();
}
// The method that does the work once the lock is acquired.
@@ -499,6 +503,7 @@ class GroupRetained extends NodeRetained implements BHLeafInterface {
}
void moveTo(BranchGroup bg) {
+ ((GroupRetained)bg.retained).dirtyBoundsCache();
if (this.source.isLive()) {
universe.resetWaitMCFlag();
synchronized (universe.sceneGraphLock) {
@@ -519,6 +524,7 @@ class GroupRetained extends NodeRetained implements BHLeafInterface {
}
}
}
+ dirtyBoundsCache();
}
// The method that does the work once the lock is acquired.
@@ -2218,7 +2224,6 @@ class GroupRetained extends NodeRetained implements BHLeafInterface {
s.fogs = savedScopedFogs;
s.altAppearances = savedScopedAltApps;
s.modelClips = savedScopedMclips;
-
}
void setScopingInfo(SetLiveState s) {
@@ -2419,19 +2424,42 @@ class GroupRetained extends NodeRetained implements BHLeafInterface {
}
void computeCombineBounds(Bounds bounds) {
-
- if (boundsAutoCompute) {
- for (int i=children.size()-1; i>=0; i--) {
- NodeRetained child = (NodeRetained)children.get(i);
- if(child != null)
- child.computeCombineBounds(bounds);
- }
- } else {
- // Should this be lock too ? ( MT safe ? )
- synchronized(localBounds) {
- bounds.combine(localBounds);
- }
- }
+ if (!VirtualUniverse.mc.cacheAutoComputedBounds) {
+ if (boundsAutoCompute) {
+ for (int i=children.size()-1; i>=0; i--) {
+ NodeRetained child = (NodeRetained)children.get(i);
+ if(child != null)
+ child.computeCombineBounds(bounds);
+ }
+ } else {
+ // Should this be lock too ? ( MT safe ? )
+ synchronized(localBounds) {
+ bounds.combine(localBounds);
+ }
+ }
+ } else {
+ if (cachedBounds!=null && boundsAutoCompute) {
+ bounds.combine(cachedBounds);
+ return;
+ }
+
+ if (boundsAutoCompute) {
+ cachedBounds = new BoundingSphere();
+ ((BoundingSphere)cachedBounds).setRadius(-1);
+ for (int i=children.size()-1; i>=0; i--) {
+ NodeRetained child = (NodeRetained)children.get(i);
+ if(child != null)
+ child.computeCombineBounds(cachedBounds);
+ }
+ bounds.combine(cachedBounds);
+ } else {
+ // Should this be lock too ? ( MT safe ? )
+ synchronized(localBounds) {
+ bounds.combine(localBounds);
+ }
+ }
+ }
+
}
@@ -2442,6 +2470,10 @@ class GroupRetained extends NodeRetained implements BHLeafInterface {
Bounds getBounds() {
if ( boundsAutoCompute) {
+ if (cachedBounds!=null) {
+ return (Bounds) cachedBounds.clone();
+ }
+
BoundingSphere boundingSphere = new BoundingSphere();
boundingSphere.setRadius(-1.0);
diff --git a/src/classes/share/javax/media/j3d/MasterControl.java b/src/classes/share/javax/media/j3d/MasterControl.java
index c0b1ae6..c503697 100644
--- a/src/classes/share/javax/media/j3d/MasterControl.java
+++ b/src/classes/share/javax/media/j3d/MasterControl.java
@@ -472,6 +472,10 @@ class MasterControl {
//Set as true if you have memory leaks after disposing Canvas3D.
//Default false value does affect Java3D View dispose behavior.
boolean forceReleaseView = false;
+
+ // Issue 480: Cache the bounds of nodes so that getBounds does not
+ // recompute the boounds of the entire graph per call
+ boolean cacheAutoComputedBounds = false;
/**
* Constructs a new MasterControl object. Note that there is
@@ -661,7 +665,13 @@ class MasterControl {
disableXinerama = true;
}
- // Initialize the native J3D library
+ // Issue 480 : Cache bounds returned by getBounds()
+ cacheAutoComputedBounds =
+ getBooleanProperty("j3d.cacheAutoComputeBounds",
+ cacheAutoComputedBounds,
+ "Cache AutoCompute Bounds, accelerates getBounds()");
+
+ // Initialize the native J3D library
if (!Pipeline.getPipeline().initializeJ3D(disableXinerama)) {
throw new RuntimeException(J3dI18N.getString("MasterControl0"));
}
diff --git a/src/classes/share/javax/media/j3d/NodeRetained.java b/src/classes/share/javax/media/j3d/NodeRetained.java
index fe8f0c6..6978854 100644
--- a/src/classes/share/javax/media/j3d/NodeRetained.java
+++ b/src/classes/share/javax/media/j3d/NodeRetained.java
@@ -140,6 +140,8 @@ abstract class NodeRetained extends SceneGraphObjectRetained implements NnuId {
// Bounds set by the API
Bounds apiBounds;
+ protected Bounds cachedBounds=null; // Cached auto compute bounds, could we use localBounds ?
+
/**
* Each element, p, of branchGroupPaths is a list of BranchGroup from
* root of the tree to this.
@@ -275,7 +277,12 @@ abstract class NodeRetained extends SceneGraphObjectRetained implements NnuId {
* of bounds
*/
void setBoundsAutoCompute(boolean autoCompute) {
+ if (this.boundsAutoCompute==autoCompute) {
+ return;
+ }
+
this.boundsAutoCompute = autoCompute;
+ dirtyBoundsCache();
}
/**
@@ -941,5 +948,20 @@ abstract class NodeRetained extends SceneGraphObjectRetained implements NnuId {
}
void searchGeometryAtoms(UnorderList list) {}
+
+ /**
+ * Make the boundsCache of this node and all its parents dirty
+ */
+ void dirtyBoundsCache() {
+ // Possible optimisation is to not traverse up the tree
+ // if the cachedBounds==null. However this is not the case
+ // if the node is the child of a SharedGroup
+ if (VirtualUniverse.mc.cacheAutoComputedBounds) {
+ cachedBounds = null;
+ if (parent!=null) {
+ parent.dirtyBoundsCache();
+ }
+ }
+ }
}
diff --git a/src/classes/share/javax/media/j3d/Shape3DRetained.java b/src/classes/share/javax/media/j3d/Shape3DRetained.java
index 2b82163..b4ec88c 100644
--- a/src/classes/share/javax/media/j3d/Shape3DRetained.java
+++ b/src/classes/share/javax/media/j3d/Shape3DRetained.java
@@ -286,7 +286,7 @@ class Shape3DRetained extends LeafRetained {
geometryList.add(null);
}
}
-
+ dirtyBoundsCache();
}
/**
@@ -350,6 +350,7 @@ class Shape3DRetained extends LeafRetained {
geometryList.set(index,null);
}
}
+ dirtyBoundsCache();
}
/**
@@ -396,7 +397,8 @@ class Shape3DRetained extends LeafRetained {
} else {
geometryList.add(index,null);
}
- }
+ }
+ dirtyBoundsCache();
}
/**
@@ -435,7 +437,7 @@ class Shape3DRetained extends LeafRetained {
geometryList.remove(index);
}
-
+ dirtyBoundsCache();
}
@@ -838,7 +840,9 @@ class Shape3DRetained extends LeafRetained {
if(boundsAutoCompute) {
// System.err.println("getBounds ---- localBounds is " + localBounds);
-
+ if (cachedBounds!=null) {
+ return (Bounds) cachedBounds.clone();
+ }
if(geometryList != null) {
BoundingBox bbox = new BoundingBox((Bounds) null);
@@ -880,43 +884,66 @@ class Shape3DRetained extends LeafRetained {
*/
void computeCombineBounds(Bounds bounds) {
- if(boundsAutoCompute) {
-
- if(geometryList != null) {
- GeometryRetained geometry;
- BoundingBox bbox = null;
-
- if (staticTransform != null) {
- bbox = new BoundingBox((BoundingBox) null);
- }
-
- for(int i=0; i<geometryList.size(); i++) {
- geometry = (GeometryRetained) geometryList.get(i);
- if ((geometry != null) &&
- (geometry.geoType != GeometryRetained.GEO_TYPE_NONE)) {
- geometry.computeBoundingBox();
- // Should this be lock too ? ( MT safe ? )
- synchronized(geometry.geoBounds) {
- if (staticTransform != null) {
- bbox.set(geometry.geoBounds);
- bbox.transform(staticTransform.transform);
- bounds.combine((Bounds)bbox);
- } else {
- bounds.combine((Bounds)geometry.geoBounds);
- }
- }
- }
- }
- }
-
- } else {
-
- // Should this be lock too ? ( MT safe ? )
- synchronized(localBounds) {
- bounds.combine((Bounds) localBounds);
- }
- }
- }
+ if(boundsAutoCompute) {
+ if(geometryList != null) {
+ GeometryRetained geometry;
+ BoundingBox bbox = null;
+
+ if (staticTransform != null) {
+ bbox = new BoundingBox((BoundingBox) null);
+ }
+
+ if (!VirtualUniverse.mc.cacheAutoComputedBounds) {
+ for(int i=0; i<geometryList.size(); i++) {
+ geometry = (GeometryRetained) geometryList.get(i);
+ if ((geometry != null) &&
+ (geometry.geoType != GeometryRetained.GEO_TYPE_NONE)) {
+ geometry.computeBoundingBox();
+ // Should this be lock too ? ( MT safe ? )
+ synchronized(geometry.geoBounds) {
+ if (staticTransform != null) {
+ bbox.set(geometry.geoBounds);
+ bbox.transform(staticTransform.transform);
+ bounds.combine((Bounds)bbox);
+ } else {
+ bounds.combine((Bounds)geometry.geoBounds);
+ }
+ }
+ }
+ }
+ } else {
+ if (cachedBounds==null) {
+ cachedBounds = new BoundingBox((BoundingBox) null);
+
+ for(int i=0; i<geometryList.size(); i++) {
+ geometry = (GeometryRetained) geometryList.get(i);
+ if ((geometry != null) &&
+ (geometry.geoType != GeometryRetained.GEO_TYPE_NONE)) {
+ geometry.computeBoundingBox();
+ // Should this be lock too ? ( MT safe ? )
+ synchronized(geometry.geoBounds) {
+ if (staticTransform != null) {
+ bbox.set(geometry.geoBounds);
+ bbox.transform(staticTransform.transform);
+ cachedBounds.combine((Bounds)bbox);
+ } else {
+ cachedBounds.combine((Bounds)geometry.geoBounds);
+ }
+ }
+ }
+ }
+ }
+ bounds.combine(cachedBounds);
+ }
+ }
+ } else {
+
+ // Should this be lock too ? ( MT safe ? )
+ synchronized(localBounds) {
+ bounds.combine((Bounds) localBounds);
+ }
+ }
+ }
/**
* assign a name to this node when it is made live.
@@ -2700,6 +2727,7 @@ class Shape3DRetained extends LeafRetained {
geometryList.remove(index);
}
}
+ dirtyBoundsCache();
}
boolean willRemainOpaque(int geoType) {
diff --git a/src/classes/share/javax/media/j3d/SharedGroupRetained.java b/src/classes/share/javax/media/j3d/SharedGroupRetained.java
index ac4036c..7c0be0a 100644
--- a/src/classes/share/javax/media/j3d/SharedGroupRetained.java
+++ b/src/classes/share/javax/media/j3d/SharedGroupRetained.java
@@ -873,4 +873,25 @@ class SharedGroupRetained extends GroupRetained implements TargetsInterface {
s.parentTransformLink = this;
child.setLive(s);
}
+
+ /**
+ * Make the boundsCache of this node and all its parents dirty
+ */
+ void dirtyBoundsCache() {
+ // Possible optimisation is to not traverse up the tree
+ // if the cachedBounds==null. However this is not the case
+ // if the node is the child of a SharedGroup
+ if (VirtualUniverse.mc.cacheAutoComputedBounds) {
+ cachedBounds = null;
+ synchronized(parents) {
+ Enumeration e = parents.elements();
+ while(e.hasMoreElements()) {
+ LinkRetained parent = (LinkRetained) e.nextElement();
+ if (parent!=null) {
+ parent.dirtyBoundsCache();
+ }
+ }
+ }
+ }
+ }
}
diff --git a/src/classes/share/javax/media/j3d/SwitchRetained.java b/src/classes/share/javax/media/j3d/SwitchRetained.java
index 4f99c26..3156d58 100644
--- a/src/classes/share/javax/media/j3d/SwitchRetained.java
+++ b/src/classes/share/javax/media/j3d/SwitchRetained.java
@@ -130,6 +130,7 @@ class SwitchRetained extends GroupRetained implements TargetsInterface
}
sendMessage(updateList);
}
+ dirtyBoundsCache();
}
/**
@@ -182,6 +183,7 @@ class SwitchRetained extends GroupRetained implements TargetsInterface
}
sendMessage(updateList);
}
+ dirtyBoundsCache();
}
void sendMessage(ArrayList updateList) {
@@ -614,37 +616,62 @@ class SwitchRetained extends GroupRetained implements TargetsInterface
NodeRetained child;
if(boundsAutoCompute) {
-
- if(whichChild == Switch.CHILD_ALL) {
- for(i=0; i<children.size(); i++) {
- child = (NodeRetained)children.get(i);
- if(child != null)
- child.computeCombineBounds(bounds);
- }
- }
- else if(whichChild == Switch.CHILD_MASK) {
- for(i=0; i<children.size(); i++) {
- if(childMask.get(i)) {
- child = (NodeRetained)children.get(i);
- if(child != null)
- child.computeCombineBounds(bounds);
- }
- }
- }
- else if(whichChild != Switch.CHILD_NONE) {
- if (whichChild < children.size()) {
- child = (NodeRetained)children.get(whichChild);
- if(child != null)
- child.computeCombineBounds(bounds);
- }
- }
-
+ if (!VirtualUniverse.mc.cacheAutoComputedBounds) {
+ if(whichChild == Switch.CHILD_ALL) {
+ for(i=0; i<children.size(); i++) {
+ child = (NodeRetained)children.get(i);
+ if(child != null)
+ child.computeCombineBounds(bounds);
+ }
+ } else if(whichChild == Switch.CHILD_MASK) {
+ for(i=0; i<children.size(); i++) {
+ if(childMask.get(i)) {
+ child = (NodeRetained)children.get(i);
+ if(child != null)
+ child.computeCombineBounds(bounds);
+ }
+ }
+ } else if(whichChild != Switch.CHILD_NONE) {
+ if (whichChild < children.size()) {
+ child = (NodeRetained)children.get(whichChild);
+ if(child != null)
+ child.computeCombineBounds(bounds);
+ }
+ }
+ } else {
+ if (cachedBounds==null) {
+ cachedBounds = new BoundingSphere();
+ ((BoundingSphere)cachedBounds).setRadius(-1);
+ if(whichChild == Switch.CHILD_ALL) {
+ for(i=0; i<children.size(); i++) {
+ child = (NodeRetained)children.get(i);
+ if(child != null)
+ child.computeCombineBounds(cachedBounds);
+ }
+ } else if(whichChild == Switch.CHILD_MASK) {
+ for(i=0; i<children.size(); i++) {
+ if(childMask.get(i)) {
+ child = (NodeRetained)children.get(i);
+ if(child != null)
+ child.computeCombineBounds(cachedBounds);
+ }
+ }
+ } else if(whichChild != Switch.CHILD_NONE) {
+ if (whichChild < children.size()) {
+ child = (NodeRetained)children.get(whichChild);
+ if(child != null)
+ child.computeCombineBounds(cachedBounds);
+ }
+ }
+ }
+ bounds.combine(cachedBounds);
+ }
+ } else {
+ // Should this be lock too ? ( MT safe ? )
+ synchronized(localBounds) {
+ bounds.combine(localBounds);
+ }
}
- else
- // Should this be lock too ? ( MT safe ? )
- synchronized(localBounds) {
- bounds.combine(localBounds);
- }
}
@@ -658,6 +685,10 @@ class SwitchRetained extends GroupRetained implements TargetsInterface
NodeRetained child;
if(boundsAutoCompute) {
+ if (cachedBounds!=null) {
+ return (Bounds) cachedBounds.clone();
+ }
+
BoundingSphere boundingSphere = new BoundingSphere();
boundingSphere.setRadius(-1.0);
diff --git a/src/classes/share/javax/media/j3d/TransformGroupRetained.java b/src/classes/share/javax/media/j3d/TransformGroupRetained.java
index f51a5fd..3ef24af 100644
--- a/src/classes/share/javax/media/j3d/TransformGroupRetained.java
+++ b/src/classes/share/javax/media/j3d/TransformGroupRetained.java
@@ -147,6 +147,7 @@ class TransformGroupRetained extends GroupRetained implements TargetsInterface
//System.err.println("TransformGroupRetained --- TRANSFORM_CHANGED " + this);
VirtualUniverse.mc.processMessage(tchangeMessage);
}
+ dirtyBoundsCache();
}
/**
@@ -768,10 +769,16 @@ class TransformGroupRetained extends GroupRetained implements TargetsInterface
void computeCombineBounds(Bounds bounds) {
+
+ if (cachedBounds!=null && boundsAutoCompute) {
+ bounds.combine(cachedBounds);
+ return;
+ }
+
NodeRetained child;
BoundingSphere boundingSphere = new BoundingSphere();
boundingSphere.setRadius(-1.0);
-
+
if(boundsAutoCompute) {
for (int i=children.size()-1; i>=0; i--) {
child = (NodeRetained)children.get(i);
@@ -794,6 +801,9 @@ class TransformGroupRetained extends GroupRetained implements TargetsInterface
}
bounds.combine(boundingSphere);
+ if (boundsAutoCompute && VirtualUniverse.mc.cacheAutoComputedBounds) {
+ cachedBounds = boundingSphere;
+ }
}
void processChildLocalToVworld(ArrayList dirtyTransformGroups,