javax.media.j3d.ViewSpecificGroupRetained 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 2001-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;
import java.util.Enumeration;
import java.util.Vector;
/**
* The ViewSpecificGroup node retained object.
*/
class ViewSpecificGroupRetained extends GroupRetained {
ArrayList apiViewList = new ArrayList();
// Used by leaf objects particularly GAs
// Updated in a MT Safe manner and also used by RenderBin
ArrayList> cachedViewList = new ArrayList>();
// The object that contains the dynamic HashKey - a string type object
// Used in scoping
HashKey tempKey = new HashKey(250);
// ArrayList of Integer indices
ArrayList> parentLists = new ArrayList>();
static final int SET_VIEW = 0x1;
static final int ADD_VIEW = 0x2;
static final int REMOVE_VIEW = 0x4;
// Construct retained object
ViewSpecificGroupRetained() {
this.nodeType = NodeRetained.VIEWSPECIFICGROUP;
viewLists = new ArrayList>();
}
void addView(View view) {
int i;
Integer mtype = new Integer(ADD_VIEW);
apiViewList.add(view);
if (source.isLive() && view != null) {
// Gather all affected leaf nodes and send a message to
// RenderingEnv and RenderBin
if (inSharedGroup) {
for (int k = 0; k < localToVworldKeys.length; k++) {
ArrayList parentList = parentLists.get(k);
// If the parentList contains this view or if this is the
// first VSG then ..
if (parentList == null || parentList.contains(view)) {
Object[] objAry = new Object[4];
ArrayList addVsgList = new ArrayList();
ArrayList addLeafList = new ArrayList();
int[] addKeyList = new int[10];
HashKey key = localToVworldKeys[k];
addVsgList.add(this);
addKeyList[0] = k;
objAry[0] = view;
objAry[1] = addVsgList;
objAry[2] = addLeafList;
/*
for (int n = 0; n < addLeafList.size(); n++) {
System.err.println("Shared:n = "+n+" addLeafList = "+addLeafList.get(n));
}
*/
objAry[3] = super.processViewSpecificInfo(ADD_VIEW,
key, view,
addVsgList, addKeyList, addLeafList);
J3dMessage message = new J3dMessage();
message.type = J3dMessage.VIEWSPECIFICGROUP_CHANGED;
message.threads = (J3dThread.UPDATE_RENDERING_ENVIRONMENT|
J3dThread.UPDATE_RENDER |
J3dThread.UPDATE_SOUND|
J3dThread.SOUND_SCHEDULER);
message.universe = universe;
message.args[0] = mtype;
message.args[1] = objAry;
VirtualUniverse.mc.processMessage(message);
}
}
}
else {
ArrayList parentList = parentLists.get(0);
// If the parentList contains this view or if this is the
// first VSG then ..
if (parentList == null || parentList.contains(view)) {
Object[] objAry = new Object[4];
ArrayList addVsgList = new ArrayList();
ArrayList addLeafList = new ArrayList();
int[] addKeyList = new int[10];
objAry[0] = view;
objAry[1] = addVsgList;
objAry[2] = addLeafList;
addVsgList.add(this);
addKeyList[0] = 0;
tempKey.reset();
objAry[3] = super.processViewSpecificInfo(ADD_VIEW,
tempKey, view,
addVsgList, addKeyList, addLeafList);
/*
for (int n = 0; n < addLeafList.size(); n++) {
System.err.println("n = "+n+" addLeafList = "+addLeafList.get(n));
}
*/
J3dMessage message = new J3dMessage();
message.type = J3dMessage.VIEWSPECIFICGROUP_CHANGED;
message.threads = (J3dThread.UPDATE_RENDERING_ENVIRONMENT|
J3dThread.UPDATE_RENDER |
J3dThread.UPDATE_SOUND|
J3dThread.SOUND_SCHEDULER);
message.universe = universe;
message.args[0] = mtype;
message.args[1] = objAry;
VirtualUniverse.mc.processMessage(message);
}
}
}
}
void setView(View view, int index) {
View oldView = apiViewList.get(index);
Integer mtype = new Integer(SET_VIEW);
if (oldView == view)
return;
apiViewList.set(index, view);
if (source.isLive()) {
// Gather all affected leaf nodes and send a message to
// RenderingEnv and RenderBin
if (inSharedGroup) {
for (int k = 0; k < localToVworldKeys.length; k++) {
ArrayList parentList = parentLists.get(k);
Object[] objAry = new Object[8];
ArrayList addVsgList = new ArrayList();
ArrayList removeVsgList = new ArrayList();
ArrayList addLeafList = new ArrayList();
ArrayList removeLeafList = new ArrayList();
int[] addKeyList = new int[10];
int[] removeKeyList = new int[10];
objAry[0] = view;
objAry[1] = addVsgList ;
objAry[2] = addLeafList;
objAry[4] = oldView;
objAry[5] = removeVsgList;
objAry[6] = removeLeafList;
HashKey key = localToVworldKeys[k];
if (oldView != null && (parentList == null || parentList.contains(oldView))) {
removeVsgList.add(this);
removeKeyList[0] = k;
objAry[7] = super.processViewSpecificInfo(REMOVE_VIEW, key,
oldView, removeVsgList, removeKeyList, removeLeafList);
}
if (view != null && (parentList == null || parentList.contains(view))) {
addVsgList.add(this);
addKeyList[0] = k;
objAry[3] = super.processViewSpecificInfo(ADD_VIEW, key,
view, addVsgList, addKeyList, addLeafList);
}
J3dMessage message = new J3dMessage();
message.type = J3dMessage.VIEWSPECIFICGROUP_CHANGED;
message.threads = (J3dThread.UPDATE_RENDERING_ENVIRONMENT|
J3dThread.UPDATE_RENDER |
J3dThread.UPDATE_SOUND|
J3dThread.SOUND_SCHEDULER);
message.universe = universe;
message.args[0] = mtype;
message.args[1] = objAry;
VirtualUniverse.mc.processMessage(message);
}
}
else {
ArrayList parentList = parentLists.get(0);
Object[] objAry = new Object[8];
ArrayList addVsgList = new ArrayList();
ArrayList removeVsgList = new ArrayList();
ArrayList addLeafList = new ArrayList();
ArrayList removeLeafList = new ArrayList();
int[] addKeyList = new int[10];
int[] removeKeyList = new int[10];
objAry[0] = view;
objAry[1] = addVsgList ;
objAry[2] = addLeafList;
objAry[4] = oldView;
objAry[5] = removeVsgList;
objAry[6] = removeLeafList;
tempKey.reset();
if (oldView != null && (parentList == null || parentList.contains(oldView))) {
removeVsgList.add(this);
removeKeyList[0] = 0;
objAry[7] = super.processViewSpecificInfo(REMOVE_VIEW, tempKey,
oldView, removeVsgList, removeKeyList, removeLeafList);
}
if (view != null && (parentList == null || parentList.contains(view))) {
tempKey.reset();
addVsgList.add(this);
addKeyList[0] = 0;
objAry[3] = super.processViewSpecificInfo(ADD_VIEW, tempKey,
view, addVsgList, addKeyList, addLeafList);
}
J3dMessage message = new J3dMessage();
message.type = J3dMessage.VIEWSPECIFICGROUP_CHANGED;
message.threads = (J3dThread.UPDATE_RENDERING_ENVIRONMENT|
J3dThread.UPDATE_RENDER |
J3dThread.UPDATE_SOUND|
J3dThread.SOUND_SCHEDULER);
message.universe = universe;
message.args[0] = mtype;
message.args[1] = objAry;
VirtualUniverse.mc.processMessage(message);
}
}
}
@Override
int[] processViewSpecificInfo(int mode, HashKey key, View v, ArrayList vsgList, int[] keyList, ArrayList leaflist) {
int hkIndex = 0;
Integer hashInt = null;
int[] newKeyList = null;
// Get the intersection of the viewList with this view,
if (source.isLive()) {
if (inSharedGroup) {
hkIndex = key.equals(localToVworldKeys, 0, localToVworldKeys.length);
}
if (mode == ADD_VIEW) {
ArrayList parentList = parentLists.get(hkIndex);
parentList.add(v);
}
else if (mode == REMOVE_VIEW) {
ArrayList parentList = parentLists.get(hkIndex);
parentList.remove(v);
}
if(apiViewList.contains(v)) {
// System.err.println("processViewSpecificInfo, this = "+this+" key = "+key);
vsgList.add(this);
if (keyList.length< vsgList.size()) {
// System.err.println("====> allocating new array");
newKeyList = new int[keyList.length+20];
System.arraycopy(keyList, 0, newKeyList, 0, keyList.length);
keyList = newKeyList;
}
if (mode == ADD_VIEW) {
if (inSharedGroup) {
keyList[vsgList.size()-1] = hkIndex;
}
else {
keyList[vsgList.size()-1] = 0;
}
}
else if (mode == REMOVE_VIEW) {
if (inSharedGroup) {
keyList[vsgList.size()-1] = hkIndex;
}
else {
keyList[vsgList.size()-1] = 0;
}
}
return super.processViewSpecificInfo(mode, key, v, vsgList, keyList, leaflist);
}
}
return keyList;
}
View getView(int index) {
return apiViewList.get(index);
}
void insertView(View view, int index) {
int i;
Integer mtype = new Integer(ADD_VIEW);
apiViewList.add(index, view);
if (source.isLive() && view != null) {
// Gather all affected leaf nodes and send a message to
// RenderingEnv and RenderBin
if (inSharedGroup) {
for (int k = 0; k < localToVworldKeys.length; k++) {
ArrayList parentList = parentLists.get(k);
// If the parentList contains this view or if this is the
// first VSG then ..
if (parentList == null || parentList.contains(view)) {
Object[] objAry = new Object[4];
ArrayList addVsgList = new ArrayList();
ArrayList addLeafList = new ArrayList();
int[] addKeyList = new int[10];
HashKey key = localToVworldKeys[k];
addVsgList.add(this);
addKeyList[0] = k;
objAry[0] = view;
objAry[1] = addVsgList;
objAry[2] = addLeafList;
/*
for (int n = 0; n < addLeafList.size(); n++) {
System.err.println("Shared:n = "+n+" addLeafList = "+addLeafList.get(n));
}
*/
objAry[3] = super.processViewSpecificInfo(ADD_VIEW,
key, view,
addVsgList, addKeyList, addLeafList);
J3dMessage message = new J3dMessage();
message.type = J3dMessage.VIEWSPECIFICGROUP_CHANGED;
message.threads = (J3dThread.UPDATE_RENDERING_ENVIRONMENT|
J3dThread.UPDATE_RENDER |
J3dThread.UPDATE_SOUND|
J3dThread.SOUND_SCHEDULER);
message.universe = universe;
message.args[0] = mtype;
message.args[1] = objAry;
VirtualUniverse.mc.processMessage(message);
}
}
}
else {
ArrayList parentList = parentLists.get(0);
// If the parentList contains this view or if this is the
// first VSG then ..
if (parentList == null || parentList.contains(view)) {
Object[] objAry = new Object[4];
ArrayList addVsgList = new ArrayList();
ArrayList addLeafList = new ArrayList();
int[] addKeyList = new int[10];
objAry[0] = view;
objAry[1] = addVsgList;
objAry[2] = addLeafList;
addVsgList.add(this);
addKeyList[0] = 0;
tempKey.reset();
objAry[3] = super.processViewSpecificInfo(ADD_VIEW,
tempKey, view,
addVsgList, addKeyList, addLeafList);
/*
for (int n = 0; n < addLeafList.size(); n++) {
System.err.println("n = "+n+" addLeafList = "+addLeafList.get(n));
}
*/
J3dMessage message = new J3dMessage();
message.type = J3dMessage.VIEWSPECIFICGROUP_CHANGED;
message.threads = (J3dThread.UPDATE_RENDERING_ENVIRONMENT|
J3dThread.UPDATE_RENDER |
J3dThread.UPDATE_SOUND|
J3dThread.SOUND_SCHEDULER);
message.universe = universe;
message.args[0] = mtype;
message.args[1] = objAry;
VirtualUniverse.mc.processMessage(message);
}
}
}
}
void removeView(int index) {
int i;
View v = apiViewList.remove(index);
if (source.isLive() && v != null) {
// Gather all affected leaf nodes and send a message to
// RenderingEnv and RenderBin
if (inSharedGroup) {
for (int k = 0; k < localToVworldKeys.length; k++) {
ArrayList parentList = parentLists.get(k);
// If the parentList contains this view or if this is the
// first VSG then ..
if (parentList == null || parentList.contains(v)) {
Object[] objAry = new Object[4];
ArrayList removeVsgList = new ArrayList();
ArrayList removeLeafList = new ArrayList();
int[] removeKeyList = new int[10];
objAry[0] = v;
objAry[1] = removeVsgList;
objAry[2] = removeLeafList;
HashKey key = localToVworldKeys[k];
removeVsgList.add(this);
removeKeyList[0] = k;
objAry[3] = super.processViewSpecificInfo(REMOVE_VIEW,
key,v,
removeVsgList, removeKeyList, removeLeafList);
J3dMessage message = new J3dMessage();
message.type = J3dMessage.VIEWSPECIFICGROUP_CHANGED;
message.threads = (J3dThread.UPDATE_RENDERING_ENVIRONMENT|
J3dThread.UPDATE_RENDER |
J3dThread.UPDATE_SOUND|
J3dThread.SOUND_SCHEDULER);
message.universe = universe;
message.args[0] = new Integer(REMOVE_VIEW);
message.args[1] = objAry;
VirtualUniverse.mc.processMessage(message);
}
}
}
else {
ArrayList parentList = parentLists.get(0);
// If the parentList contains this view or if this is the
// first VSG then ..
if (parentList == null || parentList.contains(v)) {
Object[] objAry = new Object[4];
ArrayList removeVsgList = new ArrayList();
ArrayList removeLeafList = new ArrayList();
int[] removeKeyList = new int[10];
objAry[0] = v;
objAry[1] = removeVsgList;
objAry[2] = removeLeafList;
removeVsgList.add(this);
removeKeyList[0] = 0;
tempKey.reset();
objAry[3] = super.processViewSpecificInfo(REMOVE_VIEW,
tempKey, v,
removeVsgList, removeKeyList, removeLeafList);
/*
for (int n = 0; n < removeKeyList.size(); n++) {
System.err.println("n = "+n+" keyValue = "+removeKeyList.get(n));
}
*/
J3dMessage message = new J3dMessage();
message.type = J3dMessage.VIEWSPECIFICGROUP_CHANGED;
message.threads = (J3dThread.UPDATE_RENDERING_ENVIRONMENT|
J3dThread.UPDATE_RENDER |
J3dThread.UPDATE_SOUND|
J3dThread.SOUND_SCHEDULER);
message.universe = universe;
message.args[0] = new Integer(REMOVE_VIEW);
message.args[1] = objAry;
VirtualUniverse.mc.processMessage(message);
}
}
}
}
Enumeration getAllViews() {
Vector viewList = new Vector(apiViewList.size());
for (int i = 0; i < apiViewList.size(); i++) {
viewList.add(apiViewList.get(i));
}
return viewList.elements();
}
int numViews() {
return apiViewList.size();
}
int indexOfView(View view) {
return apiViewList.indexOf(view);
}
void removeView(View view) {
removeView(apiViewList.indexOf(view));
}
void removeAllViews() {
int size = apiViewList.size();
for (int i = 0; i < size; i++) {
removeView(0);
}
}
@Override
void compile(CompileState compState) {
super.compile(compState);
// don't remove this group node
mergeFlag = SceneGraphObjectRetained.DONT_MERGE;
// XXXX: complete this
}
@Override
void setLive(SetLiveState s) {
if (inBackgroundGroup) {
throw new
IllegalSceneGraphException(J3dI18N.getString("ViewSpecificGroup3"));
}
s.inViewSpecificGroup = true;
ArrayList> savedViewList = s.viewLists;
if (s.changedViewGroup == null) {
s.changedViewGroup = new ArrayList();
s.changedViewList = new ArrayList>();
s.keyList = new int[10];
s.viewScopedNodeList = new ArrayList();
s.scopedNodesViewList = new ArrayList>();
}
super.setLive(s);
s.viewLists = savedViewList;
}
@Override
void clearLive(SetLiveState s) {
ArrayList> savedViewList = s.viewLists;
if (s.changedViewGroup == null) {
s.changedViewGroup = new ArrayList();
s.changedViewList = new ArrayList>();
s.keyList = new int[10];
s.viewScopedNodeList = new ArrayList();
s.scopedNodesViewList = new ArrayList>();
}
// XXXX: This is a hack since removeNodeData is called before
// children are clearLives
int[] tempIndex = null;
// Don't keep the indices if everything will be cleared
if (inSharedGroup && (s.keys.length != localToVworld.length)) {
tempIndex = new int[s.keys.length];
for (int i = 0; i < s.keys.length; i++) {
tempIndex[i] = s.keys[i].equals(localToVworldKeys, 0, localToVworldKeys.length);
}
}
super.clearLive(s);
// Do this after children clearlive since part of the viewLists may get cleared
// during removeNodeData
// If the last SharedGroup is being cleared
if((!inSharedGroup) || (localToVworld == null)) {
viewLists.clear();
}
else {
// Must be in reverse, to preserve right indexing.
for (int i = tempIndex.length-1; i >= 0 ; i--) {
if(tempIndex[i] >= 0) {
viewLists.remove(tempIndex[i]);
}
}
}
s.viewLists = savedViewList;
}
@Override
void removeNodeData(SetLiveState s) {
if((!inSharedGroup) || (s.keys.length == localToVworld.length)) {
s.changedViewGroup.add(this);
// Remove everything ..
int size = s.changedViewGroup.size();
if (s.keyList.length < size) {
int[] newKeyList = new int[s.keyList.length+20];
System.arraycopy(s.keyList, 0, newKeyList, 0, s.keyList.length);
s.keyList = newKeyList;
// System.err.println("====> RemovedNodeData: Allocating Non-shared");
}
s.keyList[size -1] = -1;
parentLists.clear();
}
// A path of the shared group is removed
else {
int i, index;
int size = s.changedViewGroup.size();
if (s.keyList.length < size+1+s.keys.length) {
int[] newKeyList = new int[s.keyList.length+s.keys.length+20];
System.arraycopy(s.keyList, 0, newKeyList, 0, s.keyList.length);
s.keyList = newKeyList;
// System.err.println("====> RemovedNodeData: Allocating Shared");
}
// 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) {
s.changedViewGroup.add(this);
s.keyList[s.changedViewGroup.size() -1] = index;
parentLists.remove(index);
}
}
}
s.viewLists =viewLists;
super.removeNodeData(s);
}
void updateCachedInformation(int component, View view, int index) {
ArrayList list = cachedViewList.get(index);
/*
System.err.println("updateCachedInformation v = "+this+" index = "+index+" list = "+list+" cachedViewList.size() = "+cachedViewList.size());
for (int k = 0; k < cachedViewList.size(); k++) {
System.err.println("v = "+this+" k = "+k+" v.cachedViewList.get(k) = "+cachedViewList.get(k));
}
*/
if ((component & ADD_VIEW) != 0) {
list.add(view);
}
else if ((component & REMOVE_VIEW) != 0) {
list.remove(view);
}
/*
System.err.println("After updateCachedInformation v = "+this+" index = "+index+" list = "+list+" cachedViewList.size() = "+cachedViewList.size());
for (int k = 0; k < cachedViewList.size(); k++) {
System.err.println("v = "+this+" k = "+k+" v.cachedViewList.get(k) = "+cachedViewList.get(k));
}
*/
}
@Override
void setNodeData(SetLiveState s) {
super.setNodeData(s);
if (!inSharedGroup) {
int size = s.changedViewGroup.size();
if (s.keyList.length < size+1) {
int[] newKeyList = new int[s.keyList.length+20];
System.arraycopy(s.keyList, 0, newKeyList, 0, s.keyList.length);
s.keyList = newKeyList;
// System.err.println("====> setNodeData: Allocating Non-shared");
}
setAuxData(s, 0, 0);
} else {
// For inSharedGroup case.
int j, hkIndex;
int size = s.changedViewGroup.size();
if (s.keyList.length < size+1+s.keys.length) {
int[] newKeyList = new int[s.keyList.length+s.keys.length+20];
System.arraycopy(s.keyList, 0, newKeyList, 0, s.keyList.length);
s.keyList = newKeyList;
// System.err.println("====> setNodeData: Allocating Shared");
}
for(j=0; j= 0) {
setAuxData(s, j, hkIndex);
} else {
MasterControl.getCoreLogger().severe("Can't Find matching hashKey in setNodeData.");
}
}
}
// Make the VSG's viewLists as the relavant one for its children
s.viewLists = viewLists;
}
@Override
void setAuxData(SetLiveState s, int index, int hkIndex) {
ArrayList vl = new ArrayList();
ArrayList parentList = null;
int size = apiViewList.size();
if (s.viewLists != null) {
// System.err.println("=====> VSG: = "+this+" hkIndex = "+hkIndex+" s.viewLists = "+s.viewLists);
parentList = s.viewLists.get(hkIndex);
if (parentList != null) {
for (int i = 0; i < size; i++) {
View v = apiViewList.get(i);
// Get the intersection of the parentlist and this vsg's api list
for (int j = 0; j < parentList.size(); j++) {
if (v == parentList.get(j)) {
vl.add(v);
break;
}
}
}
}
else {
// Only include the non null ones in the apiViewList
for (int i = 0; i < size; i++) {
View v = apiViewList.get(i);
if (v != null) {
vl.add(v);
}
}
}
}
else {
// Only include the non null ones in the apiViewList
for (int i = 0; i < size; i++) {
View v = apiViewList.get(i);
if (v != null) {
vl.add(v);
}
}
}
if (parentList != null) {
parentLists.add(hkIndex, new ArrayList(parentList));
}
else {
parentLists.add(hkIndex, null);
}
viewLists.add(hkIndex,vl);
s.changedViewGroup.add(this);
s.changedViewList.add(vl);
if (localToVworldKeys != null) {
s.keyList[s.changedViewGroup.size() -1] = hkIndex;
}
else {
s.keyList[s.changedViewGroup.size() -1] = 0;
}
}
}