1 /* 2 * $RCSfile: LwsLight.java,v $ 3 * 4 * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * - Redistribution of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * - Redistribution in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 18 * Neither the name of Sun Microsystems, Inc. or the names of 19 * contributors may be used to endorse or promote products derived 20 * from this software without specific prior written permission. 21 * 22 * This software is provided "AS IS," without a warranty of any 23 * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND 24 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, 25 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY 26 * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL 27 * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF 28 * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS 29 * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR 30 * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, 31 * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND 32 * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR 33 * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE 34 * POSSIBILITY OF SUCH DAMAGES. 35 * 36 * You acknowledge that this software is not designed, licensed or 37 * intended for use in the design, construction, operation or 38 * maintenance of any nuclear facility. 39 * 40 * $Revision: 1.4 $ 41 * $Date: 2007/02/09 17:20:08 $ 42 * $State: Exp $ 43 */ 44 45 package com.sun.j3d.loaders.lw3d; 46 47 48 49 import java.io.*; 50 import java.util.Vector; 51 import javax.media.j3d.*; 52 import javax.vecmath.*; 53 import java.util.Enumeration; 54 import com.sun.j3d.loaders.ParsingErrorException; 55 56 /** 57 * This class creates a light object from the data in a Scene file. It 58 * instantiates an LwsMotion object to create any associated 59 * animations. 60 */ 61 62 class LwsLight extends TextfileParser implements LwsPrimitive { 63 64 // data from the file 65 String fileName; 66 String objName; 67 LwsMotion motion; 68 int parent; 69 TransformGroup objectTransform; 70 Vector objectBehavior; 71 Color3f color; 72 int type; 73 Point3f attenuation = new Point3f(1.0f, 0.0f, 0.0f); 74 float spotConeAngle = (float)(Math.PI); 75 // Meta object, used for holding light and 76 LwLightObject lwLight; 77 // light parameters 78 LwsEnvelopeLightIntensity intensityEnvelope = null; 79 Light light = null; 80 final static int DIRECTIONAL = 0, POINT = 1, SPOT = 2; 81 82 /** 83 * Constructor: parses stream and creates data structures for all 84 * light parameters currently handled by the loader 85 */ LwsLight(StreamTokenizer st, int totalFrames, float totalTime, int debugVals)86 LwsLight(StreamTokenizer st, int totalFrames, float totalTime, 87 int debugVals) throws ParsingErrorException { 88 89 debugPrinter.setValidOutput(debugVals); 90 91 debugOutput(TRACE, "LwsLight()"); 92 color = new Color3f(1f, 1f, 1f); 93 lwLight = new LwLightObject(null, 0.0f, null); 94 95 parent = -1; 96 debugOutputLn(LINE_TRACE, "about to get LightName"); 97 getAndCheckString(st, "LightName"); 98 debugOutputLn(LINE_TRACE, "about to get LightName value"); 99 objName = getName(st); 100 debugOutputLn(LINE_TRACE, "got LightName"); 101 skip(st, "ShowLight", 2); 102 debugOutputLn(LINE_TRACE, "got ShowLight"); 103 getAndCheckString(st, "LightMotion"); 104 debugOutputLn(LINE_TRACE, "got LightMotion"); 105 motion = new LwsMotion(st, totalFrames, totalTime); 106 debugOutputLn(LINE_TRACE, "got motions"); 107 108 // TODO: buggy way to stop processing the light. Should actually 109 // process required/optional fields in order and stop when there's 110 // no more. However, spec says "ShadowCasing" but the files say 111 // "ShadowType". 112 113 while (!isCurrentToken(st, "ShowCamera") && 114 !isCurrentToken(st, "AddLight")) { 115 // TODO: 116 // Things that we're not yet processing (and should): 117 // - EdgeAngle: for spotlights, this is the angle which 118 // contains the linear falloff toward the edge of the 119 // ConeAngle. This doesn't directly map to J3d's 120 // "concentration" value, so it's left out for now. 121 122 debugOutputLn(LINE_TRACE, "currentToken = " + st.sval); 123 124 if (isCurrentToken(st, "ParentObject")) { 125 parent = (int)getNumber(st); 126 } 127 else if (isCurrentToken(st, "LightColor")) { 128 color.x = (float)getNumber(st)/255f; 129 color.y = (float)getNumber(st)/255f; 130 color.z = (float)getNumber(st)/255f; 131 lwLight.setColor(color); 132 } 133 else if (isCurrentToken(st, "LgtIntensity")) { 134 // TODO: must be able to handle envelopes here 135 String className = getClass().getName(); 136 int classIndex = className.lastIndexOf('.'); 137 String packageName; 138 if (classIndex < 0) 139 packageName = ""; 140 else 141 packageName = className.substring(0, classIndex) + "."; 142 EnvelopeHandler env = 143 new EnvelopeHandler(st, totalFrames, totalTime, 144 packageName + "LwsEnvelopeLightIntensity"); 145 if (env.hasValue) { 146 float intensity = (float)env.theValue; 147 color.x *= intensity; 148 color.y *= intensity; 149 color.z *= intensity; 150 lwLight.setIntensity(intensity); 151 } 152 else { 153 intensityEnvelope = 154 (LwsEnvelopeLightIntensity)env.theEnvelope; 155 } 156 } 157 else if (isCurrentToken(st, "LightType")) { 158 type = (int)getNumber(st); 159 } 160 else if (isCurrentToken(st, "Falloff")) { 161 float falloff = (float)getNumber(st); 162 attenuation.y = 1.0f/(1.0f - falloff) - 1.0f; 163 } 164 else if (isCurrentToken(st, "ConeAngle")) { 165 spotConeAngle = (float)getNumber(st) * (float)(Math.PI / 180.0); 166 } 167 try { 168 st.nextToken(); 169 } 170 catch (IOException e) { 171 throw new ParsingErrorException(e.getMessage()); 172 } 173 } 174 st.pushBack(); // push "ShowCamera" or "AddLight" back on stack 175 } 176 getParent()177 int getParent() { 178 return parent; 179 } 180 181 /** 182 * Create Java3D objects from the data we got from the file 183 */ createJava3dObject(int loadBehaviors)184 void createJava3dObject(int loadBehaviors) { 185 Matrix4d mat = new Matrix4d(); 186 mat.setIdentity(); 187 // Set the node's transform matrix according to the first frame 188 // of the object's motion 189 LwsFrame firstFrame = motion.getFirstFrame(); 190 firstFrame.setMatrix(mat); 191 debugOutputLn(VALUES, "Light transform = " + mat); 192 Transform3D t1 = new Transform3D(); 193 t1.set(mat); 194 objectTransform = new TransformGroup(t1); 195 objectTransform.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); 196 Vector3f defaultDir = new Vector3f(0f, 0f, -1f); 197 Point3f defaultPos = new Point3f(0f, 0f, 0f); 198 199 switch (type) { 200 case DIRECTIONAL: 201 light = new DirectionalLight(color, defaultDir); 202 break; 203 case POINT: 204 light = new PointLight(color, defaultPos, attenuation); 205 break; 206 case SPOT: 207 // Note: spotConeAngle in lw3d is half that of Java3d... 208 light = new SpotLight(color, defaultPos, attenuation, defaultDir, 209 2 * spotConeAngle, 0.0f); 210 break; 211 default: 212 // Shouldn't get here 213 break; 214 } 215 216 light.setCapability(Light.ALLOW_COLOR_WRITE); 217 if (light != null) { 218 lwLight.setLight(light); 219 BoundingSphere bounds = 220 new BoundingSphere(new Point3d(0.0,0.0,0.0), 100000.0); 221 light.setInfluencingBounds(bounds); 222 objectTransform.addChild(light); 223 224 // load behaviors if we have to 225 objectBehavior = new Vector(); 226 if (loadBehaviors != 0) { 227 Behavior b; 228 b = null; 229 motion.createJava3dBehaviors(objectTransform); 230 b = motion.getBehaviors(); 231 if (b != null) 232 objectBehavior.addElement(b); 233 234 if (intensityEnvelope != null) { 235 b = null; 236 intensityEnvelope.createJava3dBehaviors(lwLight); 237 b = intensityEnvelope.getBehaviors(); 238 if (b != null) 239 objectBehavior.addElement(b); 240 } 241 } 242 } 243 } 244 getObjectNode()245 public TransformGroup getObjectNode() 246 { 247 return objectTransform; 248 } 249 getLight()250 Light getLight() { 251 return light; 252 } 253 getObjectBehaviors()254 public Vector getObjectBehaviors() 255 { 256 debugOutputLn(TRACE, "getObjectBehaviors()"); 257 return objectBehavior; 258 } 259 260 printVals()261 void printVals() 262 { 263 debugOutputLn(VALUES, " LIGHT vals: "); 264 debugOutputLn(VALUES, " objName = " + objName); 265 motion.printVals(); 266 } 267 268 269 } 270