001: /*
002: * $RCSfile: LwsLight.java,v $
003: *
004: * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * - Redistribution of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * - Redistribution in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in
015: * the documentation and/or other materials provided with the
016: * distribution.
017: *
018: * Neither the name of Sun Microsystems, Inc. or the names of
019: * contributors may be used to endorse or promote products derived
020: * from this software without specific prior written permission.
021: *
022: * This software is provided "AS IS," without a warranty of any
023: * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
024: * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
025: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
026: * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
027: * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
028: * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
029: * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
030: * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
031: * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
032: * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
033: * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
034: * POSSIBILITY OF SUCH DAMAGES.
035: *
036: * You acknowledge that this software is not designed, licensed or
037: * intended for use in the design, construction, operation or
038: * maintenance of any nuclear facility.
039: *
040: * $Revision: 1.4 $
041: * $Date: 2007/02/09 17:20:08 $
042: * $State: Exp $
043: */
044:
045: package com.sun.j3d.loaders.lw3d;
046:
047: import java.io.*;
048: import java.util.Vector;
049: import javax.media.j3d.*;
050: import javax.vecmath.*;
051: import java.util.Enumeration;
052: import com.sun.j3d.loaders.ParsingErrorException;
053:
054: /**
055: * This class creates a light object from the data in a Scene file. It
056: * instantiates an LwsMotion object to create any associated
057: * animations.
058: */
059:
060: class LwsLight extends TextfileParser implements LwsPrimitive {
061:
062: // data from the file
063: String fileName;
064: String objName;
065: LwsMotion motion;
066: int parent;
067: TransformGroup objectTransform;
068: Vector objectBehavior;
069: Color3f color;
070: int type;
071: Point3f attenuation = new Point3f(1.0f, 0.0f, 0.0f);
072: float spotConeAngle = (float) (Math.PI);
073: // Meta object, used for holding light and
074: LwLightObject lwLight;
075: // light parameters
076: LwsEnvelopeLightIntensity intensityEnvelope = null;
077: Light light = null;
078: final static int DIRECTIONAL = 0, POINT = 1, SPOT = 2;
079:
080: /**
081: * Constructor: parses stream and creates data structures for all
082: * light parameters currently handled by the loader
083: */
084: LwsLight(StreamTokenizer st, int totalFrames, float totalTime,
085: int debugVals) throws ParsingErrorException {
086:
087: debugPrinter.setValidOutput(debugVals);
088:
089: debugOutput(TRACE, "LwsLight()");
090: color = new Color3f(1f, 1f, 1f);
091: lwLight = new LwLightObject(null, 0.0f, null);
092:
093: parent = -1;
094: debugOutputLn(LINE_TRACE, "about to get LightName");
095: getAndCheckString(st, "LightName");
096: debugOutputLn(LINE_TRACE, "about to get LightName value");
097: objName = getName(st);
098: debugOutputLn(LINE_TRACE, "got LightName");
099: skip(st, "ShowLight", 2);
100: debugOutputLn(LINE_TRACE, "got ShowLight");
101: getAndCheckString(st, "LightMotion");
102: debugOutputLn(LINE_TRACE, "got LightMotion");
103: motion = new LwsMotion(st, totalFrames, totalTime);
104: debugOutputLn(LINE_TRACE, "got motions");
105:
106: // TODO: buggy way to stop processing the light. Should actually
107: // process required/optional fields in order and stop when there's
108: // no more. However, spec says "ShadowCasing" but the files say
109: // "ShadowType".
110:
111: while (!isCurrentToken(st, "ShowCamera")
112: && !isCurrentToken(st, "AddLight")) {
113: // TODO:
114: // Things that we're not yet processing (and should):
115: // - EdgeAngle: for spotlights, this is the angle which
116: // contains the linear falloff toward the edge of the
117: // ConeAngle. This doesn't directly map to J3d's
118: // "concentration" value, so it's left out for now.
119:
120: debugOutputLn(LINE_TRACE, "currentToken = " + st.sval);
121:
122: if (isCurrentToken(st, "ParentObject")) {
123: parent = (int) getNumber(st);
124: } else if (isCurrentToken(st, "LightColor")) {
125: color.x = (float) getNumber(st) / 255f;
126: color.y = (float) getNumber(st) / 255f;
127: color.z = (float) getNumber(st) / 255f;
128: lwLight.setColor(color);
129: } else if (isCurrentToken(st, "LgtIntensity")) {
130: // TODO: must be able to handle envelopes here
131: String className = getClass().getName();
132: int classIndex = className.lastIndexOf('.');
133: String packageName;
134: if (classIndex < 0)
135: packageName = "";
136: else
137: packageName = className.substring(0, classIndex)
138: + ".";
139: EnvelopeHandler env = new EnvelopeHandler(st,
140: totalFrames, totalTime, packageName
141: + "LwsEnvelopeLightIntensity");
142: if (env.hasValue) {
143: float intensity = (float) env.theValue;
144: color.x *= intensity;
145: color.y *= intensity;
146: color.z *= intensity;
147: lwLight.setIntensity(intensity);
148: } else {
149: intensityEnvelope = (LwsEnvelopeLightIntensity) env.theEnvelope;
150: }
151: } else if (isCurrentToken(st, "LightType")) {
152: type = (int) getNumber(st);
153: } else if (isCurrentToken(st, "Falloff")) {
154: float falloff = (float) getNumber(st);
155: attenuation.y = 1.0f / (1.0f - falloff) - 1.0f;
156: } else if (isCurrentToken(st, "ConeAngle")) {
157: spotConeAngle = (float) getNumber(st)
158: * (float) (Math.PI / 180.0);
159: }
160: try {
161: st.nextToken();
162: } catch (IOException e) {
163: throw new ParsingErrorException(e.getMessage());
164: }
165: }
166: st.pushBack(); // push "ShowCamera" or "AddLight" back on stack
167: }
168:
169: int getParent() {
170: return parent;
171: }
172:
173: /**
174: * Create Java3D objects from the data we got from the file
175: */
176: void createJava3dObject(int loadBehaviors) {
177: Matrix4d mat = new Matrix4d();
178: mat.setIdentity();
179: // Set the node's transform matrix according to the first frame
180: // of the object's motion
181: LwsFrame firstFrame = motion.getFirstFrame();
182: firstFrame.setMatrix(mat);
183: debugOutputLn(VALUES, "Light transform = " + mat);
184: Transform3D t1 = new Transform3D();
185: t1.set(mat);
186: objectTransform = new TransformGroup(t1);
187: objectTransform
188: .setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
189: Vector3f defaultDir = new Vector3f(0f, 0f, -1f);
190: Point3f defaultPos = new Point3f(0f, 0f, 0f);
191:
192: switch (type) {
193: case DIRECTIONAL:
194: light = new DirectionalLight(color, defaultDir);
195: break;
196: case POINT:
197: light = new PointLight(color, defaultPos, attenuation);
198: break;
199: case SPOT:
200: // Note: spotConeAngle in lw3d is half that of Java3d...
201: light = new SpotLight(color, defaultPos, attenuation,
202: defaultDir, 2 * spotConeAngle, 0.0f);
203: break;
204: default:
205: // Shouldn't get here
206: break;
207: }
208:
209: light.setCapability(Light.ALLOW_COLOR_WRITE);
210: if (light != null) {
211: lwLight.setLight(light);
212: BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,
213: 0.0, 0.0), 100000.0);
214: light.setInfluencingBounds(bounds);
215: objectTransform.addChild(light);
216:
217: // load behaviors if we have to
218: objectBehavior = new Vector();
219: if (loadBehaviors != 0) {
220: Behavior b;
221: b = null;
222: motion.createJava3dBehaviors(objectTransform);
223: b = motion.getBehaviors();
224: if (b != null)
225: objectBehavior.addElement(b);
226:
227: if (intensityEnvelope != null) {
228: b = null;
229: intensityEnvelope.createJava3dBehaviors(lwLight);
230: b = intensityEnvelope.getBehaviors();
231: if (b != null)
232: objectBehavior.addElement(b);
233: }
234: }
235: }
236: }
237:
238: public TransformGroup getObjectNode() {
239: return objectTransform;
240: }
241:
242: Light getLight() {
243: return light;
244: }
245:
246: public Vector getObjectBehaviors() {
247: debugOutputLn(TRACE, "getObjectBehaviors()");
248: return objectBehavior;
249: }
250:
251: void printVals() {
252: debugOutputLn(VALUES, " LIGHT vals: ");
253: debugOutputLn(VALUES, " objName = " + objName);
254: motion.printVals();
255: }
256:
257: }
|