diff options
Diffstat (limited to 'src/javax/media/j3d/PointLightRetained.java')
-rw-r--r-- | src/javax/media/j3d/PointLightRetained.java | 339 |
1 files changed, 339 insertions, 0 deletions
diff --git a/src/javax/media/j3d/PointLightRetained.java b/src/javax/media/j3d/PointLightRetained.java new file mode 100644 index 0000000..4ea69d7 --- /dev/null +++ b/src/javax/media/j3d/PointLightRetained.java @@ -0,0 +1,339 @@ +/* + * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +package javax.media.j3d; + +import javax.vecmath.Point3f; + +/** + * A Retained PointLight source. + */ +class PointLightRetained extends LightRetained { + static final int POSITION_CHANGED = LAST_DEFINED_BIT << 1; + static final int ATTENUATION_CHANGED = LAST_DEFINED_BIT << 2; + static final int LAST_POINTLIGHT_DEFINED_BIT = ATTENUATION_CHANGED; + + /** + * The attenuation vector consisting of + * constant, linear, and quadratic coefficients. + */ + Point3f attenuation = new Point3f(1.0f, 0.0f, 0.0f); + + // The position at which this light source exists. + Point3f position = new Point3f(); + + // The transformed position of this light + Point3f xformPosition = new Point3f(); + + // local to vworld scale for attenuation + double localToVworldScale; + + // scaled linearAttenuation from lc to ec + float linearAttenuationInEc; + + // scaled quadraticAttenuation from lc to ec + float quadraticAttenuationInEc; + + PointLightRetained() { + this.nodeType = NodeRetained.POINTLIGHT; + lightType = 3; + localBounds = new BoundingBox((Bounds)null); + } + + /** + * Initializes this light's position from the vector provided. + * @param position the new position + */ + void initPosition(Point3f position) { + this.position.set(position); + + if (staticTransform != null) { + staticTransform.transform.transform(this.position, this.position); + } + } + + /** + * Sets this light's position from the vector provided. + * @param position the new position + */ + void setPosition(Point3f position) { + initPosition(position); + sendMessage(POSITION_CHANGED, new Point3f(position)); + } + + + /** + * Initializes this light's position from the three values provided. + * @param x the new x position + * @param y the new y position + * @param z the new z position + */ + void initPosition(float x, float y, float z) { + this.position.x = x; + this.position.y = y; + this.position.z = z; + + if (staticTransform != null) { + staticTransform.transform.transform(this.position, this.position); + } + } + + + /** + * Sets this light's position from the three values provided. + * @param x the new x position + * @param y the new y position + * @param z the new z position + */ + void setPosition(float x, float y, float z) { + setPosition(new Point3f(x, y, z)); + } + + + /** + * Retrieves this light's position and places it in the + * vector provided. + * @param position the variable to receive the position vector + */ + void getPosition(Point3f position) { + position.set(this.position); + + if (staticTransform != null) { + Transform3D invTransform = staticTransform.getInvTransform(); + invTransform.transform(position, position); + } + } + + + /** + * Initializes the point light's attenuation constants. + * @param attenuation a vector consisting of constant, linear, and quadratic coefficients + */ + void initAttenuation(Point3f attenuation) { + this.attenuation.set(attenuation); + } + + /** + * Sets the point light's attenuation constants. + * @param attenuation a vector consisting of constant, linear, and quadratic coefficients + */ + void setAttenuation(Point3f attenuation) { + initAttenuation(attenuation); + sendMessage(ATTENUATION_CHANGED, new Point3f(attenuation)); + } + + /** + * Sets the point light's attenuation. + * @param constant the point light's constant attenuation + * @param linear the linear attenuation of the light + * @param quadratic the quadratic attenuation of the light + */ + void initAttenuation(float constant, + float linear, + float quadratic) { + this.attenuation.x = constant; + this.attenuation.y = linear; + this.attenuation.z = quadratic; + } + + /** + * Sets the point light's attenuation. + * @param constant the point light's constant attenuation + * @param linear the linear attenuation of the light + * @param quadratic the quadratic attenuation of the light + */ + void setAttenuation(float constant, + float linear, + float quadratic) { + setAttenuation(new Point3f(constant, linear, quadratic)); + } + + /** + * Retrieves the light's attenuation and places the value in the parameter + * specified. + * @param attenuation the variable that will contain the attenuation + */ + void getAttenuation(Point3f attenuation) { + attenuation.set(this.attenuation); + } + + /** + * This update function, and its native counterpart, + * updates a point light. This includes its color, attenuation, + * and its transformed position. + */ + @Override + void update(Context ctx, int lightSlot, double scale) { + validateAttenuationInEc(scale); + Pipeline.getPipeline().updatePointLight(ctx, + lightSlot, color.x, color.y, color.z, + attenuation.x, linearAttenuationInEc, + quadraticAttenuationInEc, + xformPosition.x, xformPosition.y, + xformPosition.z); + } + + @Override + void setLive(SetLiveState s) { + super.setLive(s); + J3dMessage createMessage = super.initMessage(9); + Object[] objs = (Object[])createMessage.args[4]; + objs[7] = new Point3f(position); + objs[8] = new Point3f(attenuation); + + VirtualUniverse.mc.processMessage(createMessage); + } + + // This is called only from SpotLightRetained, so as + // to not create a message for initialization. for spotlight + // the initialization of the message is done by SpotLightRetained + @Override + void doSetLive(SetLiveState s) { + super.setLive(s); + } + + @Override + J3dMessage initMessage(int num) { + J3dMessage createMessage = super.initMessage(num); + Object[] objs = (Object[])createMessage.args[4]; + objs[7] = new Point3f(position); + objs[8] = new Point3f(attenuation); + return createMessage; + } + + + // Note : if you add any more fields here , you need to update + // updateLight() in RenderingEnvironmentStructure + @Override + void updateMirrorObject(Object[] objs) { + + int component = ((Integer)objs[1]).intValue(); + Transform3D mlLastLocalToVworld; + int i; + int numLgts = ((Integer)objs[2]).intValue(); + LightRetained[] mLgts = (LightRetained[]) objs[3]; + + + if ((component & POSITION_CHANGED) != 0) { + for (i = 0; i < numLgts; i++) { + if (mLgts[i] instanceof PointLightRetained) { + PointLightRetained ml = (PointLightRetained)mLgts[i]; + mlLastLocalToVworld = ml.getLastLocalToVworld(); + ml.position = (Point3f) objs[4]; + mlLastLocalToVworld.transform(ml.position, + ml.xformPosition); + ml.localToVworldScale = + mlLastLocalToVworld.getDistanceScale(); + } + } + } + else if ((component & ATTENUATION_CHANGED) != 0) { + for (i = 0; i < numLgts; i++) { + if (mLgts[i] instanceof PointLightRetained) { + PointLightRetained ml = (PointLightRetained)mLgts[i]; + ml.attenuation.set((Point3f)objs[4]); + } + } + } + else if ((component & INIT_MIRROR) != 0) { + for (i = 0; i < numLgts; i++) { + if (mLgts[i] instanceof PointLightRetained) { + PointLightRetained ml = (PointLightRetained)mirrorLights[i]; + ml.position = (Point3f)((Object[]) objs[4])[7]; + ml.attenuation.set((Point3f)((Object[]) objs[4])[8]); + mlLastLocalToVworld = ml.getLastLocalToVworld(); + mlLastLocalToVworld.transform(ml.position, + ml.xformPosition); + ml.localToVworldScale = + mlLastLocalToVworld.getDistanceScale(); + } + } + } + + // call the parent's mirror object update routine + super.updateMirrorObject(objs); + } + + void validateAttenuationInEc(double vworldToCoexistenceScale) { + double localToEcScale = localToVworldScale * vworldToCoexistenceScale; + + linearAttenuationInEc = (float)(attenuation.y / localToEcScale); + quadraticAttenuationInEc = + (float)(attenuation.z / (localToEcScale * localToEcScale)); + } + + + + // Clones only the retained side, internal use only + @Override + protected Object clone() { + PointLightRetained pr = + (PointLightRetained)super.clone(); + + pr.attenuation = new Point3f(attenuation); + pr.position = new Point3f(position); + pr.xformPosition = new Point3f(); + return pr; + } + + + // Called on the mirror object + @Override + void updateTransformChange() { + super.updateTransformChange(); + + Transform3D lastLocalToVworld = getLastLocalToVworld(); + + lastLocalToVworld.transform(position, xformPosition); + localToVworldScale = lastLocalToVworld.getDistanceScale(); + + validateAttenuationInEc(0.0861328125); + } + + @Override + void sendMessage(int attrMask, Object attr) { + + J3dMessage createMessage = new J3dMessage(); + createMessage.threads = targetThreads; + createMessage.universe = universe; + createMessage.type = J3dMessage.LIGHT_CHANGED; + createMessage.args[0] = this; + createMessage.args[1]= new Integer(attrMask); + if (inSharedGroup) + createMessage.args[2] = new Integer(numMirrorLights); + else + createMessage.args[2] = new Integer(1); + createMessage.args[3] = mirrorLights.clone(); + createMessage.args[4] = attr; + VirtualUniverse.mc.processMessage(createMessage); + } + + @Override + void mergeTransform(TransformGroupRetained xform) { + super.mergeTransform(xform); + xform.transform.transform(position, position); + } +} |