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 1998-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.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;
/**
* The RenderBin is a structure that optimizes rendering by doing efficient
* state sorting of objects to be rendered.
*/
class RenderBin extends J3dStructure implements ObjectUpdate {
/**
* The list of RenderAtoms
*/
ArrayList renderAtoms = new ArrayList(5);
/**
* A couple ArrayLists used during light Processing
*/
ArrayList lightMessageList = new ArrayList(5);
// Messges retrieved when a message is sent to RenderingEnv Structure
J3dMessage[] m;
/**
* List of renderMolecules that are soleUser have to do a 2 pass, first update
* values then sort based on equivalent material
*/
ArrayList rmUpdateList = new ArrayList();
ArrayList aBinUpdateList = new ArrayList();
/**
* List of ShaderBin that are soleUser that needs to have its components updated @updateObject
* time
*/
ArrayList sBinUpdateList = new ArrayList();
/**
* List of TextureBin that are soleUser that needs to have its components
* updated @updateObject time
*/
ArrayList tbUpdateList = new ArrayList();
/**
* List of Bins that are soleUser that have new renderAtom added into, which
* requires a pre-update screening to check if any of its node component changes
* could have been missed because the changes happen when all the render atoms
* are temporarily removed from the bin.
*/
ArrayList updateCheckList = new ArrayList();
/**
* The number of lights supported by the underlying context.
*/
int maxLights;
/**
* The opaque objects
*/
LightBin opaqueBin = null;
/**
* OpaqueBins to be added for the next frame
*/
LightBin addOpaqueBin = null;
// This is a list of textureBins to be rendered, if the transpSortPolicy
// is NONE, otherwise, if the transpSortPolicy is geometry, then
// this is the list of renderAtoms to be rendered
ArrayList allTransparentObjects = new ArrayList(5);
TransparentRenderingInfo transparentInfo;
/**
* List of RenderAtoms whose postion have changed - only used for depth sorted
* transparency
*/
ArrayList positionDirtyList = new ArrayList(5);
/**
* Used when ColoringAttributes is null
*/
Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
/**
* Used when Background is null
*/
Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
/**
* The backgound color data.
*/
BackgroundRetained background = new BackgroundRetained();
/**
* The view platform transforms.
*/
// used for rendering - lights and fog modelling
Transform3D vworldToVpc = new Transform3D();
// used for updating vpSchedSphere
Transform3D vpcToVworld = new Transform3D();
/**
* Two bounding spheres to track the scheduling region of
* the view platform.
*/
BoundingSphere vpSchedSphereInVworld = new BoundingSphere();
/**
* To cache the view frustum bounding box.
*/
BoundingBox viewFrustumBBox = new BoundingBox();
BoundingBox canvasFrustumBBox = new BoundingBox();
/**
* To ensure that vpcToVworld is valid (not null) for the first pass
*/
boolean afterFirst = false;
/**
* back clip distance in vworld
*/
double backClipDistanceInVworld;
boolean backClipActive = false;
/**
* These variables control when compaction occurs
*/
int frameCount = 0;
int frameCountCutoff = 150;
int notVisibleCount = 75;
long removeCutoffTime = -1;
/**
* variables to process transform messages
*/
boolean transformMsg = false;
UpdateTargets targets = null;
ArrayList blUsers = null;
/**
* The View for this render bin
*/
View view = null;
private Comparator transparencySortComparator = null;
private ArrayList toBeAddedTextureResourceFreeList = new ArrayList(5);
private ArrayList displayListResourceFreeList = new ArrayList(5);
// a list of top level OrderedGroups
ArrayList orderedBins = new ArrayList(5);
// List of changed elements in the environment that needs to
// be reloaded
ArrayList changedLts = new ArrayList(5);
ArrayList changedFogs = new ArrayList(5);
ArrayList changedModelClips = new ArrayList(5);
// Flag to indicate whether the canvas should be marked
static int REEVALUATE_LIGHTS = 0x1;
static int REEVALUATE_FOG = 0x2;
static int REEVALUATE_MCLIP = 0x4;
static int REEVALUATE_ALL_ENV = REEVALUATE_LIGHTS | REEVALUATE_FOG | REEVALUATE_MCLIP;
int envDirty = 0;
private boolean reEvaluateBg = true;
private boolean reloadBgTexture = true;
boolean reEvaluateClip = true;
boolean reEvaluateSortMode = false;
// list of renderMolecule
// RenderBin will not reused in two different universe, so it is
// safe to pass null in last parameters in new IndexedUnorderSet()
IndexedUnorderSet renderMoleculeList =
new IndexedUnorderSet(RenderMolecule.class,
RenderMolecule.RENDER_MOLECULE_LIST, null);
// List of renderAtoms that have a shared dlist (due to geo.refCount > 1)
// Fix for Issue 5: change this to a Set rather than a list to
// avoid duplicates entried
Collection sharedDList = new HashSet();
ArrayList dirtyRenderMoleculeList = new ArrayList(5);
/**
* ArrayList of objects to be updated
*/
ArrayList objUpdateList = new ArrayList(5);
ArrayList raLocaleVwcBoundsUpdateList = new ArrayList(5);
/**
* remove the bins first before adding them to new ones
*/
IndexedUnorderSet removeRenderAtomInRMList =
new IndexedUnorderSet(RenderMolecule.class,
RenderMolecule.REMOVE_RENDER_ATOM_IN_RM_LIST, null);
/**
* list of affect OrderedGroups with childIndexOrder changed.
*/
ArrayList ogCIOList = new ArrayList(5);
/**
* list of ordered bins from which orderedCollection are added/removed
*/
ArrayList obList = new ArrayList(5);
/**
* Ordered Bin processing
*/
ArrayList> orderedBinsList = new ArrayList>(5);
ArrayList> toBeAddedBinList = new ArrayList>(5);
/**
* arraylist of geometry that should be locked to ensure
* that the same snapshot of the geometry is rendered
* across all canvases
*/
ArrayList lockGeometryList = new ArrayList(5);
/**
* arraylist of dlist that will be rebuilt
*/
ArrayList dlistLockList = new ArrayList(5);
// Background node that contains geometry
BackgroundRetained geometryBackground = null;
// background geometry processing
LightBin bgOpaqueBin = null;
LightBin bgAddOpaqueBin = null;
ArrayList bgOrderedBins = new ArrayList(5);
TransparentRenderingInfo bgTransparentInfo;
// vworldToVpc for background geometry
Transform3D infVworldToVpc = new Transform3D();
// true if vpcToVworld has been modified
boolean vpcToVworldDirty = true;
// current active background
BackgroundRetained currentActiveBackground = new BackgroundRetained();
// Flag to indicate that alternate app is dirty
boolean altAppearanceDirty = true;
// List of node components that need special processing, due to
// extensions
ArrayList nodeComponentList = new ArrayList(5);
// List of node components ***for this frame*** that need special
// processing due to extension
ArrayList newNodeComponentList = new ArrayList(5);
ArrayList removeNodeComponentList = new ArrayList(5);
ArrayList dirtyNodeComponentList = new ArrayList(5);
ArrayList textureBinList = new ArrayList(5);
/**
* arraylist of refernce geometry that should be locked when transparency
* is on, so that we can make a mirror copy of the colors safely
*/
ArrayList dirtyReferenceGeomList = new ArrayList(5);
// list of all Oriented RenderAtoms
ArrayList orientedRAs = new ArrayList(5);
// list of Oriented RenderAtoms whose orientedTransforms require update
ArrayList dirtyOrientedRAs = new ArrayList(5);
// Cached copy of dirty oriented RAs to be updated in MasterControl
ArrayList cachedDirtyOrientedRAs = null;
// list of offScreen message that
ArrayList offScreenMessage = new ArrayList(5);
// Vector used for locale translation
Vector3d localeTranslation = new Vector3d();
// Separate dlists that were added/removed in this snapshot
private HashSet addDlist = new HashSet();
private HashSet removeDlist = new HashSet();
// Separate dlists per rinfo that were added/removed in this snapshot
ArrayList addDlistPerRinfo = new ArrayList(5);
ArrayList removeDlistPerRinfo = new ArrayList(5);
Locale locale = null;
// Set to true if locale changes as part of UPDATE_VIEW message
boolean localeChanged = false;
// Cached copy to be used by all RenderMolecules
DisplayListRenderMethod dlistRenderMethod = null;
// Need to query BHTree again with visibility policy change
boolean reactivateView = false;
/**
* A flag indicates that the cached visible GeometryAtoms for this RenderBin might
* be invalid.
*/
private boolean visGAIsDirty = false;
/**
* A flag indicates that a visibility query to the GeometryStructure is needed.
*/
private boolean visQuery = false;
// Temporary dirtylist
ArrayList dirtyList = new ArrayList(5);
// Transaprency sort mode
int transpSortMode = View.TRANSPARENCY_SORT_NONE;
int cachedTranspSortMode = View.TRANSPARENCY_SORT_NONE;
// Temporary dirtylist
private LinkedHashSet dirtyDepthSortRenderAtom = new LinkedHashSet();
private int numDirtyTinfo = 0;
// Eye position in vworld
Point3d eyeInVworld = new Point3d();
// Number of RenderAtomListInfo in the depthSortedList
int nElements = 0;
/**
* Constructs a new RenderBin
*/
RenderBin(VirtualUniverse u, View v) {
super(u, J3dThread.UPDATE_RENDER);
vworldToVpc.setIdentity();
universe = u;
view = v;
transpSortMode = v.transparencySortingPolicy;
cachedTranspSortMode = v.transparencySortingPolicy;
maxLights = VirtualUniverse.mc.maxLights;
ViewPlatform vp = view.getViewPlatform();
if (vp != null) {
locale = ((ViewPlatformRetained) (vp.retained)).locale;
}
dlistRenderMethod = (DisplayListRenderMethod)
VirtualUniverse.mc.getDisplayListRenderMethod();
}
/**
* updateObject
*/
@Override
public void updateObject() {
int i, j, k;
RenderAtomListInfo ra;
LightBin tmp;
ObjectUpdate ob;
OrderedBin orderBin;
int size;
// System.err.println("dirtyRenderMoleculeList.size = "+dirtyRenderMoleculeList.size());
// System.err.println("reEvaluateBg = "+reEvaluateBg);
// System.err.println("reEvaluateClip = "+reEvaluateClip);
// System.err.println("<========+End All Cached Values===========>");
// Add the new lightBins that have been created
// System.err.println("objUpdateList.size = "+objUpdateList.size());
// System.err.println("addOpaqueBin = "+addOpaqueBin);
// System.err.println("opaqueBin = "+opaqueBin);
// List of renderMolecule from which renderAtoms have been removed
size = removeRenderAtomInRMList.size();
if (size > 0) {
RenderMolecule[] rmArr = (RenderMolecule[])
removeRenderAtomInRMList.toArray(false);
for (i=0 ; i 0) {
for (i = 0 ; i < size; i++) {
orderBin = obList.get(i);
orderBin.addRemoveOrderedCollection();
}
}
size = ogCIOList.size();
if(size > 0) {
for(i=0; i 0 ) {
for (i = 0; i < size; i++) {
ArrayList obs = orderedBinsList.get(i);
ArrayList list = toBeAddedBinList.get(i);
int lSize = list.size();
for (j = 0; j < lSize; j++) {
obs.add(list.get(j));
}
}
}
size = raLocaleVwcBoundsUpdateList.size();
if ( size > 0) {
RenderAtom renderAtom;
for (i = 0; i < size; i++) {
renderAtom = raLocaleVwcBoundsUpdateList.get(i);
renderAtom.updateLocaleVwcBounds();
}
}
if ((size = aBinUpdateList.size()) > 0) {
for (i = 0; i < size; i++) {
AttributeBin abin = aBinUpdateList.get(i);
abin.updateNodeComponent();
}
}
if ((size = sBinUpdateList.size()) > 0) {
for (i = 0; i < size; i++) {
ShaderBin sbin = sBinUpdateList.get(i);
sbin.updateNodeComponent();
}
}
// Update the sole user TextureBins.
if (tbUpdateList.size() > 0) {
TextureBin tb;
size = tbUpdateList.size();
for (i = 0; i < size; i++) {
tb = tbUpdateList.get(i);
tb.updateNodeComponent();
}
// do another pass to re-sort TextureBin based on the
// texture in the first texture unit state
for (i = 0; i < size; i++) {
tb = tbUpdateList.get(i);
// Bug Id : 4701430 - Have to be sure tb.shaderBin is
// not equal to null. This is a temporary fix for j3d1.3.
if (((tb.tbFlag & TextureBin.RESORT) != 0) &&
(tb.shaderBin != null)) {
tb.shaderBin.reInsertTextureBin(tb);
tb.tbFlag &= ~TextureBin.RESORT;
}
}
}
// Update the soleUser node components first
// This way material equivalence during insertion
// of new RMs is based on the updated ones
if ((size = rmUpdateList.size()) > 0) {
for (i = 0; i < size; i++) {
RenderMolecule rm = rmUpdateList.get(i);
boolean changeLists = rm.updateNodeComponent();
// If an existing rm went from opaque to transparent or vice-versa
// and has not been removed, then switch the RM
if (changeLists && rm.textureBin != null) {
rm.textureBin.changeLists(rm);
}
}
for (i = 0; i < size; i++) {
rmUpdateList.get(i).reEvaluateEquivalence();
}
}
size = objUpdateList.size();
if ( size > 0) {
for (i = 0; i < size; i++) {
ob = objUpdateList.get(i);
ob.updateObject();
}
}
size = dirtyReferenceGeomList.size();
if ( size > 0) {
GeometryArrayRetained geo;
Canvas3D canvases[] = view.getCanvases();
for (i = 0; i < size; i++) {
geo = dirtyReferenceGeomList.get(i);
// Evaluate the nodeComponentList for all the canvases
geo.geomLock.getLock();
j = 0;
// Do the setup only once{if necessary} for each geometry
boolean found = false;
while(j < canvases.length && !found) {
if ((geo.vertexFormat & GeometryArray.INTERLEAVED) != 0) {
geo.setupMirrorInterleavedColorPointer(true);
found = true;
}
else {
geo.setupMirrorColorPointer((geo.vertexType & GeometryArrayRetained.COLOR_DEFINED),true);
found = true;
}
j++;
}
geo.geomLock.unLock();
}
}
if (reEvaluateBg) {
setBackground(currentActiveBackground);
}
size = textureBinList.size();
//System.err.println("textureBinList.size= " + size);
if (size > 0) {
Canvas3D canvasList[][] = view.getCanvasList(false);
Canvas3D cv;
boolean useSharedCtx = false;
TextureRetained texture;
// do a quick check to see if there is any canvas using
// shared context
for (j = 0; j < canvasList.length && !useSharedCtx; j++) {
cv = canvasList[j][0];
if (cv.useSharedCtx) {
useSharedCtx = true;
}
}
for (int m = 0; m 0) {
//System.err.println("newNodeComponentlist.size= " + size);
Canvas3D canvases[] = view.getCanvases();
for (i = 0; i < size; i++) {
// Evaluate the nodeComponentList for all the canvases
ImageComponentRetained nc = (ImageComponentRetained)newNodeComponentList.get(i);
if (nc.isByReference()) {
nc.geomLock.getLock();
for (j = 0; j 0) {
for (i = 0; i < size; i++) {
nodeComponentList.remove(removeNodeComponentList.get(i));
}
}
// reevaluate dirty node component
size = dirtyNodeComponentList.size();
if (size > 0) {
Canvas3D canvases[] = view.getCanvases();
for (i = 0; i < size; i++) {
// Evaluate the nodeComponentList for all the canvases
ImageComponentRetained nc =
(ImageComponentRetained)dirtyNodeComponentList.get(i);
if (nc.isByReference()) {
nc.geomLock.getLock();
for (j = 0; j 1);
// renderBin is ready now, so send the offScreen message
size = offScreenMessage.size();
if ( size > 0) {
for (i=size-1; i>=0; i--) {
J3dMessage m = offScreenMessage.get(i);
m.threads = J3dThread.RENDER_THREAD;
((Canvas3D)m.args[0]).screen.renderer.rendererStructure.addMessage(m);
// the above call will increment the reference count again
m.decRefcount();
}
}
// called from renderBin when there are dirtyOrientedRAs
// This routin cache the dirtyOrintedRAs to be updated
// by mastercontrol
if (dirtyOrientedRAs.size() > 0) {
// Keep a copy to be handled by mastercontrol
cachedDirtyOrientedRAs = new ArrayList(dirtyOrientedRAs);
}
boolean sortAll = false;
if (reEvaluateSortMode && transpSortMode != cachedTranspSortMode) {
convertTransparentRenderingStruct(transpSortMode, cachedTranspSortMode);
transpSortMode = cachedTranspSortMode;
if (transpSortMode == View.TRANSPARENCY_SORT_GEOMETRY) {
if (transparentInfo != null){
sortAll = true;
}
}
}
if (vpcToVworldDirty) {
vworldToVpc.invert(vpcToVworld);
// Have the send down the lights, so set the canvas
// lightbin to null
Canvas3D canvases[] = view.getCanvases();
for (i = 0; i < canvases.length; i++) {
canvases[i].lightBin = null;
}
if (canvases.length > 0) {
Transform3D xform;
canvases[0].getCenterEyeInImagePlate(eyeInVworld);
// xform is imagePlateToLocal
xform = canvases[0].canvasViewCache.getImagePlateToVworld();
xform.transform(eyeInVworld);
}
if (transpSortMode == View.TRANSPARENCY_SORT_GEOMETRY && transparentInfo != null) {
// System.err.println("sortAll 1");
sortAll = true;
}
}
size = dirtyDepthSortRenderAtom.size();
if (sortAll || size > 0) {
int tsize = allTransparentObjects.size();
double zVal;
for (i = 0; i < tsize; i++) {
RenderAtom renderAtom = (RenderAtom)allTransparentObjects.get(i);
for (k = 0; k < renderAtom.rListInfo.length; k++) {
if (renderAtom.rListInfo[k].geometry() == null)
continue;
zVal = renderAtom.geometryAtom.centroid[k].distanceSquared(eyeInVworld);
renderAtom.parentTInfo[k].zVal = zVal;
renderAtom.parentTInfo[k].geometryAtom = renderAtom.geometryAtom;
}
}
// Check to see if a majority of the transparent Objects have changed
// If less than 66% of all transparentStructs are dirty
// then, remove and insert, otherwise resort everything
if (size > 0 && 1.5f * numDirtyTinfo > nElements) {
// System.err.println("sortAll 3, size = "+size);
sortAll = true;
}
if (size > 0) {
TransparentRenderingInfo dirtyList = null;
Iterator dirtyDepthSortIterator = dirtyDepthSortRenderAtom.iterator();
while (dirtyDepthSortIterator.hasNext()) {
RenderAtom renderAtom = dirtyDepthSortIterator.next();
if (!renderAtom.inRenderBin())
continue;
renderAtom.dirtyMask &= ~RenderAtom.IN_SORTED_POS_DIRTY_TRANSP_LIST;
if (!sortAll) {
dirtyList = collectDirtyTRInfo(dirtyList, renderAtom);
}
}
if (dirtyList != null) {
// System.err.println("====> sort Some");
dirtyList = depthSortAll(dirtyList);
// Now merge the newly sorted list with the old one
transparentInfo = mergeDepthSort(transparentInfo, dirtyList);
}
}
// Sort all the transparent renderAtoms
if (sortAll) {
transparentInfo = depthSortAll(transparentInfo);
}
}
// Remove entries that are found on both the add and remove lists
if (addDlist.size() > 0 && removeDlist.size() > 0) {
RenderAtomListInfo arr[] = new RenderAtomListInfo[addDlist.size()];
arr = addDlist.toArray(arr);
for (i = 0; i < arr.length; i++) {
if (removeDlist.contains(arr[i])) {
addDlist.remove(arr[i]);
removeDlist.remove(arr[i]);
}
}
}
if (addDlist.size() > 0 || removeDlist.size() > 0) {
Canvas3D canvasList[][] = view.getCanvasList(false);
Canvas3D cv;
ArrayList rlist = new ArrayList(5);
for (i = 0; i < canvasList.length; i++) {
cv = canvasList[i][0];
if (cv.useSharedCtx) {
// Do this only once per renderer for this view
if (!rlist.contains(cv.screen.renderer)) {
rlist.add(cv.screen.renderer);
updateDlistRendererResource(cv.screen.renderer);
}
} else {
updateDlistCanvasResource(canvasList[i]);
}
}
}
if (dirtyRenderMoleculeList.size() > 0 ||
addDlistPerRinfo.size() > 0 ||
removeDlistPerRinfo.size() > 0 ||
displayListResourceFreeList.size() > 0 ||
toBeAddedTextureResourceFreeList.size() > 0 ) {
Canvas3D canvasList[][] = view.getCanvasList(false);
Canvas3D cv;
for (i = 0; i < canvasList.length; i++) {
cv = canvasList[i][0];
if (cv.useSharedCtx && (cv.screen.renderer != null)) {
updateRendererResource(cv.screen.renderer);
} else {
updateCanvasResource(canvasList[i]);
}
}
Integer id;
size = displayListResourceFreeList.size();
for (i = 0; i < size; i++) {
id = displayListResourceFreeList.get(i);
VirtualUniverse.mc.freeDisplayListId(id);
}
// lock list of dlist
// XXXX: Instead of copying could we keep 2 arrays
// and just toggle?
size = dirtyRenderMoleculeList.size();
for (i = 0; i < size; i++) {
RenderMolecule rm = dirtyRenderMoleculeList.get(i);
rm.onUpdateList = 0;
ra = rm.primaryRenderAtomList;
while (ra != null) {
dlistLockList.add(ra.geometry());
ra = ra.next;
}
}
size = addDlistPerRinfo.size();
for (i = 0; i < size; i++) {
ra = addDlistPerRinfo.get(i);
if (ra.geometry() != null) {
dlistLockList.add(ra.geometry());
}
}
}
clearAllUpdateObjectState();
/*
if (opaqueBin != null) {
System.err.println(this + "***** Begin Dumping OpaqueBin *****");
dumpBin(opaqueBin);
System.err.println("***** End Dumping OpaqueBin *****");
}
*/
}
// Shared context case
void updateDlistRendererResource(Renderer rdr) {
int i;
int size = 0;
RenderAtomListInfo arr[];
RenderAtomListInfo ra;
// XXXX: there is a possible problem in the case of multiple
// renderers (i.e., multiple screens). Unless the
// MasterControl sends us a separate message for each
// renderer, we won't create a new display list for renderers
// other than the one passed into this method.
if (rdr == null) {
return;
}
if ((size = addDlist.size()) > 0) {
arr = new RenderAtomListInfo[size];
arr = addDlist.toArray(arr);
for (i = 0; i < size; i++) {
ra = arr[i];
GeometryArrayRetained geo = (GeometryArrayRetained)ra.geometry();
// First time thru this renderer or the context that
// it is built for no longer matches the context
// used in the renderer, create a dlist
sharedDList.add(ra);
geo.addDlistUser(this, ra);
if (((geo.resourceCreationMask & rdr.rendererBit) == 0) ||
(geo.getDlistTimeStamp(rdr.rendererBit) !=
rdr.sharedCtxTimeStamp)) {
geo.resourceCreationMask |= rdr.rendererBit;
dirtyList.add(ra);
}
}
}
if ((size = removeDlist.size()) > 0) {
arr = new RenderAtomListInfo[size];
arr = removeDlist.toArray(arr);
for (i = 0; i < size; i++) {
ra = arr[i];
sharedDList.remove(ra);
GeometryArrayRetained geo = (GeometryArrayRetained)ra.geometry();
geo.removeDlistUser(this, ra);
// System.err.println("========> geo.refcount = "+geo.refCount);
// add this geometry's dlist to be freed
if (geo.isDlistUserSetEmpty(this)) {
rdr.displayListResourceFreeList.add(geo.dlistObj);
geo.resourceCreationMask &= ~rdr.rendererBit;
// All Dlist on all renderer have been freed, then return dlistID
if (geo.resourceCreationMask == 0) {
geo.freeDlistId();
}
}
}
}
if ((size = dirtyList.size()) > 0) {
for (i = 0; i < size; i++) {
ra = dirtyList.get(i);
GeometryArrayRetained geo = (GeometryArrayRetained)ra.geometry();
if ( (geo.resourceCreationMask & rdr.rendererBit) != 0) {
rdr.dirtyRenderAtomList.add(ra);
}
}
rdr.dirtyDisplayList = true;
dirtyList.clear();
}
}
// Non-shared context case
void updateDlistCanvasResource(Canvas3D[] canvases) {
int i, j;
Canvas3D cv;
int size = 0;
RenderAtomListInfo arr[];
RenderAtomListInfo ra;
// Add the newly added dlist to the sharedList
if ((size = addDlist.size()) > 0) {
arr = new RenderAtomListInfo[size];
arr = addDlist.toArray(arr);
for (i = 0; i 0) {
arr = new RenderAtomListInfo[size];
arr = removeDlist.toArray(arr);
for (i = 0; i < size; i++) {
sharedDList.remove(arr[i]);
// Fix for Issue 5: remove this render atom from the list of users
// of its geometry for this RenderBin
GeometryArrayRetained geo = (GeometryArrayRetained) arr[i].geometry();
geo.removeDlistUser(this, arr[i]);
}
}
// add to the dirty list per canvas
for (j = 0; j < canvases.length; j++) {
cv = canvases[j];
if ((size = addDlist.size()) > 0) {
arr = new RenderAtomListInfo[size];
arr = addDlist.toArray(arr);
for (i = 0; i 0) {
arr = new RenderAtomListInfo[size];
arr = removeDlist.toArray(arr);
for (i = 0; i < size; i++) {
GeometryArrayRetained geo =
(GeometryArrayRetained) arr[i].geometry();
// add this geometry's dlist to be freed
if (geo.isDlistUserSetEmpty(this)) {
if (cv.ctx != null) {
canvases[j].displayListResourceFreeList.add(geo.dlistObj);
}
geo.resourceCreationMask &= ~canvases[j].canvasBit;
// All Dlist on all canvases have been freed, then return dlistID
if (geo.resourceCreationMask == 0)
geo.freeDlistId();
}
}
}
if ((size = dirtyList.size()) > 0) {
for (i = 0; i 0) {
for (int j = 0; j < size; j++) {
RenderAtomListInfo rinfo = addDlistPerRinfo.get(j);
if (rinfo.renderAtom.inRenderBin()) {
Object[] obj = new Object[2];
obj[0] = rinfo;
obj[1] = rinfo.renderAtom.renderMolecule;
rdr.dirtyDlistPerRinfoList.add(obj);
}
}
rdr.dirtyDisplayList = true;
}
// Take care of display lists that should be rebuilt
size = dirtyRenderMoleculeList.size();
if (size > 0) {
for (int j = 0; j < size; j++) {
rm = dirtyRenderMoleculeList.get(j);
rdr.dirtyRenderMoleculeList.add(rm);
}
rdr.dirtyDisplayList = true;
}
// Take care of texture that should be freed
size = toBeAddedTextureResourceFreeList.size();
int id;
for (int j=0; j < size; j++) {
tex = toBeAddedTextureResourceFreeList.get(j);
id = tex.objectId;
if ((id >= rdr.textureIDResourceTable.size()) ||
(id <= 0) ||
(rdr.textureIDResourceTable.get(id) != tex)) {
// tex.objectId may change by another Renderer thread,
// need find original texID from searching
// rdr.textureIdResourceTable
id = rdr.textureIDResourceTable.indexOf(tex);
if (id <= 0) {
continue;
}
}
// Since multiple renderBins (in the same screen)
// can share a texture object, make sure that
// we are not duplicating what has been added
// by a different renderBin in the same screen
if ((tex.resourceCreationMask & rdr.rendererBit) != 0) {
texIdObj = new Integer(id);
if (!rdr.textureIdResourceFreeList.contains(texIdObj)) {
rdr.textureIdResourceFreeList.add(texIdObj);
tex.resourceCreationMask &= ~rdr.rendererBit;
}
}
}
// Take care of display list that should be freed
size = displayListResourceFreeList.size();
Integer displayListIDObj;
for (int j=0; j 0) {
for ( j = 0; j < size; j++) {
RenderAtomListInfo rinfo = addDlistPerRinfo.get(j);
if (rinfo.renderAtom.inRenderBin()) {
Object[] obj = new Object[2];
obj[0] = rinfo;
obj[1] = rinfo.renderAtom.renderMolecule;
cv.dirtyDlistPerRinfoList.add(obj);
}
}
cv.dirtyDisplayList = true;
}
// Take care of display lists that should be rebuilt
size = dirtyRenderMoleculeList.size();
if (size > 0) {
for (j = 0; j < size; j++) {
rm = dirtyRenderMoleculeList.get(j);
cv.dirtyRenderMoleculeList.add(rm);
}
cv.dirtyDisplayList = true;
}
// Take care of texture that should be freed
size = toBeAddedTextureResourceFreeList.size();
int id;
for (j=0; j < size; j++) {
tex = toBeAddedTextureResourceFreeList.get(j);
id = tex.objectId;
if ((id >= cv.textureIDResourceTable.size()) ||
(id <= 0) ||
(cv.textureIDResourceTable.get(id) != tex)) {
// tex.objectId may change by another Renderer thread,
// need find original texID from searching
// rdr.textureIdResourceTable
id = cv.textureIDResourceTable.indexOf(tex);
if (id <= 0) {
continue;
}
}
if ((tex.resourceCreationMask & cv.canvasBit) != 0) {
texIdObj = new Integer(id);
cv.textureIdResourceFreeList.add(texIdObj);
tex.resourceCreationMask &= ~cv.canvasBit;
}
}
// Take care of display list that should be freed
size = displayListResourceFreeList.size();
for (j=0; j < size; j++) {
cv.displayListResourceFreeList.add(displayListResourceFreeList.get(j));
}
// Take care of display list that should be freed
size = removeDlistPerRinfo.size();
for (j=0; j < size; j++) {
RenderAtomListInfo ra = removeDlistPerRinfo.get(j);
cv.displayListResourceFreeList.add(new Integer(ra.renderAtom.dlistIds[ra.index]));
ra.groupType = 0;
ra.renderAtom.dlistIds[ra.index] = -1;
}
}
}
@Override
void processMessages(long referenceTime) {
int i;
J3dMessage messages[], m;
int component;
messages = getMessages(referenceTime);
int nMsg = getNumMessage();
if (nMsg > 0) {
for (i=0; i < nMsg; i++) {
m = messages[i];
switch (m.type) {
case J3dMessage.INSERT_NODES:
insertNodes(m);
m.decRefcount();
break;
case J3dMessage.REMOVE_NODES:
removeNodes(m);
m.decRefcount();
break;
case J3dMessage.TRANSFORM_CHANGED:
transformMsg = true;
m.decRefcount();
break;
case J3dMessage.LIGHT_CHANGED:
// if none of the mirror lights are scoped to this view
// ignore this message
LightRetained[] mLts =(LightRetained[])m.args[3] ;
for (int k = 0; k < mLts.length; k++) {
if (universe.renderingEnvironmentStructure.isLightScopedToThisView(mLts[k], view)) {
lightMessageList.add(m);
break;
}
}
break;
case J3dMessage.SWITCH_CHANGED:
visGAIsDirty = true;
visQuery = true;
processSwitchChanged(m, referenceTime);
// may need to process dirty switched-on transform
if (universe.transformStructure.getLazyUpdate()) {
transformMsg = true;
}
m.decRefcount();
break;
case J3dMessage.BACKGROUND_CHANGED:
BackgroundRetained bg = (BackgroundRetained)m.args[0];
if (universe.renderingEnvironmentStructure.isBgScopedToThisView(bg, view)) {
reEvaluateBg = true;
reloadBgTexture = true;
}
m.decRefcount();
break;
case J3dMessage.CLIP_CHANGED:
ClipRetained c = (ClipRetained)m.args[0];
if (universe.renderingEnvironmentStructure.isClipScopedToThisView(c, view))
reEvaluateClip = true;
m.decRefcount();
break;
case J3dMessage.TRANSPARENCYATTRIBUTES_CHANGED:
{
NodeComponentRetained nc = (NodeComponentRetained) m.args[0];
GeometryAtom[] gaArr = (GeometryAtom[])m.args[3];
RenderAtom ra = null;
int start = -1;
// Get the first ra that is visible
for (int k = 0; (k < gaArr.length && (start < 0)); k++) {
ra = gaArr[k].getRenderAtom(view);
if (ra== null || !ra.inRenderBin()) {
continue;
}
else {
start = k;
}
}
if (start >= 0) {
boolean restructure = (nc.mirror.changedFrequent == 0 ||
ra.renderMolecule.definingTransparency != nc.mirror);
processRenderMoleculeNodeComponentChanged(m.args,
RenderMolecule.TRANSPARENCY_DIRTY,
start, restructure);
}
m.decRefcount();
break;
}
case J3dMessage.POLYGONATTRIBUTES_CHANGED:
{
NodeComponentRetained nc = (NodeComponentRetained) m.args[0];
GeometryAtom[] gaArr = (GeometryAtom[])m.args[3];
RenderAtom ra = null;
int start = -1;
// Get the first ra that is visible
// Get the first ra that is visible
for (int k = 0; (k < gaArr.length && (start < 0)); k++) {
ra = gaArr[k].getRenderAtom(view);
if (ra== null || !ra.inRenderBin()) {
continue;
}
else {
start = k;
}
}
if (start >= 0) {
boolean restructure = (nc.mirror.changedFrequent == 0 ||
ra.renderMolecule.definingPolygonAttributes != nc.mirror);
processRenderMoleculeNodeComponentChanged(m.args,
RenderMolecule.POLYGONATTRS_DIRTY,
start, restructure);
}
m.decRefcount();
break;
}
case J3dMessage.LINEATTRIBUTES_CHANGED:
{
NodeComponentRetained nc = (NodeComponentRetained) m.args[0];
GeometryAtom[] gaArr = (GeometryAtom[])m.args[3];
RenderAtom ra = null;
int start = -1;
// Get the first ra that is visible
// Get the first ra that is visible
for (int k = 0; (k < gaArr.length && (start < 0)); k++) {
ra = gaArr[k].getRenderAtom(view);
if (ra== null || !ra.inRenderBin()) {
continue;
}
else {
start = k;
}
}
if (start >= 0) {
boolean restructure = (nc.mirror.changedFrequent == 0 ||
ra.renderMolecule.definingLineAttributes != nc.mirror);
processRenderMoleculeNodeComponentChanged(m.args,
RenderMolecule.LINEATTRS_DIRTY,
start, restructure);
}
m.decRefcount();
break;
}
case J3dMessage.POINTATTRIBUTES_CHANGED:
{
NodeComponentRetained nc = (NodeComponentRetained) m.args[0];
GeometryAtom[] gaArr = (GeometryAtom[])m.args[3];
RenderAtom ra = null;
int start = -1;
// Get the first ra that is visible
// Get the first ra that is visible
for (int k = 0; (k < gaArr.length && (start < 0)); k++) {
ra = gaArr[k].getRenderAtom(view);
if (ra== null || !ra.inRenderBin()) {
continue;
}
else {
start = k;
}
}
if (start >= 0) {
boolean restructure = (nc.mirror.changedFrequent == 0 ||
ra.renderMolecule.definingPointAttributes != nc.mirror);
processRenderMoleculeNodeComponentChanged(m.args,
RenderMolecule.POINTATTRS_DIRTY,
start, restructure);
}
m.decRefcount();
break;
}
case J3dMessage.MATERIAL_CHANGED:
{
NodeComponentRetained nc = (NodeComponentRetained) m.args[0];
GeometryAtom[] gaArr = (GeometryAtom[])m.args[3];
RenderAtom ra = null;
int start = -1;
// Get the first ra that is visible
// Get the first ra that is visible
for (int k = 0; (k < gaArr.length && (start < 0)); k++) {
ra = gaArr[k].getRenderAtom(view);
if (ra== null || !ra.inRenderBin()) {
continue;
}
else {
start = k;
}
}
if (start >= 0) {
boolean restructure = (nc.mirror.changedFrequent == 0 ||
ra.renderMolecule.definingMaterial != nc.mirror);
processRenderMoleculeNodeComponentChanged(m.args,
RenderMolecule.MATERIAL_DIRTY,
start, restructure);
}
m.decRefcount();
break;
}
case J3dMessage.COLORINGATTRIBUTES_CHANGED:
{
NodeComponentRetained nc = (NodeComponentRetained) m.args[0];
GeometryAtom[] gaArr = (GeometryAtom[])m.args[3];
RenderAtom ra = null;
int start = -1;
// Get the first ra that is visible
// Get the first ra that is visible
for (int k = 0; (k < gaArr.length && (start < 0)); k++) {
ra = gaArr[k].getRenderAtom(view);
if (ra== null || !ra.inRenderBin()) {
continue;
}
else {
start = k;
}
}
if (start >= 0) {
boolean restructure = (nc.mirror.changedFrequent == 0 ||
ra.renderMolecule.definingColoringAttributes != nc.mirror);
processRenderMoleculeNodeComponentChanged(m.args,
RenderMolecule.COLORINGATTRS_DIRTY,
start, restructure);
}
m.decRefcount();
break;
}
case J3dMessage.TEXTUREATTRIBUTES_CHANGED:
processTextureAttributesChanged(
(NodeComponentRetained) m.args[0],
(GeometryAtom[])m.args[3]);
m.decRefcount();
break;
case J3dMessage.IMAGE_COMPONENT_CHANGED:
addDirtyNodeComponent((NodeComponentRetained)m.args[0]);
m.decRefcount();
break;
case J3dMessage.TEXTURE_UNIT_STATE_CHANGED:
processTextureUnitStateChanged(
(NodeComponentRetained) m.args[0],
(GeometryAtom[])m.args[3]);
m.decRefcount();
break;
case J3dMessage.TEXCOORDGENERATION_CHANGED:
processTexCoordGenerationChanged( (NodeComponentRetained) m.args[0],
(GeometryAtom[])m.args[3]);
m.decRefcount();
break;
case J3dMessage.TEXTURE_CHANGED:
// Texture is always in a sole user position
processTextureChanged((NodeComponentRetained) m.args[0],
(GeometryAtom[])m.args[3],
m.args);
m.decRefcount();
break;
case J3dMessage.SHADER_APPEARANCE_CHANGED:
case J3dMessage.SHADER_ATTRIBUTE_SET_CHANGED:
case J3dMessage.SHADER_ATTRIBUTE_CHANGED:
processShaderComponentChanged(m.args);
m.decRefcount();
break;
case J3dMessage.RENDERINGATTRIBUTES_CHANGED:
processAttributeBinNodeComponentChanged(m.args);
component = ((Integer)m.args[1]).intValue();
if (component == RenderingAttributesRetained.VISIBLE) {
visGAIsDirty = true;
visQuery = true;
}
m.decRefcount();
break;
case J3dMessage.APPEARANCE_CHANGED:
processAppearanceChanged(m.args);
m.decRefcount();
break;
case J3dMessage.FOG_CHANGED:
FogRetained mfog = ((FogRetained)m.args[0]).mirrorFog;
if (universe.renderingEnvironmentStructure.isFogScopedToThisView(mfog, view)) {
processFogChanged(m.args);
}
m.decRefcount();
break;
case J3dMessage.ALTERNATEAPPEARANCE_CHANGED:
AlternateAppearanceRetained maltapp = ((AlternateAppearanceRetained)m.args[0]).mirrorAltApp;
if (universe.renderingEnvironmentStructure.isAltAppScopedToThisView(maltapp, view)) {
altAppearanceDirty = true;
}
m.decRefcount();
break;
case J3dMessage.MODELCLIP_CHANGED:
ModelClipRetained mc= ((ModelClipRetained)m.args[0]).mirrorModelClip;
if (universe.renderingEnvironmentStructure.isMclipScopedToThisView(mc, view)) {
processModelClipChanged(m.args);
}
m.decRefcount();
break;
case J3dMessage.BOUNDINGLEAF_CHANGED:
processBoundingLeafChanged(m.args,
referenceTime);
m.decRefcount();
break;
case J3dMessage.SHAPE3D_CHANGED:
processShapeChanged(m.args, referenceTime);
m.decRefcount();
break;
case J3dMessage.ORIENTEDSHAPE3D_CHANGED:
processOrientedShape3DChanged((Object[])m.args[0]);
m.decRefcount();
break;
case J3dMessage.MORPH_CHANGED:
processMorphChanged(m.args, referenceTime);
component = ((Integer)m.args[1]).intValue();
if ((component & MorphRetained.GEOMETRY_CHANGED) == 0) {
visGAIsDirty = true;
visQuery = true;
}
m.decRefcount();
break;
case J3dMessage.UPDATE_VIEW:
{
View v = (View)m.args[0];
ViewPlatform vp = v.getViewPlatform();
int comp = ((Integer)(m.args[2])).intValue();
int value = ((Integer)(m.args[3])).intValue();
if (comp == View.TRANSP_SORT_POLICY_CHANGED) {
if (value != transpSortMode) {
reEvaluateSortMode = true;
cachedTranspSortMode = value;
}
} else if (vp != null) {
if (value != transpSortMode) {
reEvaluateSortMode = true;
cachedTranspSortMode = value;
}
updateViewPlatform((ViewPlatformRetained)vp.retained,
((Float)m.args[1]).floatValue());
visQuery = true;
// XXXX : Handle view.visibilityPolicy changed.
if(((View.VISIBILITY_POLICY_DIRTY != 0) &&
(View.VISIBILITY_DRAW_ALL != view.viewCache.visibilityPolicy)) ||
locale != ((ViewPlatformRetained) (vp.retained)).locale) {
for (int n = (renderAtoms.size() - 1); n>=0 ; n--) {
removeARenderAtom(renderAtoms.get(n));
}
renderAtoms.clear();
visGAIsDirty = true;
if (locale != ((ViewPlatformRetained) (vp.retained)).locale) {
locale = ((ViewPlatformRetained) (vp.retained)).locale;
localeChanged = true;
}
}
}
m.decRefcount();
}
break;
case J3dMessage.UPDATE_VIEWPLATFORM:
updateViewPlatform((ViewPlatformRetained) m.args[0],
((Float)m.args[1]).floatValue());
m.decRefcount();
break;
case J3dMessage.TEXT3D_DATA_CHANGED:
processDataChanged((Object[])m.args[0],
(Object[])m.args[1],
referenceTime);
m.decRefcount();
break;
case J3dMessage.GEOMETRY_CHANGED:
processGeometryChanged(m.args);
visGAIsDirty = true;
visQuery = true;
m.decRefcount();
break;
case J3dMessage.BOUNDS_AUTO_COMPUTE_CHANGED:
case J3dMessage.REGION_BOUND_CHANGED:
processGeometryAtomsChanged((Object[])m.args[0]);
visGAIsDirty = true;
visQuery = true;
m.decRefcount();
break;
case J3dMessage.TEXT3D_TRANSFORM_CHANGED:
processText3DTransformChanged((Object[])m.args[0],
(Object[])m.args[1],
referenceTime);
visQuery = true;
m.decRefcount();
break;
case J3dMessage.ORDERED_GROUP_INSERTED:
processOrderedGroupInserted(m);
// Do not do decRefcount() here. We'll do it in updateObject().
ogCIOList.add(m);
break;
case J3dMessage.ORDERED_GROUP_REMOVED:
processOrderedGroupRemoved(m);
// Do not do decRefcount() here. We'll do it in updateObject().
ogCIOList.add(m);
break;
case J3dMessage.ORDERED_GROUP_TABLE_CHANGED:
// Do not do decRefcount() here. We'll do it in updateObject().
ogCIOList.add(m);
break;
case J3dMessage.RENDER_OFFSCREEN:
offScreenMessage.add(m);
break;
case J3dMessage.VIEWSPECIFICGROUP_CHANGED:
processViewSpecificGroupChanged(m);
visQuery = true;
m.decRefcount();
break;
default:
m.decRefcount();
}
}
if (transformMsg) {
processTransformChanged(referenceTime);
transformMsg = false;
}
if (lightMessageList.size() > 0) {
processLightChanged();
lightMessageList.clear();
}
VirtualUniverse.mc.addMirrorObject(this);
// clear the array to prevent memory leaks
Arrays.fill(messages, 0, nMsg, null);
}
if (reEvaluateBg) {
currentActiveBackground = universe.renderingEnvironmentStructure.
getApplicationBackground(vpSchedSphereInVworld, locale, view);
}
if (visQuery) {
GeometryAtom[] bgGeometryAtoms;
boolean allEnComp;
// computeViewFrustumBox in VisibilityStructure.
computeViewFrustumBBox(viewFrustumBBox);
// System.err.println("viewFrustumBBox = " + this);
ViewPlatform vp = view.getViewPlatform();
if (vp != null) {
allEnComp = universe.geometryStructure.
getVisibleBHTrees(this, viewFrustumBBox,
locale, referenceTime,
visGAIsDirty || reactivateView || localeChanged ||
((view.viewCache.vcDirtyMask &
View.VISIBILITY_POLICY_DIRTY) != 0),
view.viewCache.visibilityPolicy);
reactivateView = false;
// process background geometry atoms
if (currentActiveBackground != null &&
currentActiveBackground.geometryBranch != null) {
bgGeometryAtoms =
currentActiveBackground.getBackgroundGeometryAtoms();
if (bgGeometryAtoms != null) {
processBgGeometryAtoms(bgGeometryAtoms, referenceTime);
}
}
if(!allEnComp) {
// Increment the framecount for compaction ...
frameCount++;
if (frameCount > frameCountCutoff) {
frameCount = 0;
checkForCompaction();
}
else if (frameCount == notVisibleCount) {
removeCutoffTime = referenceTime;
}
}
}
// Reset dirty bits.
visGAIsDirty = false;
visQuery = false;
}
// Two environments are dirty
// If lights, fog or model clip have been added/removed, then
// reEvaluate RenderAtoms and mark the lightbin and
// env set dirty if applicable
if (envDirty == REEVALUATE_ALL_ENV || envDirty == 3 ||
envDirty > 4) {
reEvaluateEnv(changedLts, changedFogs, changedModelClips, true,
altAppearanceDirty);
}
else if (envDirty == 0 && altAppearanceDirty) {
reEvaluateAlternateAppearance();
}
else {
if ((envDirty & REEVALUATE_LIGHTS) != 0) {
reEvaluateLights(altAppearanceDirty);
}
else if ((envDirty & REEVALUATE_FOG) != 0)
reEvaluateFog(changedFogs, (changedFogs.size() > 0), altAppearanceDirty);
else if ((envDirty & REEVALUATE_MCLIP) != 0)
reEvaluateModelClip(changedModelClips, (changedModelClips.size() > 0), altAppearanceDirty);
}
// do any pre-update node component screening
if (updateCheckList.size() > 0) {
int size = updateCheckList.size();
for (int k = 0; k < size; k++) {
updateCheckList.get(k).updateNodeComponentCheck();
}
updateCheckList.clear();
}
changedLts.clear();
changedFogs.clear();
changedModelClips.clear();
envDirty = 0;
altAppearanceDirty = false;
view.renderBinReady = true;
VirtualUniverse.mc.sendRunMessage(view,
J3dThread.RENDER_THREAD);
}
void processSwitchChanged(J3dMessage m, long refTime) {
int i;
UnorderList arrList;
int size;
Object[] nodes, nodesArr;
RenderingEnvironmentStructure rdrEnvStr =
universe.renderingEnvironmentStructure;
UpdateTargets targets = (UpdateTargets)m.args[0];
arrList = targets.targetList[Targets.ENV_TARGETS];
if (arrList != null) {
size = arrList.size();
nodesArr = arrList.toArray(false);
for (int h=0; h= 0) {
// Issue 471 - Don't check ATTRIBUTE_VALUE_UPDATE, there is no need
// to do anything to the shader bins when a value changes.
boolean spUpdate =
((component & ShaderAppearanceRetained.SHADER_PROGRAM) != 0);
boolean sasUpdate =
(((component & ShaderAppearanceRetained.SHADER_ATTRIBUTE_SET) != 0) ||
((component & ShaderConstants.ATTRIBUTE_SET_PUT) != 0) ||
((component & ShaderConstants.ATTRIBUTE_SET_REMOVE) != 0) ||
((component & ShaderConstants.ATTRIBUTE_SET_CLEAR) != 0));
if (spUpdate) {
/* TODO : JADA - Sole user logic is incomplete. Will disable for JavaOne */
//if (false && (sApp.mirror.changedFrequent & component) != 0) {
if(false) {
/*
System.err.println("RenderBin : Shader sole user (SHADER_PROGRAM)" +
ra.renderMolecule.textureBin.shaderBin);
*/
ShaderBin sBin;
for (i = start; i < gaArr.length; i++) {
ra = gaArr[i].getRenderAtom(view);
if (ra== null || !ra.inRenderBin())
continue;
sBin = ra.renderMolecule.textureBin.shaderBin;
if (sBin.componentDirty == 0) {
sBinUpdateList.add(sBin);
sBin.componentDirty |= ShaderBin.SHADER_PROGRAM_DIRTY;
}
}
} else {
/*
System.err.println("RenderBin : not soleUser (SHADER_PROGRAM)" +
ra.renderMolecule.textureBin.shaderBin);
*/
for (i = 0; i < gaArr.length; i++) {
ra = gaArr[i].getRenderAtom(view);
if (ra== null || !ra.inRenderBin())
continue;
AttributeBin attrBin = ra.renderMolecule.textureBin.attributeBin;
ra.renderMolecule.removeRenderAtom(ra);
reInsertShaderBin(attrBin, ra);
}
}
} else if (sasUpdate) {
/* TODO : JADA - Sole user logic is incomplete. Will disable for JavaOne */
//if (false && (sApp.mirror.changedFrequent & component) != 0) {
if(false) {
/*
System.err.println("RenderBin : sole user (SHADER_ATTRIBUTE_SET)" +
ra.renderMolecule.textureBin.shaderBin);
*/
ShaderBin sBin;
for (i = 0; i < gaArr.length; i++) {
ra = gaArr[i].getRenderAtom(view);
if (ra== null || !ra.inRenderBin())
continue;
sBin = ra.renderMolecule.textureBin.shaderBin;
if (sBin.componentDirty == 0) {
sBinUpdateList.add(sBin);
sBin.componentDirty |= ShaderBin.SHADER_ATTRIBUTE_SET_DIRTY;
}
}
} else {
/*
System.err.println("RenderBin :not soleUser (SHADER_ATTRIBUTE_SET) " +
ra.renderMolecule.textureBin.shaderBin);
*/
for (i = 0; i < gaArr.length; i++) {
ra = gaArr[i].getRenderAtom(view);
if (ra== null || !ra.inRenderBin())
continue;
AttributeBin attrBin = ra.renderMolecule.textureBin.attributeBin;
ra.renderMolecule.removeRenderAtom(ra);
reInsertShaderBin(attrBin, ra);
}
}
}
}
}
void processFogChanged(Object[] args) {
FogRetained fog = (FogRetained)args[0];
EnvironmentSet e;
int component = ((Integer)args[1]).intValue();
if ((component &(FogRetained.SCOPE_CHANGED |
FogRetained.BOUNDS_CHANGED |
FogRetained.BOUNDINGLEAF_CHANGED)) != 0){
envDirty |= REEVALUATE_FOG;
}
else {
UnorderList list = fog.mirrorFog.environmentSets;
synchronized (list) {
EnvironmentSet envsets[] = (EnvironmentSet []) list.toArray(false);
int size = list.size();
for (int i = 0; i < size; i++) {
e = envsets[i];
e.canvasDirty |= Canvas3D.FOG_DIRTY;
if (!e.onUpdateList) {
objUpdateList.add(e);
e.onUpdateList = true;
}
}
}
}
}
/**
* This routine get called whenever a component of the appearance
* changes
*/
void processAppearanceChanged(Object[] args){
int component = ((Integer)args[1]).intValue();
int i;
GeometryAtom[] gaArr = (GeometryAtom[] )args[3];
RenderAtom ra = null;
AppearanceRetained app = (AppearanceRetained) args[0];
int TEXTURE_STATE_CHANGED =
AppearanceRetained.TEXTURE_UNIT_STATE |
AppearanceRetained.TEXTURE |
AppearanceRetained.TEXTURE_ATTR |
AppearanceRetained.TEXCOORD_GEN ;
int start = -1;
// Get the first ra that is visible
for (i = 0; (i < gaArr.length && (start < 0)); i++) {
ra = gaArr[i].getRenderAtom(view);
if (ra== null || !ra.inRenderBin()) {
continue;
}
else {
start = i;
}
}
if (start >= 0) {
if ((component & TEXTURE_STATE_CHANGED) != 0) {
if (((app.mirror.changedFrequent & TEXTURE_STATE_CHANGED) != 0) &&
((ra.renderMolecule.textureBin.tbFlag &
TextureBin.SOLE_USER) != 0)) {
/*
System.err.println("renderbin. texture state changed tb sole user " +
ra.renderMolecule.textureBin + " tb.tbFlag= " +
ra.renderMolecule.textureBin.tbFlag);
*/
TextureBin tb;
for (i = start; i < gaArr.length; i++) {
ra = gaArr[i].getRenderAtom(view);
if (ra== null || !ra.inRenderBin())
continue;
tb = ra.renderMolecule.textureBin;
if (tb.soleUserCompDirty == 0) {
tbUpdateList.add(tb);
}
// mark that the texture unit state ref is changed
// also mark that the TextureBin needs to reevaluate
// number of active textures
tb.soleUserCompDirty |=
TextureBin.SOLE_USER_DIRTY_REF;
}
} else {
/*
System.err.println("renderbin. texture state changed tb not sole user " +
ra.renderMolecule.textureBin + " tb.tbFlag= " +
ra.renderMolecule.textureBin.tbFlag);
System.err.println("......tb.soleUser= " +
((ra.renderMolecule.textureBin.tbFlag & TextureBin.SOLE_USER) != 0) +
" app.mirror.changedFrequent= " +
((app.mirror.changedFrequent & TEXTURE_STATE_CHANGED) != 0));
*/
for (i = start; i < gaArr.length; i++) {
ra = gaArr[i].getRenderAtom(view);
if (ra== null || !ra.inRenderBin())
continue;
ShaderBin sb = ra.renderMolecule.textureBin.shaderBin;
ra.renderMolecule.removeRenderAtom(ra);
reInsertTextureBin(sb, ra);
}
}
} else if ((component & AppearanceRetained.RENDERING) != 0) {
boolean visible = ((Boolean)args[4]).booleanValue();
visGAIsDirty = true;
visQuery = true;
if (!visible) {
// remove all gaAttrs
for (i = start; i < gaArr.length; i++) {
ra = gaArr[i].getRenderAtom(view);
if (ra== null || !ra.inRenderBin())
continue;
renderAtoms.remove(renderAtoms.indexOf(ra));
removeARenderAtom(ra);
}
}
else {
if ((app.mirror.changedFrequent & component) != 0 &&
ra.renderMolecule.textureBin.attributeBin.soleUser) {
for (i = start; i < gaArr.length; i++) {
ra = gaArr[i].getRenderAtom(view);
if (ra== null || !ra.inRenderBin())
continue;
AttributeBin aBin = ra.renderMolecule.textureBin.attributeBin;
if ((aBin.onUpdateList & AttributeBin.ON_CHANGED_FREQUENT_UPDATE_LIST) == 0 ) {
aBinUpdateList.add(aBin);
aBin.onUpdateList |= AttributeBin.ON_CHANGED_FREQUENT_UPDATE_LIST;
}
}
}
else {
for (i = start; i < gaArr.length; i++) {
ra = gaArr[i].getRenderAtom(view);
if (ra== null || !ra.inRenderBin())
continue;
EnvironmentSet e = ra.renderMolecule.textureBin.environmentSet;
ra.renderMolecule.removeRenderAtom(ra);
reInsertAttributeBin(e, ra);
}
}
}
}
else if ((component & (AppearanceRetained.COLOR |
AppearanceRetained.MATERIAL|
AppearanceRetained.TRANSPARENCY|
AppearanceRetained.POLYGON |
AppearanceRetained.LINE|
AppearanceRetained.POINT)) != 0) {
// System.err.println("AppearanceRetained.POINT = "+AppearanceRetained.POINT);
// System.err.println("(app.mirror.changedFrequent & component) != 0 "+app.mirror.changedFrequent );
// System.err.println("ra.renderMolecule.soleUser "+ra.renderMolecule.soleUser);
if ((app.mirror.changedFrequent & component) != 0 &&
ra.renderMolecule.soleUser) {
for (i = start; i < gaArr.length; i++) {
ra = gaArr[i].getRenderAtom(view);
if (ra== null || !ra.inRenderBin())
continue;
if ((ra.renderMolecule.soleUserCompDirty& RenderMolecule.ALL_DIRTY_BITS) == 0 ) {
rmUpdateList.add(ra.renderMolecule);
}
ra.renderMolecule.soleUserCompDirty |= component;
}
}
else {
for (i = start; i < gaArr.length; i++) {
ra = gaArr[i].getRenderAtom(view);
if (ra== null || !ra.inRenderBin())
continue;
TextureBin tb = ra.renderMolecule.textureBin;
ra.renderMolecule.removeRenderAtom(ra);
reInsertRenderAtom(tb, ra);
}
}
}
} else {
// Nothing is visible
if ((component & AppearanceRetained.RENDERING) != 0) {
// Rendering attributes change
visGAIsDirty = true;
visQuery = true;
}
}
}
void processModelClipChanged(Object[] args) {
ModelClipRetained modelClip =
(ModelClipRetained)args[0];
EnvironmentSet e;
int component = ((Integer)args[1]).intValue();
if ((component & (ModelClipRetained.SCOPE_CHANGED |
ModelClipRetained.BOUNDS_CHANGED |
ModelClipRetained.BOUNDINGLEAF_CHANGED)) != 0){
envDirty |= REEVALUATE_MCLIP;
} else if ((component & (ModelClipRetained.ENABLE_CHANGED |
ModelClipRetained.ENABLES_CHANGED)) != 0) {
// need to render modelclip
if (!changedModelClips.contains(modelClip.mirrorModelClip))
changedModelClips.add(modelClip.mirrorModelClip);
// need to reevaluate envset
envDirty |= REEVALUATE_MCLIP;
} else {
UnorderList list = modelClip.mirrorModelClip.environmentSets;
synchronized (list) {
EnvironmentSet envsets[] = (EnvironmentSet []) list.toArray(false);
int size = list.size();
for (int i = 0; i < size; i++) {
e = envsets[i];
e.canvasDirty |= Canvas3D.MODELCLIP_DIRTY;
if (!e.onUpdateList) {
objUpdateList.add(e);
e.onUpdateList = true;
}
}
}
}
}
/**
* This routine get called whenever a region of the boundingleaf
* changes
*/
void processBoundingLeafChanged(Object[] args, long refTime){
// Notify all users of this bounding leaf, it may
// result in the re-evaluation of the lights/fogs/backgrounds
Object[] users = (Object[])(args[3]);
int i;
// XXXX: Handle other object affected by bounding leaf changes
for (i = 0; i < users.length; i++) {
LeafRetained leaf = (LeafRetained)users[i];
switch(leaf.nodeType) {
case NodeRetained.AMBIENTLIGHT:
case NodeRetained.POINTLIGHT:
case NodeRetained.SPOTLIGHT:
case NodeRetained.DIRECTIONALLIGHT:
if (universe.renderingEnvironmentStructure.isLightScopedToThisView(leaf, view))
envDirty |= REEVALUATE_LIGHTS;
break;
case NodeRetained.LINEARFOG:
case NodeRetained.EXPONENTIALFOG:
if (universe.renderingEnvironmentStructure.isFogScopedToThisView(leaf, view))
envDirty |= REEVALUATE_FOG;
break;
case NodeRetained.BACKGROUND:
if (universe.renderingEnvironmentStructure.isBgScopedToThisView(leaf, view))
reEvaluateBg = true;
break;
case NodeRetained.CLIP:
if (universe.renderingEnvironmentStructure.isClipScopedToThisView(leaf, view))
reEvaluateClip = true;
break;
case NodeRetained.MODELCLIP:
if (universe.renderingEnvironmentStructure.isMclipScopedToThisView(leaf, view))
envDirty |= REEVALUATE_MCLIP;
break;
case NodeRetained.ALTERNATEAPPEARANCE:
if (universe.renderingEnvironmentStructure.isAltAppScopedToThisView(leaf, view)) altAppearanceDirty = true;
break;
default:
break;
}
}
}
void processOrientedShape3DChanged(Object[] gaArr) {
RenderAtom ra;
for (int i = 0; i < gaArr.length; i++) {
ra = ((GeometryAtom)gaArr[i]).getRenderAtom(view);
if (ra!= null && ra.inRenderBin() && !ra.inDirtyOrientedRAs()) {
dirtyOrientedRAs.add(ra);
ra.dirtyMask |= RenderAtom.IN_DIRTY_ORIENTED_RAs;
}
}
}
void processShapeChanged(Object[] args, long refTime) {
int component = ((Integer)args[1]).intValue();
int i;
RenderAtom ra;
EnvironmentSet e;
if ((component & Shape3DRetained.APPEARANCE_CHANGED) != 0) {
GeometryAtom[] gaArr = (GeometryAtom[])args[4];
if (gaArr.length > 0) {
if (!gaArr[0].source.appearanceOverrideEnable) {
for (i =0; i < gaArr.length; i++) {
ra = gaArr[i].getRenderAtom(view);
if (ra == null || !ra.inRenderBin()) {
continue;
}
ra.app = ra.geometryAtom.source.appearance;
e = ra.renderMolecule.textureBin.environmentSet;
ra.renderMolecule.removeRenderAtom(ra);
reInsertAttributeBin(e, ra);
}
}
else {
for (i =0; i < gaArr.length; i++) {
ra = gaArr[i].getRenderAtom(view);
if (ra == null || !ra.inRenderBin()) {
continue;
}
// if its using the alternate appearance continue ..
if (ra.app == ra.geometryAtom.source.otherAppearance)
continue;
ra.app = ra.geometryAtom.source.appearance;
e = ra.renderMolecule.textureBin.environmentSet;
ra.renderMolecule.removeRenderAtom(ra);
reInsertAttributeBin(e, ra);
}
}
}
}
else if ((component & Shape3DRetained.GEOMETRY_CHANGED) != 0) {
processDataChanged((Object[])args[2], (Object[])args[3], refTime);
}
else if ((component & Shape3DRetained.APPEARANCEOVERRIDE_CHANGED) != 0) {
AppearanceRetained app, saveApp = null;
Shape3DRetained saveShape = null;
GeometryAtom[] gaArr = (GeometryAtom[])args[4];
Object[] retVal;
for (i =0; i < gaArr.length; i++) {
ra = gaArr[i].getRenderAtom(view);
if (ra == null || !ra.inRenderBin())
continue;
// Once shape could have many geometryAtoms, add the
// mirrorShape as a user of an appearance only once
if (saveShape != ra.geometryAtom.source) {
saveShape = ra.geometryAtom.source;
if (ra.geometryAtom.source.appearanceOverrideEnable) {
retVal =universe.renderingEnvironmentStructure.getInfluencingAppearance(ra, view);
saveShape.otherAppearance = (AppearanceRetained)retVal[1];
if (retVal[0] == Boolean.TRUE) {
app = (AppearanceRetained)retVal[1];
if (app != null) {
app.sgApp.addAMirrorUser(saveShape);
}
}
else {// use the default
app = ra.geometryAtom.source.appearance;
}
}
else {
// If it were using the alternate appearance
// remove itself as the user
if (ra.app == saveShape.otherAppearance &&
ra.app != null) {
ra.app.sgApp.removeAMirrorUser(saveShape);
}
app = ra.geometryAtom.source.appearance;
saveShape.otherAppearance = null;
}
saveApp = app;
}
else {
app = saveApp;
}
ra.app = app;
e = ra.renderMolecule.textureBin.environmentSet;
ra.renderMolecule.removeRenderAtom(ra);
reInsertAttributeBin(e, ra);
}
}
}
/**
* Process a Text3D data change. This involves removing all the
* old geometry atoms in the list, and the creating new ones.
*/
void processDataChanged(Object[] oldGaList,
Object[] newGaList, long referenceTime) {
RenderAtom ra;
int i;
GeometryRetained geo;
GeometryAtom ga;
for (i=0; i 0) {
if (!gaArr[0].source.appearanceOverrideEnable) {
for (i =0; i < gaArr.length; i++) {
ra = gaArr[i].getRenderAtom(view);
if (ra == null || !ra.inRenderBin()) {
continue;
}
ra.app = ra.geometryAtom.source.appearance;
e = ra.renderMolecule.textureBin.environmentSet;
ra.renderMolecule.removeRenderAtom(ra);
reInsertAttributeBin(e, ra);
}
}
else {
for (i =0; i < gaArr.length; i++) {
ra = gaArr[i].getRenderAtom(view);
if (ra == null || !ra.inRenderBin())
continue;
// if its using the alternate appearance continue ..
if (ra.app == ra.geometryAtom.source.otherAppearance)
continue;
ra.app = ra.geometryAtom.source.appearance;
e = ra.renderMolecule.textureBin.environmentSet;
ra.renderMolecule.removeRenderAtom(ra);
reInsertAttributeBin(e, ra);
}
}
}
}
else if ((component & MorphRetained.APPEARANCEOVERRIDE_CHANGED) != 0) {
AppearanceRetained app, saveApp = null;
Shape3DRetained saveShape = null;
GeometryAtom[] gaArr = (GeometryAtom[])args[4];
Object[] retVal;
for (i =0; i < gaArr.length; i++) {
ra = gaArr[i].getRenderAtom(view);
if (ra == null || !ra.inRenderBin())
continue;
// Once shape could have many geometryAtoms, add the
// mirrorShape as a user of an appearance only once
if (saveShape != ra.geometryAtom.source) {
saveShape = ra.geometryAtom.source;
if (ra.geometryAtom.source.appearanceOverrideEnable) {
retVal =universe.renderingEnvironmentStructure.getInfluencingAppearance(ra, view);
saveShape.otherAppearance = (AppearanceRetained)retVal[1];
if (retVal[0] == Boolean.TRUE) {
app = (AppearanceRetained)retVal[1];
if (app != null) {
app.sgApp.addAMirrorUser(saveShape);
}
}
else {// use the default
app = ra.geometryAtom.source.appearance;
}
}
else {
// If it were using the alternate appearance
// remove itself as the user
if (ra.app == saveShape.otherAppearance &&
ra.app != null) {
ra.app.sgApp.removeAMirrorUser(saveShape);
}
app = ra.geometryAtom.source.appearance;
saveShape.otherAppearance = null;
}
saveApp = app;
}
else {
app = saveApp;
}
ra.app = app;
e = ra.renderMolecule.textureBin.environmentSet;
ra.renderMolecule.removeRenderAtom(ra);
reInsertAttributeBin(e, ra);
}
}
}
/**
* This routine gets called whenever the position of the view platform
* has changed.
*/
void updateViewPlatform(ViewPlatformRetained vp, float radius) {
ViewPlatform viewP = view.getViewPlatform();
if (viewP != null && (ViewPlatformRetained)viewP.retained == vp) {
vpcToVworld = vp.getCurrentLocalToVworld(null);
vpcToVworldDirty = true;
synchronized(vp) {
vp.vprDirtyMask |= View.VPR_VIEWPLATFORM_DIRTY;
}
// vp schedSphere is already set and transform in
// BehaviorStructure thread which is run before
// RenderBin using vp.updateActivationRadius()
vpSchedSphereInVworld = vp.schedSphere;
reEvaluateBg = true;
reEvaluateClip = true;
}
}
/**
* This routine removes the GeometryAtoms from RenderBin
*/
void processGeometryAtomsChanged(Object[] gaArr) {
int i;
RenderAtom ra;
for (i = 0; i < gaArr.length; i++) {
ra = ((GeometryAtom)gaArr[i]).getRenderAtom(view);
if (ra != null && ra.inRenderBin()) {
renderAtoms.remove(renderAtoms.indexOf(ra));
removeARenderAtom(ra);
}
}
}
/**
* process Geometry changed, mark the display list
* in which renderMolecule is as dirty
*/
void processGeometryChanged(Object[] args) {
Object[] gaList = (Object[]) args[0];
GeometryRetained g = (GeometryRetained)args[1];
GeometryAtom ga;
int i;
for (i = 0; i < gaList.length; i++) {
ga = ((GeometryAtom)gaList[i]);
RenderAtom renderAtom = ga.getRenderAtom(view);
if (renderAtom == null || !renderAtom.inRenderBin()) {
continue;
}
// Add the renderMolecule to the dirty list so that
// display list will be recreated
int j = 0;
for ( j = 0; j < renderAtom.rListInfo.length; j++) {
if (g == renderAtom.rListInfo[j].geometry())
break;
}
RenderAtomListInfo ra = renderAtom.rListInfo[j];
if ((ra.groupType & RenderAtom.DLIST) != 0)
addDirtyRenderMolecule(ra.renderAtom.renderMolecule);
if ((ra.groupType & RenderAtom.SEPARATE_DLIST_PER_RINFO) != 0) {
addDlistPerRinfo.add(ra);
}
if ((ra.groupType & RenderAtom.SEPARATE_DLIST_PER_GEO) != 0)
addGeometryDlist(ra);
// Raster send this message only for setImage()
if (g instanceof RasterRetained) {
Object[] objs = (Object[]) args[2];
Texture2DRetained oldTex = (Texture2DRetained) objs[0];
Texture2DRetained newTex = (Texture2DRetained) objs[1];
RasterRetained geo = (RasterRetained)ra.geometry();
if (oldTex != null) {
addTextureResourceFreeList(oldTex);
ImageComponentRetained oldImage = oldTex.images[0][0];
if (oldImage != null) {
removeNodeComponent(oldImage);
}
}
if (newTex != null) {
ImageComponentRetained newImage = newTex.images[0][0];
if (newImage != null) {
addNodeComponent(newImage);
}
}
}
}
}
void addTextureBin(TextureBin tb) {
textureBinList.add(tb);
}
void removeTextureBin(TextureBin tb) {
textureBinList.remove(tb);
}
void addDirtyRenderMolecule(RenderMolecule rm) {
if ((rm.onUpdateList & RenderMolecule.IN_DIRTY_RENDERMOLECULE_LIST) == 0) {
if (rm.onUpdateList == 0) {
objUpdateList.add(rm);
}
rm.onUpdateList |= RenderMolecule.IN_DIRTY_RENDERMOLECULE_LIST;
dirtyRenderMoleculeList.add(rm);
}
}
void removeDirtyRenderMolecule(RenderMolecule rm) {
if ((rm.onUpdateList & RenderMolecule.IN_DIRTY_RENDERMOLECULE_LIST) != 0) {
rm.onUpdateList &= ~RenderMolecule.IN_DIRTY_RENDERMOLECULE_LIST;
if (rm.onUpdateList == 0) {
objUpdateList.remove(rm);
}
dirtyRenderMoleculeList.remove(dirtyRenderMoleculeList.indexOf(rm));
}
}
void updateDirtyDisplayLists(Canvas3D cv,
ArrayList rmList, ArrayList