001: /*
002: * $RCSfile: ViewSpecificGroup.java,v $
003: *
004: * Copyright 2001-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.7 $
028: * $Date: 2008/02/28 20:17:33 $
029: * $State: Exp $
030: */
031:
032: package javax.media.j3d;
033:
034: import java.util.Enumeration;
035:
036: /**
037: * The ViewSpecificGroup node is a Group whose descendants are
038: * rendered only on a specified set of views. It
039: * contains a list of views on which its descendants are
040: * rendered. Methods are provided to add, remove, and enumerate the
041: * list of views. The list of views is initially empty, meaning that
042: * the descendants of this group will not be rendered on any view. At
043: * least one view must be added to the list of views for rendering to
044: * occur.
045: *
046: * <p>
047: * All nodes except ViewPlatform may appear as a descendant of
048: * ViewSpecificGroup, including another ViewSpecificGroup. If a
049: * ViewSpecificGroup is a descendant of a ViewSpecificGroup, the
050: * effect is to intersect the view sets of the ViewSpecificGroup nodes
051: * in the hierarchy; each ViewSpecificGroup encountered when
052: * traversing the scene graph further restricts the set of views on
053: * which its descendants are rendered. More formally, descendant
054: * nodes of ViewSpecificGroups are rendered in (or apply to) only
055: * those views that are contained in the set of views of every
056: * ViewSpecificGroup in the scene graph path from the Locale to the
057: * Node.
058: *
059: * <p>
060: * Behavior
061: * nodes may appear under a ViewSpecificGroup, but are not affected by
062: * it--the Behavior scheduler is per-universe rather than per-View.
063: * BoundingLeaf nodes are similarly unaffected by being under a
064: * ViewSpecificGroup. A BoundingLeaf under a ViewSpecificGroup
065: * provides a valid bounds for any node that refers to it,
066: * irrespective of the view.
067: *
068: * <p>
069: * The rest of the leaf nodes either: A) are only rendered within the
070: * specified view(s), for example, Shape3D, Morph, and Sound; or B)
071: * only affect other objects when they are rendered in the specified
072: * view(s), for example, AlternateAppearance, Clip, ModelClip, Fog,
073: * Light, Soundscape, Background.
074: *
075: * @since Java 3D 1.3
076: */
077:
078: public class ViewSpecificGroup extends Group {
079: /**
080: * Specifies that this ViewSpecificGroup node allows reading its
081: * view information at runtime.
082: */
083: public static final int ALLOW_VIEW_READ = CapabilityBits.VIEW_SPECIFIC_GROUP_ALLOW_VIEW_READ;
084:
085: /**
086: * Specifies that this ViewSpecificGroup node allows writing its
087: * view information at runtime.
088: */
089: public static final int ALLOW_VIEW_WRITE = CapabilityBits.VIEW_SPECIFIC_GROUP_ALLOW_VIEW_WRITE;
090:
091: // Array for setting default read capabilities
092: private static final int[] readCapabilities = { ALLOW_VIEW_READ };
093:
094: /**
095: * Constructs and initializes a new ViewSpecificGroup node object.
096: */
097: public ViewSpecificGroup() {
098: // set default read capabilities
099: setDefaultReadCapabilities(readCapabilities);
100: }
101:
102: /**
103: * Creates the retained mode ViewSpecificGroupRetained object that this
104: * ViewSpecificGroup component object will point to.
105: */
106: void createRetained() {
107: this .retained = new ViewSpecificGroupRetained();
108: this .retained.setSource(this );
109: }
110:
111: /**
112: * Replaces the view at the specified index in this node's
113: * list of views with the specified View object.
114: *
115: * @param view the View object to be stored at the specified index.
116: * @param index the index of the View object to be replaced.
117: * @exception CapabilityNotSetException if appropriate capability is
118: * not set and this object is part of live or compiled scene graph
119: */
120: public void setView(View view, int index) {
121: if (isLiveOrCompiled())
122: if (!this .getCapability(ALLOW_VIEW_WRITE))
123: throw new CapabilityNotSetException(J3dI18N
124: .getString("ViewSpecificGroup1"));
125:
126: ((ViewSpecificGroupRetained) this .retained)
127: .setView(view, index);
128: }
129:
130: /**
131: * Retrieves the View object at the specified index from this node's
132: * list of views.
133: *
134: * @param index the index of the View object to be returned.
135: * @return the View object at the specified index.
136: * @exception CapabilityNotSetException if appropriate capability is
137: * not set and this object is part of live or compiled scene graph
138: */
139: public View getView(int index) {
140: if (isLiveOrCompiled())
141: if (!this .getCapability(ALLOW_VIEW_READ))
142: throw new CapabilityNotSetException(J3dI18N
143: .getString("ViewSpecificGroup2"));
144:
145: return ((ViewSpecificGroupRetained) this .retained)
146: .getView(index);
147: }
148:
149: /**
150: * Inserts the specified View object into this node's
151: * list of views at the specified index.
152: *
153: * @param view the View object to be inserted at the specified index.
154: * @param index the index at which the View object is inserted.
155: * @exception CapabilityNotSetException if appropriate capability is
156: * not set and this object is part of live or compiled scene graph
157: */
158: public void insertView(View view, int index) {
159: if (isLiveOrCompiled())
160: if (!this .getCapability(ALLOW_VIEW_WRITE))
161: throw new CapabilityNotSetException(J3dI18N
162: .getString("ViewSpecificGroup1"));
163:
164: ((ViewSpecificGroupRetained) this .retained).insertView(view,
165: index);
166: }
167:
168: /**
169: * Removes the View object at the specified index from this node's
170: * list of views.
171: * If this operation causes the list of views to become empty,
172: * then the descendants of this ViewSpecificGroup node will not be
173: * rendered.
174: *
175: * @param index the index of the View object to be removed.
176: * @exception CapabilityNotSetException if appropriate capability is
177: * not set and this object is part of live or compiled scene graph
178: */
179: public void removeView(int index) {
180: if (isLiveOrCompiled())
181: if (!this .getCapability(ALLOW_VIEW_WRITE))
182: throw new CapabilityNotSetException(J3dI18N
183: .getString("ViewSpecificGroup1"));
184: ((ViewSpecificGroupRetained) this .retained).removeView(index);
185:
186: }
187:
188: /**
189: * Returns an enumeration of this ViewSpecificGroup node's list
190: * of views.
191: *
192: * @return an Enumeration object containing all the views.
193: * @exception CapabilityNotSetException if appropriate capability is
194: * not set and this object is part of live or compiled scene graph
195: */
196: public Enumeration getAllViews() {
197: if (isLiveOrCompiled())
198: if (!this .getCapability(ALLOW_VIEW_READ))
199: throw new CapabilityNotSetException(J3dI18N
200: .getString("ViewSpecificGroup2"));
201:
202: return ((ViewSpecificGroupRetained) this .retained)
203: .getAllViews();
204: }
205:
206: /**
207: * Appends the specified View object to this node's list of views.
208: *
209: * @param view the View object to be appended.
210: * @exception CapabilityNotSetException if appropriate capability is
211: * not set and this object is part of live or compiled scene graph
212: */
213: public void addView(View view) {
214: if (isLiveOrCompiled())
215: if (!this .getCapability(ALLOW_VIEW_WRITE))
216: throw new CapabilityNotSetException(J3dI18N
217: .getString("ViewSpecificGroup1"));
218:
219: ((ViewSpecificGroupRetained) this .retained).addView(view);
220: }
221:
222: /**
223: * Returns the number of View objects in this node's list of views.
224: * If this number is 0, then the list of views is empty and
225: * the descendants of this ViewSpecificGroup node will not be
226: * rendered.
227: *
228: * @return the number of views in this node's list of views.
229: * @exception CapabilityNotSetException if appropriate capability is
230: * not set and this object is part of live or compiled scene graph
231: */
232: public int numViews() {
233: if (isLiveOrCompiled())
234: if (!this .getCapability(ALLOW_VIEW_READ))
235: throw new CapabilityNotSetException(J3dI18N
236: .getString("ViewSpecificGroup2"));
237:
238: return ((ViewSpecificGroupRetained) this .retained).numViews();
239: }
240:
241: /**
242: * Retrieves the index of the specified View object in this
243: * node's list of views.
244: *
245: * @param view the View object to be looked up.
246: * @return the index of the specified View object;
247: * returns -1 if the object is not in the list.
248: * @exception CapabilityNotSetException if appropriate capability is
249: * not set and this object is part of live or compiled scene graph
250: *
251: * @since Java 3D 1.3
252: */
253: public int indexOfView(View view) {
254: if (isLiveOrCompiled())
255: if (!this .getCapability(ALLOW_VIEW_READ))
256: throw new CapabilityNotSetException(J3dI18N
257: .getString("ViewSpecificGroup2"));
258:
259: return ((ViewSpecificGroupRetained) this .retained)
260: .indexOfView(view);
261: }
262:
263: /**
264: * Removes the specified View object from this
265: * node's list of views. If the specified object is not in the
266: * list, the list is not modified.
267: * If this operation causes the list of views to become empty,
268: * then the descendants of this ViewSpecificGroup node will not be
269: * rendered.
270: *
271: * @param view the View object to be removed.
272: * @exception CapabilityNotSetException if appropriate capability is
273: * not set and this object is part of live or compiled scene graph
274: *
275: * @since Java 3D 1.3
276: */
277: public void removeView(View view) {
278: if (isLiveOrCompiled())
279: if (!this .getCapability(ALLOW_VIEW_WRITE))
280: throw new CapabilityNotSetException(J3dI18N
281: .getString("ViewSpecificGroup1"));
282:
283: ((ViewSpecificGroupRetained) this .retained).removeView(view);
284: }
285:
286: /**
287: * Removes all View objects from this node's
288: * list of views.
289: * Since this method clears the list of views, the descendants of
290: * this ViewSpecificGroup node will not be rendered.
291: *
292: * @exception CapabilityNotSetException if appropriate capability is
293: * not set and this object is part of live or compiled scene graph
294: *
295: * @since Java 3D 1.3
296: */
297: public void removeAllViews() {
298: if (isLiveOrCompiled())
299: if (!this .getCapability(ALLOW_VIEW_WRITE))
300: throw new CapabilityNotSetException(J3dI18N
301: .getString("ViewSpecificGroup1"));
302:
303: ((ViewSpecificGroupRetained) this .retained).removeAllViews();
304: }
305:
306: /**
307: * Used to create a new instance of the node. This routine is called
308: * by <code>cloneTree</code> to duplicate the current node.
309: * @param forceDuplicate when set to <code>true</code>, causes the
310: * <code>duplicateOnCloneTree</code> flag to be ignored. When
311: * <code>false</code>, the value of each node's
312: * <code>duplicateOnCloneTree</code> variable determines whether
313: * NodeComponent data is duplicated or copied.
314: *
315: * @see Node#cloneTree
316: * @see Node#cloneNode
317: * @see Node#duplicateNode
318: * @see NodeComponent#setDuplicateOnCloneTree
319: */
320: public Node cloneNode(boolean forceDuplicate) {
321: ViewSpecificGroup vsg = new ViewSpecificGroup();
322: vsg.duplicateNode(this , forceDuplicate);
323: return vsg;
324: }
325:
326: /**
327: * Copies all ViewSpecificGroup information from
328: * <code>originalNode</code> into
329: * the current node. This method is called from the
330: * <code>cloneNode</code> method which is, in turn, called by the
331: * <code>cloneTree</code> method.<P>
332: *
333: * @param originalNode the original node to duplicate.
334: * @param forceDuplicate when set to <code>true</code>, causes the
335: * <code>duplicateOnCloneTree</code> flag to be ignored. When
336: * <code>false</code>, the value of each node's
337: * <code>duplicateOnCloneTree</code> variable determines whether
338: * NodeComponent data is duplicated or copied.
339: *
340: * @exception RestrictedAccessException if this object is part of a live
341: * or compiled scenegraph.
342: *
343: * @see Group#cloneNode
344: * @see Node#duplicateNode
345: * @see Node#cloneTree
346: * @see NodeComponent#setDuplicateOnCloneTree
347: */
348: void duplicateAttributes(Node originalNode, boolean forceDuplicate) {
349:
350: // XXXX: implement this?
351: super .duplicateAttributes(originalNode, forceDuplicate);
352:
353: ViewSpecificGroupRetained attr = (ViewSpecificGroupRetained) originalNode.retained;
354: ViewSpecificGroupRetained rt = (ViewSpecificGroupRetained) retained;
355:
356: for (Enumeration e = attr.getAllViews(); e.hasMoreElements();) {
357: rt.addView((View) e.nextElement());
358: }
359: }
360:
361: }
|