001: /*
002: * Copyright (c) 2001 Silvere Martin-Michiellot All Rights Reserved.
003: *
004: * Silvere Martin-Michiellot grants you ("Licensee") a non-exclusive,
005: * royalty free, license to use, modify and redistribute this
006: * software in source and binary code form,
007: * provided that i) this copyright notice and license appear on all copies of
008: * the software; and ii) Licensee does not utilize the software in a manner
009: * which is disparaging to Silvere Martin-Michiellot.
010: *
011: * This software is provided "AS IS," without a warranty of any kind. ALL
012: * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
013: * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
014: * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. Silvere Martin-Michiellot
015: * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES
016: * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
017: * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
018: * Silvere Martin-Michiellot OR ITS LICENSORS BE LIABLE
019: * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
020: * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
021: * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
022: * OR INABILITY TO USE SOFTWARE, EVEN IF Silvere Martin-Michiellot HAS BEEN
023: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
024: *
025: * This software is not designed or intended for use in on-line control of
026: * aircraft, air traffic, aircraft navigation or aircraft communications; or in
027: * the design, construction, operation or maintenance of any nuclear
028: * facility. Licensee represents and warrants that it will not use or
029: * redistribute the Software for such purposes.
030: *
031: * @Author: Silvere Martin-Michiellot
032: *
033: */
034:
035: // This code is repackaged after the code from Sun by Rick Goldberg and Doug Gehringer
036: // Site http://java.sun.com/
037: // Email
038: package com.db.utils.tree;
039:
040: import javax.media.j3d.*;
041: import javax.vecmath.Color3f;
042: import java.util.*;
043:
044: public class TreeCleaner {
045:
046: private static final int CLEAN_UNUSED = 1;
047: private static final int CLEAN_NONE = 2;
048:
049: private static final int ALREADY_CLEANED = -1;
050:
051: static final boolean debug = false;
052:
053: /**
054: * Clears pickable and collidable flags in Shape3Ds in the subgraph
055: * under the input node. The pickable flag is set to false if there
056: * are no groups above the Shape3D with ENABLE_PICK_REPORTING set. The
057: * collidable flag on Shape3ds is always set to false.
058: */
059: static public void cleanSubgraph(javax.media.j3d.Node implNode)
060: throws RestrictedAccessException {
061:
062: Hashtable sharedGroups = new Hashtable();
063:
064: checkAndClean(implNode, CLEAN_UNUSED, sharedGroups);
065:
066: // now go through the shared groups we found, since traversing
067: // the sg's can find new sg's, we need to iterate
068: int numGroupsCleaned = 0;
069: Integer alreadyCleaned = new Integer(ALREADY_CLEANED);
070:
071: while (numGroupsCleaned < sharedGroups.size()) {
072: if (debug) {
073: System.out.println("Cleaning shared groups: "
074: + numGroupsCleaned + " done out of "
075: + sharedGroups.size());
076: }
077: Enumeration e = sharedGroups.keys();
078: while (e.hasMoreElements()) {
079: SharedGroup sg = (SharedGroup) e.nextElement();
080: int sgFlag = ((Integer) sharedGroups.get(sg))
081: .intValue();
082: if (sgFlag != ALREADY_CLEANED) {
083: checkAndClean(sg, sgFlag, sharedGroups);
084: sharedGroups.put(sg, alreadyCleaned);
085: numGroupsCleaned++;
086: }
087: }
088: }
089:
090: }
091:
092: static void checkAndClean(javax.media.j3d.Node node,
093: int pickingFlag, Hashtable sharedGroups)
094: throws RestrictedAccessException {
095:
096: if (node != null) {
097: if (node.isLive()) {
098: throw new RestrictedAccessException(
099: "Can't clean a live scene graph");
100: } else {
101: clean(node, pickingFlag, sharedGroups);
102: }
103: }
104:
105: }
106:
107: static void clean(javax.media.j3d.Node node, int pickingFlag,
108: Hashtable sharedGroups) {
109:
110: if (node instanceof javax.media.j3d.Group) {
111: // if current flag is unused and this group is pickable, keep it's
112: // children pickable
113: if ((pickingFlag == CLEAN_UNUSED)
114: && (node
115: .getCapability(javax.media.j3d.Node.ENABLE_PICK_REPORTING))) {
116: pickingFlag = CLEAN_NONE;
117: }
118: Enumeration e = ((javax.media.j3d.Group) node)
119: .getAllChildren();
120: while (e.hasMoreElements()) {
121: clean((javax.media.j3d.Node) (e.nextElement()),
122: pickingFlag, sharedGroups);
123: }
124: } else if (node instanceof Link) {
125: Link link = (Link) node;
126: SharedGroup sg = link.getSharedGroup();
127: Integer value = (Integer) sharedGroups.get(sg);
128: // Set value if none set before or this value is more restrictive
129: if ((value == null) || (pickingFlag > value.intValue())) {
130: value = new Integer(pickingFlag);
131: sharedGroups.put(sg, new Integer(pickingFlag));
132: }
133: } else if (node instanceof Shape3D) {
134: if (pickingFlag != CLEAN_NONE) {
135: node.setPickable(false);
136: }
137: node.setCollidable(false);
138: }
139:
140: }
141:
142: }
|