001: /*
002: * $RCSfile: LOD.java,v $
003: *
004: * @(#)LOD.java 1.12 98/11/05 20:34:36
005: *
006: * Copyright (c) 1996-1998 Sun Microsystems, Inc. All Rights Reserved.
007: *
008: * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
009: * modify and redistribute this software in source and binary code form,
010: * provided that i) this copyright notice and license appear on all copies of
011: * the software; and ii) Licensee does not utilize the software in a manner
012: * which is disparaging to Sun.
013: *
014: * This software is provided "AS IS," without a warranty of any kind. ALL
015: * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
016: * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
017: * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
018: * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
019: * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
020: * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
021: * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
022: * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
023: * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
024: * POSSIBILITY OF SUCH DAMAGES.
025: *
026: * This software is not designed or intended for use in on-line control of
027: * aircraft, air traffic, aircraft navigation or aircraft communications; or in
028: * the design, construction, operation or maintenance of any nuclear
029: * facility. Licensee represents and warrants that it will not use or
030: * redistribute the Software for such purposes.
031: * $Revision: 1.2 $
032: * $Date: 2005/02/03 23:06:57 $
033: * $State: Exp $
034: */
035: package org.jdesktop.j3d.loaders.vrml97.impl;
036:
037: import java.util.Vector;
038: import javax.media.j3d.*;
039: import javax.vecmath.*;
040:
041: /** Description of the Class */
042: public class LOD extends NonSharedNode {
043: // exposedField
044: MFNode level;
045:
046: // field
047: SFVec3f center;
048: MFFloat range;
049:
050: javax.media.j3d.Group impl;
051: javax.media.j3d.Switch implSwitch;
052: DistanceLOD implLOD;
053:
054: /**
055: *Constructor for the LOD object
056: *
057: *@param loader Description of the Parameter
058: */
059: public LOD(Loader loader) {
060: super (loader);
061: level = new MFNode();
062: center = new SFVec3f();
063: range = new MFFloat();
064: initFields();
065: }
066:
067: /**
068: *Constructor for the LOD object
069: *
070: *@param loader Description of the Parameter
071: *@param level Description of the Parameter
072: *@param center Description of the Parameter
073: *@param range Description of the Parameter
074: */
075: LOD(Loader loader, MFNode level, SFVec3f center, MFFloat range) {
076: super (loader);
077: this .level = level;
078: this .center = center;
079: this .range = range;
080: initFields();
081: }
082:
083: /** Description of the Method */
084: void initImpl() {
085: impl = new javax.media.j3d.Group();
086: // init the switch to the furthest level
087: implSwitch = new javax.media.j3d.Switch();
088: implSwitch.setUserData(new Vector());
089: double furthest;
090: if (range.mfloat.length >= 1) {
091: // set to the furthest
092: implSwitch.setWhichChild(range.mfloat.length - 1);
093: furthest = (double) range.mfloat[range.mfloat.length - 1];
094: implSwitch
095: .setCapability(javax.media.j3d.Switch.ALLOW_SWITCH_READ);
096: implSwitch
097: .setCapability(javax.media.j3d.Switch.ALLOW_SWITCH_WRITE);
098: implSwitch.setUserData(new Vector());
099: Point3f lodCenter = new Point3f(center.value[0],
100: center.value[1], center.value[2]);
101: implLOD = new DistanceLOD(range.mfloat, lodCenter);
102: implLOD.addSwitch(implSwitch);
103: // set the scheduling bounds to be just outside the furthest
104: // distance
105: Point3d boundCenter = new Point3d(lodCenter);
106: implLOD.setSchedulingBounds(new BoundingSphere(boundCenter,
107: furthest * 1.1));
108: impl.addChild(implLOD);
109: } else {
110: // wrl has selected "auto", can't really do, so just set
111: // switch to most detailed and don't bother with LOD behavior
112: implSwitch.setWhichChild(0);
113: }
114: impl.addChild(implSwitch);
115: replaceLevels();
116: implNode = impl;
117: implReady = true;
118: }
119:
120: /** Description of the Method */
121: void replaceLevels() {
122: int numChildren;
123: if ((numChildren = implSwitch.numChildren()) != 0) {
124: for (int i = 0; i < numChildren; i++) {
125: implSwitch.removeChild(0);
126: }
127: }
128: for (int i = 0; i < level.nodes.length; i++) {
129: BaseNode child = level.nodes[i];
130:
131: // let the new child know this is their parent
132: child.updateParent(implSwitch);
133:
134: // add the child's impl to the j3d group
135: javax.media.j3d.Node implNode = child.getImplNode();
136: if (loader.debug) {
137: System.out.println(this .toStringId() + ": index = "
138: + i + " child node type is " + child.getType()
139: + " " + child.toStringId()
140: + " gets implNoded to " + implNode);
141: }
142: if (implNode != null) {
143: if (implNode.getParent() == null) {
144: implSwitch.addChild(implNode);
145: } else {
146: implSwitch.addChild(implNode.cloneNode(true));
147: }
148: if (child instanceof DirectionalLight) {
149: DirectionalLight dirLight = (DirectionalLight) child;
150: dirLight.setScope(implSwitch);
151: }
152: }
153: }
154: }
155:
156: // return the number of tris in level 0
157: /**
158: * Gets the numTris attribute of the LOD object
159: *
160: *@return The numTris value
161: */
162: public int getNumTris() {
163: int numTris = 0;
164: if (level.nodes.length > 0) {
165: BaseNode child = level.nodes[0];
166: if (child != null) {
167: numTris += child.getNumTris();
168: }
169: }
170: return numTris;
171: }
172:
173: /**
174: * Description of the Method
175: *
176: *@param eventInName Description of the Parameter
177: *@param time Description of the Parameter
178: */
179: public void notifyMethod(String eventInName, double time) {
180: // spec says range needs to be 1 element less than the number
181: // of elements in level, but range is not an updatable field.
182: // if level nodes change, need to either clip the levels to
183: // range+1 or add values to range
184: if (eventInName.equals("level")) {
185: replaceLevels();
186: }
187: }
188:
189: /**
190: * Description of the Method
191: *
192: *@return Description of the Return Value
193: */
194: public Object clone() {
195: return new LOD(loader, (MFNode) level.clone(), (SFVec3f) center
196: .clone(), (MFFloat) range.clone());
197: }
198:
199: /**
200: * Gets the type attribute of the LOD object
201: *
202: *@return The type value
203: */
204: public String getType() {
205: return "LOD";
206: }
207:
208: /** Description of the Method */
209: void initFields() {
210: level.init(this , FieldSpec, Field.EXPOSED_FIELD, "level");
211: center.init(this , FieldSpec, Field.FIELD, "center");
212: range.init(this , FieldSpec, Field.FIELD, "range");
213: }
214:
215: }
|