javax.media.j3d.OrderedGroupRetained Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of java3d-core Show documentation
Show all versions of java3d-core Show documentation
Java3D Core And Java3D Util Libraries
The newest version!
/*
* 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;
/**
* The OrderedGroup is a group node that ensures its children rendered
* in index increasing order.
*/
class OrderedGroupRetained extends GroupRetained {
// mapping of ordered child id to child index
int orderedChildIdTable[];
// This is a counter for ordered child id
private int orderedChildIdCount = 0;
// This is a vector of free orderedChildId
private ArrayList orderedChildIdFreeList = new ArrayList();
// used to lock the orderedBin array
private final Object lockObj = new Object();
// One OrderedBin per view
private OrderedBin[] orderedBin = new OrderedBin[0];
// ChildCount used by renderBin to initialize the
// orderedCollection in each orderedBin (per view)
int childCount = 0;
// per children ordered path data
ArrayList> childrenOrderedPaths = new ArrayList>(1);
// child index order - set by the user.
int[] userChildIndexOrder = null;
// child index order - use by j3d internal.
int[] childIndexOrder = null;
OrderedGroupRetained() {
this.nodeType = NodeRetained.ORDEREDGROUP;
}
void setChildIndexOrder(int[] cIOArr) {
if(cIOArr != null) {
if((userChildIndexOrder == null) ||
(userChildIndexOrder.length != cIOArr.length)) {
userChildIndexOrder = new int[cIOArr.length];
}
System.arraycopy(cIOArr, 0, userChildIndexOrder,
0, userChildIndexOrder.length);
}
else {
userChildIndexOrder = null;
}
if (source.isLive()) {
int[] newArr = new int[cIOArr.length];
System.arraycopy(cIOArr, 0, newArr,
0, newArr.length);
J3dMessage m;
m = new J3dMessage();
m.threads = J3dThread.UPDATE_RENDER;
m.type = J3dMessage.ORDERED_GROUP_TABLE_CHANGED;
m.universe = universe;
m.args[3] = this;
m.args[4] = newArr;
VirtualUniverse.mc.processMessage(m);
}
}
int[] getChildIndexOrder() {
if (userChildIndexOrder == null) {
return null;
}
int[] newArr = new int[userChildIndexOrder.length];
System.arraycopy(userChildIndexOrder, 0,
newArr, 0, userChildIndexOrder.length);
return newArr;
}
Integer getOrderedChildId() {
Integer orderedChildId;
synchronized(orderedChildIdFreeList) {
if (orderedChildIdFreeList.size() == 0) {
orderedChildId = new Integer(orderedChildIdCount);
orderedChildIdCount++;
} else {
orderedChildId = (Integer)orderedChildIdFreeList.remove(0);
}
}
return(orderedChildId);
}
void freeOrderedChildId(int id) {
synchronized(orderedChildIdFreeList) {
orderedChildIdFreeList.add(new Integer(id));
}
}
int getOrderedChildCount() {
int count;
synchronized (orderedChildIdFreeList) {
count = orderedChildIdCount;
}
return count;
}
@Override
void addChild(Node child) {
if(userChildIndexOrder != null) {
doAddChildIndexEntry();
}
// GroupRetained.addChild have to check for case of non-null child index order
// array and handle it.
super.addChild(child);
}
void addChild(Node child, int[] cIOArr) {
if(cIOArr != null) {
userChildIndexOrder = new int[cIOArr.length];
System.arraycopy(cIOArr, 0, userChildIndexOrder,
0, userChildIndexOrder.length);
}
else {
userChildIndexOrder = null;
}
// GroupRetained.addChild have to check for case of non-null child
// index order array and handle it.
super.addChild(child);
}
@Override
void moveTo(BranchGroup bg) {
if(userChildIndexOrder != null) {
doAddChildIndexEntry();
}
// GroupRetained.moveto have to check for case of non-null child
// index order array and handle it.
super.moveTo(bg);
}
void doRemoveChildIndexEntry(int index) {
int[] newArr = new int[userChildIndexOrder.length - 1];
for(int i=0, j=0; i index) {
newArr[j] = userChildIndexOrder[i] - 1;
j++;
}
else if(userChildIndexOrder[i] < index) {
newArr[j] = userChildIndexOrder[i];
j++;
}
}
userChildIndexOrder = newArr;
}
void doAddChildIndexEntry() {
int[] newArr = new int[userChildIndexOrder.length + 1];
System.arraycopy(userChildIndexOrder, 0, newArr,
0, userChildIndexOrder.length);
newArr[userChildIndexOrder.length] = userChildIndexOrder.length;
userChildIndexOrder = newArr;
}
/**
* Compiles the children of the OrderedGroup, preventing shape merging at
* this level or above
*/
@Override
void compile(CompileState compState) {
super.compile(compState);
// don't remove this group node
mergeFlag = SceneGraphObjectRetained.DONT_MERGE;
if (J3dDebug.devPhase && J3dDebug.debug) {
compState.numOrderedGroups++;
}
}
void setOrderedBin(OrderedBin ob, int index) {
synchronized (lockObj) {
if (index < orderedBin.length) {
orderedBin[index] = ob;
return;
}
// If we're clearing the entry to null, just return, don't bother
// expanding the array
if (ob == null)
return;
OrderedBin[] newList = new OrderedBin[index + 1];
System.arraycopy(orderedBin, 0, newList, 0, orderedBin.length);
orderedBin = newList;
orderedBin[index] = ob;
}
}
// Get the orderedBin for this view index
OrderedBin getOrderedBin(int index) {
synchronized (lockObj) {
if (index >= orderedBin.length)
return null;
else
return orderedBin[index];
}
}
void updateChildIdTableInserted(int childId, int orderedId) {
int size = 0;
int i;
//System.err.println("updateChildIdTableInserted childId " + childId + " orderedId " + orderedId + " " + this);
if (orderedChildIdTable != null) {
size = orderedChildIdTable.length;
for (i=0; i= childId) {
orderedChildIdTable[i]++; // shift upward
}
}
}
}
if (orderedId >= size) {
int newTable[];
newTable = new int[orderedId+1];
if (size > 0) {
System.arraycopy(orderedChildIdTable,0,newTable,0,
orderedChildIdTable.length);
}
else {
for (i = 0; i < newTable.length; i++) {
newTable[i] = -1;
}
}
orderedChildIdTable = newTable;
}
orderedChildIdTable[orderedId] = childId;
//printTable(orderedChildIdTable);
}
void updateChildIdTableRemoved(int childId ) {
// If the orderedGroup itself has been clearLived, then the ids
// have been returned, if only some of the children of the
// OGs is removed, then removed the specific entries
// from the table
if (orderedChildIdTable == null)
return;
for (int i=0; i childId) {
orderedChildIdTable[i]--; // shift downward
}
else if (orderedChildIdTable[i] == childId) {
orderedChildIdTable[i] = -1;
//System.err.println("og.updateChildIdTableRemoved freeId " + i);
freeOrderedChildId(i);
}
}
}
}
@Override
void setAuxData(SetLiveState s, int index, int hkIndex) {
OrderedPath setLiveStateOrderedPath = s.orderedPaths.get(hkIndex);
for (int i=0; i= 0) {
setAuxData(s, j, hkIndex);
} else {
MasterControl.getCoreLogger().severe("Can't Find matching hashKey in setNodeData.");
}
}
}
// Note s.orderedPaths is to be updated in GroupRetained.setLive
// for each of its children
}
@Override
void removeNodeData(SetLiveState s) {
if((inSharedGroup) && (s.keys.length != localToVworld.length)) {
int i, index;
ArrayList childOrderedPaths;
// Must be in reverse, to preserve right indexing.
for (i = s.keys.length-1; i >= 0; i--) {
index = s.keys[i].equals(localToVworldKeys, 0,
localToVworldKeys.length);
if(index >= 0) {
for (int j=0; j(1));
}
@Override
void appendChildrenData() {
childrenOrderedPaths.add(new ArrayList(1));
}
@Override
void doRemoveChild(int index, J3dMessage messages[], int messageIndex) {
if(userChildIndexOrder != null) {
doRemoveChildIndexEntry(index);
}
super.doRemoveChild(index, messages, messageIndex);
}
@Override
void removeChildrenData(int index) {
childrenOrderedPaths.remove(index);
}
@Override
void childDoSetLive(NodeRetained child, int childIndex, SetLiveState s) {
if (refCount == s.refCount) {
s.ogList.add(this);
s.ogChildIdList.add(new Integer(childIndex));
s.ogOrderedIdList.add(child.orderedId);
}
s.orderedPaths = childrenOrderedPaths.get(childIndex);
if(child!=null)
child.setLive(s);
}
@Override
void childCheckSetLive(NodeRetained child, int childIndex,
SetLiveState s, NodeRetained linkNode) {
ArrayList childOrderedPaths;
if (linkNode != null) {
int ci = children.indexOf(linkNode);
childOrderedPaths = childrenOrderedPaths.get(ci);
} else {
child.orderedId = getOrderedChildId();
// set this regardless of refCount
s.ogList.add(this);
s.ogChildIdList.add(new Integer(childIndex));
s.ogOrderedIdList.add(child.orderedId);
if(userChildIndexOrder != null) {
s.ogCIOList.add(this);
int[] newArr = new int[userChildIndexOrder.length];
System.arraycopy(userChildIndexOrder, 0, newArr,
0, userChildIndexOrder.length);
s.ogCIOTableList.add(newArr);
}
childOrderedPaths = childrenOrderedPaths.get(childIndex);
for(int i=0; i< orderedPaths.size();i++){
OrderedPath childOrderedPath = orderedPaths.get(i).clonePath();
childOrderedPath.addElementToPath(this, child.orderedId);
childOrderedPaths.add(childOrderedPath);
}
}
s.orderedPaths = childOrderedPaths;
child.setLive(s);
}
}