Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* 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 org.scijava.java3d;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Vector;
import org.scijava.vecmath.Color3f;
/**
* LightRetained is an abstract class that contains instance variable common to
* all lights.
*/
abstract class LightRetained extends LeafRetained {
// Statics used when something in the light changes
static final int ENABLE_CHANGED = 0x0001;
static final int SCOPE_CHANGED = 0x0002;
static final int BOUNDS_CHANGED = 0x0004;
static final int COLOR_CHANGED = 0x0008;
static final int BOUNDINGLEAF_CHANGED = 0x0010;
static final int INIT_MIRROR = 0x0020;
static final int CLEAR_MIRROR = 0x0040;
static final int LAST_DEFINED_BIT = 0x0040;
// Indicates whether the light is turned on.
boolean lightOn = true;
// The color of the light (white by default).
Color3f color = new Color3f(1.0f, 1.0f, 1.0f);
// This node which specifies the hierarchical scope of the
// light. A null reference means that this light has universal
// scope.
Vector scopes = new Vector();
/**
* The Boundary object defining the lights's region of influence.
*/
Bounds regionOfInfluence = null;
/**
* The bounding leaf reference
*/
BoundingLeafRetained boundingLeaf = null;
/**
* The transformed value of the applicationRegion.
*/
Bounds region = null;
/**
* This bitmask is set when something changes in the light
*/
int lightDirty = 0xffff;
// This is a copy of the sgLight's dirty bits
int sgLightDirty = 0xffff;
// The type of light
int lightType = -1;
// This is true when this light is needed in the current light set
boolean isNeeded = false;
// This is true when this light is referenced in an immediate mode context
boolean inImmCtx = false;
// A back reference to the scene graph light, when this is a mirror light
LightRetained sgLight = null;
// A HashKey for lights in a shared group
HashKey key = null;
// An array of mirror lights, one for each instance of this light in a
// shared group. Entry 0 is the only one valid if we are not in a shared
// group.
LightRetained[] mirrorLights = new LightRetained[1];
// The number of valid lights in mirrorLights
int numMirrorLights = 0;
// Indicated whether the light is a scoped light
boolean isScoped = false;
// The object that contains the dynamic HashKey - a string type object
// Used in scoping
HashKey tempKey = new HashKey(250);
/**
* A list of all the EnvironmentSets that reference this light.
* Note that multiple RenderBin update thread may access
* this shared environmentSets simultaneously.
* So we use UnorderList when sync. all the operations.
*/
UnorderList environmentSets = new UnorderList(1, EnvironmentSet.class);
// Is true, if the mirror light is viewScoped
boolean isViewScoped = false;
/**
* Temporary list of newly added mirror lights, during any setlive
*/
ArrayList newlyAddedMirrorLights = new ArrayList();
// Target threads to be notified when light changes
static final int targetThreads = J3dThread.UPDATE_RENDERING_ENVIRONMENT |
J3dThread.UPDATE_RENDER;
/**
* Initialize the light on or off.
* @param state true or false to enable or disable the light
*/
void initEnable(boolean state) {
this.lightOn = state;
}
/**
* Turns the light on or off and send a message
* @param state true or false to enable or disable the light
*/
void setEnable(boolean state) {
initEnable(state);
sendMessage(ENABLE_CHANGED,
(state ? Boolean.TRUE: Boolean.FALSE));
}
/**
* Returns the state of the light (on/off).
* @return true if the light is on, false if the light is off.
*/
boolean getEnable() {
return this.lightOn;
}
/**
* Initialize the color of this light node.
* @param color the value of this new light color
*/
void initColor(Color3f color) {
this.color.set(color);
}
/**
* Sets the color of this light node and send a message
* @param color the value of this new light color
*/
void setColor(Color3f color) {
initColor(color);
sendMessage(COLOR_CHANGED, new Color3f(color));
}
/**
* Retrieves the color of this light.
* @param color the vector that will receive the color of this light
*/
void getColor(Color3f color) {
color.set(this.color);
}
/**
* Initializes the specified scope with the scope provided.
* @param scope the new scope
* @param index which scope to replace
*/
void initScope(Group scope, int index) {
GroupRetained group = (GroupRetained)scope.retained;
scopes.setElementAt(group, index);
}
/**
* Replaces the specified scope with the scope provided and
* send a message
* @param scope the new scope
* @param index which scope to replace
*/
void setScope(Group scope, int index) {
ArrayList addScopeList = new ArrayList();
ArrayList removeScopeList = new ArrayList();
Object[] scopeInfo = new Object[3];
GroupRetained group = scopes.get(index);
tempKey.reset();
group.removeAllNodesForScopedLight((inSharedGroup?numMirrorLights:1), mirrorLights, removeScopeList, tempKey);
group = (GroupRetained)scope.retained;
tempKey.reset();
// If its a group, then add the scope to the group, if
// its a shape, then keep a list to be added during
// updateMirrorObject
group.addAllNodesForScopedLight((inSharedGroup?numMirrorLights:1), mirrorLights,addScopeList, tempKey);
initScope(scope, index);
scopeInfo[0] = addScopeList;
scopeInfo[1] = removeScopeList;
scopeInfo[2] = (scopes.size() > 0 ? Boolean.TRUE: Boolean.FALSE);
sendMessage(SCOPE_CHANGED, scopeInfo);
}
/**
* Inserts the specified scope at specified index.
* @param scope the new scope
* @param index position to insert new scope at
*/
void initInsertScope(Group scope, int index) {
GroupRetained group = (GroupRetained)scope.retained;
scopes.insertElementAt(group, index);
group.setLightScope();
}
/**
* Inserts the specified scope at specified index.
* @param scope the new scope
* @param index position to insert new scope at
*/
void insertScope(Group scope, int index) {
Object[] scopeInfo = new Object[3];
ArrayList addScopeList = new ArrayList();
GroupRetained group = (GroupRetained)scope.retained;
tempKey.reset();
group.addAllNodesForScopedLight((inSharedGroup?numMirrorLights:1), mirrorLights,addScopeList, tempKey);
initInsertScope(scope, index);
scopeInfo[0] = addScopeList;
scopeInfo[1] = null;
scopeInfo[2] = (scopes.size() > 0 ? Boolean.TRUE: Boolean.FALSE);
sendMessage(SCOPE_CHANGED, scopeInfo);
}
/**
* Removes the scope at specified index.
* @param index which scope to remove
*/
void initRemoveScope(int index) {
GroupRetained group = scopes.remove(index);
group.removeLightScope();
}
/**
* Removes the scope at specified index.
* @param index which scope to remove
*/
void removeScope(int index) {
Object[] scopeInfo = new Object[3];
ArrayList removeScopeList = new ArrayList();
GroupRetained group = scopes.elementAt(index);
tempKey.reset();
group.removeAllNodesForScopedLight((inSharedGroup?numMirrorLights:1), mirrorLights, removeScopeList, tempKey);
initRemoveScope(index); scopeInfo[0] = null;
scopeInfo[1] = removeScopeList;
scopeInfo[2] = (scopes.size() > 0 ? Boolean.TRUE: Boolean.FALSE);
sendMessage(SCOPE_CHANGED, scopeInfo);
}
/**
* Removes the specified scope
* @param scope to be removed
*/
void removeScope(Group scope) {
int ind = indexOfScope(scope);
if(ind >= 0)
removeScope(ind);
}
void initRemoveScope(Group scope) {
int ind = indexOfScope(scope);
if(ind >= 0)
initRemoveScope(ind);
}
/**
* Removes all the scopes from this Light's list of scopes
*/
void removeAllScopes() {
int n = scopes.size();
Object[] scopeInfo = new Object[3];
ArrayList removeScopeList = new ArrayList();
for(int index = n-1; index >= 0; index--) {
GroupRetained group = scopes.elementAt(index);
tempKey.reset();
group.removeAllNodesForScopedLight((inSharedGroup?numMirrorLights:1), mirrorLights, removeScopeList, tempKey);
initRemoveScope(index);
}
scopeInfo[0] = null;
scopeInfo[1] = removeScopeList;
scopeInfo[2] = (Boolean.FALSE);
sendMessage(SCOPE_CHANGED, scopeInfo);
}
void initRemoveAllScopes() {
int n = scopes.size();
for(int i = n-1; i >= 0; i--)
initRemoveScope(i);
}
/**
* Returns the scope specified by the index.
* @param index of the scope to be returned
* @return the scope at location index
*/
Group getScope(int index) {
return (Group)scopes.elementAt(index).source;
}
/**
* Returns an enumeration object of the scope
* @return an enumeration object of the scope
*/
Enumeration getAllScopes() {
Enumeration elm = scopes.elements();
Vector v = new Vector(scopes.size());
while (elm.hasMoreElements()) {
v.add((Group)elm.nextElement().source);
}
return v.elements();
}
/**
* Appends the specified scope to this node's list of scopes.
* @param scope the scope to add to this node's list of scopes
*/
void initAddScope(Group scope) {
GroupRetained group = (GroupRetained)scope.retained;
scopes.addElement(group);
group.setLightScope();
}
/**
* Appends the specified scope to this node's list of scopes.
* @param scope the scope to add to this node's list of scopes
*/
void addScope(Group scope) {
Object[] scopeInfo = new Object[3];
ArrayList addScopeList = new ArrayList();
GroupRetained group = (GroupRetained)scope.retained;
initAddScope(scope);
tempKey.reset();
group.addAllNodesForScopedLight((inSharedGroup?numMirrorLights:1), mirrorLights,addScopeList, tempKey);
scopeInfo[0] = addScopeList;
scopeInfo[1] = null;
scopeInfo[2] = (scopes.size() > 0 ? Boolean.TRUE: Boolean.FALSE);
sendMessage(SCOPE_CHANGED, scopeInfo);
}
/**
* Returns a count of this nodes' scopes.
* @return the number of scopes descendant from this node
*/
int numScopes() {
return scopes.size();
}
/**
* Returns the index of the specified scope
* @return index of the scope in this Light's list of scopes
*/
int indexOfScope(Group scope) {
if(scope != null)
return scopes.indexOf(scope.retained);
else
return scopes.indexOf(null);
}
/**
* Initializes the Light's region of influence.
* @param region a region that contains the Light's new region of influence
*/
void initInfluencingBounds(Bounds region) {
if (region != null) {
regionOfInfluence = (Bounds) region.clone();
if (staticTransform != null) {
regionOfInfluence.transform(staticTransform.transform);
}
} else {
regionOfInfluence = null;
}
}
/**
* Set the Light's region of influence and send a message
* @param region a region that contains the Light's new region of influence
*/
void setInfluencingBounds(Bounds region) {
initInfluencingBounds(region);
sendMessage(BOUNDS_CHANGED,
(region != null ? region.clone() : null));
}
/**
* Get the Light's region of influence
* @return this Light's region of influence information
*/
Bounds getInfluencingBounds() {
Bounds b = null;
if (regionOfInfluence != null) {
b = (Bounds) regionOfInfluence.clone();
if (staticTransform != null) {
Transform3D invTransform = staticTransform.getInvTransform();
b.transform(invTransform);
}
}
return b;
}
/**
* Initializes the Light's region of influence to the specified Leaf node.
*/
void initInfluencingBoundingLeaf(BoundingLeaf region) {
if (region != null) {
boundingLeaf = (BoundingLeafRetained)region.retained;
} else {
boundingLeaf = null;
}
}
/**
* Set the Light's region of influence to the specified Leaf node.
*/
void setInfluencingBoundingLeaf(BoundingLeaf region) {
int i, numLgts;
numLgts = numMirrorLights;
if (numMirrorLights == 0)
numLgts = 1;
if (boundingLeaf != null) {
// Remove the mirror lights as users of the original bounding leaf
for (i = 0; i < numLgts; i++) {
boundingLeaf.mirrorBoundingLeaf.removeUser(mirrorLights[i]);
}
}
if (region != null) {
boundingLeaf = (BoundingLeafRetained)region.retained;
// Add all mirror lights as user of this bounding leaf
for (i = 0; i < numLgts; i++) {
boundingLeaf.mirrorBoundingLeaf.addUser(mirrorLights[i]);
}
} else {
boundingLeaf = null;
}
sendMessage(BOUNDINGLEAF_CHANGED,
(boundingLeaf != null ?
boundingLeaf.mirrorBoundingLeaf : null));
}
/**
* Get the Light's region of influence.
*/
BoundingLeaf getInfluencingBoundingLeaf() {
return (boundingLeaf != null ?
(BoundingLeaf)boundingLeaf.source : null);
}
/**
* This sets the immedate mode context flag
*/
void setInImmCtx(boolean inCtx) {
inImmCtx = inCtx;
}
/**
* This gets the immedate mode context flag
*/
boolean getInImmCtx() {
return (inImmCtx);
}
// Called on the parent Light object and loops over the mirror object
void initMirrorObject(Object[] args) {
Shape3DRetained shape;
Object[] scopeInfo = (Object[])((Object[])args[4])[5];
ArrayList gAtomList = (ArrayList)scopeInfo[1];
Boolean scoped = (Boolean)scopeInfo[0];
BoundingLeafRetained bl=(BoundingLeafRetained)((Object[])args[4])[0];
Bounds bnds = (Bounds)((Object[])args[4])[1];
int numLgts = ((Integer)args[2]).intValue();
LightRetained[] mLgts = (LightRetained[]) args[3];
int k;
for ( k = 0; k < numLgts; k++) {
for (int i = 0; i < gAtomList.size(); i++) {
shape = ((GeometryAtom)gAtomList.get(i)).source;
shape.addLight(mLgts[k]);
}
mLgts[k].isScoped = scoped.booleanValue();
}
for (k = 0; k < numLgts; k++) {
mLgts[k].inBackgroundGroup = ((Boolean)((Object[])args[4])[2]).booleanValue();
mLgts[k].geometryBackground = (BackgroundRetained)((Object[])args[4])[3];
if (bl != null) {
mLgts[k].boundingLeaf = bl.mirrorBoundingLeaf;
mLgts[k].region = mLgts[k].boundingLeaf.transformedRegion;
} else {
mLgts[k].boundingLeaf = null;
mLgts[k].region = null;
}
if (bnds != null) {
mLgts[k].regionOfInfluence = bnds;
if (mLgts[k].region == null) {
mLgts[k].region = (Bounds)regionOfInfluence.clone();
mLgts[k].region.transform(regionOfInfluence, getLastLocalToVworld());
}
}
else {
mLgts[k].regionOfInfluence = null;
}
mLgts[k].lightOn = ((Boolean)((Object[])args[4])[4]).booleanValue();
}
// if its a ambient light,then do a immediate update of color
if (this instanceof AmbientLightRetained) {
Color3f clr = (Color3f) ((Object[])args[4])[6];
for (int i = 0; i < numLgts; i++) {
mLgts[i].color.set(clr);
}
}
}
/**
* This method is implemented by each light for rendering
* context updates. This default one does nothing.
*/
abstract void update(Context ctx, int lightSlot, double scale);
// This routine is called when rendering Env structure
// get a message, this routine updates values in the mirror object
// that are not used by the renderer
void updateImmediateMirrorObject(Object[] objs) {
int component = ((Integer)objs[1]).intValue();
int numLgts = ((Integer)objs[2]).intValue();
LightRetained[] mLgts = (LightRetained[]) objs[3];
// Color changed called immediately only for ambient lights
if ((component & COLOR_CHANGED) != 0) {
for (int i = 0; i < numLgts; i++) {
mLgts[i].color.set(((Color3f)objs[4]));
}
}
else if ((component & ENABLE_CHANGED) != 0) {
for (int i = 0; i < numLgts; i++)
mLgts[i].lightOn = ((Boolean)objs[4]).booleanValue();
}
else if ((component & BOUNDS_CHANGED) != 0) {
for (int i = 0; i < numLgts; i++) {
mLgts[i].regionOfInfluence = (Bounds) objs[4];
if (mLgts[i].boundingLeaf == null) {
if (objs[4] != null) {
mLgts[i].region = mLgts[i].regionOfInfluence.copy(mLgts[i].region);
mLgts[i].region.transform(mLgts[i].regionOfInfluence,
mLgts[i].getCurrentLocalToVworld());
}
else {
mLgts[i].region = null;
}
}
}
}
else if ((component & BOUNDINGLEAF_CHANGED) != 0) {
for (int i = 0; i < numLgts; i++) {
mLgts[i].boundingLeaf=((BoundingLeafRetained)objs[4]);
if (objs[4] != null) {
mLgts[i].region = mLgts[i].boundingLeaf.transformedRegion;
}
else { // evaluate regionOfInfluence if not null
if (mLgts[i].regionOfInfluence != null) {
mLgts[i].region = mLgts[i].regionOfInfluence.copy(mLgts[i].region);
mLgts[i].region.transform(mLgts[i].regionOfInfluence,
mLgts[i].getCurrentLocalToVworld());
}
else {
mLgts[i].region = null;
}
}
}
}
else if ((component & SCOPE_CHANGED) != 0) {
int j, i;
Object[] scopeList = (Object[])objs[4];
ArrayList addList = (ArrayList)scopeList[0];
ArrayList removeList = (ArrayList)scopeList[1];
boolean isScoped = ((Boolean)scopeList[2]).booleanValue();
if (addList != null) {
for (i = 0; i < numLgts; i++) {
mLgts[i].isScoped = isScoped;
for (j = 0; j < addList.size(); j++) {
Shape3DRetained obj = ((GeometryAtom)addList.get(j)).source;
obj.addLight(mLgts[i]);
}
}
}
if (removeList != null) {
for (i = 0; i < numLgts; i++) {
mLgts[i].isScoped = isScoped;
for (j = 0; j < removeList.size(); j++) {
Shape3DRetained obj = ((GeometryAtom)removeList.get(j)).source;
obj.removeLight(mLgts[i]);
}
}
}
}
}
// The update Object function called during RenderingEnv objUpdate
// 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();
int numLgts = ((Integer)objs[2]).intValue();
LightRetained[] mLgts = (LightRetained[]) objs[3];
if ((component & COLOR_CHANGED) != 0) {
for (int i = 0; i < numLgts; i++) {
mLgts[i].color.set(((Color3f)objs[4]));
}
}
if ((component & INIT_MIRROR) != 0) {
for (int i = 0; i < numLgts; i++) {
Color3f clr = (Color3f) ((Object[])objs[4])[6];
mLgts[i].color.set(clr);
}
}
}
/** Note: This routine will only be called on
* the mirror object - will update the object's
* cached region and transformed region
*/
@Override
void updateBoundingLeaf() {
// This is necessary, if for example, the region
// changes from sphere to box.
if (boundingLeaf != null && boundingLeaf.switchState.currentSwitchOn) {
region = boundingLeaf.transformedRegion;
} else { // evaluate regionOfInfluence if not null
if (regionOfInfluence != null) {
region = regionOfInfluence.copy(region);
region.transform(regionOfInfluence, getCurrentLocalToVworld());
} else {
region = null;
}
}
}
@Override
void getMirrorObjects(ArrayList leafList, HashKey key) {
if (!inSharedGroup) {
leafList.add(mirrorLights[0]);
}
else {
for (int i=0; i 0) {
J3dMessage createMessage = new J3dMessage();
LightRetained[] mlts = new LightRetained[newlyAddedMirrorLights.size()];
for (int i = 0; i < mlts.length; i++) {
mlts[i] = newlyAddedMirrorLights.get(i);
}
createMessage.threads = J3dThread.UPDATE_RENDERING_ENVIRONMENT;
createMessage.universe = universe;
createMessage.type = J3dMessage.LIGHT_CHANGED;
createMessage.args[0] = this;
createMessage.args[1]= new Integer(CLEAR_MIRROR);
ArrayList removeScopeList = new ArrayList();
for (int i = 0; i < scopes.size(); i++) {
GroupRetained group = scopes.get(i);
tempKey.reset();
group.removeAllNodesForScopedLight(mlts.length, mlts, removeScopeList, tempKey);
}
createMessage.args[2] = removeScopeList;
createMessage.args[3] = new Integer(mlts.length);
createMessage.args[4] = mlts;
VirtualUniverse.mc.processMessage(createMessage);
}
}
void clearMirrorObject(Object[] args) {
Shape3DRetained shape;
ArrayList shapeList = (ArrayList)args[2];
LightRetained[] mLgts = (LightRetained[]) args[4];
int numLgts = ((Integer)args[3]).intValue();
for (int k = 0; k < numLgts; k++) {
for (int i = 0; i < shapeList.size(); i++) {
shape = ((GeometryAtom)shapeList.get(i)).source;
shape.removeLight(mLgts[k]);
}
mLgts[k].isScoped = false;
}
}
/**
* Clones only the retained side, internal use only
*/
@Override
protected Object clone() {
LightRetained lr = (LightRetained)super.clone();
lr.color = new Color3f(color);
lr.scopes = new Vector(scopes);
lr.initInfluencingBoundingLeaf(getInfluencingBoundingLeaf());
lr.region = null;
lr.lightDirty = 0xffff;
lr.sgLightDirty = 0xffff;
lr.universe = null;
lr.isNeeded = false;
lr.inImmCtx = false;
lr.sgLight = null;
lr.key = null;
lr.mirrorLights = new LightRetained[1];
lr.numMirrorLights = 0;
lr.environmentSets = new UnorderList(1, EnvironmentSet.class);
return lr;
}
// Called during RenderingEnv object update
@Override
void updateTransformChange() {
}
// Called on mirror object and updated when message is received
void updateImmediateTransformChange() {
// If bounding leaf is null, tranform the bounds object
if (boundingLeaf == null) {
if (regionOfInfluence != null) {
region = regionOfInfluence.copy(region);
region.transform(regionOfInfluence,
getCurrentLocalToVworld());
}
}
}
void sendMessage(int attrMask, Object attr) {
J3dMessage createMessage = new J3dMessage();
createMessage.threads = targetThreads;
createMessage.type = J3dMessage.LIGHT_CHANGED;
createMessage.universe = universe;
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);
if (regionOfInfluence != null) {
regionOfInfluence.transform(xform.transform);
}
}
}