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 javax.media.j3d;
import java.util.ArrayList;
/**
* Group node that contains a transform.
*/
class TransformGroupRetained extends GroupRetained implements TargetsInterface
{
/**
* The Transform value for the TransformGroup.
*/
Transform3D transform = new Transform3D();
/**
* The inverse of the transform
*/
Transform3D invTransform = null;
/**
* The transpose of the inverse of the transform
*/
Transform3D normalTransform = null;
/**
* The Transform value currently being used internally
*/
Transform3D currentTransform = new Transform3D();
/**
* localVworld values for children of this TG
*/
Transform3D[][] childLocalToVworld = null;
int[][] childLocalToVworldIndex = null;
// working variable for children transforms
Transform3D[][] childTrans = null;
int[][] childTransIndex = null;
/**
* A bitmask of the types in targets
*/
int localTargetThreads = 0;
// combined localTargetThreads and decendants' localTargetThreads
int targetThreads = 0;
/**
* A list of WakeupOnTransformChange conditions for this Transform
*/
WakeupIndexedList transformChange = null;
// The current list of child transform group nodes or link nodes
// under a transform group
ArrayList childTransformLinks = new ArrayList(1);
// working area while compile
boolean needNormalsTransform = false; // true if normals transformation
// is needed to push this
// transform down to geometry
// key which identifies a unique path from a
// locale to this transform group
HashKey currentKey = new HashKey();
boolean aboveAViewPlatform = false;
// maximum transform level of all shared path
int maxTransformLevel = -1;
// List of transform level, one per shared path
int transformLevels[] = null;
// J3d copy.
CachedTargets[] j3dCTs = null;
// User copy.
CachedTargets[] cachedTargets = null;
// Contains per path data, XXXX: move to NodeRetained
TransformGroupData[] perPathData = null;
/**
* The constructor
*/
TransformGroupRetained() {
this.nodeType = NodeRetained.TRANSFORMGROUP;
}
/**
* Sets the transform component of this TransformGroup to the value of
* the passed transform.
* @param t1 the transform to be copied
*/
void setTransform(Transform3D t1) {
J3dMessage tchangeMessage = null;
int i, j;
Transform3D trans = null;
if (staticTransform != null) {
// this writeable transformGroup has a static transform
// merged into this node
trans = new Transform3D(staticTransform.transform);
trans.mul(t1);
transform.setWithLock(trans);
} else {
trans = new Transform3D(t1);
transform.setWithLock(t1);
}
if (transformChange != null) {
notifyConditions();
}
if (source.isLive()) {
if (aboveAViewPlatform && !t1.isCongruent()) {
throw new BadTransformException(J3dI18N.getString("ViewPlatformRetained0"));
}
tchangeMessage = new J3dMessage();
tchangeMessage.type = J3dMessage.TRANSFORM_CHANGED;
tchangeMessage.threads = targetThreads;
tchangeMessage.args[1] = this;
tchangeMessage.args[2] = trans;
tchangeMessage.universe = universe;
//System.err.println("TransformGroupRetained --- TRANSFORM_CHANGED " + this);
VirtualUniverse.mc.processMessage(tchangeMessage);
}
dirtyBoundsCache();
}
/**
* Copies the transform component of this TransformGroup into
* the passed transform object.
* @param t1 the transform object to be copied into
*/
void getTransform(Transform3D t1) {
transform.getWithLock(t1);
// if staticTransform exists for this node, need to
// redetermine the original user specified transform
if (staticTransform != null) {
Transform3D invTransform = staticTransform.getInvTransform();
t1.mul(invTransform, t1);
}
}
// get the inverse of the transform -- note: this method only
// supports static transform
Transform3D getInvTransform() {
if (invTransform == null) {
invTransform = new Transform3D(transform);
invTransform.invert();
}
return invTransform;
}
// get the inverse of the transpose -- note: this method only
// supports static transform, the translation component will
// not transform
Transform3D getNormalTransform() {
if (normalTransform == null) {
normalTransform = new Transform3D(transform);
normalTransform.invert();
normalTransform.transpose();
}
return normalTransform;
}
// synchronized with TransformStructure
@Override
synchronized void setNodeData(SetLiveState s) {
int i;
super.setNodeData(s);
childTrans = new Transform3D[s.currentTransforms.length][2];
childTransIndex = new int[s.currentTransforms.length][2];
for (i=0; i< s.currentTransforms.length; i++) {
childTrans[i][0] = new Transform3D();
childTrans[i][0].mul(s.currentTransforms[i]
[s.currentTransformsIndex[i]
[CURRENT_LOCAL_TO_VWORLD]], currentTransform);
childTrans[i][1] = new Transform3D(childTrans[i][0]);
childTransIndex[i][0] = 0;
childTransIndex[i][1] = 0;
}
if (!s.inSharedGroup) {
s.transformLevels[0] += 1;
maxTransformLevel = s.transformLevels[0];
} else {
for (i=0; i maxTransformLevel) {
maxTransformLevel = s.transformLevels[i];
}
}
}
if (!inSharedGroup) {
if (childLocalToVworld == null) {
// If the node is a transformGroup then need to keep
// the child transforms as well
childLocalToVworld = new Transform3D[1][];
childLocalToVworldIndex = new int[1][];
transformLevels = new int[1];
// Use by TransformStructure
cachedTargets = new CachedTargets[1];
perPathData = new TransformGroupData[1];
}
childLocalToVworld[0] = childTrans[0];
childLocalToVworldIndex[0] = childTransIndex[0];
transformLevels[0] = s.transformLevels[0];
setAuxData(s, 0, 0);
} else {
// For inSharedGroup case.
int j, len;
if (childLocalToVworld == null) {
childLocalToVworld = new Transform3D[s.keys.length][];
childLocalToVworldIndex = new int[s.keys.length][];
transformLevels = new int[s.keys.length];
cachedTargets = new CachedTargets[s.keys.length];
perPathData = new TransformGroupData[s.keys.length];
len=0;
} else {
len = localToVworld.length - s.keys.length;
int newLen = localToVworld.length;
Transform3D newChildTList[][] = new Transform3D[newLen][];
int newChildIndexList[][] = new int[newLen][];
int newTransformLevels[] = new int[newLen];
CachedTargets newTargets[] = new CachedTargets[newLen];
TransformGroupData newPerPathData[] = new TransformGroupData[newLen];
System.arraycopy(childLocalToVworld, 0,
newChildTList, 0, childLocalToVworld.length);
System.arraycopy(childLocalToVworldIndex, 0,
newChildIndexList, 0, childLocalToVworldIndex.length);
System.arraycopy(transformLevels, 0,
newTransformLevels, 0, transformLevels.length);
System.arraycopy(cachedTargets, 0,
newTargets, 0, cachedTargets.length);
System.arraycopy(perPathData, 0,
newPerPathData, 0, perPathData.length);
childLocalToVworld = newChildTList;
childLocalToVworldIndex = newChildIndexList;
transformLevels = newTransformLevels;
cachedTargets = newTargets;
perPathData = newPerPathData;
}
int hkIndex;
int hkIndexPlus1, blkSize;
for(i=len, j=0; i= i) { // Append to last.
childLocalToVworld[i] = childTrans[j];
childLocalToVworldIndex[i] = childTransIndex[j];
transformLevels[i] = s.transformLevels[j];
} else {
hkIndexPlus1 = hkIndex + 1;
blkSize = i - hkIndex;
System.arraycopy(childLocalToVworld, hkIndex,
childLocalToVworld, hkIndexPlus1, blkSize);
System.arraycopy(childLocalToVworldIndex, hkIndex,
childLocalToVworldIndex, hkIndexPlus1, blkSize);
System.arraycopy(transformLevels, hkIndex,
transformLevels, hkIndexPlus1, blkSize);
System.arraycopy(cachedTargets, hkIndex,
cachedTargets, hkIndexPlus1, blkSize);
System.arraycopy(perPathData, hkIndex,
perPathData, hkIndexPlus1, blkSize);
childLocalToVworld[hkIndex] = childTrans[j];
childLocalToVworldIndex[hkIndex] = childTransIndex[j];
transformLevels[hkIndex] = s.transformLevels[j];
}
setAuxData(s, j, hkIndex);
}
}
if (s.childTransformLinks != null) {
// do not duplicate shared nodes
synchronized(s.childTransformLinks) {
if(!inSharedGroup || !s.childTransformLinks.contains(this)) {
s.childTransformLinks.add(this);
}
}
}
s.localToVworld = childLocalToVworld;
s.localToVworldIndex = childLocalToVworldIndex;
s.currentTransforms = childTrans;
s.currentTransformsIndex = childTransIndex;
s.childTransformLinks = childTransformLinks;
s.parentTransformLink = this;
}
@Override
void setAuxData(SetLiveState s, int index, int hkIndex) {
super.setAuxData(s, index, hkIndex);
perPathData[hkIndex] = new TransformGroupData();
perPathData[hkIndex].switchState = s.switchStates.get(hkIndex);
}
// Add a WakeupOnTransformChange to the list
void removeCondition(WakeupOnTransformChange wakeup) {
synchronized (transformChange) {
transformChange.remove(wakeup);
}
}
// Add a WakeupOnTransformChange to the list
void addCondition(WakeupOnTransformChange wakeup) {
synchronized (transformChange) {
transformChange.add(wakeup);
}
}
void notifyConditions() {
synchronized (transformChange) {
WakeupOnTransformChange list[] = (WakeupOnTransformChange [])
transformChange.toArray(false);
for (int i=transformChange.size()-1; i >=0; i--) {
list[i].setTriggered();
}
}
}
@Override
boolean isStatic() {
if (!super.isStatic() ||
source.getCapability(TransformGroup.ALLOW_TRANSFORM_READ) ||
source.getCapability(TransformGroup.ALLOW_TRANSFORM_WRITE)) {
return false;
} else {
return true;
}
}
@Override
void mergeTransform(TransformGroupRetained xform) {
super.mergeTransform(xform);
transform.mul(xform.transform, transform);
}
@Override
void traverse(boolean sameLevel, int level) {
System.err.println();
for (int i = 0; i < level; i++) {
System.err.print(".");
}
System.err.print(this);
if (isStatic()) {
System.err.print(" (s)");
} else {
System.err.print(" (w)");
}
System.err.println();
System.err.println(transform.toString());
super.traverse(true, level);
}
@Override
void compile(CompileState compState) {
// save and reset the keepTG and needNormalsTransform flags
boolean saveKeepTG = compState.keepTG;
compState.keepTG = false;
boolean saveNeedNormalsTransform = compState.needNormalsTransform;
compState.needNormalsTransform = false;
super.compile(compState);
if (compState.keepTG) {
// keep this transform group, don't merge it
mergeFlag = SceneGraphObjectRetained.DONT_MERGE;
}
if (J3dDebug.devPhase && J3dDebug.debug) {
compState.numTransformGroups++;
if (isStatic())
compState.numStaticTransformGroups++;
if (mergeFlag == SceneGraphObjectRetained.MERGE)
compState.numMergedTransformGroups++;
}
if (mergeFlag == SceneGraphObjectRetained.DONT_MERGE) {
// a non-mergeable TG will trigger a merge of its subtree
compState.staticTransform = null;
compState.parentGroup = null;
super.merge(compState);
} else {
// flag this TG as to be merged later on
mergeFlag = SceneGraphObjectRetained.MERGE;
}
// restore compile state
compState.keepTG = saveKeepTG;
this.needNormalsTransform = compState.needNormalsTransform;
compState.needNormalsTransform = saveNeedNormalsTransform;
}
@Override
void merge(CompileState compState) {
TransformGroupRetained saveStaticTransform;
// merge the transforms
if (compState.staticTransform != null) {
staticTransform = compState.staticTransform;
mergeTransform(compState.staticTransform);
}
if (mergeFlag == SceneGraphObjectRetained.MERGE) {
// before we push down the static transform, check
// to see if the transform will be pushed down to shapes
// with geometry_with_normals and if so, check if
// the normal transform has uniform scale or not. If
// it doesn't, don't push it down.
if (this.needNormalsTransform) {
Transform3D normalXform = this.getNormalTransform();
if (!normalXform.isCongruent()) {
mergeFlag = SceneGraphObjectRetained.DONT_MERGE;
}
}
}
if (mergeFlag == SceneGraphObjectRetained.MERGE) {
saveStaticTransform = compState.staticTransform;
compState.staticTransform = this;
// go to the merge method of the group node to start
// pushing down the static transform until it hits
// a leaf or a subtree which is already merged.
super.merge(compState);
// reset the compile state
compState.staticTransform = saveStaticTransform;
} else {
compState.parentGroup.compiledChildrenList.add(this);
parent = compState.parentGroup;
}
mergeFlag = SceneGraphObjectRetained.MERGE_DONE;
}
/**
* This setlive simply concatinates it's transform onto all the ones
* passed in.
*/
@Override
void setLive(SetLiveState s) {
int i,j;
Transform3D trans = null;
Targets[] newTargets = null;
Targets[] savedTransformTargets = null;
int oldTraverseFlags = 0;
int len;
Object obj;
// XXXX - optimization for targetThreads computation, require
// cleanup in GroupRetained.doSetLive()
//int savedTargetThreads = 0;
//savedTargetThreads = s.transformTargetThreads;
//s.transformTargetThreads = 0;
oldTraverseFlags = s.traverseFlags;
savedTransformTargets = s.transformTargets;
int numPaths = (s.inSharedGroup)? s.keys.length : 1;
newTargets = new Targets[numPaths];
for(i=0; i savedChildTransformLinks = s.childTransformLinks;
GroupRetained savedParentTransformLink = s.parentTransformLink;
Transform3D[][] oldCurrentList = s.currentTransforms;
int[][] oldCurrentIndexList = s.currentTransformsIndex;
super.doSetLive(s);
if (! inSharedGroup) {
if (s.transformTargets[0] != null) {
cachedTargets[0] = s.transformTargets[0].snapShotInit();
}
if (s.switchTargets != null &&
s.switchTargets[0] != null) {
s.switchTargets[0].addNode(this, Targets.GRP_TARGETS);
}
} else {
int hkIndex;
for(i=0; i obj;
if (parentTransformLink
instanceof TransformGroupRetained) {
obj = ((TransformGroupRetained)
parentTransformLink).childTransformLinks;
} else {
obj = ((SharedGroupRetained)
parentTransformLink).childTransformLinks;
}
synchronized(obj) {
obj.remove(this);
}
}
aboveAViewPlatform = false;
}
else {
int i, index, len;
// Remove the localToVworld key
int newLen = localToVworld.length - s.keys.length;
Transform3D[][] newChildTList = new Transform3D[newLen][];
int[][] newChildIndexList = new int[newLen][];
int[] newTransformLevels = new int[newLen];
ArrayList[] newChildPTG = new ArrayList[newLen];
CachedTargets[] newTargets = new CachedTargets[newLen];
TransformGroupData[] newPerPathData = new TransformGroupData[newLen];
int[] tempIndex = new int[s.keys.length];
int curStart =0, newStart =0;
boolean found = false;
for(i=0;i= 0) {
found = true;
if(index == curStart) {
curStart++;
}
else {
len = index - curStart;
System.arraycopy(childLocalToVworld, curStart, newChildTList,
newStart, len);
System.arraycopy(childLocalToVworldIndex, curStart, newChildIndexList,
newStart, len);
System.arraycopy(transformLevels, curStart, newTransformLevels,
newStart, len);
System.arraycopy(cachedTargets, curStart, newTargets, newStart, len);
System.arraycopy(perPathData, curStart,
newPerPathData, newStart, len);
curStart = index+1;
newStart = newStart + len;
}
}
else {
found = false;
MasterControl.getCoreLogger().severe("TG.removeNodeData-Can't find matching hashKey.");
}
}
if((found == true) && (curStart < localToVworld.length)) {
len = localToVworld.length - curStart;
System.arraycopy(childLocalToVworld, curStart, newChildTList,
newStart, len);
System.arraycopy(childLocalToVworldIndex, curStart, newChildIndexList,
newStart, len);
System.arraycopy(transformLevels, curStart, newTransformLevels,
newStart, len);
System.arraycopy(cachedTargets, curStart, newTargets, newStart, len);
System.arraycopy(perPathData, curStart,
newPerPathData, newStart, len);
}
childLocalToVworld = newChildTList;
childLocalToVworldIndex = newChildIndexList;
transformLevels = newTransformLevels;
cachedTargets = newTargets;
perPathData = newPerPathData;
}
super.removeNodeData(s);
// Set it back to its parent localToVworld data.
// This is b/c the parent has changed it localToVworld data arrays.
s.localToVworld = childLocalToVworld;
s.localToVworldIndex = childLocalToVworldIndex;
}
}
@Override
void clearLive(SetLiveState s) {
Targets[] savedTransformTargets = null;
savedTransformTargets = s.transformTargets;
// no need to gather targets from tg in clear live
s.transformTargets = null;
super.clearLive(s);
// restore setLiveState from it's local variables.
// removeNodeData has altered these variables.
s.localToVworld = localToVworld;
s.localToVworldIndex = localToVworldIndex;
s.transformTargets = savedTransformTargets;
synchronized (this) { // synchronized with TransformStructure
if (inSharedGroup) {
if (transformLevels != null) {
maxTransformLevel = transformLevels[0];
for (int i=1; i maxTransformLevel) {
maxTransformLevel = transformLevels[i];
}
}
} else {
maxTransformLevel = -1;
}
if (s.switchTargets != null) {
for (int i=0; i=0; i--) {
NodeRetained child = children.get(i);
if(child != null)
child.computeCombineBounds(boundingObject);
}
if (VirtualUniverse.mc.cacheAutoComputedBounds) {
cachedBounds = (Bounds) boundingObject.clone();
}
}
else {
// Should this be lock too ? ( MT safe ? )
synchronized(localBounds) {
boundingObject.set(localBounds);
}
}
// Should this be lock too ? ( MT safe ? )
// Thoughts :
// Make a temp copy with lock : transform.getWithLock(trans);, but this will cause gc ...
synchronized(transform) {
boundingObject.transform(transform);
}
bounds.combine(boundingObject);
}
void processChildLocalToVworld(ArrayList dirtyTransformGroups,
ArrayList keySet,
UpdateTargets targets,
ArrayList blUsers) {
synchronized(this) { // sync with setLive/clearLive
if (inSharedGroup) {
if (localToVworldKeys != null) {
for(int j=0; j dirtyTransformGroups,
ArrayList keySet,
UpdateTargets targets,
ArrayList blUsers) {
int i, j;
Transform3D lToVw, childLToVw;
TransformGroupRetained tg;
LinkRetained ln;
CachedTargets ct;
synchronized(this) { // sync with setLive/clearLive
if (localToVworld != null) {
perPathData[index].markedDirty = false;
// update immediate child's localToVworld
if (perPathData[index].switchState.currentSwitchOn ) {
lToVw = getCurrentLocalToVworld(index);
childLToVw = getUpdateChildLocalToVworld(index);
childLToVw.mul(lToVw, currentTransform);
dirtyTransformGroups.add(this);
keySet.add(key);
ct = j3dCTs[index];
if (ct != null) {
targets.addCachedTargets(ct);
if (ct.targetArr[Targets.BLN_TARGETS] != null) {
gatherBlUsers(blUsers,
ct.targetArr[Targets.BLN_TARGETS]);
}
}
} else {
perPathData[index].switchDirty = true;
//System.err.println("tg.updateChild skip");
}
// update child's localToVworld of its children
// transformLink may contain link nodes
synchronized(childTransformLinks) {
for (i=0; i dirtyTransformGroups,
ArrayList keySet,
UpdateTargets targets,
ArrayList blUsers) {
int i, j;
Transform3D lToVw, childLToVw;
TransformGroupRetained tg;
LinkRetained ln;
CachedTargets ct;
synchronized(this) { // sync with setLive/clearLive
if (localToVworld != null) {
perPathData[0].markedDirty = false;
// update immediate child's localToVworld
if (perPathData[0].switchState.currentSwitchOn ) {
lToVw = getCurrentLocalToVworld(0);
childLToVw = getUpdateChildLocalToVworld(0);
childLToVw.mul(lToVw, currentTransform);
dirtyTransformGroups.add(this);
ct = j3dCTs[0];
if (ct != null) {
targets.addCachedTargets(ct);
if (ct.targetArr[Targets.BLN_TARGETS] != null) {
gatherBlUsers(blUsers,
ct.targetArr[Targets.BLN_TARGETS]);
}
}
} else {
perPathData[0].switchDirty = true;
//System.err.println("tg.updateChild skip");
}
// update child's localToVworld of its children
// transformLink contains top level transform group nodes
// and link nodes
synchronized(childTransformLinks) {
for (i=0; i= 0) {
return childLocalToVworld[i]
[childLocalToVworldIndex[i][NodeRetained.CURRENT_LOCAL_TO_VWORLD]];
}
}
return new Transform3D();
}
/**
* Get the last child localToVworld transform for a node
*/
Transform3D getLastChildLocalToVworld(HashKey key) {
if (!inSharedGroup) {
return childLocalToVworld[0][childLocalToVworldIndex[0][NodeRetained.LAST_LOCAL_TO_VWORLD]];
} else {
int i = key.equals(localToVworldKeys, 0, localToVworldKeys.length);
if(i>= 0) {
return childLocalToVworld[i]
[childLocalToVworldIndex[i][NodeRetained.LAST_LOCAL_TO_VWORLD]];
}
}
return new Transform3D();
}
// ****************************
// TargetsInterface methods
// ****************************
@Override
public int getTargetThreads(int type) {
// type is ignored here, only need for SharedGroup
if (type == TargetsInterface.TRANSFORM_TARGETS) {
return targetThreads;
} else {
System.err.println("getTargetsThreads: wrong arguments");
return -1;
}
}
@Override
public CachedTargets getCachedTargets(int type, int index, int child) {
// type is ignored here, only need for SharedGroup
// child is ignored here
if (type == TargetsInterface.TRANSFORM_TARGETS) {
return cachedTargets[index];
} else {
System.err.println("getCachedTargets: wrong arguments");
return null;
}
}
@Override
TargetsInterface getClosestTargetsInterface(int type) {
return (type == TargetsInterface.TRANSFORM_TARGETS)?
(TargetsInterface)this:
(TargetsInterface)parentSwitchLink;
}
// re-evalute localTargetThreads using newCachedTargets and
// re-evaluate targetThreads
@Override
public void computeTargetThreads(int type,
CachedTargets[] newCachedTargets) {
// type is ignored here, only need for SharedGroup
if (type == TargetsInterface.TRANSFORM_TARGETS) {
localTargetThreads = J3dThread.UPDATE_TRANSFORM;
for(int i=0; i getTargetsData(int type, int index) {
// not used
return null;
}
@Override
void childCheckSetLive(NodeRetained child, int childIndex,
SetLiveState s, NodeRetained linkNode) {
s.currentTransforms = childLocalToVworld;
s.currentTransformsIndex = childLocalToVworldIndex;
s.parentTransformLink = this;
s.childTransformLinks = childTransformLinks;
s.localToVworld = s.currentTransforms;
s.localToVworldIndex = s.currentTransformsIndex;
child.setLive(s);
}
}