001: /*
002: * $RCSfile: PointLightRetained.java,v $
003: *
004: * Copyright 1996-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:28 $
029: * $State: Exp $
030: */
031:
032: package javax.media.j3d;
033:
034: import javax.vecmath.*;
035:
036: /**
037: * A Retained PointLight source.
038: */
039: class PointLightRetained extends LightRetained {
040: static final int POSITION_CHANGED = LAST_DEFINED_BIT << 1;
041: static final int ATTENUATION_CHANGED = LAST_DEFINED_BIT << 2;
042: static final int LAST_POINTLIGHT_DEFINED_BIT = ATTENUATION_CHANGED;
043:
044: /**
045: * The attenuation vector consisting of
046: * constant, linear, and quadratic coefficients.
047: */
048: Point3f attenuation = new Point3f(1.0f, 0.0f, 0.0f);
049:
050: // The position at which this light source exists.
051: Point3f position = new Point3f();
052:
053: // The transformed position of this light
054: Point3f xformPosition = new Point3f();
055:
056: // local to vworld scale for attenuation
057: double localToVworldScale;
058:
059: // scaled linearAttenuation from lc to ec
060: float linearAttenuationInEc;
061:
062: // scaled quadraticAttenuation from lc to ec
063: float quadraticAttenuationInEc;
064:
065: PointLightRetained() {
066: this .nodeType = NodeRetained.POINTLIGHT;
067: lightType = 3;
068: localBounds = new BoundingBox();
069: ((BoundingBox) localBounds).setLower(1.0, 1.0, 1.0);
070: ((BoundingBox) localBounds).setUpper(-1.0, -1.0, -1.0);
071: }
072:
073: /**
074: * Initializes this light's position from the vector provided.
075: * @param position the new position
076: */
077: void initPosition(Point3f position) {
078: this .position.set(position);
079:
080: if (staticTransform != null) {
081: staticTransform.transform.transform(this .position,
082: this .position);
083: }
084: }
085:
086: /**
087: * Sets this light's position from the vector provided.
088: * @param position the new position
089: */
090: void setPosition(Point3f position) {
091: initPosition(position);
092: sendMessage(POSITION_CHANGED, new Point3f(position));
093: }
094:
095: /**
096: * Initializes this light's position from the three values provided.
097: * @param x the new x position
098: * @param y the new y position
099: * @param z the new z position
100: */
101: void initPosition(float x, float y, float z) {
102: this .position.x = x;
103: this .position.y = y;
104: this .position.z = z;
105:
106: if (staticTransform != null) {
107: staticTransform.transform.transform(this .position,
108: this .position);
109: }
110: }
111:
112: /**
113: * Sets this light's position from the three values provided.
114: * @param x the new x position
115: * @param y the new y position
116: * @param z the new z position
117: */
118: void setPosition(float x, float y, float z) {
119: setPosition(new Point3f(x, y, z));
120: }
121:
122: /**
123: * Retrieves this light's position and places it in the
124: * vector provided.
125: * @param position the variable to receive the position vector
126: */
127: void getPosition(Point3f position) {
128: position.set(this .position);
129:
130: if (staticTransform != null) {
131: Transform3D invTransform = staticTransform
132: .getInvTransform();
133: invTransform.transform(position, position);
134: }
135: }
136:
137: /**
138: * Initializes the point light's attenuation constants.
139: * @param attenuation a vector consisting of constant, linear, and quadratic coefficients
140: */
141: void initAttenuation(Point3f attenuation) {
142: this .attenuation.set(attenuation);
143: }
144:
145: /**
146: * Sets the point light's attenuation constants.
147: * @param attenuation a vector consisting of constant, linear, and quadratic coefficients
148: */
149: void setAttenuation(Point3f attenuation) {
150: initAttenuation(attenuation);
151: sendMessage(ATTENUATION_CHANGED, new Point3f(attenuation));
152: }
153:
154: /**
155: * Sets the point light's attenuation.
156: * @param constant the point light's constant attenuation
157: * @param linear the linear attenuation of the light
158: * @param quadratic the quadratic attenuation of the light
159: */
160: void initAttenuation(float constant, float linear, float quadratic) {
161: this .attenuation.x = constant;
162: this .attenuation.y = linear;
163: this .attenuation.z = quadratic;
164: }
165:
166: /**
167: * Sets the point light's attenuation.
168: * @param constant the point light's constant attenuation
169: * @param linear the linear attenuation of the light
170: * @param quadratic the quadratic attenuation of the light
171: */
172: void setAttenuation(float constant, float linear, float quadratic) {
173: setAttenuation(new Point3f(constant, linear, quadratic));
174: }
175:
176: /**
177: * Retrieves the light's attenuation and places the value in the parameter
178: * specified.
179: * @param attenuation the variable that will contain the attenuation
180: */
181: void getAttenuation(Point3f attenuation) {
182: attenuation.set(this .attenuation);
183: }
184:
185: /**
186: * This update function, and its native counterpart,
187: * updates a point light. This includes its color, attenuation,
188: * and its transformed position.
189: */
190: void update(Context ctx, int lightSlot, double scale) {
191: validateAttenuationInEc(scale);
192: Pipeline.getPipeline().updatePointLight(ctx, lightSlot,
193: color.x, color.y, color.z, attenuation.x,
194: linearAttenuationInEc, quadraticAttenuationInEc,
195: xformPosition.x, xformPosition.y, xformPosition.z);
196: }
197:
198: void setLive(SetLiveState s) {
199: super .setLive(s);
200: J3dMessage createMessage = super .initMessage(9);
201: Object[] objs = (Object[]) createMessage.args[4];
202: objs[7] = new Point3f(position);
203: objs[8] = new Point3f(attenuation);
204:
205: VirtualUniverse.mc.processMessage(createMessage);
206: }
207:
208: // This is called only from SpotLightRetained, so as
209: // to not create a message for initialization. for spotlight
210: // the initialization of the message is done by SpotLightRetained
211: void doSetLive(SetLiveState s) {
212: super .setLive(s);
213: }
214:
215: J3dMessage initMessage(int num) {
216: J3dMessage createMessage = super .initMessage(num);
217: Object[] objs = (Object[]) createMessage.args[4];
218: objs[7] = new Point3f(position);
219: objs[8] = new Point3f(attenuation);
220: return createMessage;
221: }
222:
223: // Note : if you add any more fields here , you need to update
224: // updateLight() in RenderingEnvironmentStructure
225: void updateMirrorObject(Object[] objs) {
226:
227: int component = ((Integer) objs[1]).intValue();
228: Transform3D mlLastLocalToVworld;
229: int i;
230: int numLgts = ((Integer) objs[2]).intValue();
231: LightRetained[] mLgts = (LightRetained[]) objs[3];
232:
233: if ((component & POSITION_CHANGED) != 0) {
234: for (i = 0; i < numLgts; i++) {
235: if (mLgts[i] instanceof PointLightRetained) {
236: PointLightRetained ml = (PointLightRetained) mLgts[i];
237: mlLastLocalToVworld = ml.getLastLocalToVworld();
238: ml.position = (Point3f) objs[4];
239: mlLastLocalToVworld.transform(ml.position,
240: ml.xformPosition);
241: ml.localToVworldScale = mlLastLocalToVworld
242: .getDistanceScale();
243: }
244: }
245: } else if ((component & ATTENUATION_CHANGED) != 0) {
246: for (i = 0; i < numLgts; i++) {
247: if (mLgts[i] instanceof PointLightRetained) {
248: PointLightRetained ml = (PointLightRetained) mLgts[i];
249: ml.attenuation.set((Point3f) objs[4]);
250: }
251: }
252: } else if ((component & INIT_MIRROR) != 0) {
253: for (i = 0; i < numLgts; i++) {
254: if (mLgts[i] instanceof PointLightRetained) {
255: PointLightRetained ml = (PointLightRetained) mirrorLights[i];
256: ml.position = (Point3f) ((Object[]) objs[4])[7];
257: ml.attenuation
258: .set((Point3f) ((Object[]) objs[4])[8]);
259: mlLastLocalToVworld = ml.getLastLocalToVworld();
260: mlLastLocalToVworld.transform(ml.position,
261: ml.xformPosition);
262: ml.localToVworldScale = mlLastLocalToVworld
263: .getDistanceScale();
264: }
265: }
266: }
267:
268: // call the parent's mirror object update routine
269: super .updateMirrorObject(objs);
270: }
271:
272: void validateAttenuationInEc(double vworldToCoexistenceScale) {
273: double localToEcScale = localToVworldScale
274: * vworldToCoexistenceScale;
275:
276: linearAttenuationInEc = (float) (attenuation.y / localToEcScale);
277: quadraticAttenuationInEc = (float) (attenuation.z / (localToEcScale * localToEcScale));
278: }
279:
280: // Clones only the retained side, internal use only
281: protected Object clone() {
282: PointLightRetained pr = (PointLightRetained) super .clone();
283:
284: pr.attenuation = new Point3f(attenuation);
285: pr.position = new Point3f(position);
286: pr.xformPosition = new Point3f();
287: return pr;
288: }
289:
290: // Called on the mirror object
291: void updateTransformChange() {
292: super .updateTransformChange();
293:
294: Transform3D lastLocalToVworld = getLastLocalToVworld();
295:
296: lastLocalToVworld.transform(position, xformPosition);
297: localToVworldScale = lastLocalToVworld.getDistanceScale();
298:
299: validateAttenuationInEc(0.0861328125);
300: }
301:
302: void sendMessage(int attrMask, Object attr) {
303:
304: J3dMessage createMessage = new J3dMessage();
305: createMessage.threads = targetThreads;
306: createMessage.universe = universe;
307: createMessage.type = J3dMessage.LIGHT_CHANGED;
308: createMessage.args[0] = this ;
309: createMessage.args[1] = new Integer(attrMask);
310: if (inSharedGroup)
311: createMessage.args[2] = new Integer(numMirrorLights);
312: else
313: createMessage.args[2] = new Integer(1);
314: createMessage.args[3] = mirrorLights.clone();
315: createMessage.args[4] = attr;
316: VirtualUniverse.mc.processMessage(createMessage);
317: }
318:
319: void mergeTransform(TransformGroupRetained xform) {
320: super.mergeTransform(xform);
321: xform.transform.transform(position, position);
322: }
323: }
|