001: /*
002: * $RCSfile: BranchGroupRetained.java,v $
003: *
004: * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
006: *
007: * This code is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU General Public License version 2 only, as
009: * published by the Free Software Foundation. Sun designates this
010: * particular file as subject to the "Classpath" exception as provided
011: * by Sun in the LICENSE file that accompanied this code.
012: *
013: * This code is distributed in the hope that it will be useful, but WITHOUT
014: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: * version 2 for more details (a copy is included in the LICENSE file that
017: * accompanied this code).
018: *
019: * You should have received a copy of the GNU General Public License version
020: * 2 along with this work; if not, write to the Free Software Foundation,
021: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
022: *
023: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
024: * CA 95054 USA or visit www.sun.com if you need additional information or
025: * have any questions.
026: *
027: * $Revision: 1.10 $
028: * $Date: 2008/02/28 20:17:20 $
029: * $State: Exp $
030: */
031:
032: package javax.media.j3d;
033:
034: import java.util.*;
035:
036: /**
037: * The BranchGroup node provides the ability to insert a branch of
038: * a scene graph into the virtual world.
039: */
040:
041: class BranchGroupRetained extends GroupRetained {
042:
043: // This boolean is used in a moveTo operation to get transforms to update
044: boolean isDirty = false;
045:
046: // This boolean is used when the BG is inserted into the scene
047: boolean isNew = false;
048:
049: /**
050: * True, if this branchGroup is directly attached to the locale
051: */
052: boolean attachedToLocale = false;
053:
054: BranchGroupRetained() {
055: this .nodeType = NodeRetained.BRANCHGROUP;
056: }
057:
058: /**
059: * This sets the current locale.
060: */
061: void setLocale(Locale loc) {
062: locale = loc;
063: }
064:
065: /**
066: * This gets the current locale
067: */
068: Locale getLocale() {
069: return locale;
070: }
071:
072: /**
073: * Detaches this BranchGroup from its parent.
074: */
075: void detach() {
076: dirtyBoundsCache();
077: if (universe != null) {
078: universe.resetWaitMCFlag();
079: synchronized (universe.sceneGraphLock) {
080: boolean isLive = source.isLive();
081: if (isLive) {
082: notifySceneGraphChanged(true);
083: }
084: GroupRetained oldParent = (GroupRetained) parent;
085: do_detach();
086: universe.setLiveState.clear();
087: if (isLive) {
088: if (oldParent == null) {
089: universe.notifyStructureChangeListeners(false,
090: locale, (BranchGroup) this .source);
091: } else {
092: universe.notifyStructureChangeListeners(false,
093: oldParent.source,
094: (BranchGroup) this .source);
095: }
096: }
097: }
098: universe.waitForMC();
099: } else { // Not live yet, just do it.
100: this .do_detach();
101: if (universe != null) {
102: synchronized (universe.sceneGraphLock) {
103: universe.setLiveState.clear();
104: }
105: }
106: }
107: }
108:
109: // The method that does the work once the lock is acquired.
110: void do_detach() {
111: if (attachedToLocale) {
112: locale.doRemoveBranchGraph((BranchGroup) this .source, null,
113: 0);
114: } else if (parent != null) {
115: GroupRetained g = (GroupRetained) parent;
116: g.doRemoveChild(g.children.indexOf(this ), null, 0);
117: }
118: }
119:
120: void setNodeData(SetLiveState s) {
121: // super.setNodeData will set branchGroupPaths
122: // based on s.parentBranchGroupPaths, we need to
123: // set it earlier in order to undo the effect.
124: s.parentBranchGroupPaths = branchGroupPaths;
125:
126: super .setNodeData(s);
127:
128: if (!inSharedGroup) {
129: setAuxData(s, 0, 0);
130: } else {
131: // For inSharedGroup case.
132: int j, hkIndex;
133: for (j = 0; j < s.keys.length; j++) {
134: hkIndex = s.keys[j].equals(localToVworldKeys, 0,
135: localToVworldKeys.length);
136:
137: if (hkIndex >= 0) {
138: setAuxData(s, j, hkIndex);
139:
140: } else {
141: // XXXX: change this to an assertion exception
142: MasterControl
143: .getCoreLogger()
144: .severe(
145: "Can't Find matching hashKey in setNodeData.");
146: }
147: }
148: }
149: }
150:
151: void setAuxData(SetLiveState s, int index, int hkIndex) {
152: super .setAuxData(s, index, hkIndex);
153:
154: BranchGroupRetained path[] = (BranchGroupRetained[]) s.branchGroupPaths
155: .get(index);
156: BranchGroupRetained clonePath[] = new BranchGroupRetained[path.length + 1];
157: System.arraycopy(path, 0, clonePath, 0, path.length);
158: clonePath[path.length] = this ;
159: s.branchGroupPaths.set(index, clonePath);
160: branchGroupPaths.add(hkIndex, clonePath);
161: }
162:
163: /**
164: * remove the localToVworld transform for this node.
165: */
166: void removeNodeData(SetLiveState s) {
167:
168: if ((!inSharedGroup) || (s.keys.length == localToVworld.length)) {
169: // restore to default and avoid calling clear()
170: // that may clear parent reference branchGroupPaths
171: branchGroupPaths = new ArrayList(1);
172: } else {
173: int i, index;
174: // Must be in reverse, to preserve right indexing.
175: for (i = s.keys.length - 1; i >= 0; i--) {
176: index = s.keys[i].equals(localToVworldKeys, 0,
177: localToVworldKeys.length);
178: if (index >= 0) {
179: branchGroupPaths.remove(index);
180: }
181: }
182: // Set it back to its parent localToVworld data. This is b/c the parent has
183: // changed it localToVworld data arrays.
184: }
185: super .removeNodeData(s);
186: }
187:
188: void setLive(SetLiveState s) {
189: // recursively call child
190: super .doSetLive(s);
191: super .markAsLive();
192: }
193:
194: // Top level compile call
195: void compile() {
196:
197: if (source.isCompiled() || VirtualUniverse.mc.disableCompile)
198: return;
199:
200: if (J3dDebug.devPhase && J3dDebug.debug) {
201: J3dDebug.doDebug(J3dDebug.compileState, J3dDebug.LEVEL_3,
202: "BranchGroupRetained.compile()....\n");
203: }
204:
205: CompileState compState = new CompileState();
206:
207: isRoot = true;
208:
209: compile(compState);
210: merge(compState);
211:
212: if (J3dDebug.devPhase && J3dDebug.debug) {
213: if (J3dDebug.doDebug(J3dDebug.compileState,
214: J3dDebug.LEVEL_3)) {
215: compState.printStats();
216: }
217: if (J3dDebug.doDebug(J3dDebug.compileState,
218: J3dDebug.LEVEL_5)) {
219: this .traverse(false, 1);
220: System.err.println();
221: }
222: }
223: }
224:
225: void compile(CompileState compState) {
226: // if this branch group is previously compiled, don't
227: // go any further. Mark the keepTG flag for now. Static
228: // transform doesn't go beyond previously compiled group.
229:
230: if (mergeFlag == SceneGraphObjectRetained.MERGE_DONE) {
231: compState.keepTG = true;
232: return;
233: }
234:
235: super .compile(compState);
236:
237: // don't remove this node because user can do pickAll on this node
238: // without any capabilities set
239: mergeFlag = SceneGraphObjectRetained.DONT_MERGE;
240: }
241:
242: SceneGraphPath[] pickAll(PickShape pickShape) {
243:
244: PickInfo[] pickInfoArr = pickAll(PickInfo.PICK_BOUNDS,
245: PickInfo.SCENEGRAPHPATH, pickShape);
246:
247: if (pickInfoArr == null) {
248: return null;
249: }
250:
251: SceneGraphPath[] sgpArr = new SceneGraphPath[pickInfoArr.length];
252: for (int i = 0; i < sgpArr.length; i++) {
253: sgpArr[i] = pickInfoArr[i].getSceneGraphPath();
254: }
255:
256: return sgpArr;
257: }
258:
259: PickInfo[] pickAll(int mode, int flags, PickShape pickShape) {
260:
261: if (inSharedGroup) {
262: throw new RestrictedAccessException(J3dI18N
263: .getString("BranchGroup9"));
264: }
265:
266: GeometryAtom geomAtoms[] = locale.universe.geometryStructure
267: .pickAll(locale, pickShape);
268:
269: return PickInfo.pick(this , geomAtoms, mode, flags, pickShape,
270: PickInfo.PICK_ALL);
271:
272: }
273:
274: SceneGraphPath[] pickAllSorted(PickShape pickShape) {
275:
276: PickInfo[] pickInfoArr = pickAllSorted(PickInfo.PICK_BOUNDS,
277: PickInfo.SCENEGRAPHPATH, pickShape);
278:
279: if (pickInfoArr == null) {
280: return null;
281: }
282:
283: SceneGraphPath[] sgpArr = new SceneGraphPath[pickInfoArr.length];
284: for (int i = 0; i < sgpArr.length; i++) {
285: sgpArr[i] = pickInfoArr[i].getSceneGraphPath();
286: }
287:
288: return sgpArr;
289:
290: }
291:
292: PickInfo[] pickAllSorted(int mode, int flags, PickShape pickShape) {
293:
294: if (inSharedGroup) {
295: throw new RestrictedAccessException(J3dI18N
296: .getString("BranchGroup9"));
297: }
298:
299: GeometryAtom geomAtoms[] = locale.universe.geometryStructure
300: .pickAll(locale, pickShape);
301:
302: PickInfo[] pickInfoArr = null;
303:
304: if ((geomAtoms == null) || (geomAtoms.length == 0)) {
305: return null;
306: }
307:
308: if (mode == PickInfo.PICK_GEOMETRY) {
309: // Need to have closestDistance set
310: flags |= PickInfo.CLOSEST_DISTANCE;
311: pickInfoArr = PickInfo.pick(this , geomAtoms, mode, flags,
312: pickShape, PickInfo.PICK_ALL);
313: if (pickInfoArr != null) {
314: PickInfo.sortPickInfoArray(pickInfoArr);
315: }
316: } else {
317: PickInfo.sortGeomAtoms(geomAtoms, pickShape);
318: pickInfoArr = PickInfo.pick(this , geomAtoms, mode, flags,
319: pickShape, PickInfo.PICK_ALL);
320: }
321:
322: return pickInfoArr;
323:
324: }
325:
326: SceneGraphPath pickClosest(PickShape pickShape) {
327:
328: PickInfo pickInfo = pickClosest(PickInfo.PICK_BOUNDS,
329: PickInfo.SCENEGRAPHPATH, pickShape);
330:
331: if (pickInfo == null) {
332: return null;
333: }
334:
335: return pickInfo.getSceneGraphPath();
336:
337: }
338:
339: PickInfo pickClosest(int mode, int flags, PickShape pickShape) {
340:
341: PickInfo[] pickInfoArr = null;
342:
343: pickInfoArr = pickAllSorted(mode, flags, pickShape);
344:
345: if (pickInfoArr == null) {
346: return null;
347: }
348:
349: return pickInfoArr[0];
350:
351: }
352:
353: SceneGraphPath pickAny(PickShape pickShape) {
354:
355: PickInfo pickInfo = pickAny(PickInfo.PICK_BOUNDS,
356: PickInfo.SCENEGRAPHPATH, pickShape);
357:
358: if (pickInfo == null) {
359: return null;
360: }
361: return pickInfo.getSceneGraphPath();
362: }
363:
364: PickInfo pickAny(int mode, int flags, PickShape pickShape) {
365:
366: if (inSharedGroup) {
367: throw new RestrictedAccessException(J3dI18N
368: .getString("BranchGroup9"));
369: }
370:
371: GeometryAtom geomAtoms[] = locale.universe.geometryStructure
372: .pickAll(locale, pickShape);
373:
374: PickInfo[] pickInfoArr = PickInfo.pick(this , geomAtoms, mode,
375: flags, pickShape, PickInfo.PICK_ANY);
376:
377: if (pickInfoArr == null) {
378: return null;
379: }
380:
381: return pickInfoArr[0];
382:
383: }
384: }
|