001: /*
002: * $RCSfile: Clip.java,v $
003: *
004: * Copyright 1997-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.6 $
028: * $Date: 2008/02/28 20:17:20 $
029: * $State: Exp $
030: */
031:
032: package javax.media.j3d;
033:
034: /**
035: * The Clip leaf node defines the back, or far, clip distance in
036: * the virtual universe.
037: * The distance is specified in the local coordinate system of this node.
038: * This node also specifies an application
039: * region in which this clip node is active.
040: * A Clip node is active when its application region intersects
041: * the ViewPlatform's activation volume. If multiple Clip nodes
042: * are active, the Clip node that is "closest" to the eye will be
043: * used.
044: * If no clip node is in scope of the view platform
045: * associated with the current view, then the back clip distance is
046: * defined by the View object.
047: * The front clip distance is always defined by the
048: * View object.
049: *
050: * @see View
051: */
052: public class Clip extends Leaf {
053:
054: /**
055: * Specifies that the Clip allows read access to its application
056: * bounds and bounding leaf at runtime.
057: */
058: public static final int ALLOW_APPLICATION_BOUNDS_READ = CapabilityBits.CLIP_ALLOW_APPLICATION_BOUNDS_READ;
059:
060: /**
061: * Specifies that the Clip allows write access to its application
062: * bounds and bounding leaf at runtime.
063: */
064: public static final int ALLOW_APPLICATION_BOUNDS_WRITE = CapabilityBits.CLIP_ALLOW_APPLICATION_BOUNDS_WRITE;
065:
066: /**
067: * Specifies that the Clip allows read access to its back distance
068: * at runtime.
069: */
070: public static final int ALLOW_BACK_DISTANCE_READ = CapabilityBits.CLIP_ALLOW_BACK_DISTANCE_READ;
071:
072: /**
073: * Specifies that the Clip allows write access to its back distance
074: * at runtime.
075: */
076: public static final int ALLOW_BACK_DISTANCE_WRITE = CapabilityBits.CLIP_ALLOW_BACK_DISTANCE_WRITE;
077:
078: // Array for setting default read capabilities
079: private static final int[] readCapabilities = {
080: ALLOW_APPLICATION_BOUNDS_READ, ALLOW_BACK_DISTANCE_READ };
081:
082: /**
083: * Constructs a Clip node with default parameters. The default
084: * values are as follows:
085: * <ul>
086: * back clip distance : 100 meters<sr>
087: * application bounds : null<br>
088: * application bounding leaf : null<br>
089: * </ul>
090: */
091: public Clip() {
092: // Just use the defaults
093: // set default read capabilities
094: setDefaultReadCapabilities(readCapabilities);
095: }
096:
097: /**
098: * Constructs a Clip node with the specified back clip distance.
099: */
100: public Clip(double backDistance) {
101: // set default read capabilities
102: setDefaultReadCapabilities(readCapabilities);
103:
104: ((ClipRetained) this .retained).initBackDistance(backDistance);
105: }
106:
107: /**
108: * Sets the back clip distance to the specified value.
109: * There are several considerations that need to be taken into
110: * account when choosing values for the front and back clip
111: * distances. These are enumerated in the description of
112: * <a href=View.html#setFrontClipDistance(double)>
113: * View.setFrontClipDistance</a>.
114: * @param backDistance the new back clip distance in meters
115: * @see View#setFrontClipDistance
116: * @see View#setBackClipDistance
117: */
118: public void setBackDistance(double backDistance) {
119: if (isLiveOrCompiled())
120: if (!this .getCapability(ALLOW_BACK_DISTANCE_WRITE))
121: throw new CapabilityNotSetException(J3dI18N
122: .getString("Clip0"));
123:
124: if (isLive())
125: ((ClipRetained) this .retained)
126: .setBackDistance(backDistance);
127: else
128: ((ClipRetained) this .retained)
129: .initBackDistance(backDistance);
130: }
131:
132: /**
133: * Retrieves the back clip distance.
134: * @return the current back clip distance, in meters
135: */
136: public double getBackDistance() {
137: if (isLiveOrCompiled())
138: if (!this .getCapability(ALLOW_BACK_DISTANCE_READ))
139: throw new CapabilityNotSetException(J3dI18N
140: .getString("Clip1"));
141: return ((ClipRetained) this .retained).getBackDistance();
142: }
143:
144: /**
145: * Set the Clip's application region to the specified bounds.
146: * This is used when the application bounding leaf is set to null.
147: * @param region the bounds that contains the Clip's new application
148: * region.
149: * @exception CapabilityNotSetException if appropriate capability is
150: * not set and this object is part of live or compiled scene graph
151: */
152: public void setApplicationBounds(Bounds region) {
153: if (isLiveOrCompiled())
154: if (!this .getCapability(ALLOW_APPLICATION_BOUNDS_WRITE))
155: throw new CapabilityNotSetException(J3dI18N
156: .getString("Clip2"));
157:
158: if (isLive())
159: ((ClipRetained) this .retained).setApplicationBounds(region);
160: else
161: ((ClipRetained) this .retained)
162: .initApplicationBounds(region);
163: }
164:
165: /**
166: * Retrieves the Clip node's application bounds.
167: * @return this Clip's application bounds information
168: * @exception CapabilityNotSetException if appropriate capability is
169: * not set and this object is part of live or compiled scene graph
170: */
171: public Bounds getApplicationBounds() {
172: if (isLiveOrCompiled())
173: if (!this .getCapability(ALLOW_APPLICATION_BOUNDS_READ))
174: throw new CapabilityNotSetException(J3dI18N
175: .getString("Clip3"));
176:
177: return ((ClipRetained) this .retained).getApplicationBounds();
178: }
179:
180: /**
181: * Set the Clip's application region to the specified bounding leaf.
182: * When set to a value other than null, this overrides the application
183: * bounds object.
184: * @param region the bounding leaf node used to specify the Clip
185: * node's new application region.
186: * @exception CapabilityNotSetException if appropriate capability is
187: * not set and this object is part of live or compiled scene graph
188: */
189: public void setApplicationBoundingLeaf(BoundingLeaf region) {
190: if (isLiveOrCompiled())
191: if (!this .getCapability(ALLOW_APPLICATION_BOUNDS_WRITE))
192: throw new CapabilityNotSetException(J3dI18N
193: .getString("Clip2"));
194:
195: if (isLive())
196: ((ClipRetained) this .retained)
197: .setApplicationBoundingLeaf(region);
198: else
199: ((ClipRetained) this .retained)
200: .initApplicationBoundingLeaf(region);
201: }
202:
203: /**
204: * Retrieves the Clip node's application bounding leaf.
205: * @return this Clip's application bounding leaf information
206: * @exception CapabilityNotSetException if appropriate capability is
207: * not set and this object is part of live or compiled scene graph
208: */
209: public BoundingLeaf getApplicationBoundingLeaf() {
210: if (isLiveOrCompiled())
211: if (!this .getCapability(ALLOW_APPLICATION_BOUNDS_READ))
212: throw new CapabilityNotSetException(J3dI18N
213: .getString("Clip3"));
214:
215: return ((ClipRetained) this .retained)
216: .getApplicationBoundingLeaf();
217: }
218:
219: /**
220: * Creates the retained mode ClipRetained object that this
221: * Clip component object will point to.
222: */
223: void createRetained() {
224: this .retained = new ClipRetained();
225: this .retained.setSource(this );
226: }
227:
228: /**
229: * Used to create a new instance of the node. This routine is called
230: * by <code>cloneTree</code> to duplicate the current node.
231: * @param forceDuplicate when set to <code>true</code>, causes the
232: * <code>duplicateOnCloneTree</code> flag to be ignored. When
233: * <code>false</code>, the value of each node's
234: * <code>duplicateOnCloneTree</code> variable determines whether
235: * NodeComponent data is duplicated or copied.
236: *
237: * @see Node#cloneTree
238: * @see Node#cloneNode
239: * @see Node#duplicateNode
240: * @see NodeComponent#setDuplicateOnCloneTree
241: */
242: public Node cloneNode(boolean forceDuplicate) {
243: Clip c = new Clip();
244: c.duplicateNode(this , forceDuplicate);
245: return c;
246: }
247:
248: /**
249: * Callback used to allow a node to check if any scene graph objects
250: * referenced
251: * by that node have been duplicated via a call to <code>cloneTree</code>.
252: * This method is called by <code>cloneTree</code> after all nodes in
253: * the sub-graph have been duplicated. The cloned Leaf node's method
254: * will be called and the Leaf node can then look up any object references
255: * by using the <code>getNewObjectReference</code> method found in the
256: * <code>NodeReferenceTable</code> object. If a match is found, a
257: * reference to the corresponding object in the newly cloned sub-graph
258: * is returned. If no corresponding reference is found, either a
259: * DanglingReferenceException is thrown or a reference to the original
260: * object is returned depending on the value of the
261: * <code>allowDanglingReferences</code> parameter passed in the
262: * <code>cloneTree</code> call.
263: * <p>
264: * NOTE: Applications should <i>not</i> call this method directly.
265: * It should only be called by the cloneTree method.
266: *
267: * @param referenceTable a NodeReferenceTableObject that contains the
268: * <code>getNewObjectReference</code> method needed to search for
269: * new object instances.
270: * @see NodeReferenceTable
271: * @see Node#cloneTree
272: * @see DanglingReferenceException
273: */
274: public void updateNodeReferences(NodeReferenceTable referenceTable) {
275: ClipRetained rt = (ClipRetained) retained;
276: BoundingLeaf bl = rt.getApplicationBoundingLeaf();
277:
278: // check for applicationBoundingLeaf
279: if (bl != null) {
280: Object o = referenceTable.getNewObjectReference(bl);
281: rt.initApplicationBoundingLeaf((BoundingLeaf) o);
282: }
283: }
284:
285: /**
286: * Copies all Clip information from
287: * <code>originalNode</code> into
288: * the current node. This method is called from the
289: * <code>cloneNode</code> method which is, in turn, called by the
290: * <code>cloneTree</code> method.<P>
291: *
292: * @param originalNode the original node to duplicate.
293: * @param forceDuplicate when set to <code>true</code>, causes the
294: * <code>duplicateOnCloneTree</code> flag to be ignored. When
295: * <code>false</code>, the value of each node's
296: * <code>duplicateOnCloneTree</code> variable determines whether
297: * NodeComponent data is duplicated or copied.
298: *
299: * @exception RestrictedAccessException if this object is part of a live
300: * or compiled scenegraph.
301: *
302: * @see Node#duplicateNode
303: * @see Node#cloneTree
304: * @see NodeComponent#setDuplicateOnCloneTree
305: */
306: void duplicateAttributes(Node originalNode, boolean forceDuplicate) {
307: super .duplicateAttributes(originalNode, forceDuplicate);
308:
309: ClipRetained attr = (ClipRetained) originalNode.retained;
310: ClipRetained rt = (ClipRetained) retained;
311:
312: rt.initBackDistance(attr.getBackDistance());
313: rt.initApplicationBounds(attr.getApplicationBounds());
314:
315: // correct value will set in updateNodeReferences
316: rt.initApplicationBoundingLeaf(attr
317: .getApplicationBoundingLeaf());
318: }
319: }
|