001: /*
002: * $RCSfile: SpotLight.java,v $
003: *
004: * @(#)SpotLight.java 1.17 98/11/05 20:35:23
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: *
032: * $Revision: 1.2 $
033: * $Date: 2005/02/03 23:07:02 $
034: * $State: Exp $
035: */
036: /*
037: * @Author: Rick Goldberg
038: * @Author: Doug Gehringer
039: *
040: */
041: package org.jdesktop.j3d.loaders.vrml97.impl;
042:
043: import javax.media.j3d.AmbientLight;
044: import javax.media.j3d.BoundingSphere;
045: import javax.media.j3d.SharedGroup;
046: import javax.vecmath.Color3f;
047: import javax.vecmath.Point3f;
048: import javax.vecmath.Vector3f;
049:
050: /** Description of the Class */
051: public class SpotLight extends Light {
052:
053: // exposedField
054:
055: SFFloat ambientIntensity;
056: SFVec3f attenuation;
057: SFFloat beamWidth;
058: SFColor color;
059: SFFloat cutOffAngle;
060: SFVec3f direction;
061: SFFloat intensity;
062: SFVec3f location;
063: SFBool on;
064: SFFloat radius;
065:
066: Color3f lightColor;
067: Point3f lightPos;
068: Vector3f lightDir;
069: Point3f lightAtt;
070: BoundingSphere bounds;
071: javax.media.j3d.SpotLight spotLight;
072:
073: /**
074: *Constructor for the SpotLight object
075: *
076: *@param loader Description of the Parameter
077: */
078: public SpotLight(Loader loader) {
079: super (loader);
080: ambientIntensity = new SFFloat(0.0f);
081: attenuation = new SFVec3f(1.0f, 0.0f, 0.0f);
082: beamWidth = new SFFloat(1.570796f);
083: color = new SFColor(1.0f, 1.0f, 1.0f);
084: cutOffAngle = new SFFloat(.785398f);
085: direction = new SFVec3f(0.0f, 0.0f, -1.0f);
086: intensity = new SFFloat(1.0f);
087: location = new SFVec3f(0.0f, 0.0f, 0.0f);
088: on = new SFBool(true);
089: radius = new SFFloat(100.0f);
090:
091: initFields();
092: }
093:
094: /**
095: *Constructor for the SpotLight object
096: *
097: *@param loader Description of the Parameter
098: *@param ambientIntensity Description of the Parameter
099: *@param attenuation Description of the Parameter
100: *@param color Description of the Parameter
101: *@param cutOffAngle Description of the Parameter
102: *@param direction Description of the Parameter
103: *@param intensity Description of the Parameter
104: *@param on Description of the Parameter
105: *@param radius Description of the Parameter
106: */
107: SpotLight(Loader loader, SFFloat ambientIntensity,
108: SFVec3f attenuation, SFColor color, SFFloat cutOffAngle,
109: SFVec3f direction, SFFloat intensity, SFBool on,
110: SFFloat radius) {
111: super (loader);
112: this .ambientIntensity = ambientIntensity;
113: this .attenuation = attenuation;
114: this .color = color;
115: this .cutOffAngle = cutOffAngle;
116: this .direction = direction;
117: this .intensity = intensity;
118: this .on = on;
119:
120: initFields();
121: }
122:
123: /** Description of the Method */
124: void initImpl() {
125: lightColor = new Color3f();
126: lightPos = new Point3f();
127: lightDir = new Vector3f();
128: lightAtt = new Point3f();
129: bounds = new BoundingSphere();
130: bounds.setRadius((double) radius.value);
131: sharedGroup = new SharedGroup();
132: lightColor.x = color.color[0] * ambientIntensity.value;
133: lightColor.y = color.color[1] * ambientIntensity.value;
134: lightColor.z = color.color[2] * ambientIntensity.value;
135: ambLight = new AmbientLight(on.value, lightColor);
136: ambLight.setInfluencingBounds(bounds);
137: sharedGroup.addChild(ambLight);
138: lightColor.x = color.color[0] * intensity.value;
139: lightColor.y = color.color[1] * intensity.value;
140: lightColor.z = color.color[2] * intensity.value;
141: lightPos.x = location.value[0];
142: lightPos.y = location.value[1];
143: lightPos.z = location.value[2];
144: lightDir.x = direction.value[0];
145: lightDir.y = direction.value[1];
146: lightDir.z = direction.value[2];
147: lightAtt.x = attenuation.value[0];
148: lightAtt.y = attenuation.value[1];
149: lightAtt.z = attenuation.value[2];
150:
151: // VRML and Java3D disconnect on the spread angle. VRML uses two
152: // angles: beamWidth and curOffAngle:
153: // if (angle > cutOffAngle) {
154: // multiplier = 0.0;
155: // } else if (angle <= beamWidth) {
156: // multiplier = 1.0;
157: // } else {
158: // multiplier = (angle - cutOffAngle) / (beamWidth - cutOffAngle);
159: // }
160: //
161: // Java3D has only one angle with a exponential concentration:
162: // if (angle > spreadAngle) {
163: // multiplier = 0.0;
164: // } else {
165: // multiplier = cos(angle) ** concentration;
166: // }
167: // TODO: look for an optimal mapping for now just use 0.0 for
168: // concentration (no attenuation)
169: //
170: light = spotLight = new javax.media.j3d.SpotLight(on.value,
171: lightColor, lightPos, lightAtt, lightDir,
172: cutOffAngle.value, 0.0f);
173: spotLight.setInfluencingBounds(bounds);
174: sharedGroup.addChild(spotLight);
175: implReady = true;
176: }
177:
178: /**
179: * Description of the Method
180: *
181: *@param eventInName Description of the Parameter
182: *@param time Description of the Parameter
183: */
184: public void notifyMethod(String eventInName, double time) {
185: if (eventInName.equals("ambientIntensity")) {
186: lightColor.x = color.color[0] * ambientIntensity.value;
187: lightColor.y = color.color[1] * ambientIntensity.value;
188: lightColor.z = color.color[2] * ambientIntensity.value;
189: ambLight.setColor(lightColor);
190: } else if (eventInName.equals("color")
191: || eventInName.equals("intensity")) {
192: lightColor.x = color.color[0] * ambientIntensity.value;
193: lightColor.y = color.color[1] * ambientIntensity.value;
194: lightColor.z = color.color[2] * ambientIntensity.value;
195: ambLight.setColor(lightColor);
196: lightColor.x = color.color[0] * intensity.value;
197: lightColor.y = color.color[1] * intensity.value;
198: lightColor.z = color.color[2] * intensity.value;
199: spotLight.setColor(lightColor);
200: } else if (eventInName.equals("location")) {
201: lightPos.x = location.value[0];
202: lightPos.y = location.value[1];
203: lightPos.z = location.value[2];
204: spotLight.setPosition(lightPos);
205: } else if (eventInName.equals("attenuation")) {
206: lightAtt.x = attenuation.value[0];
207: lightAtt.y = attenuation.value[1];
208: lightAtt.z = attenuation.value[2];
209: spotLight.setAttenuation(lightAtt);
210: } else if (eventInName.equals("direction")) {
211: lightDir.x = direction.value[0];
212: lightDir.y = direction.value[1];
213: lightDir.z = direction.value[2];
214: spotLight.setDirection(lightDir);
215: } else if (eventInName.equals("cutOffAngle")) {
216: spotLight.setSpreadAngle(cutOffAngle.value);
217: } else if (eventInName.equals("beamWidth")) {
218: // no mapping yet
219: } else if (eventInName.equals("on")) {
220: ambLight.setEnable(on.value);
221: spotLight.setEnable(on.value);
222: } else if (eventInName.equals("radius")) {
223: bounds.setRadius((double) radius.value);
224: ambLight.setInfluencingBounds(bounds);
225: spotLight.setInfluencingBounds(bounds);
226: } else if (eventInName.equals("route_on")) {
227: ambLight
228: .setCapability(javax.media.j3d.Light.ALLOW_STATE_WRITE);
229: spotLight
230: .setCapability(javax.media.j3d.Light.ALLOW_STATE_WRITE);
231: } else if (eventInName.equals("route_location")) {
232: spotLight
233: .setCapability(javax.media.j3d.SpotLight.ALLOW_POSITION_WRITE);
234: } else if (eventInName.equals("route_direction")) {
235: spotLight
236: .setCapability(javax.media.j3d.SpotLight.ALLOW_DIRECTION_WRITE);
237: } else if (eventInName.equals("route_cutOffAngle")) {
238: spotLight
239: .setCapability(javax.media.j3d.SpotLight.ALLOW_SPREAD_ANGLE_WRITE);
240: } else if (eventInName.equals("route_beamWidth")) {
241: spotLight
242: .setCapability(javax.media.j3d.SpotLight.ALLOW_CONCENTRATION_WRITE);
243: } else if (eventInName.equals("route_attenuation")) {
244: spotLight
245: .setCapability(javax.media.j3d.SpotLight.ALLOW_ATTENUATION_WRITE);
246: } else if (eventInName.equals("route_color")
247: || eventInName.equals("route_intensity")) {
248: ambLight
249: .setCapability(javax.media.j3d.Light.ALLOW_COLOR_WRITE);
250: spotLight
251: .setCapability(javax.media.j3d.Light.ALLOW_COLOR_WRITE);
252: } else if (eventInName.equals("route_ambientIntensity")) {
253: ambLight
254: .setCapability(javax.media.j3d.Light.ALLOW_COLOR_WRITE);
255: } else if (eventInName.equals("route_radius")) {
256: ambLight
257: .setCapability(javax.media.j3d.Light.ALLOW_INFLUENCING_BOUNDS_WRITE);
258: spotLight
259: .setCapability(javax.media.j3d.Light.ALLOW_INFLUENCING_BOUNDS_WRITE);
260: }
261: }
262:
263: /**
264: * Description of the Method
265: *
266: *@return Description of the Return Value
267: */
268: public Object clone() {
269: return new SpotLight(loader,
270: (SFFloat) ambientIntensity.clone(),
271: (SFVec3f) attenuation.clone(), (SFColor) color.clone(),
272: (SFFloat) cutOffAngle.clone(), (SFVec3f) direction
273: .clone(), (SFFloat) intensity.clone(),
274: (SFBool) on.clone(), (SFFloat) radius.clone());
275: }
276:
277: /**
278: * Gets the type attribute of the SpotLight object
279: *
280: *@return The type value
281: */
282: public String getType() {
283: return "SpotLight";
284: }
285:
286: /** Description of the Method */
287: void initFields() {
288: ambientIntensity.init(this , FieldSpec, Field.EXPOSED_FIELD,
289: "ambientIntensity");
290: attenuation.init(this , FieldSpec, Field.EXPOSED_FIELD,
291: "attenuation");
292: beamWidth.init(this , FieldSpec, Field.EXPOSED_FIELD,
293: "beamWidth");
294: color.init(this , FieldSpec, Field.EXPOSED_FIELD, "color");
295: cutOffAngle.init(this , FieldSpec, Field.EXPOSED_FIELD,
296: "cutOffAngle");
297: direction.init(this , FieldSpec, Field.EXPOSED_FIELD,
298: "direction");
299: intensity.init(this , FieldSpec, Field.EXPOSED_FIELD,
300: "intensity");
301: location.init(this , FieldSpec, Field.EXPOSED_FIELD, "location");
302: on.init(this , FieldSpec, Field.EXPOSED_FIELD, "on");
303: radius.init(this , FieldSpec, Field.EXPOSED_FIELD, "radius");
304: }
305: }
|