0001: /*
0002: * $RCSfile: RenderBin.java,v $
0003: *
0004: * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
0005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0006: *
0007: * This code is free software; you can redistribute it and/or modify it
0008: * under the terms of the GNU General Public License version 2 only, as
0009: * published by the Free Software Foundation. Sun designates this
0010: * particular file as subject to the "Classpath" exception as provided
0011: * by Sun in the LICENSE file that accompanied this code.
0012: *
0013: * This code is distributed in the hope that it will be useful, but WITHOUT
0014: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0015: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0016: * version 2 for more details (a copy is included in the LICENSE file that
0017: * accompanied this code).
0018: *
0019: * You should have received a copy of the GNU General Public License version
0020: * 2 along with this work; if not, write to the Free Software Foundation,
0021: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0022: *
0023: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0024: * CA 95054 USA or visit www.sun.com if you need additional information or
0025: * have any questions.
0026: *
0027: * $Revision: 1.18 $
0028: * $Date: 2008/02/28 20:17:28 $
0029: * $State: Exp $
0030: */
0031:
0032: package javax.media.j3d;
0033:
0034: import javax.vecmath.*;
0035: import java.util.*;
0036:
0037: /**
0038: * The RenderBin is a structure that optimizes rendering by doing efficient
0039: * state sorting of objects to be rendered.
0040: */
0041:
0042: class RenderBin extends J3dStructure implements ObjectUpdate {
0043:
0044: /**
0045: * The list of RenderAtoms
0046: */
0047: ArrayList renderAtoms = new ArrayList(5);
0048:
0049: /**
0050: * A couple ArrayLists used during light Processing
0051: */
0052: ArrayList lightMessageList = new ArrayList(5);
0053:
0054: // Messges retrieved when a message is sent to RenderingEnv Structure
0055: J3dMessage[] m;
0056:
0057: /**
0058: * List of renderMolecules that are soleUser
0059: * have to do a 2 pass, first update values
0060: * then sort based on equivalent material
0061: */
0062: ArrayList rmUpdateList = new ArrayList();
0063: ArrayList aBinUpdateList = new ArrayList();
0064:
0065: /**
0066: * List of ShaderBin that are soleUser that
0067: * needs to have its components updated @updateObject time
0068: */
0069: ArrayList sBinUpdateList = new ArrayList();
0070:
0071: /**
0072: * List of TextureBin that are soleUser that
0073: * needs to have its components updated @updateObject time
0074: */
0075: ArrayList tbUpdateList = new ArrayList();
0076:
0077: /**
0078: * List of Bins that are soleUser that have new renderAtom
0079: * added into, which requires a pre-update screening to
0080: * check if any of its node component changes could have been
0081: * missed because the changes happen when all the render atoms
0082: * are temporarily removed from the bin.
0083: */
0084: ArrayList updateCheckList = new ArrayList();
0085:
0086: /**
0087: * The number of lights supported by the underlying context.
0088: */
0089: int maxLights;
0090:
0091: /**
0092: * The opaque objects
0093: */
0094: LightBin opaqueBin = null;
0095:
0096: /**
0097: * OpaqueBins to be added for the next frame
0098: */
0099: LightBin addOpaqueBin = null;
0100:
0101: // This is a list of textureBins to be rendered, if the transpSortPolicy
0102: // is NONE, otherwise, if the transpSortPolicy is geometry, then
0103: // this is the list of renderAtoms to be rendered
0104: ArrayList allTransparentObjects = new ArrayList(5);
0105:
0106: TransparentRenderingInfo transparentInfo;
0107:
0108: /**
0109: * List of RenderAtoms whose postion have changed - only used for
0110: * depth sorted transparency
0111: */
0112: ArrayList positionDirtyList = new ArrayList(5);
0113:
0114: /**
0115: * Used when ColoringAttributes is null
0116: */
0117: Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
0118:
0119: /**
0120: * Used when Background is null
0121: */
0122: Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
0123:
0124: /**
0125: * The backgound color data.
0126: */
0127: BackgroundRetained background = new BackgroundRetained();
0128:
0129: /**
0130: * The view platform transforms.
0131: */
0132: // used for rendering - lights and fog modelling
0133: Transform3D vworldToVpc = new Transform3D();
0134:
0135: // used for updating vpSchedSphere
0136: Transform3D vpcToVworld = new Transform3D();
0137:
0138: /**
0139: * Two bounding spheres to track the scheduling region of
0140: * the view platform.
0141: */
0142: BoundingSphere vpSchedSphereInVworld = new BoundingSphere();
0143:
0144: /**
0145: * To cache the view frustum bounding box.
0146: */
0147: BoundingBox viewFrustumBBox = new BoundingBox();
0148: BoundingBox canvasFrustumBBox = new BoundingBox();
0149:
0150: /**
0151: * To ensure that vpcToVworld is valid (not null) for the first pass
0152: */
0153: boolean afterFirst = false;
0154:
0155: /**
0156: * back clip distance in vworld
0157: */
0158: double backClipDistanceInVworld;
0159:
0160: boolean backClipActive = false;
0161:
0162: /**
0163: * These variables control when compaction occurs
0164: */
0165: int frameCount = 0;
0166: int frameCountCutoff = 150;
0167: int notVisibleCount = 75;
0168: long removeCutoffTime = -1;
0169:
0170: /**
0171: * variables to process transform messages
0172: */
0173: boolean transformMsg = false;
0174: UpdateTargets targets = null;
0175: ArrayList blUsers = null;
0176:
0177: /**
0178: * The View for this render bin
0179: */
0180: View view = null;
0181:
0182: private Comparator transparencySortComparator = null;
0183:
0184: private ArrayList toBeAddedTextureResourceFreeList = new ArrayList(
0185: 5);
0186: private ArrayList displayListResourceFreeList = new ArrayList(5);
0187:
0188: // a list of top level OrderedGroups
0189: ArrayList orderedBins = new ArrayList(5);
0190:
0191: // List of changed elements in the environment that needs to
0192: // be reloaded
0193: ArrayList changedLts = new ArrayList(5);
0194: ArrayList changedFogs = new ArrayList(5);
0195: ArrayList changedModelClips = new ArrayList(5);
0196:
0197: // Flag to indicate whether the canvas should be marked
0198: static int REEVALUATE_LIGHTS = 0x1;
0199: static int REEVALUATE_FOG = 0x2;
0200: static int REEVALUATE_MCLIP = 0x4;
0201: static int REEVALUATE_ALL_ENV = REEVALUATE_LIGHTS | REEVALUATE_FOG
0202: | REEVALUATE_MCLIP;
0203: int envDirty = 0;
0204:
0205: private boolean reEvaluateBg = true;
0206: private boolean reloadBgTexture = true;
0207:
0208: boolean reEvaluateClip = true;
0209:
0210: boolean reEvaluateSortMode = false;
0211:
0212: // list of renderMolecule
0213: // RenderBin will not reused in two different universe, so it is
0214: // safe to pass null in last parameters in new IndexedUnorderSet()
0215: IndexedUnorderSet renderMoleculeList = new IndexedUnorderSet(
0216: RenderMolecule.class, RenderMolecule.RENDER_MOLECULE_LIST,
0217: null);
0218:
0219: // List of renderAtoms that have a shared dlist (due to geo.refCount > 1)
0220: // Fix for Issue 5: change this to a Set rather than a list to
0221: // avoid duplicates entried
0222: Collection sharedDList = new HashSet();
0223:
0224: ArrayList dirtyRenderMoleculeList = new ArrayList(5);
0225:
0226: /**
0227: * ArrayList of objects to be updated
0228: */
0229: ArrayList objUpdateList = new ArrayList(5);
0230:
0231: ArrayList raLocaleVwcBoundsUpdateList = new ArrayList(5);
0232:
0233: /**
0234: * remove the bins first before adding them to new ones
0235: */
0236: IndexedUnorderSet removeRenderAtomInRMList = new IndexedUnorderSet(
0237: RenderMolecule.class,
0238: RenderMolecule.REMOVE_RENDER_ATOM_IN_RM_LIST, null);
0239:
0240: /**
0241: * list of affect OrderedGroups with childIndexOrder changed.
0242: */
0243: ArrayList ogCIOList = new ArrayList(5);
0244:
0245: /**
0246: * list of ordered bins from which orderedCollection are added/removed
0247: */
0248: ArrayList obList = new ArrayList(5);
0249:
0250: /**
0251: * Ordered Bin processing
0252: */
0253: ArrayList orderedBinsList = new ArrayList(5);
0254: ArrayList toBeAddedBinList = new ArrayList(5);
0255:
0256: /**
0257: * arraylist of geometry that should be locked to ensure
0258: * that the same snapshot of the geometry is rendered
0259: * across all canvases
0260: */
0261: ArrayList lockGeometryList = new ArrayList(5);
0262:
0263: /**
0264: * arraylist of dlist that will be rebuilt
0265: */
0266: ArrayList dlistLockList = new ArrayList(5);
0267:
0268: // Background node that contains geometry
0269: BackgroundRetained geometryBackground = null;
0270:
0271: // background geometry processing
0272: LightBin bgOpaqueBin = null;
0273: LightBin bgAddOpaqueBin = null;
0274: ArrayList bgOrderedBins = new ArrayList(5);
0275: TransparentRenderingInfo bgTransparentInfo;
0276:
0277: // vworldToVpc for background geometry
0278: Transform3D infVworldToVpc = new Transform3D();
0279:
0280: // true if vpcToVworld has been modified
0281: boolean vpcToVworldDirty = true;
0282:
0283: // current active background
0284: BackgroundRetained currentActiveBackground = new BackgroundRetained();
0285:
0286: // Flag to indicate that alternate app is dirty
0287: boolean altAppearanceDirty = true;
0288:
0289: // List of node components that need special processing, due to
0290: // extensions
0291: ArrayList nodeComponentList = new ArrayList(5);
0292:
0293: // List of node components ***for this frame*** that need special
0294: // processing due to extension
0295: ArrayList newNodeComponentList = new ArrayList(5);
0296: ArrayList removeNodeComponentList = new ArrayList(5);
0297: ArrayList dirtyNodeComponentList = new ArrayList(5);
0298:
0299: ArrayList textureBinList = new ArrayList(5);
0300:
0301: /**
0302: * arraylist of refernce geometry that should be locked when transparency
0303: * is on, so that we can make a mirror copy of the colors safely
0304: */
0305: ArrayList dirtyReferenceGeomList = new ArrayList(5);
0306:
0307: // list of all Oriented RenderAtoms
0308: ArrayList orientedRAs = new ArrayList(5);
0309:
0310: // list of Oriented RenderAtoms whose orientedTransforms require update
0311: ArrayList dirtyOrientedRAs = new ArrayList(5);
0312:
0313: // Cached copy of dirty oriented RAs to be updated in MasterControl
0314: ArrayList cachedDirtyOrientedRAs = null;
0315:
0316: // list of offScreen message that
0317: ArrayList offScreenMessage = new ArrayList(5);
0318:
0319: // Vector used for locale translation
0320: Vector3d localeTranslation = new Vector3d();
0321:
0322: // Separate dlists that were added/removed in this snapshot
0323: private HashSet addDlist = new HashSet();
0324: private HashSet removeDlist = new HashSet();
0325:
0326: // Separate dlists per rinfo that were added/removed in this snapshot
0327: ArrayList addDlistPerRinfo = new ArrayList(5);
0328: ArrayList removeDlistPerRinfo = new ArrayList(5);
0329:
0330: Locale locale = null;
0331:
0332: // Set to true if locale changes as part of UPDATE_VIEW message
0333: boolean localeChanged = false;
0334:
0335: // Cached copy to be used by all RenderMolecules
0336: DisplayListRenderMethod dlistRenderMethod = null;
0337:
0338: // Need to query BHTree again with visibility policy change
0339: boolean reactivateView = false;
0340:
0341: /**
0342: * A flag indicates that the cached visible GeometryAtoms for this RenderBin might
0343: * be invalid.
0344: */
0345: private boolean visGAIsDirty = false;
0346:
0347: /**
0348: * A flag indicates that a visibility query to the GeometryStructure is needed.
0349: */
0350: private boolean visQuery = false;
0351:
0352: // Temporary dirtylist
0353: ArrayList dirtyList = new ArrayList(5);
0354:
0355: // Transaprency sort mode
0356: int transpSortMode = View.TRANSPARENCY_SORT_NONE;
0357: int cachedTranspSortMode = View.TRANSPARENCY_SORT_NONE;
0358:
0359: // Temporary dirtylist
0360: private LinkedHashSet dirtyDepthSortRenderAtom = new LinkedHashSet();
0361: private int numDirtyTinfo = 0;
0362:
0363: // Eye position in vworld
0364: Point3d eyeInVworld = new Point3d();
0365: // Number of RenderAtomListInfo in the depthSortedList
0366: int nElements = 0;
0367:
0368: /**
0369: * Constructs a new RenderBin
0370: */
0371: RenderBin(VirtualUniverse u, View v) {
0372: super (u, J3dThread.UPDATE_RENDER);
0373: vworldToVpc.setIdentity();
0374: universe = u;
0375: view = v;
0376: transpSortMode = v.transparencySortingPolicy;
0377: cachedTranspSortMode = v.transparencySortingPolicy;
0378: maxLights = VirtualUniverse.mc.maxLights;
0379: ViewPlatform vp = view.getViewPlatform();
0380: if (vp != null) {
0381: locale = ((ViewPlatformRetained) (vp.retained)).locale;
0382: }
0383: dlistRenderMethod = (DisplayListRenderMethod) VirtualUniverse.mc
0384: .getDisplayListRenderMethod();
0385: }
0386:
0387: /**
0388: * updateObject
0389: */
0390: public void updateObject() {
0391: int i, j, k;
0392: RenderMolecule rm;
0393: RenderAtomListInfo ra;
0394: LightBin tmp;
0395: float radius;
0396: BackgroundRetained bg;
0397: ObjectUpdate ob;
0398: OrderedBin orderBin;
0399: TextureRetained tex;
0400: Integer texIdObj;
0401: int size;
0402:
0403: // System.err.println("dirtyRenderMoleculeList.size = "+dirtyRenderMoleculeList.size());
0404: // System.err.println("reEvaluateBg = "+reEvaluateBg);
0405: // System.err.println("reEvaluateClip = "+reEvaluateClip);
0406: // System.err.println("<========+End All Cached Values===========>");
0407: // Add the new lightBins that have been created
0408: // System.err.println("objUpdateList.size = "+objUpdateList.size());
0409: // System.err.println("addOpaqueBin = "+addOpaqueBin);
0410: // System.err.println("opaqueBin = "+opaqueBin);
0411:
0412: // List of renderMolecule from which renderAtoms have been removed
0413: size = removeRenderAtomInRMList.size();
0414: if (size > 0) {
0415: RenderMolecule[] rmArr = (RenderMolecule[]) removeRenderAtomInRMList
0416: .toArray(false);
0417: for (i = 0; i < size; i++) {
0418: rmArr[i].updateRemoveRenderAtoms();
0419: }
0420: }
0421:
0422: // Add any OGs that need to be added to this frame
0423: // List of Ordered Groups that have been removed
0424:
0425: size = obList.size();
0426: if (size > 0) {
0427: for (i = 0; i < size; i++) {
0428: orderBin = (OrderedBin) obList.get(i);
0429: orderBin.addRemoveOrderedCollection();
0430: }
0431: }
0432:
0433: size = ogCIOList.size();
0434: if (size > 0) {
0435: J3dMessage m;
0436: for (i = 0; i < size; i++) {
0437: m = (J3dMessage) ogCIOList.get(i);
0438:
0439: switch (m.type) {
0440: case J3dMessage.ORDERED_GROUP_TABLE_CHANGED:
0441: OrderedGroupRetained og = (OrderedGroupRetained) m.args[3];
0442: if (og != null) {
0443: og.childIndexOrder = ((int[]) m.args[4]);
0444: }
0445: break;
0446:
0447: case J3dMessage.ORDERED_GROUP_INSERTED:
0448: case J3dMessage.ORDERED_GROUP_REMOVED:
0449: if (m.args[3] != null) {
0450: Object[] ogArr = (Object[]) m.args[3];
0451: Object[] ogTableArr = (Object[]) m.args[4];
0452: for (j = 0; j < ogArr.length; j++) {
0453: if (ogArr[j] != null) {
0454: ((OrderedGroupRetained) ogArr[j]).childIndexOrder = ((int[]) ogTableArr[j]);
0455: }
0456: }
0457: }
0458:
0459: break;
0460: }
0461: m.decRefcount();
0462: }
0463: }
0464:
0465: if (addOpaqueBin != null) {
0466:
0467: if (opaqueBin != null) {
0468: tmp = opaqueBin;
0469: while (tmp.next != null) {
0470: tmp = tmp.next;
0471: }
0472: addOpaqueBin.prev = tmp;
0473: tmp.next = addOpaqueBin;
0474: } else {
0475: opaqueBin = addOpaqueBin;
0476: }
0477: }
0478:
0479: if (bgAddOpaqueBin != null) {
0480: if (bgOpaqueBin != null) {
0481: tmp = bgOpaqueBin;
0482: while (tmp.next != null) {
0483: tmp = tmp.next;
0484: }
0485: bgAddOpaqueBin.prev = tmp;
0486: tmp.next = bgAddOpaqueBin;
0487: } else {
0488: bgOpaqueBin = bgAddOpaqueBin;
0489: }
0490: }
0491:
0492: size = orderedBinsList.size();
0493: if (size > 0) {
0494:
0495: for (i = 0; i < size; i++) {
0496: ArrayList obs = (ArrayList) orderedBinsList.get(i);
0497: ArrayList list = (ArrayList) toBeAddedBinList.get(i);
0498:
0499: int lSize = list.size();
0500: for (j = 0; j < lSize; j++) {
0501: obs.add(list.get(j));
0502: }
0503: }
0504: }
0505:
0506: size = raLocaleVwcBoundsUpdateList.size();
0507: if (size > 0) {
0508: RenderAtom renderAtom;
0509: for (i = 0; i < size; i++) {
0510: renderAtom = (RenderAtom) raLocaleVwcBoundsUpdateList
0511: .get(i);
0512: renderAtom.updateLocaleVwcBounds();
0513: }
0514: }
0515:
0516: if ((size = aBinUpdateList.size()) > 0) {
0517: for (i = 0; i < size; i++) {
0518: AttributeBin abin = (AttributeBin) aBinUpdateList
0519: .get(i);
0520: abin.updateNodeComponent();
0521: }
0522: }
0523:
0524: if ((size = sBinUpdateList.size()) > 0) {
0525: for (i = 0; i < size; i++) {
0526: ShaderBin sbin = (ShaderBin) sBinUpdateList.get(i);
0527: sbin.updateNodeComponent();
0528: }
0529: }
0530:
0531: // Update the sole user TextureBins.
0532: if (tbUpdateList.size() > 0) {
0533: TextureBin tb;
0534: size = tbUpdateList.size();
0535: for (i = 0; i < size; i++) {
0536: tb = (TextureBin) tbUpdateList.get(i);
0537: tb.updateNodeComponent();
0538: }
0539:
0540: // do another pass to re-sort TextureBin based on the
0541: // texture in the first texture unit state
0542: for (i = 0; i < size; i++) {
0543: tb = (TextureBin) tbUpdateList.get(i);
0544: // Bug Id : 4701430 - Have to be sure tb.shaderBin is
0545: // not equal to null. This is a temporary fix for j3d1.3.
0546: if (((tb.tbFlag & TextureBin.RESORT) != 0)
0547: && (tb.shaderBin != null)) {
0548:
0549: tb.shaderBin.reInsertTextureBin(tb);
0550: tb.tbFlag &= ~TextureBin.RESORT;
0551: }
0552: }
0553: }
0554:
0555: // Update the soleUser node components first
0556: // This way material equivalence during insertion
0557: // of new RMs is based on the updated ones
0558: if ((size = rmUpdateList.size()) > 0) {
0559: for (i = 0; i < size; i++) {
0560: rm = (RenderMolecule) rmUpdateList.get(i);
0561:
0562: boolean changeLists = rm.updateNodeComponent();
0563: // If an existing rm went from opaque to transparent or vice-versa
0564: // and has not been removed, then switch the RM
0565: if (changeLists && rm.textureBin != null) {
0566: rm.textureBin.changeLists(rm);
0567: }
0568: }
0569: for (i = 0; i < size; i++) {
0570: rm = (RenderMolecule) rmUpdateList.get(i);
0571: rm.reEvaluateEquivalence();
0572: }
0573: }
0574:
0575: size = objUpdateList.size();
0576: if (size > 0) {
0577: for (i = 0; i < size; i++) {
0578: ob = (ObjectUpdate) objUpdateList.get(i);
0579: ob.updateObject();
0580: }
0581: }
0582:
0583: size = dirtyReferenceGeomList.size();
0584: if (size > 0) {
0585: GeometryArrayRetained geo;
0586: Canvas3D canvases[] = view.getCanvases();
0587:
0588: for (i = 0; i < size; i++) {
0589: geo = (GeometryArrayRetained) dirtyReferenceGeomList
0590: .get(i);
0591: // Evaluate the nodeComponentList for all the canvases
0592: geo.geomLock.getLock();
0593: j = 0;
0594: // Do the setup only once{if necessary} for each geometry
0595: boolean found = false;
0596: while (j < canvases.length && !found) {
0597: if ((canvases[j].extensionsSupported & Canvas3D.SUN_GLOBAL_ALPHA) == 0) {
0598: if ((geo.vertexFormat & GeometryArray.INTERLEAVED) != 0) {
0599: geo
0600: .setupMirrorInterleavedColorPointer(true);
0601: found = true;
0602: } else {
0603: geo
0604: .setupMirrorColorPointer(
0605: (geo.vertexType & GeometryArrayRetained.COLOR_DEFINED),
0606: true);
0607: found = true;
0608: }
0609: }
0610: j++;
0611: }
0612: geo.geomLock.unLock();
0613:
0614: }
0615:
0616: }
0617:
0618: if (reEvaluateBg) {
0619: setBackground(currentActiveBackground);
0620: }
0621:
0622: size = textureBinList.size();
0623: //System.err.println("textureBinList.size= " + size);
0624: if (size > 0) {
0625: Canvas3D canvasList[][] = view.getCanvasList(false);
0626: Canvas3D cv;
0627: boolean useSharedCtx = false;
0628: TextureRetained texture;
0629:
0630: // do a quick check to see if there is any canvas using
0631: // shared context
0632: for (j = 0; j < canvasList.length && !useSharedCtx; j++) {
0633: cv = canvasList[j][0];
0634: if (cv.useSharedCtx) {
0635: useSharedCtx = true;
0636: }
0637: }
0638:
0639: for (int m = 0; m < size; m++) {
0640: k = 0;
0641: TextureBin tb = (TextureBin) textureBinList.get(m);
0642: tb.tbFlag |= TextureBin.ON_RENDER_BIN_LIST;
0643:
0644: if (tb.texUnitState == null)
0645: continue;
0646:
0647: for (i = 0; i < tb.texUnitState.length; i++) {
0648: if (tb.texUnitState[i] != null
0649: && tb.texUnitState[i].texture != null) {
0650:
0651: texture = tb.texUnitState[i].texture;
0652:
0653: // for all the textures in this texture bin list that
0654: // need to be reloaded, add the textures to the
0655: // corresponding resource reload list if the
0656: // resource uses shared context,
0657: // so that the texture can be reloaded up front, and
0658: // we don't need to do make context current for
0659: // each texture reload. Make Context current isn't
0660: // cheap.
0661:
0662: if (useSharedCtx) {
0663: synchronized (texture.resourceLock) {
0664: for (j = 0; j < canvasList.length; j++) {
0665: cv = canvasList[j][0];
0666: if (cv.useSharedCtx
0667: && cv.screen.renderer != null
0668: && ((cv.screen.renderer.rendererBit & (texture.resourceCreationMask | texture.resourceInReloadList)) == 0)) {
0669:
0670: cv.screen.renderer.textureReloadList
0671: .add(texture);
0672:
0673: texture.resourceInReloadList |= cv.screen.renderer.rendererBit;
0674: }
0675: }
0676: }
0677: }
0678: }
0679: }
0680: }
0681: }
0682:
0683: size = newNodeComponentList.size();
0684: if (size > 0) {
0685: //System.err.println("newNodeComponentlist.size= " + size);
0686: Canvas3D canvases[] = view.getCanvases();
0687: for (i = 0; i < size; i++) {
0688: // Evaluate the nodeComponentList for all the canvases
0689: ImageComponentRetained nc = (ImageComponentRetained) newNodeComponentList
0690: .get(i);
0691: if (nc.isByReference()) {
0692: nc.geomLock.getLock();
0693: for (j = 0; j < canvases.length; j++) {
0694: // If the context is null, then the extension
0695: // will be evaluated during context creation in
0696: // the renderer
0697: if (canvases[j].ctx != null) {
0698: nc.evaluateExtensions(canvases[j]);
0699: }
0700: }
0701: nc.geomLock.unLock();
0702: } else {
0703: for (j = 0; j < canvases.length; j++) {
0704: // If the context is null, then the extension
0705: // will be evaluated during context creation in
0706: // the renderer
0707: if (canvases[j].ctx != null) {
0708: nc.evaluateExtensions(canvases[j]);
0709: }
0710: }
0711: }
0712: nodeComponentList.add(nc);
0713: }
0714: }
0715:
0716: size = removeNodeComponentList.size();
0717: if (size > 0) {
0718: for (i = 0; i < size; i++) {
0719: nodeComponentList
0720: .remove(removeNodeComponentList.get(i));
0721: }
0722: }
0723:
0724: // reevaluate dirty node component
0725: size = dirtyNodeComponentList.size();
0726: if (size > 0) {
0727: Canvas3D canvases[] = view.getCanvases();
0728: for (i = 0; i < size; i++) {
0729: // Evaluate the nodeComponentList for all the canvases
0730: ImageComponentRetained nc = (ImageComponentRetained) dirtyNodeComponentList
0731: .get(i);
0732: if (nc.isByReference()) {
0733: nc.geomLock.getLock();
0734: for (j = 0; j < canvases.length; j++) {
0735: // If the context is null, then the extension
0736: // will be evaluated during context creation in
0737: // the renderer
0738: if (canvases[j].ctx != null) {
0739: nc.evaluateExtensions(canvases[j]);
0740: }
0741: }
0742: nc.geomLock.unLock();
0743: } else {
0744: for (j = 0; j < canvases.length; j++) {
0745: // If the context is null, then the extension
0746: // will be evaluated during context creation in
0747: // the renderer
0748: if (canvases[j].ctx != null) {
0749: nc.evaluateExtensions(canvases[j]);
0750: }
0751: }
0752: }
0753: }
0754: }
0755:
0756: if (reEvaluateClip) {
0757: double[] retVal = null;
0758: if ((retVal = universe.renderingEnvironmentStructure
0759: .backClipDistanceInVworld(vpSchedSphereInVworld,
0760: view)) != null) {
0761: backClipDistanceInVworld = retVal[0];
0762: backClipActive = true;
0763: } else {
0764: backClipActive = false;
0765: }
0766: view.vDirtyMask |= View.CLIP_DIRTY;
0767: }
0768:
0769: // Issue 113 - multiScreen no longer used
0770: // multiScreen = ((view.getScreens()).length > 1);
0771:
0772: // renderBin is ready now, so send the offScreen message
0773: size = offScreenMessage.size();
0774: if (size > 0) {
0775: J3dMessage m;
0776: for (i = size - 1; i >= 0; i--) {
0777: m = (J3dMessage) offScreenMessage.get(i);
0778: m.threads = J3dThread.RENDER_THREAD;
0779: ((Canvas3D) m.args[0]).screen.renderer.rendererStructure
0780: .addMessage(m);
0781:
0782: // the above call will increment the reference count again
0783: m.decRefcount();
0784: }
0785: }
0786:
0787: // called from renderBin when there are dirtyOrientedRAs
0788: // This routin cache the dirtyOrintedRAs to be updated
0789: // by mastercontrol
0790: if (dirtyOrientedRAs.size() > 0) {
0791: // Keep a copy to be handled by mastercontrol
0792: cachedDirtyOrientedRAs = (ArrayList) dirtyOrientedRAs
0793: .clone();
0794: }
0795: boolean sortAll = false;
0796: if (reEvaluateSortMode
0797: && transpSortMode != cachedTranspSortMode) {
0798: convertTransparentRenderingStruct(transpSortMode,
0799: cachedTranspSortMode);
0800: transpSortMode = cachedTranspSortMode;
0801: if (transpSortMode == View.TRANSPARENCY_SORT_GEOMETRY) {
0802: if (transparentInfo != null) {
0803: sortAll = true;
0804: }
0805: }
0806: }
0807:
0808: if (vpcToVworldDirty) {
0809: vworldToVpc.invert(vpcToVworld);
0810: // Have the send down the lights, so set the canvas
0811: // lightbin to null
0812: Canvas3D canvases[] = view.getCanvases();
0813: for (i = 0; i < canvases.length; i++) {
0814: canvases[i].lightBin = null;
0815: }
0816: if (canvases.length > 0) {
0817: Transform3D xform;
0818: canvases[0].getCenterEyeInImagePlate(eyeInVworld);
0819: // xform is imagePlateToLocal
0820: xform = canvases[0].canvasViewCache
0821: .getImagePlateToVworld();
0822: xform.transform(eyeInVworld);
0823: }
0824: if (transpSortMode == View.TRANSPARENCY_SORT_GEOMETRY
0825: && transparentInfo != null) {
0826: // System.err.println("sortAll 1");
0827: sortAll = true;
0828: }
0829: }
0830: size = dirtyDepthSortRenderAtom.size();
0831:
0832: if (sortAll || size > 0) {
0833: int tsize = allTransparentObjects.size();
0834:
0835: double zVal;
0836: for (i = 0; i < tsize; i++) {
0837: RenderAtom renderAtom = (RenderAtom) allTransparentObjects
0838: .get(i);
0839: for (k = 0; k < renderAtom.rListInfo.length; k++) {
0840: if (renderAtom.rListInfo[k].geometry() == null)
0841: continue;
0842: zVal = renderAtom.geometryAtom.centroid[k]
0843: .distanceSquared(eyeInVworld);
0844: renderAtom.parentTInfo[k].zVal = zVal;
0845: renderAtom.parentTInfo[k].geometryAtom = renderAtom.geometryAtom;
0846: }
0847: }
0848:
0849: // Check to see if a majority of the transparent Objects have changed
0850: // If less than 66% of all transparentStructs are dirty
0851: // then, remove and insert, otherwise resort everything
0852:
0853: if (size > 0 && 1.5f * numDirtyTinfo > nElements) {
0854: // System.err.println("sortAll 3, size = "+size);
0855: sortAll = true;
0856: }
0857:
0858: if (size > 0) {
0859: TransparentRenderingInfo dirtyList = null, rList;
0860: Iterator dirtyDepthSortIterator = dirtyDepthSortRenderAtom
0861: .iterator();
0862: while (dirtyDepthSortIterator.hasNext()) {
0863: RenderAtom renderAtom = (RenderAtom) dirtyDepthSortIterator
0864: .next();
0865: if (!renderAtom.inRenderBin())
0866: continue;
0867: renderAtom.dirtyMask &= ~RenderAtom.IN_SORTED_POS_DIRTY_TRANSP_LIST;
0868: if (!sortAll) {
0869: dirtyList = collectDirtyTRInfo(dirtyList,
0870: renderAtom);
0871: }
0872: }
0873:
0874: if (dirtyList != null) {
0875: // System.err.println("====> sort Some");
0876: dirtyList = depthSortAll(dirtyList);
0877: // Now merge the newly sorted list with the old one
0878: transparentInfo = mergeDepthSort(transparentInfo,
0879: dirtyList);
0880: }
0881: }
0882: // Sort all the transparent renderAtoms
0883: if (sortAll) {
0884: transparentInfo = depthSortAll(transparentInfo);
0885: }
0886: }
0887:
0888: // Remove entries that are found on both the add and remove lists
0889: if (addDlist.size() > 0 && removeDlist.size() > 0) {
0890: RenderAtomListInfo arr[] = new RenderAtomListInfo[addDlist
0891: .size()];
0892: arr = (RenderAtomListInfo[]) addDlist.toArray(arr);
0893: for (i = 0; i < arr.length; i++) {
0894: if (removeDlist.contains(arr[i])) {
0895: addDlist.remove(arr[i]);
0896: removeDlist.remove(arr[i]);
0897: }
0898: }
0899: }
0900:
0901: if (addDlist.size() > 0 || removeDlist.size() > 0) {
0902: Canvas3D canvasList[][] = view.getCanvasList(false);
0903: Canvas3D cv;
0904: ArrayList rlist = new ArrayList(5);
0905:
0906: for (i = 0; i < canvasList.length; i++) {
0907: cv = canvasList[i][0];
0908: if (cv.useSharedCtx) {
0909: // Do this only once per renderer for this view
0910: if (!rlist.contains(cv.screen.renderer)) {
0911: rlist.add(cv.screen.renderer);
0912: updateDlistRendererResource(cv.screen.renderer);
0913: }
0914: } else {
0915: updateDlistCanvasResource(canvasList[i]);
0916: }
0917: }
0918:
0919: }
0920:
0921: if (dirtyRenderMoleculeList.size() > 0
0922: || addDlistPerRinfo.size() > 0
0923: || removeDlistPerRinfo.size() > 0
0924: || displayListResourceFreeList.size() > 0
0925: || toBeAddedTextureResourceFreeList.size() > 0) {
0926:
0927: Canvas3D canvasList[][] = view.getCanvasList(false);
0928: Canvas3D cv;
0929:
0930: for (i = 0; i < canvasList.length; i++) {
0931: cv = canvasList[i][0];
0932: if (cv.useSharedCtx && (cv.screen.renderer != null)) {
0933: updateRendererResource(cv.screen.renderer);
0934: } else {
0935: updateCanvasResource(canvasList[i]);
0936: }
0937: }
0938:
0939: Integer id;
0940: size = displayListResourceFreeList.size();
0941: for (i = 0; i < size; i++) {
0942: id = (Integer) displayListResourceFreeList.get(i);
0943: VirtualUniverse.mc.freeDisplayListId(id);
0944: }
0945:
0946: // lock list of dlist
0947: // XXXX: Instead of copying could we keep 2 arrays
0948: // and just toggle?
0949: size = dirtyRenderMoleculeList.size();
0950: for (i = 0; i < size; i++) {
0951: rm = (RenderMolecule) dirtyRenderMoleculeList.get(i);
0952: rm.onUpdateList = 0;
0953: ra = rm.primaryRenderAtomList;
0954: while (ra != null) {
0955: dlistLockList.add(ra.geometry());
0956: ra = ra.next;
0957: }
0958: }
0959: size = addDlistPerRinfo.size();
0960: for (i = 0; i < size; i++) {
0961: ra = (RenderAtomListInfo) addDlistPerRinfo.get(i);
0962: if (ra.geometry() != null) {
0963: dlistLockList.add(ra.geometry());
0964: }
0965: }
0966:
0967: }
0968:
0969: clearAllUpdateObjectState();
0970: /*
0971: if (opaqueBin != null) {
0972: System.err.println(this + "***** Begin Dumping OpaqueBin *****");
0973: dumpBin(opaqueBin);
0974: System.err.println("***** End Dumping OpaqueBin *****");
0975: }
0976: */
0977:
0978: }
0979:
0980: // Shared context case
0981: void updateDlistRendererResource(Renderer rdr) {
0982: int i;
0983: int size = 0;
0984: RenderAtomListInfo arr[];
0985: RenderAtomListInfo ra;
0986:
0987: // XXXX: there is a possible problem in the case of multiple
0988: // renderers (i.e., multiple screens). Unless the
0989: // MasterControl sends us a separate message for each
0990: // renderer, we won't create a new display list for renderers
0991: // other than the one passed into this method.
0992:
0993: if (rdr == null) {
0994: return;
0995: }
0996:
0997: if ((size = addDlist.size()) > 0) {
0998: arr = new RenderAtomListInfo[size];
0999: arr = (RenderAtomListInfo[]) addDlist.toArray(arr);
1000: for (i = 0; i < size; i++) {
1001: ra = arr[i];
1002: GeometryArrayRetained geo = (GeometryArrayRetained) ra
1003: .geometry();
1004:
1005: // First time thru this renderer or the context that
1006: // it is built for no longer matches the context
1007: // used in the renderer, create a dlist
1008: sharedDList.add(ra);
1009: geo.addDlistUser(this , ra);
1010:
1011: if (((geo.resourceCreationMask & rdr.rendererBit) == 0)
1012: || (geo.getDlistTimeStamp(rdr.rendererBit) != rdr.sharedCtxTimeStamp)) {
1013: geo.resourceCreationMask |= rdr.rendererBit;
1014: dirtyList.add(ra);
1015: }
1016: }
1017: }
1018:
1019: if ((size = removeDlist.size()) > 0) {
1020: arr = new RenderAtomListInfo[size];
1021: arr = (RenderAtomListInfo[]) removeDlist.toArray(arr);
1022: for (i = 0; i < size; i++) {
1023: ra = arr[i];
1024: sharedDList.remove(ra);
1025:
1026: GeometryArrayRetained geo = (GeometryArrayRetained) ra
1027: .geometry();
1028: geo.removeDlistUser(this , ra);
1029: // System.err.println("========> geo.refcount = "+geo.refCount);
1030: // add this geometry's dlist to be freed
1031: if (geo.isDlistUserSetEmpty(this )) {
1032: rdr.displayListResourceFreeList.add(geo.dlistObj);
1033: geo.resourceCreationMask &= ~rdr.rendererBit;
1034: // All Dlist on all renderer have been freed, then return dlistID
1035: if (geo.resourceCreationMask == 0) {
1036: geo.freeDlistId();
1037: }
1038: }
1039: }
1040: }
1041: if ((size = dirtyList.size()) > 0) {
1042: for (i = 0; i < size; i++) {
1043: ra = (RenderAtomListInfo) dirtyList.get(i);
1044: GeometryArrayRetained geo = (GeometryArrayRetained) ra
1045: .geometry();
1046: if ((geo.resourceCreationMask & rdr.rendererBit) != 0) {
1047: rdr.dirtyRenderAtomList.add(ra);
1048: }
1049: }
1050: rdr.dirtyDisplayList = true;
1051: dirtyList.clear();
1052: }
1053: }
1054:
1055: // Non-shared context case
1056: void updateDlistCanvasResource(Canvas3D[] canvases) {
1057: int i, j;
1058: Canvas3D cv;
1059: int size = 0;
1060: RenderAtomListInfo arr[];
1061: RenderAtomListInfo ra;
1062:
1063: // Add the newly added dlist to the sharedList
1064: if ((size = addDlist.size()) > 0) {
1065: arr = new RenderAtomListInfo[size];
1066: arr = (RenderAtomListInfo[]) addDlist.toArray(arr);
1067: for (i = 0; i < size; i++) {
1068: sharedDList.add(arr[i]);
1069: // Fix for Issue 5: add the render atom to the list of users
1070: // of its geometry for this RenderBin
1071: GeometryArrayRetained geo = (GeometryArrayRetained) arr[i]
1072: .geometry();
1073: geo.addDlistUser(this , arr[i]);
1074: }
1075: }
1076:
1077: // Remove the newly removed dlist from the sharedList
1078: if ((size = removeDlist.size()) > 0) {
1079: arr = new RenderAtomListInfo[size];
1080: arr = (RenderAtomListInfo[]) removeDlist.toArray(arr);
1081: for (i = 0; i < size; i++) {
1082: sharedDList.remove(arr[i]);
1083: // Fix for Issue 5: remove this render atom from the list of users
1084: // of its geometry for this RenderBin
1085: GeometryArrayRetained geo = (GeometryArrayRetained) arr[i]
1086: .geometry();
1087: geo.removeDlistUser(this , arr[i]);
1088: }
1089: }
1090:
1091: // add to the dirty list per canvas
1092: for (j = 0; j < canvases.length; j++) {
1093: cv = canvases[j];
1094:
1095: if ((size = addDlist.size()) > 0) {
1096: arr = new RenderAtomListInfo[size];
1097: arr = (RenderAtomListInfo[]) addDlist.toArray(arr);
1098: for (i = 0; i < size; i++) {
1099: ra = arr[i];
1100: GeometryArrayRetained geo = (GeometryArrayRetained) ra
1101: .geometry();
1102:
1103: if ((cv.ctx != null)
1104: && ((geo.resourceCreationMask & cv.canvasBit) == 0)
1105: || (geo.getDlistTimeStamp(cv.canvasBit) != cv.ctxTimeStamp)) {
1106: geo.resourceCreationMask |= cv.canvasBit;
1107: dirtyList.add(ra);
1108: }
1109: }
1110: }
1111: if ((size = removeDlist.size()) > 0) {
1112: arr = new RenderAtomListInfo[size];
1113: arr = (RenderAtomListInfo[]) removeDlist.toArray(arr);
1114: for (i = 0; i < size; i++) {
1115: GeometryArrayRetained geo = (GeometryArrayRetained) arr[i]
1116: .geometry();
1117:
1118: // add this geometry's dlist to be freed
1119: if (geo.isDlistUserSetEmpty(this )) {
1120: if (cv.ctx != null) {
1121: canvases[j].displayListResourceFreeList
1122: .add(geo.dlistObj);
1123: }
1124: geo.resourceCreationMask &= ~canvases[j].canvasBit;
1125: // All Dlist on all canvases have been freed, then return dlistID
1126: if (geo.resourceCreationMask == 0)
1127: geo.freeDlistId();
1128: }
1129: }
1130: }
1131: if ((size = dirtyList.size()) > 0) {
1132: for (i = 0; i < size; i++) {
1133: ra = (RenderAtomListInfo) dirtyList.get(i);
1134: GeometryArrayRetained geo = (GeometryArrayRetained) ra
1135: .geometry();
1136: if ((geo.resourceCreationMask & cv.canvasBit) != 0) {
1137: cv.dirtyRenderAtomList.add(ra);
1138: }
1139: }
1140: cv.dirtyDisplayList = true;
1141: dirtyList.clear();
1142: }
1143: }
1144:
1145: }
1146:
1147: void clearAllUpdateObjectState() {
1148: localeChanged = false;
1149: obList.clear();
1150: rmUpdateList.clear();
1151: ogCIOList.clear();
1152: aBinUpdateList.clear();
1153: sBinUpdateList.clear();
1154: tbUpdateList.clear();
1155: removeRenderAtomInRMList.clear();
1156: addOpaqueBin = null;
1157: bgAddOpaqueBin = null;
1158: orderedBinsList.clear();
1159: toBeAddedBinList.clear();
1160: objUpdateList.clear();
1161: raLocaleVwcBoundsUpdateList.clear();
1162: displayListResourceFreeList.clear();
1163: toBeAddedTextureResourceFreeList.clear();
1164: dirtyRenderMoleculeList.clear();
1165: dirtyReferenceGeomList.clear();
1166: reEvaluateBg = false;
1167: reloadBgTexture = false;
1168: textureBinList.clear();
1169: newNodeComponentList.clear();
1170: removeNodeComponentList.clear();
1171: dirtyNodeComponentList.clear();
1172: reEvaluateClip = false;
1173: vpcToVworldDirty = false;
1174: offScreenMessage.clear();
1175: addDlist.clear();
1176: removeDlist.clear();
1177: addDlistPerRinfo.clear();
1178: removeDlistPerRinfo.clear();
1179: clearDirtyOrientedRAs();
1180: reEvaluateSortMode = false;
1181: dirtyDepthSortRenderAtom.clear();
1182: numDirtyTinfo = 0;
1183: }
1184:
1185: void updateRendererResource(Renderer rdr) {
1186: RenderMolecule rm;
1187: TextureRetained tex;
1188: Integer texIdObj;
1189:
1190: if (rdr == null)
1191: return;
1192:
1193: // Take care of display lists per Rinfo that should be rebuilt
1194: int size = addDlistPerRinfo.size();
1195:
1196: if (size > 0) {
1197: for (int j = 0; j < size; j++) {
1198: RenderAtomListInfo rinfo = (RenderAtomListInfo) addDlistPerRinfo
1199: .get(j);
1200: if (rinfo.renderAtom.inRenderBin()) {
1201: Object[] obj = new Object[2];
1202: obj[0] = rinfo;
1203: obj[1] = rinfo.renderAtom.renderMolecule;
1204: rdr.dirtyDlistPerRinfoList.add(obj);
1205: }
1206: }
1207: rdr.dirtyDisplayList = true;
1208: }
1209:
1210: // Take care of display lists that should be rebuilt
1211: size = dirtyRenderMoleculeList.size();
1212: if (size > 0) {
1213: for (int j = 0; j < size; j++) {
1214: rm = (RenderMolecule) dirtyRenderMoleculeList.get(j);
1215: rdr.dirtyRenderMoleculeList.add(rm);
1216: }
1217: rdr.dirtyDisplayList = true;
1218: }
1219:
1220: // Take care of texture that should be freed
1221: size = toBeAddedTextureResourceFreeList.size();
1222: int id;
1223: for (int j = 0; j < size; j++) {
1224: tex = (TextureRetained) toBeAddedTextureResourceFreeList
1225: .get(j);
1226: id = tex.objectId;
1227: if ((id >= rdr.textureIDResourceTable.size()) || (id <= 0)
1228: || (rdr.textureIDResourceTable.get(id) != tex)) {
1229: // tex.objectId may change by another Renderer thread,
1230: // need find original texID from searching
1231: // rdr.textureIdResourceTable
1232: id = rdr.textureIDResourceTable.indexOf(tex);
1233:
1234: if (id <= 0) {
1235: continue;
1236: }
1237: }
1238:
1239: // Since multiple renderBins (in the same screen)
1240: // can share a texture object, make sure that
1241: // we are not duplicating what has been added
1242: // by a different renderBin in the same screen
1243: if ((tex.resourceCreationMask & rdr.rendererBit) != 0) {
1244: texIdObj = new Integer(id);
1245: if (!rdr.textureIdResourceFreeList.contains(texIdObj)) {
1246: rdr.textureIdResourceFreeList.add(texIdObj);
1247: tex.resourceCreationMask &= ~rdr.rendererBit;
1248: }
1249: }
1250: }
1251:
1252: // Take care of display list that should be freed
1253: size = displayListResourceFreeList.size();
1254: Integer displayListIDObj;
1255:
1256: for (int j = 0; j < size; j++) {
1257: displayListIDObj = (Integer) displayListResourceFreeList
1258: .get(j);
1259: // It doesn't harm to free the same ID twice, the
1260: // underlying graphics library just ignore the second request
1261: rdr.displayListResourceFreeList.add(displayListIDObj);
1262: }
1263: // Take care of display list that should be freed
1264: size = removeDlistPerRinfo.size();
1265: for (int j = 0; j < size; j++) {
1266: RenderAtomListInfo ra = (RenderAtomListInfo) removeDlistPerRinfo
1267: .get(j);
1268: rdr.displayListResourceFreeList.add(new Integer(
1269: ra.renderAtom.dlistIds[ra.index]));
1270: ra.groupType = 0;
1271: ra.renderAtom.dlistIds[ra.index] = -1;
1272: }
1273: }
1274:
1275: void updateCanvasResource(Canvas3D[] canvases) {
1276: int i, j;
1277: RenderMolecule rm;
1278: TextureRetained tex;
1279: Integer texIdObj;
1280:
1281: // update dirtyRenderMoleculeList for each canvas
1282: for (i = 0; i < canvases.length; i++) {
1283: Canvas3D cv = canvases[i];
1284:
1285: // Take care of display lists per Rinfo that should be rebuilt
1286: int size = addDlistPerRinfo.size();
1287: if (size > 0) {
1288: for (j = 0; j < size; j++) {
1289: RenderAtomListInfo rinfo = (RenderAtomListInfo) addDlistPerRinfo
1290: .get(j);
1291: if (rinfo.renderAtom.inRenderBin()) {
1292: Object[] obj = new Object[2];
1293: obj[0] = rinfo;
1294: obj[1] = rinfo.renderAtom.renderMolecule;
1295: cv.dirtyDlistPerRinfoList.add(obj);
1296: }
1297: }
1298: cv.dirtyDisplayList = true;
1299: }
1300: // Take care of display lists that should be rebuilt
1301: size = dirtyRenderMoleculeList.size();
1302: if (size > 0) {
1303: for (j = 0; j < size; j++) {
1304: rm = (RenderMolecule) dirtyRenderMoleculeList
1305: .get(j);
1306: cv.dirtyRenderMoleculeList.add(rm);
1307: }
1308: cv.dirtyDisplayList = true;
1309: }
1310: // Take care of texture that should be freed
1311: size = toBeAddedTextureResourceFreeList.size();
1312: int id;
1313: for (j = 0; j < size; j++) {
1314: tex = (TextureRetained) toBeAddedTextureResourceFreeList
1315: .get(j);
1316: id = tex.objectId;
1317: if ((id >= cv.textureIDResourceTable.size())
1318: || (id <= 0)
1319: || (cv.textureIDResourceTable.get(id) != tex)) {
1320: // tex.objectId may change by another Renderer thread,
1321: // need find original texID from searching
1322: // rdr.textureIdResourceTable
1323: id = cv.textureIDResourceTable.indexOf(tex);
1324:
1325: if (id <= 0) {
1326: continue;
1327: }
1328: }
1329:
1330: if ((tex.resourceCreationMask & cv.canvasBit) != 0) {
1331: texIdObj = new Integer(id);
1332: cv.textureIdResourceFreeList.add(texIdObj);
1333: tex.resourceCreationMask &= ~cv.canvasBit;
1334: }
1335: }
1336: // Take care of display list that should be freed
1337: size = displayListResourceFreeList.size();
1338: for (j = 0; j < size; j++) {
1339: cv.displayListResourceFreeList
1340: .add(displayListResourceFreeList.get(j));
1341: }
1342: // Take care of display list that should be freed
1343: size = removeDlistPerRinfo.size();
1344: for (j = 0; j < size; j++) {
1345: RenderAtomListInfo ra = (RenderAtomListInfo) removeDlistPerRinfo
1346: .get(j);
1347: cv.displayListResourceFreeList.add(new Integer(
1348: ra.renderAtom.dlistIds[ra.index]));
1349: ra.groupType = 0;
1350: ra.renderAtom.dlistIds[ra.index] = -1;
1351:
1352: }
1353: }
1354:
1355: }
1356:
1357: void processMessages(long referenceTime) {
1358: int i, j, index;
1359: Object[] nodes;
1360: J3dMessage messages[], m;
1361: int component;
1362:
1363: messages = getMessages(referenceTime);
1364: int nMsg = getNumMessage();
1365:
1366: if (nMsg > 0) {
1367: for (i = 0; i < nMsg; i++) {
1368: m = messages[i];
1369: switch (m.type) {
1370: case J3dMessage.INSERT_NODES:
1371: insertNodes(m);
1372: m.decRefcount();
1373: break;
1374: case J3dMessage.REMOVE_NODES:
1375: removeNodes(m);
1376: m.decRefcount();
1377: break;
1378: case J3dMessage.TRANSFORM_CHANGED:
1379: transformMsg = true;
1380: m.decRefcount();
1381: break;
1382: case J3dMessage.LIGHT_CHANGED:
1383: // if none of the mirror lights are scoped to this view
1384: // ignore this message
1385: LightRetained[] mLts = (LightRetained[]) m.args[3];
1386: for (int k = 0; k < mLts.length; k++) {
1387: if (universe.renderingEnvironmentStructure
1388: .isLightScopedToThisView(mLts[k], view)) {
1389: lightMessageList.add(m);
1390: break;
1391: }
1392:
1393: }
1394: break;
1395: case J3dMessage.SWITCH_CHANGED:
1396: visGAIsDirty = true;
1397: visQuery = true;
1398: processSwitchChanged(m, referenceTime);
1399: // may need to process dirty switched-on transform
1400: if (universe.transformStructure.getLazyUpdate()) {
1401: transformMsg = true;
1402: }
1403: m.decRefcount();
1404: break;
1405: case J3dMessage.BACKGROUND_CHANGED:
1406: BackgroundRetained bg = (BackgroundRetained) m.args[0];
1407: if (universe.renderingEnvironmentStructure
1408: .isBgScopedToThisView(bg, view)) {
1409: reEvaluateBg = true;
1410: reloadBgTexture = true;
1411: }
1412: m.decRefcount();
1413: break;
1414: case J3dMessage.CLIP_CHANGED:
1415: ClipRetained c = (ClipRetained) m.args[0];
1416: if (universe.renderingEnvironmentStructure
1417: .isClipScopedToThisView(c, view))
1418: reEvaluateClip = true;
1419: m.decRefcount();
1420: break;
1421: case J3dMessage.TRANSPARENCYATTRIBUTES_CHANGED: {
1422: NodeComponentRetained nc = (NodeComponentRetained) m.args[0];
1423: GeometryAtom[] gaArr = (GeometryAtom[]) m.args[3];
1424: RenderAtom ra = null;
1425: int start = -1;
1426:
1427: // Get the first ra that is visible
1428: for (int k = 0; (k < gaArr.length && (start < 0)); k++) {
1429: ra = gaArr[k].getRenderAtom(view);
1430: if (ra == null || !ra.inRenderBin()) {
1431: continue;
1432: } else {
1433: start = k;
1434: }
1435: }
1436:
1437: if (start >= 0) {
1438: boolean restructure = (nc.mirror.changedFrequent == 0 || ra.renderMolecule.definingTransparency != nc.mirror);
1439: processRenderMoleculeNodeComponentChanged(
1440: m.args,
1441: RenderMolecule.TRANSPARENCY_DIRTY,
1442: start, restructure);
1443: }
1444: m.decRefcount();
1445: break;
1446: }
1447: case J3dMessage.POLYGONATTRIBUTES_CHANGED: {
1448: NodeComponentRetained nc = (NodeComponentRetained) m.args[0];
1449: GeometryAtom[] gaArr = (GeometryAtom[]) m.args[3];
1450: RenderAtom ra = null;
1451: int start = -1;
1452:
1453: // Get the first ra that is visible
1454: // Get the first ra that is visible
1455: for (int k = 0; (k < gaArr.length && (start < 0)); k++) {
1456: ra = gaArr[k].getRenderAtom(view);
1457: if (ra == null || !ra.inRenderBin()) {
1458: continue;
1459: } else {
1460: start = k;
1461: }
1462: }
1463:
1464: if (start >= 0) {
1465: boolean restructure = (nc.mirror.changedFrequent == 0 || ra.renderMolecule.definingPolygonAttributes != nc.mirror);
1466: processRenderMoleculeNodeComponentChanged(
1467: m.args,
1468: RenderMolecule.POLYGONATTRS_DIRTY,
1469: start, restructure);
1470: }
1471: m.decRefcount();
1472: break;
1473: }
1474: case J3dMessage.LINEATTRIBUTES_CHANGED: {
1475: NodeComponentRetained nc = (NodeComponentRetained) m.args[0];
1476: GeometryAtom[] gaArr = (GeometryAtom[]) m.args[3];
1477: RenderAtom ra = null;
1478: int start = -1;
1479:
1480: // Get the first ra that is visible
1481: // Get the first ra that is visible
1482: for (int k = 0; (k < gaArr.length && (start < 0)); k++) {
1483: ra = gaArr[k].getRenderAtom(view);
1484: if (ra == null || !ra.inRenderBin()) {
1485: continue;
1486: } else {
1487: start = k;
1488: }
1489: }
1490:
1491: if (start >= 0) {
1492: boolean restructure = (nc.mirror.changedFrequent == 0 || ra.renderMolecule.definingLineAttributes != nc.mirror);
1493: processRenderMoleculeNodeComponentChanged(
1494: m.args, RenderMolecule.LINEATTRS_DIRTY,
1495: start, restructure);
1496: }
1497: m.decRefcount();
1498: break;
1499: }
1500: case J3dMessage.POINTATTRIBUTES_CHANGED: {
1501: NodeComponentRetained nc = (NodeComponentRetained) m.args[0];
1502: GeometryAtom[] gaArr = (GeometryAtom[]) m.args[3];
1503: RenderAtom ra = null;
1504: int start = -1;
1505: // Get the first ra that is visible
1506: // Get the first ra that is visible
1507: for (int k = 0; (k < gaArr.length && (start < 0)); k++) {
1508: ra = gaArr[k].getRenderAtom(view);
1509: if (ra == null || !ra.inRenderBin()) {
1510: continue;
1511: } else {
1512: start = k;
1513: }
1514: }
1515:
1516: if (start >= 0) {
1517: boolean restructure = (nc.mirror.changedFrequent == 0 || ra.renderMolecule.definingPointAttributes != nc.mirror);
1518:
1519: processRenderMoleculeNodeComponentChanged(
1520: m.args,
1521: RenderMolecule.POINTATTRS_DIRTY, start,
1522: restructure);
1523: }
1524: m.decRefcount();
1525: break;
1526: }
1527: case J3dMessage.MATERIAL_CHANGED: {
1528: NodeComponentRetained nc = (NodeComponentRetained) m.args[0];
1529: GeometryAtom[] gaArr = (GeometryAtom[]) m.args[3];
1530: RenderAtom ra = null;
1531: int start = -1;
1532:
1533: // Get the first ra that is visible
1534: // Get the first ra that is visible
1535: for (int k = 0; (k < gaArr.length && (start < 0)); k++) {
1536: ra = gaArr[k].getRenderAtom(view);
1537: if (ra == null || !ra.inRenderBin()) {
1538: continue;
1539: } else {
1540: start = k;
1541: }
1542: }
1543:
1544: if (start >= 0) {
1545: boolean restructure = (nc.mirror.changedFrequent == 0 || ra.renderMolecule.definingMaterial != nc.mirror);
1546: processRenderMoleculeNodeComponentChanged(
1547: m.args, RenderMolecule.MATERIAL_DIRTY,
1548: start, restructure);
1549: }
1550: m.decRefcount();
1551: break;
1552: }
1553: case J3dMessage.COLORINGATTRIBUTES_CHANGED: {
1554: NodeComponentRetained nc = (NodeComponentRetained) m.args[0];
1555: GeometryAtom[] gaArr = (GeometryAtom[]) m.args[3];
1556: RenderAtom ra = null;
1557: int start = -1;
1558:
1559: // Get the first ra that is visible
1560: // Get the first ra that is visible
1561: for (int k = 0; (k < gaArr.length && (start < 0)); k++) {
1562: ra = gaArr[k].getRenderAtom(view);
1563: if (ra == null || !ra.inRenderBin()) {
1564: continue;
1565: } else {
1566: start = k;
1567: }
1568: }
1569:
1570: if (start >= 0) {
1571: boolean restructure = (nc.mirror.changedFrequent == 0 || ra.renderMolecule.definingColoringAttributes != nc.mirror);
1572: processRenderMoleculeNodeComponentChanged(
1573: m.args,
1574: RenderMolecule.COLORINGATTRS_DIRTY,
1575: start, restructure);
1576: }
1577: m.decRefcount();
1578: break;
1579: }
1580: case J3dMessage.TEXTUREATTRIBUTES_CHANGED:
1581: processTextureAttributesChanged(
1582: (NodeComponentRetained) m.args[0],
1583: (GeometryAtom[]) m.args[3]);
1584: m.decRefcount();
1585: break;
1586: case J3dMessage.IMAGE_COMPONENT_CHANGED:
1587: addDirtyNodeComponent((NodeComponentRetained) m.args[0]);
1588: m.decRefcount();
1589: break;
1590: case J3dMessage.TEXTURE_UNIT_STATE_CHANGED:
1591: processTextureUnitStateChanged(
1592: (NodeComponentRetained) m.args[0],
1593: (GeometryAtom[]) m.args[3]);
1594: m.decRefcount();
1595: break;
1596: case J3dMessage.TEXCOORDGENERATION_CHANGED:
1597: processTexCoordGenerationChanged(
1598: (NodeComponentRetained) m.args[0],
1599: (GeometryAtom[]) m.args[3]);
1600: m.decRefcount();
1601: break;
1602: case J3dMessage.TEXTURE_CHANGED:
1603: // Texture is always in a sole user position
1604: processTextureChanged(
1605: (NodeComponentRetained) m.args[0],
1606: (GeometryAtom[]) m.args[3], m.args);
1607: m.decRefcount();
1608: break;
1609: case J3dMessage.SHADER_APPEARANCE_CHANGED:
1610: case J3dMessage.SHADER_ATTRIBUTE_SET_CHANGED:
1611: case J3dMessage.SHADER_ATTRIBUTE_CHANGED:
1612: processShaderComponentChanged(m.args);
1613: m.decRefcount();
1614: break;
1615: case J3dMessage.RENDERINGATTRIBUTES_CHANGED:
1616: processAttributeBinNodeComponentChanged(m.args);
1617: component = ((Integer) m.args[1]).intValue();
1618: if (component == RenderingAttributesRetained.VISIBLE) {
1619: visGAIsDirty = true;
1620: visQuery = true;
1621: }
1622: m.decRefcount();
1623: break;
1624: case J3dMessage.APPEARANCE_CHANGED:
1625: processAppearanceChanged(m.args);
1626: m.decRefcount();
1627: break;
1628: case J3dMessage.FOG_CHANGED:
1629: FogRetained mfog = ((FogRetained) m.args[0]).mirrorFog;
1630: if (universe.renderingEnvironmentStructure
1631: .isFogScopedToThisView(mfog, view)) {
1632: processFogChanged(m.args);
1633: }
1634: m.decRefcount();
1635: break;
1636: case J3dMessage.ALTERNATEAPPEARANCE_CHANGED:
1637: AlternateAppearanceRetained maltapp = ((AlternateAppearanceRetained) m.args[0]).mirrorAltApp;
1638: if (universe.renderingEnvironmentStructure
1639: .isAltAppScopedToThisView(maltapp, view)) {
1640: altAppearanceDirty = true;
1641: }
1642: m.decRefcount();
1643: break;
1644: case J3dMessage.MODELCLIP_CHANGED:
1645: ModelClipRetained mc = ((ModelClipRetained) m.args[0]).mirrorModelClip;
1646: if (universe.renderingEnvironmentStructure
1647: .isMclipScopedToThisView(mc, view)) {
1648: processModelClipChanged(m.args);
1649: }
1650: m.decRefcount();
1651: break;
1652: case J3dMessage.BOUNDINGLEAF_CHANGED:
1653: processBoundingLeafChanged(m.args, referenceTime);
1654: m.decRefcount();
1655: break;
1656: case J3dMessage.SHAPE3D_CHANGED:
1657: processShapeChanged(m.args, referenceTime);
1658: m.decRefcount();
1659: break;
1660: case J3dMessage.ORIENTEDSHAPE3D_CHANGED:
1661: processOrientedShape3DChanged((Object[]) m.args[0]);
1662: m.decRefcount();
1663: break;
1664: case J3dMessage.MORPH_CHANGED:
1665: processMorphChanged(m.args, referenceTime);
1666: component = ((Integer) m.args[1]).intValue();
1667: if ((component & MorphRetained.GEOMETRY_CHANGED) == 0) {
1668: visGAIsDirty = true;
1669: visQuery = true;
1670: }
1671: m.decRefcount();
1672: break;
1673: case J3dMessage.UPDATE_VIEW: {
1674: View v = (View) m.args[0];
1675: ViewPlatform vp = v.getViewPlatform();
1676: int comp = ((Integer) (m.args[2])).intValue();
1677: int value = ((Integer) (m.args[3])).intValue();
1678: if (comp == View.TRANSP_SORT_POLICY_CHANGED) {
1679: if (value != transpSortMode) {
1680: reEvaluateSortMode = true;
1681: cachedTranspSortMode = value;
1682: }
1683: } else if (vp != null) {
1684: if (value != transpSortMode) {
1685: reEvaluateSortMode = true;
1686: cachedTranspSortMode = value;
1687: }
1688: updateViewPlatform(
1689: (ViewPlatformRetained) vp.retained,
1690: ((Float) m.args[1]).floatValue());
1691: visQuery = true;
1692: // XXXX : Handle view.visibilityPolicy changed.
1693: if (((View.VISIBILITY_POLICY_DIRTY != 0) && (View.VISIBILITY_DRAW_ALL != view.viewCache.visibilityPolicy))
1694: || locale != ((ViewPlatformRetained) (vp.retained)).locale) {
1695:
1696: for (int n = (renderAtoms.size() - 1); n >= 0; n--) {
1697: removeARenderAtom((RenderAtom) renderAtoms
1698: .get(n));
1699: }
1700: renderAtoms.clear();
1701: visGAIsDirty = true;
1702: if (locale != ((ViewPlatformRetained) (vp.retained)).locale) {
1703: locale = ((ViewPlatformRetained) (vp.retained)).locale;
1704: localeChanged = true;
1705: }
1706: }
1707: }
1708: m.decRefcount();
1709: }
1710: break;
1711: case J3dMessage.UPDATE_VIEWPLATFORM:
1712: updateViewPlatform(
1713: (ViewPlatformRetained) m.args[0],
1714: ((Float) m.args[1]).floatValue());
1715: m.decRefcount();
1716: break;
1717: case J3dMessage.TEXT3D_DATA_CHANGED:
1718: processDataChanged((Object[]) m.args[0],
1719: (Object[]) m.args[1], referenceTime);
1720: m.decRefcount();
1721: break;
1722: case J3dMessage.GEOMETRY_CHANGED:
1723: processGeometryChanged(m.args);
1724: visGAIsDirty = true;
1725: visQuery = true;
1726: m.decRefcount();
1727: break;
1728:
1729: case J3dMessage.BOUNDS_AUTO_COMPUTE_CHANGED:
1730: case J3dMessage.REGION_BOUND_CHANGED:
1731: processGeometryAtomsChanged((Object[]) m.args[0]);
1732: visGAIsDirty = true;
1733: visQuery = true;
1734: m.decRefcount();
1735: break;
1736: case J3dMessage.TEXT3D_TRANSFORM_CHANGED:
1737: processText3DTransformChanged((Object[]) m.args[0],
1738: (Object[]) m.args[1], referenceTime);
1739: visQuery = true;
1740: m.decRefcount();
1741: break;
1742: case J3dMessage.ORDERED_GROUP_INSERTED:
1743: processOrderedGroupInserted(m);
1744: // Do not do decRefcount() here. We'll do it in updateObject().
1745: ogCIOList.add(m);
1746: break;
1747: case J3dMessage.ORDERED_GROUP_REMOVED:
1748: processOrderedGroupRemoved(m);
1749: // Do not do decRefcount() here. We'll do it in updateObject().
1750: ogCIOList.add(m);
1751: break;
1752: case J3dMessage.ORDERED_GROUP_TABLE_CHANGED:
1753: // Do not do decRefcount() here. We'll do it in updateObject().
1754: ogCIOList.add(m);
1755: break;
1756: case J3dMessage.RENDER_OFFSCREEN:
1757: offScreenMessage.add(m);
1758: break;
1759: case J3dMessage.VIEWSPECIFICGROUP_CHANGED:
1760: processViewSpecificGroupChanged(m);
1761: visQuery = true;
1762: m.decRefcount();
1763: break;
1764: default:
1765: m.decRefcount();
1766: }
1767: }
1768:
1769: if (transformMsg) {
1770: processTransformChanged(referenceTime);
1771: transformMsg = false;
1772: }
1773: if (lightMessageList.size() > 0) {
1774: processLightChanged();
1775: lightMessageList.clear();
1776: }
1777: VirtualUniverse.mc.addMirrorObject(this );
1778:
1779: // clear the array to prevent memory leaks
1780: Arrays.fill(messages, 0, nMsg, null);
1781: }
1782:
1783: if (reEvaluateBg) {
1784: currentActiveBackground = universe.renderingEnvironmentStructure
1785: .getApplicationBackground(vpSchedSphereInVworld,
1786: locale, view);
1787: }
1788:
1789: if (visQuery) {
1790: GeometryAtom[] bgGeometryAtoms;
1791: boolean allEnComp;
1792:
1793: // computeViewFrustumBox in VisibilityStructure.
1794: computeViewFrustumBBox(viewFrustumBBox);
1795: // System.err.println("viewFrustumBBox = " + this);
1796:
1797: ViewPlatform vp = view.getViewPlatform();
1798: if (vp != null) {
1799: allEnComp = universe.geometryStructure
1800: .getVisibleBHTrees(
1801: this ,
1802: viewFrustumBBox,
1803: locale,
1804: referenceTime,
1805: visGAIsDirty
1806: || reactivateView
1807: || localeChanged
1808: || ((view.viewCache.vcDirtyMask & View.VISIBILITY_POLICY_DIRTY) != 0),
1809: view.viewCache.visibilityPolicy);
1810:
1811: reactivateView = false;
1812: // process background geometry atoms
1813: if (currentActiveBackground != null
1814: && currentActiveBackground.geometryBranch != null) {
1815: bgGeometryAtoms = currentActiveBackground
1816: .getBackgroundGeometryAtoms();
1817: if (bgGeometryAtoms != null) {
1818: processBgGeometryAtoms(bgGeometryAtoms,
1819: referenceTime);
1820: }
1821: }
1822:
1823: if (!allEnComp) {
1824: // Increment the framecount for compaction ...
1825: frameCount++;
1826: if (frameCount > frameCountCutoff) {
1827: frameCount = 0;
1828: checkForCompaction();
1829: } else if (frameCount == notVisibleCount) {
1830: removeCutoffTime = referenceTime;
1831: }
1832: }
1833: }
1834: // Reset dirty bits.
1835: visGAIsDirty = false;
1836: visQuery = false;
1837:
1838: }
1839: // Two environments are dirty
1840: // If lights, fog or model clip have been added/removed, then
1841: // reEvaluate RenderAtoms and mark the lightbin and
1842: // env set dirty if applicable
1843: if (envDirty == REEVALUATE_ALL_ENV || envDirty == 3
1844: || envDirty > 4) {
1845: reEvaluateEnv(changedLts, changedFogs, changedModelClips,
1846: true, altAppearanceDirty);
1847: } else if (envDirty == 0 && altAppearanceDirty) {
1848: reEvaluateAlternateAppearance();
1849: } else {
1850: if ((envDirty & REEVALUATE_LIGHTS) != 0) {
1851: reEvaluateLights(altAppearanceDirty);
1852: } else if ((envDirty & REEVALUATE_FOG) != 0)
1853: reEvaluateFog(changedFogs, (changedFogs.size() > 0),
1854: altAppearanceDirty);
1855: else if ((envDirty & REEVALUATE_MCLIP) != 0)
1856: reEvaluateModelClip(changedModelClips,
1857: (changedModelClips.size() > 0),
1858: altAppearanceDirty);
1859: }
1860:
1861: // do any pre-update node component screening
1862:
1863: if (updateCheckList.size() > 0) {
1864: int size = updateCheckList.size();
1865: NodeComponentUpdate bin;
1866: for (int k = 0; k < size; k++) {
1867: bin = (NodeComponentUpdate) updateCheckList.get(k);
1868: bin.updateNodeComponentCheck();
1869: }
1870: updateCheckList.clear();
1871: }
1872:
1873: changedLts.clear();
1874: changedFogs.clear();
1875: changedModelClips.clear();
1876: envDirty = 0;
1877: altAppearanceDirty = false;
1878:
1879: view.renderBinReady = true;
1880:
1881: VirtualUniverse.mc
1882: .sendRunMessage(view, J3dThread.RENDER_THREAD);
1883: }
1884:
1885: void processSwitchChanged(J3dMessage m, long refTime) {
1886: int i;
1887: UnorderList arrList;
1888: int size;
1889: Object[] nodes, nodesArr;
1890: LeafRetained leaf;
1891:
1892: RenderingEnvironmentStructure rdrEnvStr = universe.renderingEnvironmentStructure;
1893:
1894: UpdateTargets targets = (UpdateTargets) m.args[0];
1895: arrList = targets.targetList[Targets.ENV_TARGETS];
1896:
1897: if (arrList != null) {
1898: size = arrList.size();
1899: nodesArr = arrList.toArray(false);
1900:
1901: for (int h = 0; h < size; h++) {
1902: nodes = (Object[]) nodesArr[h];
1903: for (i = 0; i < nodes.length; i++) {
1904:
1905: if (nodes[i] instanceof LightRetained
1906: && rdrEnvStr.isLightScopedToThisView(
1907: nodes[i], view)) {
1908: envDirty |= REEVALUATE_LIGHTS;
1909: } else if (nodes[i] instanceof FogRetained
1910: && rdrEnvStr.isFogScopedToThisView(
1911: nodes[i], view)) {
1912: envDirty |= REEVALUATE_FOG;
1913: } else if (nodes[i] instanceof ModelClipRetained
1914: && rdrEnvStr.isMclipScopedToThisView(
1915: nodes[i], view)) {
1916: envDirty |= REEVALUATE_MCLIP;
1917: } else if (nodes[i] instanceof BackgroundRetained
1918: && rdrEnvStr.isBgScopedToThisView(nodes[i],
1919: view)) {
1920: reEvaluateBg = true;
1921: } else if (nodes[i] instanceof ClipRetained
1922: && rdrEnvStr.isClipScopedToThisView(
1923: nodes[i], view)) {
1924: reEvaluateClip = true;
1925: } else if (nodes[i] instanceof AlternateAppearanceRetained
1926: && rdrEnvStr.isAltAppScopedToThisView(
1927: nodes[i], view)) {
1928: altAppearanceDirty = true;
1929: }
1930: }
1931: }
1932: }
1933:
1934: arrList = targets.targetList[Targets.BLN_TARGETS];
1935: if (arrList != null) {
1936: size = arrList.size();
1937: nodesArr = arrList.toArray(false);
1938: Object[] objArr = (Object[]) m.args[1];
1939: Object[] obj, users;
1940: BoundingLeafRetained mbleaf;
1941:
1942: for (int h = 0; h < size; h++) {
1943: nodes = (Object[]) nodesArr[h];
1944: obj = (Object[]) objArr[h];
1945: for (i = 0; i < nodes.length; i++) {
1946:
1947: users = (Object[]) obj[i];
1948: mbleaf = (BoundingLeafRetained) nodes[i];
1949: for (int j = 0; j < users.length; j++) {
1950:
1951: if (users[j] instanceof FogRetained
1952: && rdrEnvStr.isFogScopedToThisView(
1953: users[j], view)) {
1954: envDirty |= REEVALUATE_FOG;
1955: } else if (users[j] instanceof LightRetained
1956: && rdrEnvStr.isLightScopedToThisView(
1957: users[j], view)) {
1958: envDirty |= REEVALUATE_LIGHTS;
1959: } else if (users[j] instanceof ModelClipRetained
1960: && rdrEnvStr.isMclipScopedToThisView(
1961: users[j], view)) {
1962: envDirty |= REEVALUATE_MCLIP;
1963: } else if (users[j] instanceof AlternateAppearanceRetained
1964: && rdrEnvStr.isAltAppScopedToThisView(
1965: users[j], view)) {
1966: altAppearanceDirty = true;
1967: } else if (users[j] instanceof BackgroundRetained
1968: && rdrEnvStr.isBgScopedToThisView(
1969: users[j], view)) {
1970: reEvaluateBg = true;
1971: } else if (users[j] instanceof ClipRetained
1972: && rdrEnvStr.isClipScopedToThisView(
1973: users[j], view)) {
1974: reEvaluateClip = true;
1975: }
1976: }
1977: }
1978: }
1979: }
1980: }
1981:
1982: /**
1983: * Transparency/Line/point/Poly attributes is different from other renderMolecule
1984: * attributes since the renderatom could move from opaque bin
1985: * to transparent bin
1986: */
1987: void processPossibleBinChanged(Object[] args) {
1988: int i;
1989: GeometryAtom[] gaArr = (GeometryAtom[]) args[3];
1990: for (i = 0; i < gaArr.length; i++) {
1991: RenderAtom ra = gaArr[i].getRenderAtom(view);
1992: if (ra == null || !ra.inRenderBin())
1993: continue;
1994: // If renderAtom is in orderedGroup or with this
1995: // change continues to be in the same higher level
1996: // lightBin(transparent or opaque) then reInsert at
1997: // the textureBin level, other Insert at the lightBin
1998: // level
1999: TextureBin tb = ra.renderMolecule.textureBin;
2000: ra.renderMolecule.removeRenderAtom(ra);
2001: reInsertRenderAtom(tb, ra);
2002: }
2003: }
2004:
2005: /**
2006: * This processes a materiala and other rendermolecule node comp change.
2007: */
2008: void processRenderMoleculeNodeComponentChanged(Object[] args,
2009: int mask, int start, boolean restructure) {
2010: int i;
2011: NodeComponentRetained nc = (NodeComponentRetained) args[0];
2012: GeometryAtom[] gaArr = (GeometryAtom[]) args[3];
2013: for (i = start; i < gaArr.length; i++) {
2014: RenderAtom ra = gaArr[i].getRenderAtom(view);
2015: if (ra == null || !ra.inRenderBin())
2016: continue;
2017: // Check if the changed renderAtom is already in
2018: // a separate bin - this is to handle the case
2019: // when it has been changed to frequent, then to
2020: // infrequent and then to frequent again!
2021: // If the bin is in soleUser case and one of the components
2022: // has been changed to frequent then remove the clone
2023: // and point to the mirror
2024: // System.err.println("restructure = "+restructure+" ra.renderMolecule.soleUser ="+ra.renderMolecule.soleUser);
2025: if (restructure && !ra.renderMolecule.soleUser) {
2026: TextureBin tb = ra.renderMolecule.textureBin;
2027: ra.renderMolecule.removeRenderAtom(ra);
2028: reInsertRenderAtom(tb, ra);
2029: /*
2030: if (nc.mirror.changedFrequent != 0) {
2031: if ((ra.renderMolecule.soleUserCompDirty& RenderMolecule.ALL_DIRTY_BITS) == 0 ) {
2032: rmUpdateList.add(ra.renderMolecule);
2033: }
2034: ra.renderMolecule.soleUserCompDirty |= mask;
2035: }
2036: */
2037: } else {
2038: if ((ra.renderMolecule.soleUserCompDirty & RenderMolecule.ALL_DIRTY_BITS) == 0) {
2039: rmUpdateList.add(ra.renderMolecule);
2040: }
2041: ra.renderMolecule.soleUserCompDirty |= mask;
2042: }
2043: }
2044:
2045: }
2046:
2047: void processTextureAttributesChanged(NodeComponentRetained nc,
2048: GeometryAtom[] gaArr) {
2049:
2050: RenderAtom ra = null;
2051: TextureBin tb;
2052: ShaderBin sb;
2053: boolean reInsertNeeded = false;
2054:
2055: if (nc.mirror.changedFrequent == 0) {
2056: reInsertNeeded = true;
2057: }
2058:
2059: for (int k = 0; k < gaArr.length; k++) {
2060: ra = gaArr[k].getRenderAtom(view);
2061: if (ra == null || !ra.inRenderBin()) {
2062: continue;
2063: }
2064:
2065: tb = ra.renderMolecule.textureBin;
2066:
2067: if (!reInsertNeeded) {
2068:
2069: // if changedFrequent is not zero, then need
2070: // to check if the node component is currently
2071: // in an equivalent bin or not. If it is in an
2072: // equivalent bin, then the affected ra needs to
2073: // be reinserted to a bin with a soleUser
2074: // TextureAttributes
2075:
2076: for (int t = 0; t < tb.texUnitState.length; t++) {
2077:
2078: if (tb.texUnitState[t] == null) {
2079: continue;
2080:
2081: } else if (tb.texUnitState[t].texAttrs == nc.mirror) {
2082: // the TextureAttributes is already in
2083: // a sole user position, no need to do anything;
2084: // can bail out now
2085: return;
2086: }
2087: }
2088: }
2089:
2090: if ((tb.tbFlag & TextureBin.SOLE_USER) != 0) {
2091:
2092: // if the TextureBin is a sole user, then
2093: // no need to reInsert, just simply update the
2094: // TextureAttributes references @update
2095:
2096: if (tb.soleUserCompDirty == 0) {
2097: tbUpdateList.add(tb);
2098: }
2099:
2100: tb.soleUserCompDirty |= TextureBin.SOLE_USER_DIRTY_TA;
2101:
2102: } else {
2103: sb = ra.renderMolecule.textureBin.shaderBin;
2104: ra.renderMolecule.removeRenderAtom(ra);
2105: reInsertTextureBin(sb, ra);
2106: }
2107: }
2108: }
2109:
2110: void processTexCoordGenerationChanged(NodeComponentRetained nc,
2111: GeometryAtom[] gaArr) {
2112:
2113: RenderAtom ra = null;
2114: TextureBin tb;
2115: ShaderBin sb;
2116: boolean reInsertNeeded = false;
2117:
2118: if (nc.mirror.changedFrequent == 0) {
2119: reInsertNeeded = true;
2120: }
2121:
2122: for (int k = 0; k < gaArr.length; k++) {
2123: ra = gaArr[k].getRenderAtom(view);
2124: if (ra == null || !ra.inRenderBin()) {
2125: continue;
2126: }
2127:
2128: tb = ra.renderMolecule.textureBin;
2129:
2130: if (!reInsertNeeded) {
2131:
2132: // if changedFrequent is not zero, then need
2133: // to check if the node component is currently
2134: // in an equivalent bin or not. If it is in an
2135: // equivalent bin, then the affected ra needs to
2136: // be reinserted to a bin with a soleUser
2137: // TexCoordGeneration
2138:
2139: for (int t = 0; t < tb.texUnitState.length; t++) {
2140:
2141: if (tb.texUnitState[t] == null) {
2142: continue;
2143:
2144: } else if (tb.texUnitState[t].texGen == nc.mirror) {
2145: // the TexCoordGeneration is already in
2146: // a sole user position, no need to do anything;
2147: // can bail out now
2148: return;
2149: }
2150: }
2151: }
2152:
2153: if ((tb.tbFlag & TextureBin.SOLE_USER) != 0) {
2154:
2155: // if the TextureBin is a sole user, then
2156: // no need to reInsert, just simply update the
2157: // TexCoordGeneration references @update
2158:
2159: if (tb.soleUserCompDirty == 0) {
2160: tbUpdateList.add(tb);
2161: }
2162:
2163: tb.soleUserCompDirty |= TextureBin.SOLE_USER_DIRTY_TC;
2164:
2165: } else {
2166: sb = ra.renderMolecule.textureBin.shaderBin;
2167: ra.renderMolecule.removeRenderAtom(ra);
2168: reInsertTextureBin(sb, ra);
2169: }
2170: }
2171: }
2172:
2173: void processTextureChanged(NodeComponentRetained nc,
2174: GeometryAtom[] gaArr, Object args[]) {
2175:
2176: RenderAtom ra = null;
2177: TextureBin tb;
2178: ShaderBin sb;
2179: boolean reInsertNeeded = false;
2180: int command = ((Integer) args[1]).intValue();
2181:
2182: switch (command) {
2183: case TextureRetained.ENABLE_CHANGED: {
2184: for (int i = 0; i < gaArr.length; i++) {
2185: ra = gaArr[i].getRenderAtom(view);
2186:
2187: if (ra == null || !ra.inRenderBin())
2188: continue;
2189:
2190: tb = ra.renderMolecule.textureBin;
2191:
2192: if (tb.soleUserCompDirty == 0) {
2193: // put this texture unit state on the sole user
2194: // update list if it's not already there
2195: tbUpdateList.add(tb);
2196: }
2197:
2198: tb.soleUserCompDirty |= TextureBin.SOLE_USER_DIRTY_TEXTURE;
2199: }
2200: break;
2201: }
2202: case TextureRetained.IMAGE_CHANGED: {
2203:
2204: TextureRetained texture = (TextureRetained) nc.mirror;
2205: Object imgChangedArgs[] = (Object[]) args[2];
2206: int level = ((Integer) imgChangedArgs[0]).intValue();
2207: int face = ((Integer) imgChangedArgs[2]).intValue();
2208: ImageComponent newImage = (ImageComponent) imgChangedArgs[1];
2209: ImageComponentRetained oldImage;
2210:
2211: // first remove the old image from the RenderBin's
2212: // node component list if necessary.
2213: // Note: image reference in the texture mirror object
2214: // is not updated yet, so it's ok to reference
2215: // the mirror object for the old image reference
2216:
2217: oldImage = texture.images[face][level];
2218:
2219: // it is possible that oldImage.source == null because
2220: // the mipmap could have been created by the library, and
2221: // hence don't have source
2222:
2223: if (oldImage != null) {
2224: this .removeNodeComponent(oldImage);
2225: }
2226:
2227: // then add the new one to the list if it is byReference or
2228: // modifiable.
2229:
2230: if (newImage != null) {
2231: this .addNodeComponent(newImage.retained);
2232: }
2233: break;
2234: }
2235: case TextureRetained.IMAGES_CHANGED: {
2236: Object imgChangedArgs[] = (Object[]) args[2];
2237: ImageComponent images[] = (ImageComponent[]) imgChangedArgs[0];
2238: int face = ((Integer) imgChangedArgs[1]).intValue();
2239: TextureRetained texture = (TextureRetained) nc.mirror;
2240: ImageComponentRetained oldImage;
2241:
2242: for (int i = 0; i < texture.maxLevels; i++) {
2243:
2244: // first remove the old image from the RenderBin's
2245: // node component list if necessary.
2246: // Note: image reference in the texture mirror object
2247: // is not updated yet, so it's ok to reference
2248: // the mirror object for the old image reference
2249:
2250: oldImage = texture.images[face][i];
2251:
2252: // it is possible that oldImage.source == null because
2253: // the mipmap could have been created by the library, and
2254: // hence don't have source
2255:
2256: if (oldImage != null) {
2257: this .removeNodeComponent(oldImage);
2258: }
2259:
2260: // then add the new one to the list if it is byReference
2261: if (images[i] != null) {
2262: this
2263: .addNodeComponent(((ImageComponent) images[i]).retained);
2264: }
2265: }
2266: break;
2267: }
2268: }
2269: }
2270:
2271: void processTextureUnitStateChanged(NodeComponentRetained nc,
2272: GeometryAtom[] gaArr) {
2273: RenderAtom ra = null;
2274: TextureBin tb;
2275: ShaderBin sb;
2276: boolean mirrorSet = false;
2277: boolean firstTextureBin = true;
2278:
2279: for (int k = 0; k < gaArr.length; k++) {
2280: ra = gaArr[k].getRenderAtom(view);
2281: if (ra == null || !ra.inRenderBin()) {
2282: continue;
2283: }
2284:
2285: tb = ra.renderMolecule.textureBin;
2286:
2287: if (firstTextureBin) {
2288:
2289: for (int t = 0; t < tb.texUnitState.length
2290: && !mirrorSet; t++) {
2291:
2292: if (tb.texUnitState[t] == null) {
2293: continue;
2294:
2295: } else if (tb.texUnitState[t].mirror == nc.mirror) {
2296: mirrorSet = true;
2297: firstTextureBin = false;
2298: }
2299: }
2300: firstTextureBin = false;
2301: }
2302:
2303: if (mirrorSet) {
2304:
2305: if (tb.soleUserCompDirty == 0) {
2306: tbUpdateList.add(tb);
2307: }
2308:
2309: tb.soleUserCompDirty |= TextureBin.SOLE_USER_DIRTY_TUS;
2310:
2311: } else {
2312: sb = ra.renderMolecule.textureBin.shaderBin;
2313: ra.renderMolecule.removeRenderAtom(ra);
2314: reInsertTextureBin(sb, ra);
2315: }
2316: }
2317: }
2318:
2319: /**
2320: * This processes a rendering attribute change.
2321: */
2322:
2323: void processAttributeBinNodeComponentChanged(Object[] args) {
2324: int i;
2325: GeometryAtom[] gaArr = (GeometryAtom[]) args[3];
2326: int component = ((Integer) args[1]).intValue();
2327: NodeComponentRetained nc = (NodeComponentRetained) args[0];
2328:
2329: RenderAtom ra = null;
2330: int start = -1;
2331:
2332: // Get the first ra that is visible
2333: for (i = 0; (i < gaArr.length && (start < 0)); i++) {
2334: ra = gaArr[i].getRenderAtom(view);
2335: if (ra == null || !ra.inRenderBin()) {
2336: continue;
2337: } else {
2338: start = i;
2339: }
2340: }
2341: if (start >= 0) {
2342: // Force restucture, when changedFrequent is zero OR
2343: // when it is changed to changedFrequent the first time OR
2344: // when the ignoreVC changedFrequent flag is set for the first time
2345: // when the last one is set for the first time, we need to force
2346: // any separate dlist in RMs to go thru VA
2347: boolean restructure = (nc.mirror.changedFrequent == 0 || ra.renderMolecule.textureBin.attributeBin.definingRenderingAttributes != nc.mirror);
2348:
2349: if (component != RenderingAttributesRetained.VISIBLE) {
2350: for (i = start; i < gaArr.length; i++) {
2351: ra = gaArr[i].getRenderAtom(view);
2352: if (ra == null || !ra.inRenderBin())
2353: continue;
2354: if (restructure
2355: && !ra.renderMolecule.textureBin.attributeBin.soleUser) {
2356: EnvironmentSet e = ra.renderMolecule.textureBin.environmentSet;
2357: ra.renderMolecule.removeRenderAtom(ra);
2358: reInsertAttributeBin(e, ra);
2359: /*
2360: // If changed Frequent the first time,
2361: // then the cached value
2362: // may not be up-to-date since the nc is
2363: // updated in updateObject
2364: // So, add it to the list so that the cached value can
2365: // be updated
2366: if (nc.mirror.changedFrequent != 0) {
2367: AttributeBin aBin = ra.renderMolecule.textureBin.attributeBin;
2368: if ((aBin.onUpdateList & AttributeBin.ON_CHANGED_FREQUENT_UPDATE_LIST) == 0 ) {
2369: aBinUpdateList.add(aBin);
2370: aBin.onUpdateList |= AttributeBin.ON_CHANGED_FREQUENT_UPDATE_LIST;
2371: }
2372: }
2373: */
2374: } else {
2375: AttributeBin aBin = ra.renderMolecule.textureBin.attributeBin;
2376: if ((aBin.onUpdateList & AttributeBin.ON_CHANGED_FREQUENT_UPDATE_LIST) == 0) {
2377: aBinUpdateList.add(aBin);
2378: aBin.onUpdateList |= AttributeBin.ON_CHANGED_FREQUENT_UPDATE_LIST;
2379: }
2380: }
2381: }
2382: } else {
2383: for (i = start; i < gaArr.length; i++) {
2384: ra = gaArr[i].getRenderAtom(view);
2385:
2386: if (ra == null || !ra.inRenderBin())
2387: continue;
2388: renderAtoms.remove(renderAtoms.indexOf(ra));
2389: removeARenderAtom(ra);
2390: }
2391: }
2392: }
2393: }
2394:
2395: /**
2396: * This processes a shader component change.
2397: */
2398: void processShaderComponentChanged(Object[] args) {
2399:
2400: // System.err.println("RenderBin : processShaderComponentChanged");
2401:
2402: int component = ((Integer) args[1]).intValue();
2403: int i;
2404: GeometryAtom[] gaArr = (GeometryAtom[]) args[3];
2405: GeometryAtom ga;
2406: RenderAtom ra = null;
2407: /* TODO : JADA - Sole user logic is incomplete. Will disable for JavaOne */
2408: // Note : args[0] may be a ShaderAppearanceRetained or ShaderAttributeSetRetained
2409: //ShaderAppearanceRetained sApp = (ShaderAppearanceRetained) args[0];
2410: int start = -1;
2411:
2412: // Get the first ra that is visible
2413: for (i = 0; (i < gaArr.length && (start < 0)); i++) {
2414: ra = gaArr[i].getRenderAtom(view);
2415: if (ra == null || !ra.inRenderBin()) {
2416: continue;
2417: } else {
2418: start = i;
2419: }
2420: }
2421: if (start >= 0) {
2422:
2423: // Issue 471 - Don't check ATTRIBUTE_VALUE_UPDATE, there is no need
2424: // to do anything to the shader bins when a value changes.
2425: boolean spUpdate = ((component & ShaderAppearanceRetained.SHADER_PROGRAM) != 0);
2426: boolean sasUpdate = (((component & ShaderAppearanceRetained.SHADER_ATTRIBUTE_SET) != 0)
2427: || ((component & ShaderConstants.ATTRIBUTE_SET_PUT) != 0)
2428: || ((component & ShaderConstants.ATTRIBUTE_SET_REMOVE) != 0) || ((component & ShaderConstants.ATTRIBUTE_SET_CLEAR) != 0));
2429:
2430: if (spUpdate) {
2431: /* TODO : JADA - Sole user logic is incomplete. Will disable for JavaOne */
2432: //if (false && (sApp.mirror.changedFrequent & component) != 0) {
2433: if (false) {
2434: /*
2435: System.err.println("RenderBin : Shader sole user (SHADER_PROGRAM)" +
2436: ra.renderMolecule.textureBin.shaderBin);
2437: */
2438:
2439: ShaderBin sBin;
2440:
2441: for (i = start; i < gaArr.length; i++) {
2442: ra = gaArr[i].getRenderAtom(view);
2443: if (ra == null || !ra.inRenderBin())
2444: continue;
2445:
2446: sBin = ra.renderMolecule.textureBin.shaderBin;
2447:
2448: if (sBin.componentDirty == 0) {
2449: sBinUpdateList.add(sBin);
2450: sBin.componentDirty |= ShaderBin.SHADER_PROGRAM_DIRTY;
2451: }
2452: }
2453: } else {
2454: /*
2455: System.err.println("RenderBin : not soleUser (SHADER_PROGRAM)" +
2456: ra.renderMolecule.textureBin.shaderBin);
2457: */
2458:
2459: for (i = 0; i < gaArr.length; i++) {
2460: ra = gaArr[i].getRenderAtom(view);
2461: if (ra == null || !ra.inRenderBin())
2462: continue;
2463:
2464: AttributeBin attrBin = ra.renderMolecule.textureBin.attributeBin;
2465: ra.renderMolecule.removeRenderAtom(ra);
2466: reInsertShaderBin(attrBin, ra);
2467: }
2468: }
2469: } else if (sasUpdate) {
2470: /* TODO : JADA - Sole user logic is incomplete. Will disable for JavaOne */
2471: //if (false && (sApp.mirror.changedFrequent & component) != 0) {
2472: if (false) {
2473: /*
2474: System.err.println("RenderBin : sole user (SHADER_ATTRIBUTE_SET)" +
2475: ra.renderMolecule.textureBin.shaderBin);
2476: */
2477:
2478: ShaderBin sBin;
2479:
2480: for (i = 0; i < gaArr.length; i++) {
2481: ra = gaArr[i].getRenderAtom(view);
2482: if (ra == null || !ra.inRenderBin())
2483: continue;
2484:
2485: sBin = ra.renderMolecule.textureBin.shaderBin;
2486:
2487: if (sBin.componentDirty == 0) {
2488: sBinUpdateList.add(sBin);
2489: sBin.componentDirty |= ShaderBin.SHADER_ATTRIBUTE_SET_DIRTY;
2490: }
2491: }
2492: } else {
2493: /*
2494: System.err.println("RenderBin :not soleUser (SHADER_ATTRIBUTE_SET) " +
2495: ra.renderMolecule.textureBin.shaderBin);
2496: */
2497:
2498: for (i = 0; i < gaArr.length; i++) {
2499: ra = gaArr[i].getRenderAtom(view);
2500: if (ra == null || !ra.inRenderBin())
2501: continue;
2502:
2503: AttributeBin attrBin = ra.renderMolecule.textureBin.attributeBin;
2504: ra.renderMolecule.removeRenderAtom(ra);
2505: reInsertShaderBin(attrBin, ra);
2506: }
2507: }
2508: }
2509: }
2510:
2511: }
2512:
2513: void processFogChanged(Object[] args) {
2514: FogRetained fog = (FogRetained) args[0];
2515: EnvironmentSet e;
2516: int component = ((Integer) args[1]).intValue();
2517:
2518: if ((component & (FogRetained.SCOPE_CHANGED
2519: | FogRetained.BOUNDS_CHANGED | FogRetained.BOUNDINGLEAF_CHANGED)) != 0) {
2520: envDirty |= REEVALUATE_FOG;
2521: } else {
2522: UnorderList list = fog.mirrorFog.environmentSets;
2523: synchronized (list) {
2524: EnvironmentSet envsets[] = (EnvironmentSet[]) list
2525: .toArray(false);
2526: int size = list.size();
2527: for (int i = 0; i < size; i++) {
2528: e = envsets[i];
2529: e.canvasDirty |= Canvas3D.FOG_DIRTY;
2530: if (!e.onUpdateList) {
2531: objUpdateList.add(e);
2532: e.onUpdateList = true;
2533: }
2534: }
2535: }
2536: }
2537: }
2538:
2539: /**
2540: * This routine get called whenever a component of the appearance
2541: * changes
2542: */
2543: void processAppearanceChanged(Object[] args) {
2544: int component = ((Integer) args[1]).intValue();
2545: int i;
2546: GeometryAtom[] gaArr = (GeometryAtom[]) args[3];
2547: GeometryAtom ga;
2548: RenderAtom ra = null;
2549: AppearanceRetained app = (AppearanceRetained) args[0];
2550: int TEXTURE_STATE_CHANGED = AppearanceRetained.TEXTURE_UNIT_STATE
2551: | AppearanceRetained.TEXTURE
2552: | AppearanceRetained.TEXTURE_ATTR
2553: | AppearanceRetained.TEXCOORD_GEN;
2554:
2555: int start = -1;
2556:
2557: // Get the first ra that is visible
2558: for (i = 0; (i < gaArr.length && (start < 0)); i++) {
2559: ra = gaArr[i].getRenderAtom(view);
2560: if (ra == null || !ra.inRenderBin()) {
2561: continue;
2562: } else {
2563: start = i;
2564: }
2565: }
2566:
2567: if (start >= 0) {
2568:
2569: if ((component & TEXTURE_STATE_CHANGED) != 0) {
2570:
2571: if (((app.mirror.changedFrequent & TEXTURE_STATE_CHANGED) != 0)
2572: && ((ra.renderMolecule.textureBin.tbFlag & TextureBin.SOLE_USER) != 0)) {
2573:
2574: /*
2575: System.err.println("renderbin. texture state changed tb sole user " +
2576: ra.renderMolecule.textureBin + " tb.tbFlag= " +
2577: ra.renderMolecule.textureBin.tbFlag);
2578: */
2579:
2580: TextureBin tb;
2581:
2582: for (i = start; i < gaArr.length; i++) {
2583: ra = gaArr[i].getRenderAtom(view);
2584: if (ra == null || !ra.inRenderBin())
2585: continue;
2586:
2587: tb = ra.renderMolecule.textureBin;
2588: if (tb.soleUserCompDirty == 0) {
2589: tbUpdateList.add(tb);
2590: }
2591:
2592: // mark that the texture unit state ref is changed
2593: // also mark that the TextureBin needs to reevaluate
2594: // number of active textures
2595: tb.soleUserCompDirty |= TextureBin.SOLE_USER_DIRTY_REF;
2596: }
2597: } else {
2598: /*
2599: System.err.println("renderbin. texture state changed tb not sole user " +
2600: ra.renderMolecule.textureBin + " tb.tbFlag= " +
2601: ra.renderMolecule.textureBin.tbFlag);
2602:
2603: System.err.println("......tb.soleUser= " +
2604: ((ra.renderMolecule.textureBin.tbFlag & TextureBin.SOLE_USER) != 0) +
2605: " app.mirror.changedFrequent= " +
2606: ((app.mirror.changedFrequent & TEXTURE_STATE_CHANGED) != 0));
2607:
2608: */
2609:
2610: for (i = start; i < gaArr.length; i++) {
2611: ra = gaArr[i].getRenderAtom(view);
2612: if (ra == null || !ra.inRenderBin())
2613: continue;
2614: ShaderBin sb = ra.renderMolecule.textureBin.shaderBin;
2615: ra.renderMolecule.removeRenderAtom(ra);
2616: reInsertTextureBin(sb, ra);
2617: }
2618: }
2619: } else if ((component & AppearanceRetained.RENDERING) != 0) {
2620: boolean visible = ((Boolean) args[4]).booleanValue();
2621: visGAIsDirty = true;
2622: visQuery = true;
2623: if (!visible) {
2624: // remove all gaAttrs
2625: for (i = start; i < gaArr.length; i++) {
2626: ra = gaArr[i].getRenderAtom(view);
2627:
2628: if (ra == null || !ra.inRenderBin())
2629: continue;
2630: renderAtoms.remove(renderAtoms.indexOf(ra));
2631: removeARenderAtom(ra);
2632: }
2633: } else {
2634: if ((app.mirror.changedFrequent & component) != 0
2635: && ra.renderMolecule.textureBin.attributeBin.soleUser) {
2636: for (i = start; i < gaArr.length; i++) {
2637: ra = gaArr[i].getRenderAtom(view);
2638: if (ra == null || !ra.inRenderBin())
2639: continue;
2640:
2641: AttributeBin aBin = ra.renderMolecule.textureBin.attributeBin;
2642: if ((aBin.onUpdateList & AttributeBin.ON_CHANGED_FREQUENT_UPDATE_LIST) == 0) {
2643: aBinUpdateList.add(aBin);
2644: aBin.onUpdateList |= AttributeBin.ON_CHANGED_FREQUENT_UPDATE_LIST;
2645: }
2646:
2647: }
2648: } else {
2649: for (i = start; i < gaArr.length; i++) {
2650: ra = gaArr[i].getRenderAtom(view);
2651: if (ra == null || !ra.inRenderBin())
2652: continue;
2653: EnvironmentSet e = ra.renderMolecule.textureBin.environmentSet;
2654: ra.renderMolecule.removeRenderAtom(ra);
2655: reInsertAttributeBin(e, ra);
2656: }
2657: }
2658: }
2659: }
2660:
2661: else if ((component & (AppearanceRetained.COLOR
2662: | AppearanceRetained.MATERIAL
2663: | AppearanceRetained.TRANSPARENCY
2664: | AppearanceRetained.POLYGON
2665: | AppearanceRetained.LINE | AppearanceRetained.POINT)) != 0) {
2666: // System.err.println("AppearanceRetained.POINT = "+AppearanceRetained.POINT);
2667: // System.err.println("(app.mirror.changedFrequent & component) != 0 "+app.mirror.changedFrequent );
2668: // System.err.println("ra.renderMolecule.soleUser "+ra.renderMolecule.soleUser);
2669: if ((app.mirror.changedFrequent & component) != 0
2670: && ra.renderMolecule.soleUser) {
2671: for (i = start; i < gaArr.length; i++) {
2672: ra = gaArr[i].getRenderAtom(view);
2673: if (ra == null || !ra.inRenderBin())
2674: continue;
2675:
2676: if ((ra.renderMolecule.soleUserCompDirty & RenderMolecule.ALL_DIRTY_BITS) == 0) {
2677: rmUpdateList.add(ra.renderMolecule);
2678: }
2679: ra.renderMolecule.soleUserCompDirty |= component;
2680:
2681: }
2682:
2683: } else {
2684: for (i = start; i < gaArr.length; i++) {
2685: ra = gaArr[i].getRenderAtom(view);
2686: if (ra == null || !ra.inRenderBin())
2687: continue;
2688: TextureBin tb = ra.renderMolecule.textureBin;
2689: ra.renderMolecule.removeRenderAtom(ra);
2690: reInsertRenderAtom(tb, ra);
2691:
2692: }
2693: }
2694: }
2695: } else {
2696: // Nothing is visible
2697: if ((component & AppearanceRetained.RENDERING) != 0) {
2698: // Rendering attributes change
2699: visGAIsDirty = true;
2700: visQuery = true;
2701: }
2702: }
2703: }
2704:
2705: void processModelClipChanged(Object[] args) {
2706: ModelClipRetained modelClip = (ModelClipRetained) args[0];
2707: EnvironmentSet e;
2708: int component = ((Integer) args[1]).intValue();
2709:
2710: if ((component & (ModelClipRetained.SCOPE_CHANGED
2711: | ModelClipRetained.BOUNDS_CHANGED | ModelClipRetained.BOUNDINGLEAF_CHANGED)) != 0) {
2712: envDirty |= REEVALUATE_MCLIP;
2713:
2714: } else if ((component & (ModelClipRetained.ENABLE_CHANGED | ModelClipRetained.ENABLES_CHANGED)) != 0) {
2715: // need to render modelclip
2716: if (!changedModelClips.contains(modelClip.mirrorModelClip))
2717: changedModelClips.add(modelClip.mirrorModelClip);
2718:
2719: // need to reevaluate envset
2720: envDirty |= REEVALUATE_MCLIP;
2721:
2722: } else {
2723: UnorderList list = modelClip.mirrorModelClip.environmentSets;
2724: synchronized (list) {
2725: EnvironmentSet envsets[] = (EnvironmentSet[]) list
2726: .toArray(false);
2727: int size = list.size();
2728: for (int i = 0; i < size; i++) {
2729: e = envsets[i];
2730: e.canvasDirty |= Canvas3D.MODELCLIP_DIRTY;
2731: if (!e.onUpdateList) {
2732: objUpdateList.add(e);
2733: e.onUpdateList = true;
2734: }
2735: }
2736: }
2737: }
2738: }
2739:
2740: /**
2741: * This routine get called whenever a region of the boundingleaf
2742: * changes
2743: */
2744: void processBoundingLeafChanged(Object[] args, long refTime) {
2745: // Notify all users of this bounding leaf, it may
2746: // result in the re-evaluation of the lights/fogs/backgrounds
2747: Object[] users = (Object[]) (args[3]);
2748: int i;
2749:
2750: // XXXX: Handle other object affected by bounding leaf changes
2751: for (i = 0; i < users.length; i++) {
2752: LeafRetained leaf = (LeafRetained) users[i];
2753: switch (leaf.nodeType) {
2754: case NodeRetained.AMBIENTLIGHT:
2755: case NodeRetained.POINTLIGHT:
2756: case NodeRetained.SPOTLIGHT:
2757: case NodeRetained.DIRECTIONALLIGHT:
2758: if (universe.renderingEnvironmentStructure
2759: .isLightScopedToThisView(leaf, view))
2760: envDirty |= REEVALUATE_LIGHTS;
2761: break;
2762: case NodeRetained.LINEARFOG:
2763: case NodeRetained.EXPONENTIALFOG:
2764: if (universe.renderingEnvironmentStructure
2765: .isFogScopedToThisView(leaf, view))
2766: envDirty |= REEVALUATE_FOG;
2767: break;
2768: case NodeRetained.BACKGROUND:
2769: if (universe.renderingEnvironmentStructure
2770: .isBgScopedToThisView(leaf, view))
2771: reEvaluateBg = true;
2772: break;
2773: case NodeRetained.CLIP:
2774: if (universe.renderingEnvironmentStructure
2775: .isClipScopedToThisView(leaf, view))
2776: reEvaluateClip = true;
2777: break;
2778: case NodeRetained.MODELCLIP:
2779: if (universe.renderingEnvironmentStructure
2780: .isMclipScopedToThisView(leaf, view))
2781: envDirty |= REEVALUATE_MCLIP;
2782: break;
2783: case NodeRetained.ALTERNATEAPPEARANCE:
2784: if (universe.renderingEnvironmentStructure
2785: .isAltAppScopedToThisView(leaf, view))
2786: altAppearanceDirty = true;
2787: break;
2788: default:
2789: break;
2790: }
2791: }
2792:
2793: }
2794:
2795: void processOrientedShape3DChanged(Object[] gaArr) {
2796:
2797: RenderAtom ra;
2798: for (int i = 0; i < gaArr.length; i++) {
2799: ra = ((GeometryAtom) gaArr[i]).getRenderAtom(view);
2800: if (ra != null && ra.inRenderBin()
2801: && !ra.inDirtyOrientedRAs()) {
2802: dirtyOrientedRAs.add(ra);
2803: ra.dirtyMask |= RenderAtom.IN_DIRTY_ORIENTED_RAs;
2804: }
2805: }
2806: }
2807:
2808: void processShapeChanged(Object[] args, long refTime) {
2809:
2810: int component = ((Integer) args[1]).intValue();
2811: int i;
2812: RenderAtom ra;
2813: RenderAtom raNext;
2814: EnvironmentSet e;
2815: TextureBin tb;
2816: if ((component & Shape3DRetained.APPEARANCE_CHANGED) != 0) {
2817: GeometryAtom[] gaArr = (GeometryAtom[]) args[4];
2818: if (gaArr.length > 0) {
2819: if (!gaArr[0].source.appearanceOverrideEnable) {
2820: for (i = 0; i < gaArr.length; i++) {
2821: ra = gaArr[i].getRenderAtom(view);
2822: if (ra == null || !ra.inRenderBin()) {
2823: continue;
2824: }
2825: ra.app = ra.geometryAtom.source.appearance;
2826: e = ra.renderMolecule.textureBin.environmentSet;
2827: ra.renderMolecule.removeRenderAtom(ra);
2828: reInsertAttributeBin(e, ra);
2829: }
2830: } else {
2831: for (i = 0; i < gaArr.length; i++) {
2832: ra = gaArr[i].getRenderAtom(view);
2833: if (ra == null || !ra.inRenderBin()) {
2834: continue;
2835: }
2836: // if its using the alternate appearance continue ..
2837: if (ra.app == ra.geometryAtom.source.otherAppearance)
2838: continue;
2839: ra.app = ra.geometryAtom.source.appearance;
2840: e = ra.renderMolecule.textureBin.environmentSet;
2841: ra.renderMolecule.removeRenderAtom(ra);
2842: reInsertAttributeBin(e, ra);
2843: }
2844: }
2845: }
2846: } else if ((component & Shape3DRetained.GEOMETRY_CHANGED) != 0) {
2847: processDataChanged((Object[]) args[2], (Object[]) args[3],
2848: refTime);
2849: } else if ((component & Shape3DRetained.APPEARANCEOVERRIDE_CHANGED) != 0) {
2850: AppearanceRetained app, saveApp = null;
2851: Shape3DRetained saveShape = null;
2852: GeometryAtom[] gaArr = (GeometryAtom[]) args[4];
2853: Object[] retVal;
2854: for (i = 0; i < gaArr.length; i++) {
2855: ra = gaArr[i].getRenderAtom(view);
2856: if (ra == null || !ra.inRenderBin())
2857: continue;
2858: // Once shape could have many geometryAtoms, add the
2859: // mirrorShape as a user of an appearance only once
2860:
2861: if (saveShape != ra.geometryAtom.source) {
2862: saveShape = ra.geometryAtom.source;
2863: if (ra.geometryAtom.source.appearanceOverrideEnable) {
2864: retVal = universe.renderingEnvironmentStructure
2865: .getInfluencingAppearance(ra, view);
2866: saveShape.otherAppearance = (AppearanceRetained) retVal[1];
2867: if (retVal[0] == Boolean.TRUE) {
2868: app = (AppearanceRetained) retVal[1];
2869: if (app != null) {
2870: app.sgApp.addAMirrorUser(saveShape);
2871: }
2872: } else {// use the default
2873: app = ra.geometryAtom.source.appearance;
2874: }
2875: } else {
2876: // If it were using the alternate appearance
2877: // remove itself as the user
2878: if (ra.app == saveShape.otherAppearance
2879: && ra.app != null) {
2880: ra.app.sgApp.removeAMirrorUser(saveShape);
2881: }
2882: app = ra.geometryAtom.source.appearance;
2883: saveShape.otherAppearance = null;
2884: }
2885: saveApp = app;
2886: } else {
2887: app = saveApp;
2888: }
2889: ra.app = app;
2890: e = ra.renderMolecule.textureBin.environmentSet;
2891: ra.renderMolecule.removeRenderAtom(ra);
2892: reInsertAttributeBin(e, ra);
2893: }
2894: }
2895:
2896: }
2897:
2898: /**
2899: * Process a Text3D data change. This involves removing all the
2900: * old geometry atoms in the list, and the creating new ones.
2901: */
2902: void processDataChanged(Object[] oldGaList, Object[] newGaList,
2903: long referenceTime) {
2904: Shape3DRetained s, src;
2905: RenderAtom ra;
2906: RenderMolecule rm;
2907: int i, j;
2908: Transform3D trans;
2909: ArrayList rmChangedList = new ArrayList(5);
2910: GeometryRetained geo;
2911: GeometryAtom ga;
2912:
2913: for (i = 0; i < oldGaList.length; i++) {
2914: ga = ((GeometryAtom) oldGaList[i]);
2915:
2916: // Make sure that there is atleast one geo that is non-null
2917: geo = null;
2918: for (int k = 0; (k < ga.geometryArray.length && geo == null); k++) {
2919: geo = ga.geometryArray[k];
2920: }
2921: if (geo == null)
2922: continue;
2923:
2924: ra = ga.getRenderAtom(view);
2925:
2926: if (ra != null && ra.inRenderBin()) {
2927: renderAtoms.remove(renderAtoms.indexOf(ra));
2928: removeARenderAtom(ra);
2929: }
2930: }
2931:
2932: visQuery = true;
2933: visGAIsDirty = true;
2934: }
2935:
2936: void processMorphChanged(Object[] args, long refTime) {
2937:
2938: int component = ((Integer) args[1]).intValue();
2939: int i;
2940: RenderAtom ra;
2941: TextureBin tb;
2942: EnvironmentSet e;
2943: RenderAtom raNext;
2944: if ((component & MorphRetained.APPEARANCE_CHANGED) != 0) {
2945: GeometryAtom[] gaArr = (GeometryAtom[]) args[4];
2946: if (gaArr.length > 0) {
2947: if (!gaArr[0].source.appearanceOverrideEnable) {
2948: for (i = 0; i < gaArr.length; i++) {
2949: ra = gaArr[i].getRenderAtom(view);
2950: if (ra == null || !ra.inRenderBin()) {
2951: continue;
2952: }
2953: ra.app = ra.geometryAtom.source.appearance;
2954: e = ra.renderMolecule.textureBin.environmentSet;
2955: ra.renderMolecule.removeRenderAtom(ra);
2956: reInsertAttributeBin(e, ra);
2957: }
2958: } else {
2959: for (i = 0; i < gaArr.length; i++) {
2960: ra = gaArr[i].getRenderAtom(view);
2961: if (ra == null || !ra.inRenderBin())
2962: continue;
2963:
2964: // if its using the alternate appearance continue ..
2965: if (ra.app == ra.geometryAtom.source.otherAppearance)
2966: continue;
2967: ra.app = ra.geometryAtom.source.appearance;
2968: e = ra.renderMolecule.textureBin.environmentSet;
2969: ra.renderMolecule.removeRenderAtom(ra);
2970: reInsertAttributeBin(e, ra);
2971: }
2972: }
2973: }
2974: } else if ((component & MorphRetained.APPEARANCEOVERRIDE_CHANGED) != 0) {
2975: AppearanceRetained app, saveApp = null;
2976: Shape3DRetained saveShape = null;
2977: GeometryAtom[] gaArr = (GeometryAtom[]) args[4];
2978: Object[] retVal;
2979:
2980: for (i = 0; i < gaArr.length; i++) {
2981: ra = gaArr[i].getRenderAtom(view);
2982: if (ra == null || !ra.inRenderBin())
2983: continue;
2984: // Once shape could have many geometryAtoms, add the
2985: // mirrorShape as a user of an appearance only once
2986:
2987: if (saveShape != ra.geometryAtom.source) {
2988: saveShape = ra.geometryAtom.source;
2989: if (ra.geometryAtom.source.appearanceOverrideEnable) {
2990: retVal = universe.renderingEnvironmentStructure
2991: .getInfluencingAppearance(ra, view);
2992: saveShape.otherAppearance = (AppearanceRetained) retVal[1];
2993: if (retVal[0] == Boolean.TRUE) {
2994: app = (AppearanceRetained) retVal[1];
2995: if (app != null) {
2996: app.sgApp.addAMirrorUser(saveShape);
2997: }
2998: } else {// use the default
2999: app = ra.geometryAtom.source.appearance;
3000: }
3001: } else {
3002: // If it were using the alternate appearance
3003: // remove itself as the user
3004: if (ra.app == saveShape.otherAppearance
3005: && ra.app != null) {
3006: ra.app.sgApp.removeAMirrorUser(saveShape);
3007: }
3008: app = ra.geometryAtom.source.appearance;
3009: saveShape.otherAppearance = null;
3010: }
3011: saveApp = app;
3012: } else {
3013: app = saveApp;
3014: }
3015: ra.app = app;
3016: e = ra.renderMolecule.textureBin.environmentSet;
3017: ra.renderMolecule.removeRenderAtom(ra);
3018: reInsertAttributeBin(e, ra);
3019: }
3020: }
3021:
3022: }
3023:
3024: /**
3025: * This routine gets called whenever the position of the view platform
3026: * has changed.
3027: */
3028: void updateViewPlatform(ViewPlatformRetained vp, float radius) {
3029: Transform3D trans = null;
3030: ViewPlatform viewP = view.getViewPlatform();
3031: if (viewP != null
3032: && (ViewPlatformRetained) viewP.retained == vp) {
3033: vpcToVworld = vp.getCurrentLocalToVworld(null);
3034: vpcToVworldDirty = true;
3035: synchronized (vp) {
3036: vp.vprDirtyMask |= View.VPR_VIEWPLATFORM_DIRTY;
3037: }
3038:
3039: // vp schedSphere is already set and transform in
3040: // BehaviorStructure thread which is run before
3041: // RenderBin using vp.updateActivationRadius()
3042: vpSchedSphereInVworld = vp.schedSphere;
3043: reEvaluateBg = true;
3044: reEvaluateClip = true;
3045: }
3046:
3047: }
3048:
3049: /**
3050: * This routine removes the GeometryAtoms from RenderBin
3051: */
3052: void processGeometryAtomsChanged(Object[] gaArr) {
3053: int i;
3054: RenderAtom ra;
3055:
3056: for (i = 0; i < gaArr.length; i++) {
3057: ra = ((GeometryAtom) gaArr[i]).getRenderAtom(view);
3058: if (ra != null && ra.inRenderBin()) {
3059: renderAtoms.remove(renderAtoms.indexOf(ra));
3060: removeARenderAtom(ra);
3061: }
3062: }
3063: }
3064:
3065: /**
3066: * process Geometry changed, mark the display list
3067: * in which renderMolecule is as dirty
3068: */
3069: void processGeometryChanged(Object[] args) {
3070:
3071: Object[] gaList = (Object[]) args[0];
3072:
3073: GeometryRetained g = (GeometryRetained) args[1];
3074: GeometryAtom ga;
3075:
3076: int i;
3077:
3078: for (i = 0; i < gaList.length; i++) {
3079: ga = ((GeometryAtom) gaList[i]);
3080: RenderAtom renderAtom = ga.getRenderAtom(view);
3081: if (renderAtom == null || !renderAtom.inRenderBin()) {
3082: continue;
3083: }
3084:
3085: // Add the renderMolecule to the dirty list so that
3086: // display list will be recreated
3087: int j = 0;
3088: for (j = 0; j < renderAtom.rListInfo.length; j++) {
3089: if (g == renderAtom.rListInfo[j].geometry())
3090: break;
3091: }
3092: RenderAtomListInfo ra = (RenderAtomListInfo) renderAtom.rListInfo[j];
3093: if ((ra.groupType & RenderAtom.DLIST) != 0)
3094: addDirtyRenderMolecule(ra.renderAtom.renderMolecule);
3095:
3096: if ((ra.groupType & RenderAtom.SEPARATE_DLIST_PER_RINFO) != 0) {
3097: addDlistPerRinfo.add(ra);
3098: }
3099:
3100: if ((ra.groupType & RenderAtom.SEPARATE_DLIST_PER_GEO) != 0)
3101: addGeometryDlist(ra);
3102:
3103: // Raster send this message only for setImage()
3104: if (g instanceof RasterRetained) {
3105: Object[] objs = (Object[]) args[2];
3106: Texture2DRetained oldTex = (Texture2DRetained) objs[0];
3107: Texture2DRetained newTex = (Texture2DRetained) objs[1];
3108:
3109: RasterRetained geo = (RasterRetained) ra.geometry();
3110: if (oldTex != null) {
3111: addTextureResourceFreeList(oldTex);
3112: ImageComponentRetained oldImage = oldTex.images[0][0];
3113: if (oldImage != null) {
3114: removeNodeComponent(oldImage);
3115: }
3116: }
3117: if (newTex != null) {
3118: ImageComponentRetained newImage = newTex.images[0][0];
3119: if (newImage != null) {
3120: addNodeComponent(newImage);
3121: }
3122: }
3123: }
3124:
3125: }
3126:
3127: }
3128:
3129: void addTextureBin(TextureBin tb) {
3130: textureBinList.add(tb);
3131: }
3132:
3133: void removeTextureBin(TextureBin tb) {
3134: textureBinList.remove(tb);
3135: }
3136:
3137: void addDirtyRenderMolecule(RenderMolecule rm) {
3138: int i;
3139:
3140: if ((rm.onUpdateList & RenderMolecule.IN_DIRTY_RENDERMOLECULE_LIST) == 0) {
3141: if (rm.onUpdateList == 0) {
3142: objUpdateList.add(rm);
3143: }
3144: rm.onUpdateList |= RenderMolecule.IN_DIRTY_RENDERMOLECULE_LIST;
3145: dirtyRenderMoleculeList.add(rm);
3146: }
3147: }
3148:
3149: void removeDirtyRenderMolecule(RenderMolecule rm) {
3150: int i;
3151: if ((rm.onUpdateList & RenderMolecule.IN_DIRTY_RENDERMOLECULE_LIST) != 0) {
3152: rm.onUpdateList &= ~RenderMolecule.IN_DIRTY_RENDERMOLECULE_LIST;
3153: if (rm.onUpdateList == 0) {
3154: objUpdateList.remove(rm);
3155: }
3156: dirtyRenderMoleculeList.remove(dirtyRenderMoleculeList
3157: .indexOf(rm));
3158: }
3159: }
3160:
3161: void updateDirtyDisplayLists(Canvas3D cv, ArrayList rmList,
3162: ArrayList dlistPerRinfoList, ArrayList raList,
3163: boolean useSharedCtx) {
3164: int size, i, bitMask;
3165: Context ctx;
3166: long timeStamp;
3167:
3168: if (useSharedCtx) {
3169: ctx = cv.screen.renderer.sharedCtx;
3170: cv.makeCtxCurrent(ctx);
3171: bitMask = cv.screen.renderer.rendererBit;
3172: timeStamp = cv.screen.renderer.sharedCtxTimeStamp;
3173: } else {
3174: ctx = cv.ctx;
3175: bitMask = cv.canvasBit;
3176: timeStamp = cv.ctxTimeStamp;
3177: }
3178:
3179: size = rmList.size();
3180:
3181: if (size > 0) {
3182: for (i = size - 1; i >= 0; i--) {
3183: RenderMolecule rm = (RenderMolecule) rmList.get(i);
3184: rm.updateDisplayList(cv);
3185: }
3186: rmList.clear();
3187: }
3188:
3189: size = dlistPerRinfoList.size();
3190:
3191: if (size > 0) {
3192: for (i = size - 1; i >= 0; i--) {
3193: Object[] obj = (Object[]) dlistPerRinfoList.get(i);
3194: dlistRenderMethod.buildDlistPerRinfo(
3195: (RenderAtomListInfo) obj[0],
3196: (RenderMolecule) obj[1], cv);
3197: }
3198: dlistPerRinfoList.clear();
3199: }
3200:
3201: size = raList.size();
3202: if (size > 0) {
3203: RenderAtomListInfo ra;
3204: GeometryArrayRetained geo;
3205:
3206: for (i = size - 1; i >= 0; i--) {
3207: ra = (RenderAtomListInfo) raList.get(i);
3208: geo = (GeometryArrayRetained) ra.geometry();
3209: geo.resourceCreationMask &= ~bitMask;
3210: }
3211:
3212: for (i = size - 1; i >= 0; i--) {
3213: ra = (RenderAtomListInfo) raList.get(i);
3214: geo = (GeometryArrayRetained) ra.geometry();
3215: if ((geo.resourceCreationMask & bitMask) == 0) {
3216: dlistRenderMethod.buildIndividualDisplayList(ra,
3217: cv, ctx);
3218: geo.resourceCreationMask |= bitMask;
3219: geo.setDlistTimeStamp(bitMask, timeStamp);
3220: }
3221: }
3222: raList.clear();
3223: }
3224:
3225: if (useSharedCtx) {
3226: cv.makeCtxCurrent(cv.ctx);
3227: }
3228: }
3229:
3230: void removeRenderMolecule(RenderMolecule rm) {
3231:
3232: if ((rm.primaryMoleculeType & (RenderMolecule.DLIST_MOLECULE | RenderMolecule.SEPARATE_DLIST_PER_RINFO_MOLECULE)) != 0)
3233: renderMoleculeList.remove(rm);
3234: }
3235:
3236: void updateAllRenderMolecule(Canvas3D cv) {
3237: int i;
3238: int size = renderMoleculeList.size();
3239:
3240: if (size > 0) {
3241: RenderMolecule[] rmArr = (RenderMolecule[]) renderMoleculeList
3242: .toArray(false);
3243: for (i = size - 1; i >= 0; i--) {
3244: rmArr[i].updateAllPrimaryDisplayLists(cv);
3245: }
3246: }
3247:
3248: size = sharedDList.size();
3249: if (size > 0) {
3250: RenderAtomListInfo ra;
3251: GeometryArrayRetained geo;
3252: RenderAtomListInfo arr[] = new RenderAtomListInfo[size];
3253: arr = (RenderAtomListInfo[]) sharedDList.toArray(arr);
3254: int bitMask = cv.canvasBit;
3255:
3256: // We need two passes to avoid extra buildDisplayList
3257: // when geo are the same. The first pass clean the
3258: // rendererBit. Note that we can't rely on
3259: // resourceCreation since it is a force recreate.
3260:
3261: for (i = size - 1; i >= 0; i--) {
3262: geo = (GeometryArrayRetained) arr[i].geometry();
3263: geo.resourceCreationMask &= ~bitMask;
3264: }
3265:
3266: for (i = size - 1; i >= 0; i--) {
3267: ra = arr[i];
3268: geo = (GeometryArrayRetained) ra.geometry();
3269: if ((geo.resourceCreationMask & bitMask) == 0) {
3270: dlistRenderMethod.buildIndividualDisplayList(ra,
3271: cv, cv.ctx);
3272: geo.resourceCreationMask |= bitMask;
3273: geo.setDlistTimeStamp(bitMask, cv.ctxTimeStamp);
3274: }
3275: }
3276: }
3277: }
3278:
3279: /**
3280: * This method is called to update all renderMolecule
3281: * for a shared context of a renderer
3282: */
3283: void updateAllRenderMolecule(Renderer rdr, Canvas3D cv) {
3284: int i;
3285: boolean setCtx = false;
3286: GeometryArrayRetained geo;
3287: int size = renderMoleculeList.size();
3288:
3289: if (size > 0) {
3290: RenderMolecule[] rmArr = (RenderMolecule[]) renderMoleculeList
3291: .toArray(false);
3292:
3293: cv.makeCtxCurrent(rdr.sharedCtx);
3294: setCtx = true;
3295: for (i = size - 1; i >= 0; i--) {
3296: rmArr[i].updateAllPrimaryDisplayLists(cv);
3297: }
3298: }
3299:
3300: size = sharedDList.size();
3301: if (size > 0) {
3302: RenderAtomListInfo arr[] = new RenderAtomListInfo[size];
3303: arr = (RenderAtomListInfo[]) sharedDList.toArray(arr);
3304: RenderAtomListInfo ra;
3305:
3306: if (!setCtx) {
3307: cv.makeCtxCurrent(rdr.sharedCtx);
3308: setCtx = true;
3309: }
3310:
3311: // We need two passes to avoid extra buildDisplayList
3312: // when geo are the same. The first pass clean the
3313: // rendererBit.
3314: int bitMask = cv.screen.renderer.rendererBit;
3315: long timeStamp = cv.screen.renderer.sharedCtxTimeStamp;
3316:
3317: for (i = size - 1; i >= 0; i--) {
3318: geo = (GeometryArrayRetained) arr[i].geometry();
3319: geo.resourceCreationMask &= ~bitMask;
3320: }
3321:
3322: for (i = size - 1; i >= 0; i--) {
3323: ra = arr[i];
3324: geo = (GeometryArrayRetained) ra.geometry();
3325: if ((geo.resourceCreationMask & bitMask) == 0) {
3326: dlistRenderMethod.buildIndividualDisplayList(ra,
3327: cv, rdr.sharedCtx);
3328: geo.resourceCreationMask |= bitMask;
3329: geo.setDlistTimeStamp(bitMask, timeStamp);
3330: }
3331: }
3332: }
3333: if (setCtx) {
3334: cv.makeCtxCurrent(cv.ctx);
3335: }
3336: }
3337:
3338: private void processText3DTransformChanged(Object[] list,
3339: Object[] transforms, long referenceTime) {
3340: int i, j, numShapes;
3341: GeometryAtom ga;
3342: RenderMolecule rm;
3343: RenderAtom ra;
3344:
3345: if (transforms.length != 0) {
3346: numShapes = list.length;
3347: for (i = 0; i < numShapes; i++) {
3348:
3349: ga = (GeometryAtom) list[i];
3350: ra = ga.getRenderAtom(view);
3351: if (ra == null || !ra.inRenderBin()) {
3352: continue;
3353: }
3354: /*
3355: System.err.println("numShapes is " + numShapes +
3356: " transforms.length is " + transforms.length);
3357: */
3358: for (j = 0; j < transforms.length; j++) {
3359:
3360: ga.lastLocalTransformArray[j] = (Transform3D) transforms[j];
3361:
3362: for (int k = 0; k < ra.rListInfo.length; k++) {
3363: if (ra.rListInfo[k].localToVworld == null) {
3364: ra.rListInfo[k].localToVworld = new Transform3D();
3365: }
3366: }
3367:
3368: if (ra.isOriented() && !ra.inDirtyOrientedRAs()) {
3369: dirtyOrientedRAs.add(ra);
3370: ra.dirtyMask |= RenderAtom.IN_DIRTY_ORIENTED_RAs;
3371: } else if (!ra.onUpdateList()) {
3372: ra.dirtyMask |= RenderAtom.ON_UPDATELIST;
3373: objUpdateList.add(ra);
3374: }
3375: }
3376: }
3377: }
3378: }
3379:
3380: private void processOrderedGroupRemoved(J3dMessage m) {
3381: int i, n;
3382: Object[] ogList = (Object[]) m.args[0];
3383: Object[] ogChildIdList = (Object[]) m.args[1];
3384: OrderedGroupRetained og;
3385: int index;
3386: int val;
3387: OrderedBin ob;
3388: OrderedChildInfo cinfo = null;
3389:
3390: /*
3391: System.err.println("RB : processOrderedGroupRemoved message " + m);
3392: System.err.println("RB : processOrderedGroupRemoved - ogList.length is " +
3393: ogList.length);
3394: System.err.println("RB : processOrderedGroupRemoved - obList " +
3395: obList);
3396: */
3397: for (n = 0; n < ogList.length; n++) {
3398: og = (OrderedGroupRetained) ogList[n];
3399: index = ((Integer) ogChildIdList[n]).intValue();
3400:
3401: ob = og.getOrderedBin(view.viewIndex);
3402: // System.err.println("Removed, index = "+index+" ob = "+ob);
3403: if (ob != null) {
3404: // Add at the end of the childInfo, for remove we don't care about
3405: // the childId
3406: cinfo = new OrderedChildInfo(OrderedChildInfo.REMOVE,
3407: index, -1, null);
3408: ob.addChildInfo(cinfo);
3409:
3410: if (!ob.onUpdateList) {
3411: obList.add(ob);
3412: ob.onUpdateList = true;
3413: }
3414: }
3415: }
3416:
3417: }
3418:
3419: private void processOrderedGroupInserted(J3dMessage m) {
3420: Object[] ogList = (Object[]) m.args[0];
3421: Object[] ogChildIdList = (Object[]) m.args[1];
3422: Object[] ogOrderedIdList = (Object[]) m.args[2];
3423:
3424: OrderedGroupRetained og;
3425: ;
3426: int index;
3427: int orderedId;
3428: OrderedBin ob;
3429: OrderedChildInfo cinfo;
3430: // System.err.println("Inserted OG, index = "+index+" orderedId = "+orderedId+" og = "+og+" og.orderedBin = "+og.orderedBin);
3431: // System.err.println("Inserted OG, orderedId = "+orderedId);
3432: // System.err.println("Inserted, index = "+index+" oid = "+orderedId+" ob = "+ob);
3433:
3434: if (ogList == null)
3435: return;
3436:
3437: for (int n = 0; n < ogList.length; n++) {
3438: og = (OrderedGroupRetained) ogList[n];
3439: index = ((Integer) ogChildIdList[n]).intValue();
3440: orderedId = ((Integer) ogOrderedIdList[n]).intValue();
3441: ob = og.getOrderedBin(view.viewIndex);
3442: cinfo = null;
3443:
3444: if (ob != null) {
3445: // Add at the end of the childInfo
3446: cinfo = new OrderedChildInfo(OrderedChildInfo.ADD,
3447: index, orderedId, null);
3448: ob.addChildInfo(cinfo);
3449:
3450: if (!ob.onUpdateList) {
3451: obList.add(ob);
3452: ob.onUpdateList = true;
3453: }
3454: }
3455: }
3456: }
3457:
3458: private void processTransformChanged(long referenceTime) {
3459: int i, j, k, numRenderMolecules, n;
3460: Shape3DRetained s;
3461: RenderMolecule rm;
3462: RenderAtom ra;
3463: Transform3D trans;
3464: LightRetained[] lights;
3465: FogRetained fog;
3466: ModelClipRetained modelClip;
3467: AppearanceRetained app;
3468: Object[] list, nodesArr;
3469: UnorderList arrList;
3470: int size;
3471:
3472: targets = universe.transformStructure.getTargetList();
3473:
3474: // process geometry atoms
3475: arrList = targets.targetList[Targets.GEO_TARGETS];
3476: if (arrList != null) {
3477: Object[] retVal;
3478: size = arrList.size();
3479: nodesArr = arrList.toArray(false);
3480:
3481: //System.err.println("GS:");
3482: for (n = 0; n < size; n++) {
3483: list = (Object[]) nodesArr[n];
3484:
3485: for (i = 0; i < list.length; i++) {
3486:
3487: GeometryAtom ga = (GeometryAtom) list[i];
3488: //System.err.println(" ga " + ga);
3489: ra = ga.getRenderAtom(view);
3490: if (ra == null || !ra.inRenderBin())
3491: continue;
3492:
3493: rm = ra.renderMolecule;
3494:
3495: if (rm != null && rm.renderBin == this ) {
3496:
3497: if (ga.source.inBackgroundGroup
3498: && (rm.onUpdateList & RenderMolecule.UPDATE_BACKGROUND_TRANSFORM) == 0) {
3499: if (rm.onUpdateList == 0) {
3500: objUpdateList.add(rm);
3501: }
3502: rm.onUpdateList |= RenderMolecule.UPDATE_BACKGROUND_TRANSFORM;
3503: }
3504:
3505: lights = universe.renderingEnvironmentStructure
3506: .getInfluencingLights(ra, view);
3507: fog = universe.renderingEnvironmentStructure
3508: .getInfluencingFog(ra, view);
3509: modelClip = universe.renderingEnvironmentStructure
3510: .getInfluencingModelClip(ra, view);
3511:
3512: if (ra.geometryAtom.source.appearanceOverrideEnable) {
3513: retVal = universe.renderingEnvironmentStructure
3514: .getInfluencingAppearance(ra, view);
3515: if (retVal[0] == Boolean.TRUE) {
3516: app = (AppearanceRetained) retVal[1];
3517: } else {
3518: app = ra.geometryAtom.source.appearance;
3519: }
3520: } else {
3521: app = ra.geometryAtom.source.appearance;
3522: }
3523: // XXXX: Should we do a more extensive equals app?
3524: if (ra.envSet
3525: .equals(ra, lights, fog, modelClip)
3526: && app == ra.app) {
3527:
3528: if (ra.hasSeparateLocaleVwcBounds()
3529: && !ra
3530: .onLocaleVwcBoundsUpdateList()) {
3531: ra.dirtyMask |= ra.ON_LOCALE_VWC_BOUNDS_UPDATELIST;
3532: raLocaleVwcBoundsUpdateList.add(ra);
3533: }
3534:
3535: // If the locale are different and the xform has changed
3536: // then we need to translate the rm's localToVworld by
3537: // the locale differences
3538: if (locale != ga.source.locale) {
3539: if (rm.onUpdateList == 0) {
3540: objUpdateList.add(rm);
3541: }
3542: rm.onUpdateList |= RenderMolecule.LOCALE_TRANSLATION;
3543:
3544: }
3545: if ((rm.primaryMoleculeType & RenderMolecule.DLIST_MOLECULE) != 0) {
3546: if (rm.onUpdateList == 0) {
3547: objUpdateList.add(rm);
3548: }
3549: rm.onUpdateList |= RenderMolecule.BOUNDS_RECOMPUTE_UPDATE;
3550:
3551: }
3552: // Note that the rm LOCALE Translation update should ocuur
3553: // Before the ra is added to the object update list
3554: // It is a Text3D Molecule
3555: else if ((rm.primaryMoleculeType & RenderMolecule.TEXT3D_MOLECULE) != 0) {
3556:
3557: if (!ra.onUpdateList()) {
3558: ra.dirtyMask |= RenderAtom.ON_UPDATELIST;
3559: objUpdateList.add(ra);
3560: }
3561: }
3562: if (ra.isOriented()
3563: && !ra.inDirtyOrientedRAs()) {
3564: dirtyOrientedRAs.add(ra);
3565: ra.dirtyMask |= RenderAtom.IN_DIRTY_ORIENTED_RAs;
3566:
3567: }
3568: // If not opaque or in OG or is not a transparent bg geometry
3569: // and transp sort mode is sort_geometry, then ..
3570: if (!ra.renderMolecule.isOpaqueOrInOG
3571: && ra.geometryAtom.source.geometryBackground == null
3572: && transpSortMode == View.TRANSPARENCY_SORT_GEOMETRY
3573: && !ra.inDepthSortList()) {
3574: // Do the updating of the centroid
3575: // when the render is running
3576: ra.geometryAtom.updateCentroid();
3577: // System.err.println("========> adding to the dirty list .., transpSortMode = "+transpSortMode);
3578: if (dirtyDepthSortRenderAtom.add(ra)) {
3579: numDirtyTinfo += ra.rListInfo.length;
3580: }
3581: /*
3582: else {
3583: System.err.println("processTransformChanged: attempt to add RenderAtom already in dirty list");
3584: }
3585: */
3586: ra.dirtyMask |= RenderAtom.IN_SORTED_POS_DIRTY_TRANSP_LIST;
3587:
3588: }
3589: continue;
3590: }
3591: // If the appearance has changed ..
3592: if (ra.app != app) {
3593: if (ra.geometryAtom.source.appearanceOverrideEnable) {
3594: // If it was using the alternate appearance, then ..
3595: if (ra.app == ra.geometryAtom.source.otherAppearance) {
3596: if (ra.app != null) {
3597: // remove this mirror shape from the user list
3598: ra.geometryAtom.source.otherAppearance.sgApp
3599: .removeAMirrorUser(ra.geometryAtom.source);
3600: ra.geometryAtom.source.otherAppearance = null;
3601: }
3602: }
3603: // if we are using the alternate app, add the mirror
3604: // shape to the userlist
3605: if (app != ra.geometryAtom.source.appearance) {
3606: // Second check is needed to prevent,
3607: // the mirror shape
3608: // that has multiple ra's to be added more than
3609: // once
3610: if (app != null
3611: && app != ra.geometryAtom.source.otherAppearance) {
3612: app.sgApp
3613: .addAMirrorUser(ra.geometryAtom.source);
3614: ra.geometryAtom.source.otherAppearance = app;
3615: }
3616: }
3617:
3618: }
3619: }
3620:
3621: // Remove the renderAtom from the current
3622: // renderMolecule and reinsert
3623: getNewEnvironment(ra, lights, fog, modelClip,
3624: app);
3625: }
3626: }
3627: }
3628: }
3629:
3630: // process misc environment nodes
3631: arrList = targets.targetList[Targets.ENV_TARGETS];
3632: if (arrList != null) {
3633: size = arrList.size();
3634: nodesArr = arrList.toArray(false);
3635: for (n = 0; n < size; n++) {
3636: list = (Object[]) nodesArr[n];
3637: for (i = 0; i < list.length; i++) {
3638:
3639: if (list[i] instanceof LightRetained
3640: && universe.renderingEnvironmentStructure
3641: .isLightScopedToThisView(list[i],
3642: view)) {
3643: if (!changedLts.contains(list[i]))
3644: changedLts.add(list[i]);
3645: envDirty |= REEVALUATE_LIGHTS; // mark the canvas as dirty as well
3646: } else if (list[i] instanceof ModelClipRetained
3647: && universe.renderingEnvironmentStructure
3648: .isMclipScopedToThisView(list[i],
3649: view)) {
3650: if (!changedModelClips.contains(list[i]))
3651: changedModelClips.add(list[i]);
3652: envDirty |= REEVALUATE_MCLIP; // mark the canvas as dirty as well
3653: } else if (list[i] instanceof FogRetained
3654: && universe.renderingEnvironmentStructure
3655: .isFogScopedToThisView(list[i],
3656: view)) {
3657: if (!changedFogs.contains(list[i]))
3658: changedFogs.add(list[i]);
3659: envDirty |= REEVALUATE_FOG; // mark the canvas as dirty as well
3660: } else if (list[i] instanceof AlternateAppearanceRetained
3661: && universe.renderingEnvironmentStructure
3662: .isAltAppScopedToThisView(list[i],
3663: view)) {
3664: altAppearanceDirty = true;
3665: }
3666: }
3667: }
3668: }
3669:
3670: // process ViewPlatform nodes
3671: arrList = targets.targetList[Targets.VPF_TARGETS];
3672: if (arrList != null) {
3673: size = arrList.size();
3674: nodesArr = arrList.toArray(false);
3675: for (n = 0; n < size; n++) {
3676: list = (Object[]) nodesArr[n];
3677: for (i = 0; i < list.length; i++) {
3678: float radius;
3679: synchronized (list[i]) {
3680: radius = (float) ((ViewPlatformRetained) list[i]).sphere.radius;
3681: }
3682: updateViewPlatform((ViewPlatformRetained) list[i],
3683: radius);
3684: }
3685: }
3686: }
3687:
3688: targets = null;
3689:
3690: blUsers = universe.transformStructure.getBlUsers();
3691: if (blUsers != null) {
3692: size = blUsers.size();
3693: for (j = 0; j < size; j++) {
3694: LeafRetained mLeaf = (LeafRetained) blUsers.get(j);
3695: if (mLeaf instanceof LightRetained
3696: && universe.renderingEnvironmentStructure
3697: .isLightScopedToThisView(mLeaf, view)) {
3698: envDirty |= REEVALUATE_LIGHTS;
3699: } else if (mLeaf instanceof FogRetained
3700: && universe.renderingEnvironmentStructure
3701: .isFogScopedToThisView(mLeaf, view)) {
3702: envDirty |= REEVALUATE_FOG;
3703: } else if (mLeaf instanceof ModelClipRetained
3704: && universe.renderingEnvironmentStructure
3705: .isMclipScopedToThisView(mLeaf, view)) {
3706: envDirty |= REEVALUATE_MCLIP;
3707: } else if (mLeaf instanceof AlternateAppearanceRetained
3708: && universe.renderingEnvironmentStructure
3709: .isAltAppScopedToThisView(mLeaf, view)) {
3710: altAppearanceDirty = true;
3711: }
3712: }
3713: blUsers = null;
3714: }
3715:
3716: visQuery = true;
3717:
3718: }
3719:
3720: /**
3721: * This processes a LIGHT change.
3722: */
3723: private void processLightChanged() {
3724: int i, j, k, l, n;
3725: LightRetained lt;
3726: EnvironmentSet e;
3727: Object[] args;
3728: LightRetained[] mLts;
3729: int component;
3730: int lightSize = lightMessageList.size();
3731:
3732: for (n = 0; n < lightSize; n++) {
3733: J3dMessage msg = (J3dMessage) lightMessageList.get(n);
3734: args = msg.args;
3735: mLts = (LightRetained[]) args[3];
3736: component = ((Integer) args[1]).intValue();
3737: lt = (LightRetained) args[0];
3738:
3739: if ((component & (LightRetained.SCOPE_CHANGED
3740: | LightRetained.BOUNDS_CHANGED | LightRetained.BOUNDINGLEAF_CHANGED)) != 0) {
3741: envDirty |= REEVALUATE_LIGHTS;
3742: component &= ~(LightRetained.SCOPE_CHANGED
3743: | LightRetained.BOUNDS_CHANGED | LightRetained.BOUNDINGLEAF_CHANGED);
3744: }
3745: // This is a light that is not a part of any
3746: // environment set, first check if it is enabled
3747: // if it is then reEvaluate all renderAtoms in the
3748: // scene, otherwise do nothing
3749: if (component != 0) {
3750: if (lt.nodeType == LightRetained.AMBIENTLIGHT) {
3751: UnorderList list;
3752: EnvironmentSet envsets[];
3753: for (i = 0; i < mLts.length; i++) {
3754: LightRetained lti = mLts[i];
3755: list = lti.environmentSets;
3756: synchronized (list) {
3757: int size = list.size();
3758: if (size > 0) {
3759: envsets = (EnvironmentSet[]) list
3760: .toArray(false);
3761: for (j = 0; j < size; j++) {
3762: e = envsets[j];
3763: e.canvasDirty |= Canvas3D.AMBIENTLIGHT_DIRTY;
3764: if (!e.onUpdateList) {
3765: objUpdateList.add(e);
3766: e.onUpdateList = true;
3767: }
3768: }
3769: } else {
3770: if ((component & LightRetained.ENABLE_CHANGED) != 0) {
3771: boolean value = lti.lightOn;
3772: if (value) {
3773: if (!changedLts.contains(lti))
3774: changedLts.add(lti);
3775: envDirty |= REEVALUATE_LIGHTS;
3776: }
3777: }
3778: }
3779: }
3780: }
3781: } else {
3782: for (i = 0; i < mLts.length; i++) {
3783: LightRetained lti = mLts[i];
3784: if ((component & LightRetained.ENABLE_CHANGED) != 0) {
3785: boolean value = ((Boolean) args[4])
3786: .booleanValue();
3787: if (value) {
3788: if (!changedLts.contains(lti))
3789: changedLts.add(lti);
3790:
3791: envDirty |= REEVALUATE_LIGHTS;
3792: }
3793: }
3794: UnorderList list = lti.environmentSets;
3795: EnvironmentSet envsets[];
3796: synchronized (list) {
3797: int size = list.size();
3798: int lsize;
3799: if (size > 0) {
3800: envsets = (EnvironmentSet[]) list
3801: .toArray(false);
3802: if ((component & LightRetained.ENABLE_CHANGED) != 0) {
3803: boolean value = ((Boolean) args[4])
3804: .booleanValue();
3805: for (j = 0; j < size; j++) {
3806: e = envsets[j];
3807: lsize = e.lights.size();
3808: for (k = 0; k < lsize; k++) {
3809: if (e.lights.get(k) == lti) {
3810: if (value == true)
3811: e.enableMaskCache |= (1 << e.ltPos[k]);
3812: else
3813: e.enableMaskCache &= ~(1 << e.ltPos[k]);
3814: break;
3815: }
3816: }
3817: e.canvasDirty |= Canvas3D.LIGHTENABLES_DIRTY;
3818: if (!e.onUpdateList) {
3819: objUpdateList.add(e);
3820: e.onUpdateList = true;
3821: }
3822: }
3823: } else {
3824: for (j = 0; j < size; j++) {
3825: e = envsets[j];
3826: lsize = e.lights.size();
3827: for (k = 0; k < lsize; k++) {
3828: if (e.lights.get(k) == lti) {
3829: e.lightBin.canvasDirty |= Canvas3D.LIGHTBIN_DIRTY;
3830: e.lightBin.lightDirtyMaskCache |= (1 << e.ltPos[k]);
3831: if (!e.lightBin.onUpdateList) {
3832: e.lightBin.onUpdateList = true;
3833: objUpdateList
3834: .add(e.lightBin);
3835: }
3836: break;
3837: }
3838: }
3839: }
3840: }
3841: }
3842: } // end sync.
3843: }
3844: }
3845: }
3846: msg.decRefcount();
3847: }
3848:
3849: }
3850:
3851: void processGeometryAtom(GeometryAtom ga, long referenceTime) {
3852: RenderAtom renderAtom;
3853: RenderMolecule rm;
3854:
3855: // System.err.println("+");
3856:
3857: GeometryRetained geo = null;
3858: for (int k = 0; (k < ga.geometryArray.length && geo == null); k++) {
3859: geo = ga.geometryArray[k];
3860: }
3861: if (geo == null)
3862: return;
3863:
3864: renderAtom = ga.getRenderAtom(view);
3865:
3866: if (renderAtom != null) {
3867: renderAtom.lastVisibleTime = referenceTime;
3868: }
3869:
3870: if (renderAtom == null || renderAtom.inRenderBin()) {
3871: return;
3872: }
3873:
3874: // If the geometry is all null , don't insert
3875: // Make sure that there is atleast one geo that is non-null
3876:
3877: if (renderAtom.geometryAtom.source.viewList != null) {
3878: if (renderAtom.geometryAtom.source.viewList.contains(view)) {
3879: // System.err.println("Inserting RenderAtom, ra = "+renderAtom);
3880: // System.err.println("ga = "+renderAtom.geometryAtom+" renderAtom.geometryAtom.source.viewList = "+renderAtom.geometryAtom.source.viewList);
3881: rm = insertRenderAtom(renderAtom);
3882: }
3883: }
3884: // No view specific scpoing
3885: else {
3886: rm = insertRenderAtom(renderAtom);
3887: }
3888:
3889: }
3890:
3891: private void processBgGeometryAtoms(GeometryAtom[] nodes,
3892: long referenceTime) {
3893: int i;
3894: GeometryAtom ga;
3895: RenderAtom renderAtom;
3896: RenderMolecule rm;
3897: RenderAtomListInfo ra;
3898: GeometryRetained geo;
3899:
3900: for (i = 0; i < nodes.length; i++) {
3901: ga = nodes[i];
3902:
3903: // Make sure that there is atleast one geo that is non-null
3904: geo = null;
3905: for (int k = 0; (k < ga.geometryArray.length && geo == null); k++) {
3906: geo = ga.geometryArray[k];
3907: }
3908: if (geo == null)
3909: continue;
3910:
3911: renderAtom = ga.getRenderAtom(view);
3912: if (renderAtom == null)
3913: return;
3914:
3915: renderAtom.lastVisibleTime = referenceTime;
3916: if (renderAtom.inRenderBin()) {
3917: continue;
3918: }
3919:
3920: // This means that the renderAtom was not visible in the last
3921: // frame ,so , no contention with the renderer ...
3922: rm = insertRenderAtom(renderAtom);
3923: }
3924:
3925: }
3926:
3927: /**
3928: * This method looks through the list of RenderAtoms to see if
3929: * compaction is needed.
3930: */
3931: private void checkForCompaction() {
3932: int i, numRas;
3933: int numDead = 0;
3934: int numAlive = 0;
3935: RenderAtom ra;
3936:
3937: if (!VirtualUniverse.mc.doCompaction) {
3938: return;
3939: }
3940:
3941: numRas = renderAtoms.size();
3942: for (i = 0; i < numRas; i++) {
3943: ra = (RenderAtom) renderAtoms.get(i);
3944: // If the renderatom has not been visible for "notVisibleCount" then
3945: // add it to the deadlist
3946: if (ra.lastVisibleTime < removeCutoffTime) {
3947: numDead++;
3948: }
3949:
3950: }
3951: numAlive = numRas - numDead;
3952: if (numAlive * 2 < numDead) {
3953: compact();
3954: }
3955: }
3956:
3957: /**
3958: * This sets the number of frames to render before changing the
3959: * removeCutoffTime
3960: */
3961: void setFrameCountCutoff(int cutoff) {
3962: frameCountCutoff = cutoff;
3963: }
3964:
3965: /**
3966: * This method stores the timestamp of the frame frameCountCuttoff
3967: * frames ago. It also does compaction if it is needed.
3968: */
3969: void compact() {
3970: RenderAtom ra;
3971:
3972: for (int i = 0; i < renderAtoms.size();) {
3973: ra = (RenderAtom) renderAtoms.get(i);
3974: if (ra.lastVisibleTime < removeCutoffTime) {
3975: renderAtoms.remove(i);
3976: removeARenderAtom(ra);
3977: continue;
3978: }
3979: i++;
3980: }
3981:
3982: }
3983:
3984: private void reEvaluateAlternateAppearance() {
3985: AppearanceRetained app;
3986: EnvironmentSet e;
3987: Object[] retVal;
3988: int sz = renderAtoms.size();
3989:
3990: for (int n = 0; n < sz; n++) {
3991: RenderAtom ra = (RenderAtom) renderAtoms.get(n);
3992: if (!ra.inRenderBin()
3993: || !ra.geometryAtom.source.appearanceOverrideEnable)
3994: continue;
3995:
3996: retVal = universe.renderingEnvironmentStructure
3997: .getInfluencingAppearance(ra, view);
3998:
3999: if (retVal[0] == Boolean.TRUE) {
4000: app = (AppearanceRetained) retVal[1];
4001: } else {
4002: app = ra.geometryAtom.source.appearance;
4003: }
4004:
4005: if (app == ra.app)
4006: continue;
4007:
4008: if (ra.geometryAtom.source.otherAppearance != app) {
4009: if (ra.geometryAtom.source.otherAppearance != null) {
4010: ra.geometryAtom.source.otherAppearance.sgApp
4011: .removeAMirrorUser(ra.geometryAtom.source);
4012: }
4013: if (app != ra.geometryAtom.source.appearance) {
4014: if (app != null) {
4015: app.sgApp
4016: .addAMirrorUser(ra.geometryAtom.source);
4017: }
4018: ra.geometryAtom.source.otherAppearance = app;
4019: } else {
4020: ra.geometryAtom.source.otherAppearance = null;
4021: }
4022: }
4023: ra.app = app;
4024: e = ra.envSet;
4025: ra.renderMolecule.removeRenderAtom(ra);
4026: reInsertAttributeBin(e, ra);
4027: }
4028:
4029: }
4030:
4031: private void reEvaluateAllRenderAtoms(boolean altAppDirty) {
4032:
4033: int sz = renderAtoms.size();
4034:
4035: for (int n = 0; n < sz; n++) {
4036: LightRetained[] lights;
4037: FogRetained newfog;
4038: ModelClipRetained newModelClip;
4039: AppearanceRetained app;
4040: RenderAtom ra = (RenderAtom) renderAtoms.get(n);
4041: Object[] retVal;
4042:
4043: if (!ra.inRenderBin())
4044: continue;
4045:
4046: lights = universe.renderingEnvironmentStructure
4047: .getInfluencingLights(ra, view);
4048: newfog = universe.renderingEnvironmentStructure
4049: .getInfluencingFog(ra, view);
4050: newModelClip = universe.renderingEnvironmentStructure
4051: .getInfluencingModelClip(ra, view);
4052:
4053: if (altAppDirty) {
4054: if (ra.geometryAtom.source.appearanceOverrideEnable) {
4055: retVal = universe.renderingEnvironmentStructure
4056: .getInfluencingAppearance(ra, view);
4057: if (retVal[0] == Boolean.TRUE) {
4058: app = (AppearanceRetained) retVal[1];
4059: } else {
4060: app = ra.geometryAtom.source.appearance;
4061: }
4062:
4063: } else {
4064: app = ra.geometryAtom.source.appearance;
4065: }
4066: } else {
4067: app = ra.app;
4068: }
4069:
4070: // If the lights/fog/model_clip of the render atom is the same
4071: // as the old set of lights/fog/model_clip, then move on to the
4072: // next renderAtom
4073: // XXXX: Should app test for equivalent?
4074: if (ra.envSet.equals(ra, lights, newfog, newModelClip)
4075: && app == ra.app)
4076: continue;
4077:
4078: if (altAppDirty
4079: && ra.geometryAtom.source.appearanceOverrideEnable) {
4080: if (app != ra.app) {
4081: if (ra.geometryAtom.source.otherAppearance != app) {
4082: if (ra.geometryAtom.source.otherAppearance != null)
4083: ra.geometryAtom.source.otherAppearance.sgApp
4084: .removeAMirrorUser(ra.geometryAtom.source);
4085: // If it is not the default appearance
4086: if (app != ra.geometryAtom.source.appearance) {
4087: if (app != null) {
4088: app.sgApp
4089: .addAMirrorUser(ra.geometryAtom.source);
4090: }
4091: ra.geometryAtom.source.otherAppearance = app;
4092: } else {
4093: ra.geometryAtom.source.otherAppearance = null;
4094: }
4095: }
4096: }
4097: }
4098: getNewEnvironment(ra, lights, newfog, newModelClip, app);
4099:
4100: }
4101: }
4102:
4103: private void getNewEnvironment(RenderAtom ra,
4104: LightRetained[] lights, FogRetained fog,
4105: ModelClipRetained modelClip, AppearanceRetained app) {
4106:
4107: LightBin currentBin, lightBin;
4108: EnvironmentSet currentEnvSet, newBin;
4109: EnvironmentSet eNew = null;
4110: AttributeBin attributeBin;
4111: TextureBin textureBin;
4112: RenderMolecule renderMolecule;
4113: FogRetained newfog;
4114: LightBin addBin;
4115: OrderedCollection oc = null;
4116: int i;
4117:
4118: // Remove this renderAtom from this render Molecule
4119: ra.renderMolecule.removeRenderAtom(ra);
4120:
4121: eNew = null;
4122: if (ra.geometryAtom.source.geometryBackground == null) {
4123: if (ra.geometryAtom.source.orderedPath != null) {
4124: oc = findOrderedCollection(ra.geometryAtom, false);
4125: currentBin = oc.nextFrameLightBin;
4126: addBin = oc.addLightBins;
4127: } else {
4128: addBin = addOpaqueBin;
4129: currentBin = opaqueBin;
4130: }
4131: } else {
4132: if (ra.geometryAtom.source.orderedPath != null) {
4133: oc = findOrderedCollection(ra.geometryAtom, true);
4134: currentBin = oc.nextFrameLightBin;
4135: addBin = oc.addLightBins;
4136: } else {
4137: addBin = bgAddOpaqueBin;
4138: currentBin = bgOpaqueBin;
4139: }
4140: }
4141: lightBin = currentBin;
4142:
4143: while (currentBin != null && eNew == null) {
4144:
4145: // this test is always true for non-backgroundGeo bins
4146: if (currentBin.geometryBackground == ra.geometryAtom.source.geometryBackground) {
4147:
4148: currentEnvSet = currentBin.environmentSetList;
4149: while (currentEnvSet != null) {
4150: if (currentEnvSet
4151: .equals(ra, lights, fog, modelClip)) {
4152: eNew = currentEnvSet;
4153: break;
4154: }
4155: currentEnvSet = currentEnvSet.next;
4156: }
4157: // If envSet set is not found
4158: // Check the "to-be-added" list of environmentSets for a match
4159: if (eNew == null) {
4160: int size = currentBin.insertEnvSet.size();
4161: for (i = 0; i < size; i++) {
4162: newBin = (EnvironmentSet) currentBin.insertEnvSet
4163: .get(i);
4164: if (newBin.equals(ra, lights, fog, modelClip)) {
4165: eNew = newBin;
4166: break;
4167: }
4168: }
4169: }
4170: }
4171: currentBin = currentBin.next;
4172: }
4173:
4174: // Now check the to-be added lightbins
4175: if (eNew == null) {
4176: currentBin = addBin;
4177: while (currentBin != null) {
4178:
4179: // this test is always true for non-backgroundGeo bins
4180: if (currentBin.geometryBackground == ra.geometryAtom.source.geometryBackground) {
4181:
4182: // Check the "to-be-added" list of environmentSets for a match
4183: int size = currentBin.insertEnvSet.size();
4184: for (i = 0; i < size; i++) {
4185: newBin = (EnvironmentSet) currentBin.insertEnvSet
4186: .get(i);
4187: if (newBin.equals(ra, lights, fog, modelClip)) {
4188: eNew = newBin;
4189: break;
4190: }
4191: }
4192: }
4193: currentBin = currentBin.next;
4194: }
4195: }
4196:
4197: if (eNew == null) {
4198: // Need a new one
4199: currentEnvSet = getEnvironmentSet(ra, lights, fog,
4200: modelClip);
4201: // Find a lightbin that envSet fits into
4202: currentBin = lightBin;
4203: while (currentBin != null) {
4204:
4205: // the first test is always true for non-backgroundGeo bins
4206: if (currentBin.geometryBackground == ra.geometryAtom.source.geometryBackground
4207: && currentBin
4208: .willEnvironmentSetFit(currentEnvSet)) {
4209:
4210: // there may be new lights define which needs to
4211: // call native updateLight().
4212: // When using existing lightBin we have to force
4213: // reevaluate Light.
4214: for (i = 0; i < lights.length; i++) {
4215: if (!changedLts.contains(lights[i]))
4216: changedLts.add(lights[i]);
4217: envDirty |= REEVALUATE_LIGHTS;
4218:
4219: }
4220: break;
4221: }
4222: currentBin = currentBin.next;
4223: }
4224:
4225: // Now check the to-be added lightbins
4226: if (currentBin == null) {
4227: currentBin = addBin;
4228: while (currentBin != null) {
4229:
4230: // the first test is always true for non-backgroundGeo bins
4231: if (currentBin.geometryBackground == ra.geometryAtom.source.geometryBackground
4232: && currentBin
4233: .willEnvironmentSetFit(currentEnvSet)) {
4234:
4235: // there may be new lights define which needs to
4236: // call native updateLight().
4237: // When using existing lightBin we have to force
4238: // reevaluate Light.
4239: for (i = 0; i < lights.length; i++) {
4240: if (!changedLts.contains(lights[i]))
4241: changedLts.add(lights[i]);
4242: envDirty |= REEVALUATE_LIGHTS;
4243:
4244: }
4245: break;
4246: }
4247: currentBin = currentBin.next;
4248: }
4249: }
4250:
4251: if (currentBin == null) {
4252: // Need a new lightbin
4253: currentBin = getLightBin(maxLights,
4254: ra.geometryAtom.source.geometryBackground,
4255: false);
4256: if (addBin != null) {
4257: currentBin.next = addBin;
4258: addBin.prev = currentBin;
4259: }
4260: if (ra.geometryAtom.source.orderedPath != null) {
4261: if (!oc.onUpdateList) {
4262: objUpdateList.add(oc);
4263: oc.onUpdateList = true;
4264: }
4265: oc.addLightBins = currentBin;
4266: } else {
4267: if (ra.geometryAtom.source.geometryBackground == null)
4268: addOpaqueBin = currentBin;
4269: else
4270: bgAddOpaqueBin = currentBin;
4271: }
4272:
4273: }
4274: eNew = currentEnvSet;
4275: currentBin.addEnvironmentSet(eNew, this );
4276:
4277: }
4278: ra.fog = fog;
4279: ra.lights = lights;
4280: ra.modelClip = modelClip;
4281: ra.app = app;
4282: reInsertAttributeBin(eNew, ra);
4283:
4284: }
4285:
4286: private void reInsertAttributeBin(EnvironmentSet e, RenderAtom ra) {
4287: AttributeBin ab;
4288: // Just go up to the environment and re-insert
4289: ab = findAttributeBin(e, ra);
4290: reInsertShaderBin(ab, ra);
4291: }
4292:
4293: private void reInsertShaderBin(AttributeBin ab, RenderAtom ra) {
4294: ShaderBin sb;
4295:
4296: // System.err.println("RenderBin.reInsertShaderBin() ra= " + ra);
4297: sb = findShaderBin(ab, ra);
4298: reInsertTextureBin(sb, ra);
4299: }
4300:
4301: private void reInsertTextureBin(ShaderBin sb, RenderAtom ra) {
4302: TextureBin tb;
4303:
4304: tb = findTextureBin(sb, ra);
4305: reInsertRenderAtom(tb, ra);
4306: }
4307:
4308: private void reInsertRenderAtom(TextureBin tb, RenderAtom ra) {
4309: RenderMolecule newRm;
4310: // Just go up to the texture bin and re-insert
4311: newRm = findRenderMolecule(tb, ra);
4312: }
4313:
4314: private void computeViewFrustumBBox(BoundingBox viewFrustumBBox) {
4315: //Initial view frustumBBox BBox
4316: viewFrustumBBox.lower.x = Float.POSITIVE_INFINITY;
4317: viewFrustumBBox.lower.y = Float.POSITIVE_INFINITY;
4318: viewFrustumBBox.lower.z = Float.POSITIVE_INFINITY;
4319: viewFrustumBBox.upper.x = Float.NEGATIVE_INFINITY;
4320: viewFrustumBBox.upper.y = Float.NEGATIVE_INFINITY;
4321: viewFrustumBBox.upper.z = Float.NEGATIVE_INFINITY;
4322:
4323: Canvas3D canvases[] = view.getCanvases();
4324: for (int i = 0; i < canvases.length; i++) {
4325: Canvas3D canvas = canvases[i];
4326:
4327: //Initial view frustumBBox BBox
4328: canvasFrustumBBox.lower.x = Float.POSITIVE_INFINITY;
4329: canvasFrustumBBox.lower.y = Float.POSITIVE_INFINITY;
4330: canvasFrustumBBox.lower.z = Float.POSITIVE_INFINITY;
4331: canvasFrustumBBox.upper.x = Float.NEGATIVE_INFINITY;
4332: canvasFrustumBBox.upper.y = Float.NEGATIVE_INFINITY;
4333: canvasFrustumBBox.upper.z = Float.NEGATIVE_INFINITY;
4334:
4335: canvas
4336: .updateViewCache(true, null, canvasFrustumBBox,
4337: false);
4338:
4339: if (viewFrustumBBox.lower.x > canvasFrustumBBox.lower.x)
4340: viewFrustumBBox.lower.x = canvasFrustumBBox.lower.x;
4341: if (viewFrustumBBox.lower.y > canvasFrustumBBox.lower.y)
4342: viewFrustumBBox.lower.y = canvasFrustumBBox.lower.y;
4343: if (viewFrustumBBox.lower.z > canvasFrustumBBox.lower.z)
4344: viewFrustumBBox.lower.z = canvasFrustumBBox.lower.z;
4345:
4346: if (viewFrustumBBox.upper.x < canvasFrustumBBox.upper.x)
4347: viewFrustumBBox.upper.x = canvasFrustumBBox.upper.x;
4348: if (viewFrustumBBox.upper.y < canvasFrustumBBox.upper.y)
4349: viewFrustumBBox.upper.y = canvasFrustumBBox.upper.y;
4350: if (viewFrustumBBox.upper.z < canvasFrustumBBox.upper.z)
4351: viewFrustumBBox.upper.z = canvasFrustumBBox.upper.z;
4352: }
4353: }
4354:
4355: /**
4356: * This inserts a RenderAtom into the appropriate bin.
4357: */
4358: private RenderMolecule insertRenderAtom(RenderAtom ra) {
4359: LightBin lightBin;
4360: EnvironmentSet environmentSet;
4361: AttributeBin attributeBin;
4362: ShaderBin shaderBin;
4363: TextureBin textureBin;
4364: RenderMolecule renderMolecule;
4365: OrderedCollection oc;
4366: AppearanceRetained app;
4367: Object[] retVal;
4368: GeometryAtom ga = ra.geometryAtom;
4369:
4370: // System.err.println("insertRenderAtom ga " + ra.geometryAtom);
4371: // determine if a separate copy of localeVwcBounds is needed
4372: // based on the locale info
4373:
4374: if (ra.localeVwcBounds == null) {
4375: // Handle multiple locales
4376: if (!locale.hiRes.equals(ga.source.locale.hiRes)) {
4377: ga.source.locale.hiRes.difference(locale.hiRes,
4378: localeTranslation);
4379: ra.localeVwcBounds = new BoundingBox();
4380: ra.localeVwcBounds.translate(ga.source.vwcBounds,
4381: localeTranslation);
4382: ra.dirtyMask |= RenderAtom.HAS_SEPARATE_LOCALE_VWC_BOUNDS;
4383: } else {
4384: ra.dirtyMask &= ~RenderAtom.HAS_SEPARATE_LOCALE_VWC_BOUNDS;
4385: ra.localeVwcBounds = ga.source.vwcBounds;
4386: }
4387: }
4388:
4389: // If the appearance is overrideable, then get the
4390: // applicable appearance
4391: if (ga.source.appearanceOverrideEnable) {
4392: retVal = universe.renderingEnvironmentStructure
4393: .getInfluencingAppearance(ra, view);
4394: // If its a valid alternate appaearance
4395: if (retVal[0] == Boolean.TRUE) {
4396: app = (AppearanceRetained) retVal[1];
4397: ra.app = app;
4398: if (ga.source.otherAppearance != app) {
4399: if (ga.source.otherAppearance != null)
4400: ga.source.otherAppearance.sgApp
4401: .removeAMirrorUser(ga.source);
4402: ga.source.otherAppearance = app;
4403: if (app != null)
4404: ra.app.sgApp.addAMirrorUser(ga.source);
4405: }
4406: } else {
4407: ra.app = ga.source.appearance;
4408:
4409: }
4410: } else {
4411: ra.app = ga.source.appearance;
4412: }
4413: // Call environment set, only after the appearance has been
4414: // determined
4415: environmentSet = findEnvironmentSet(ra);
4416: attributeBin = findAttributeBin(environmentSet, ra);
4417:
4418: // System.err.println("RenderBin : findShaderBin()");
4419: shaderBin = findShaderBin(attributeBin, ra);
4420:
4421: textureBin = findTextureBin(shaderBin, ra);
4422: renderMolecule = findRenderMolecule(textureBin, ra);
4423: ra.setRenderBin(true);
4424: renderAtoms.add(ra);
4425:
4426: if (ga.source instanceof OrientedShape3DRetained) {
4427: // dirty initially
4428: dirtyOrientedRAs.add(ra);
4429: ra.dirtyMask |= RenderAtom.IN_DIRTY_ORIENTED_RAs;
4430: ra.dirtyMask |= RenderAtom.IS_ORIENTED;
4431: for (int k = 0; k < ra.rListInfo.length; k++) {
4432: if (ra.rListInfo[k].localToVworld == null) {
4433: ra.rListInfo[k].localToVworld = new Transform3D();
4434: }
4435: }
4436: }
4437:
4438: if (renderMolecule.primaryMoleculeType == RenderMolecule.TEXT3D_MOLECULE) {
4439: if (!ra.onUpdateList()) {
4440: ra.dirtyMask |= RenderAtom.ON_UPDATELIST;
4441: objUpdateList.add(ra);
4442: }
4443: }
4444:
4445: // ra.needSeparateLocaleVwcBounds flag is determined in
4446: // RenderMolecule.addRenderAtom based on the render method type.
4447: // That's why the localeVwcBounds has to be reevaluated here again
4448: // If after compaction being added in, then we just need to
4449: // set the updated vwcBounds, there is no need to allocate
4450: if (ra.needSeparateLocaleVwcBounds()) {
4451: if (!ra.hasSeparateLocaleVwcBounds()) {
4452: ra.dirtyMask |= RenderAtom.HAS_SEPARATE_LOCALE_VWC_BOUNDS;
4453: ra.localeVwcBounds = new BoundingBox(
4454: ga.source.vwcBounds);
4455: ra.dirtyMask |= ra.ON_LOCALE_VWC_BOUNDS_UPDATELIST;
4456: raLocaleVwcBoundsUpdateList.add(ra);
4457: } else {
4458: ra.localeVwcBounds.set(ga.source.vwcBounds);
4459: ra.dirtyMask |= ra.ON_LOCALE_VWC_BOUNDS_UPDATELIST;
4460: raLocaleVwcBoundsUpdateList.add(ra);
4461: }
4462: }
4463: return (renderMolecule);
4464: }
4465:
4466: private OrderedCollection findOrderedCollection(GeometryAtom ga,
4467: boolean doBackground) {
4468: int i, n;
4469: int oi; // an id which identifies a children of the orderedGroup
4470: int ci; // child index of the ordered group
4471: int index;
4472: ArrayList list = null;
4473: int val;
4474:
4475: OrderedGroupRetained og;
4476: OrderedCollection oc = null;
4477: ArrayList ocs;
4478: ArrayList parentChildOrderedBins;
4479: OrderedBin parentOrderedBin;
4480: int parentOrderedChildId;
4481: OrderedBin ob;
4482: OrderedPathElement ope;
4483:
4484: // Since the table has been incremented, in response to OG addition,
4485: // but the ordered collecyions has not been added yet, we need to
4486: // check what the original index into the ordered collection
4487: // should be
4488: int adjustment;
4489:
4490: if (doBackground) {
4491: parentChildOrderedBins = bgOrderedBins;
4492: } else {
4493: parentChildOrderedBins = orderedBins;
4494: }
4495:
4496: parentOrderedBin = null;
4497: parentOrderedChildId = -1;
4498:
4499: for (i = 0; i < ga.source.orderedPath.pathElements.size(); i++) {
4500: ope = (OrderedPathElement) ga.source.orderedPath.pathElements
4501: .get(i);
4502: og = ope.orderedGroup;
4503: oi = ope.childId.intValue();
4504:
4505: ob = og.getOrderedBin(view.viewIndex);
4506: if (ob == null) {
4507: // create ordered bin tree
4508: ob = new OrderedBin(og.childCount, og);
4509: og.setOrderedBin(ob, view.viewIndex);
4510:
4511: index = -1;
4512: for (n = 0; n < orderedBinsList.size(); n++) {
4513: if (parentChildOrderedBins == orderedBinsList
4514: .get(n)) {
4515: index = n;
4516: break;
4517: }
4518:
4519: }
4520: if (index == -1) {
4521: orderedBinsList.add(parentChildOrderedBins);
4522: list = new ArrayList(5);
4523: list.add(ob);
4524: toBeAddedBinList.add(list);
4525: } else {
4526: list = (ArrayList) toBeAddedBinList.get(index);
4527: list.add(ob);
4528: }
4529: }
4530: ocs = ob.orderedCollections;
4531: OrderedChildInfo cinfo = ob.lastChildInfo;
4532: boolean found = false;
4533: // Check if a oc is already creates for this oi
4534: // Start from the last child that was added and work backwards,
4535: // in case the child
4536: // was added and removed and then added back the same frame, we get the
4537: // correct oc
4538: while (cinfo != null && !found) {
4539: if (cinfo.type == OrderedChildInfo.ADD) {
4540: if (cinfo.orderedId == oi) {
4541: oc = cinfo.value;
4542: if (oc == null) {
4543: oc = new OrderedCollection();
4544: cinfo.value = oc;
4545: }
4546: found = true;
4547: }
4548: }
4549: cinfo = cinfo.prev;
4550: }
4551: // If we are in the update_view case then check the oi
4552: // exists in the setOCForOI list ..
4553: for (n = 0; n < ob.setOCForOI.size(); n++) {
4554: val = ((Integer) ob.setOCForOI.get(n)).intValue();
4555: if (oi == val) {
4556: oc = (OrderedCollection) ob.valueOfSetOCForOI
4557: .get(n);
4558: found = true;
4559: }
4560: }
4561: // The list is not going to be modified by any additions
4562: // that have happened ...
4563: // Then this child must exists from the previous frame, so
4564: // get the location
4565: if (!found) {
4566: // The case below happens when there have been some insert
4567: // ordered nodes, but update_view happens later and
4568: // so the earlier insert ordered nodes are not
4569: // seen by renderBin!
4570: if (og.orderedChildIdTable == null
4571: || oi >= og.orderedChildIdTable.length) {
4572: // Create a new category that adds Info based only on oi
4573: // which will be added to the orderedBin after the
4574: // idTable reflects the correct childId for the next frame
4575: ob.setOCForOI.add(new Integer(oi));
4576: oc = new OrderedCollection();
4577: ob.valueOfSetOCForOI.add(oc);
4578: if (!ob.onUpdateList) {
4579: obList.add(ob);
4580: ob.onUpdateList = true;
4581: }
4582: } else {
4583: ci = og.orderedChildIdTable[oi];
4584:
4585: for (n = 0; n < ob.setOCForCI.size(); n++) {
4586: val = ((Integer) ob.setOCForCI.get(n))
4587: .intValue();
4588: if (val == ci) {
4589:
4590: oc = (OrderedCollection) ob.valueOfSetOCForCI
4591: .get(n);
4592: if (oc == null) {
4593: oc = new OrderedCollection();
4594: ob.valueOfSetOCForCI.set(n, oc);
4595: }
4596:
4597: break;
4598: }
4599: }
4600: if (n == ob.setOCForCI.size()) {
4601: oc = (OrderedCollection) ocs.get(ci);
4602: if (oc == null) {
4603: oc = new OrderedCollection();
4604: ob.setOCForCI.add(new Integer(ci));
4605: ob.valueOfSetOCForCI.add(oc);
4606: if (!ob.onUpdateList) {
4607: obList.add(ob);
4608: ob.onUpdateList = true;
4609: }
4610: }
4611: }
4612: }
4613: }
4614: if (oc.nextFrameLightBin == null) {
4615: oc.nextFrameLightBin = getLightBin(maxLights,
4616: ga.source.geometryBackground, false);
4617: oc.nextFrameLightBin.setOrderedInfo(oc);
4618:
4619: if (!oc.onUpdateList) {
4620: objUpdateList.add(oc);
4621: oc.onUpdateList = true;
4622: }
4623: }
4624:
4625: parentChildOrderedBins = oc.childOrderedBins;
4626: parentOrderedBin = ob;
4627: parentOrderedChildId = oi;
4628: }
4629: return (oc);
4630: }
4631:
4632: private void removeOrderedHeadLightBin(LightBin lightBin) {
4633: int i, k;
4634: int oi; // an id which identifies a children of the orderedGroup
4635: int ci; // child index of the ordered group
4636: ArrayList ocs;
4637: OrderedCollection oc;
4638: OrderedBin ob, savedOb;
4639: int n, val;
4640:
4641: oc = lightBin.orderedCollection;
4642:
4643: oc.lightBin = lightBin.next;
4644: oc.nextFrameLightBin = oc.lightBin;
4645:
4646: if (oc.lightBin != null) {
4647: // Make this lightBin the head of the lightBin;
4648: oc.lightBin.prev = null;
4649: oc.lightBin.orderedCollection = oc;
4650: }
4651:
4652: }
4653:
4654: /**
4655: * This gets a new EnviornmentSet. It creates one if there are none
4656: * on the freelist.
4657: */
4658: private EnvironmentSet getEnvironmentSet(RenderAtom ra,
4659: LightRetained[] lights, FogRetained fog,
4660: ModelClipRetained modelClip) {
4661: EnvironmentSet envSet;
4662:
4663: envSet = new EnvironmentSet(ra, lights, fog, modelClip, this );
4664: return (envSet);
4665: }
4666:
4667: /**
4668: * This finds or creates an AttributeBin for a given RenderAtom.
4669: */
4670: private AttributeBin findAttributeBin(EnvironmentSet envSet,
4671: RenderAtom ra) {
4672: int i;
4673: AttributeBin currentBin;
4674: RenderingAttributesRetained renderingAttributes;
4675: if (ra.app == null) {
4676: renderingAttributes = null;
4677: } else {
4678: renderingAttributes = ra.app.renderingAttributes;
4679: }
4680:
4681: currentBin = envSet.attributeBinList;
4682: while (currentBin != null) {
4683: if (currentBin.equals(renderingAttributes, ra)) {
4684: return (currentBin);
4685: }
4686: currentBin = currentBin.next;
4687: }
4688: // Check the "to-be-added" list of attributeBins for a match
4689: for (i = 0; i < envSet.addAttributeBins.size(); i++) {
4690: currentBin = (AttributeBin) envSet.addAttributeBins.get(i);
4691: if (currentBin.equals(renderingAttributes, ra)) {
4692: return (currentBin);
4693: }
4694: }
4695: currentBin = getAttributeBin(ra.app, renderingAttributes);
4696: envSet.addAttributeBin(currentBin, this );
4697: return (currentBin);
4698: }
4699:
4700: /**
4701: * This finds or creates an ShaderBin for a given RenderAtom.
4702: */
4703: private ShaderBin findShaderBin(AttributeBin attributeBin,
4704: RenderAtom ra) {
4705: int i, size;
4706: ShaderBin currentBin;
4707: ShaderAppearanceRetained sApp;
4708:
4709: if ((ra != null)
4710: && (ra.app instanceof ShaderAppearanceRetained))
4711: sApp = (ShaderAppearanceRetained) ra.app;
4712: else
4713: sApp = null;
4714:
4715: currentBin = attributeBin.shaderBinList;
4716: while (currentBin != null) {
4717: if (currentBin.equals(sApp)) {
4718: return currentBin;
4719: }
4720: currentBin = currentBin.next;
4721: }
4722:
4723: // Check the "to-be-added" list of shaderBins for a match
4724: size = attributeBin.addShaderBins.size();
4725: for (i = 0; i < size; i++) {
4726: currentBin = (ShaderBin) attributeBin.addShaderBins.get(i);
4727: if (currentBin.equals(sApp)) {
4728: return currentBin;
4729: }
4730: }
4731:
4732: currentBin = getShaderBin(sApp);
4733: attributeBin.addShaderBin(currentBin, this , sApp);
4734: return currentBin;
4735: }
4736:
4737: /**
4738: * This finds or creates a TextureBin for a given RenderAtom.
4739: */
4740: private TextureBin findTextureBin(ShaderBin shaderBin, RenderAtom ra) {
4741: int i, size;
4742: TextureBin currentBin;
4743: TextureRetained texture;
4744: TextureUnitStateRetained texUnitState[];
4745:
4746: if (ra.app == null) {
4747: texUnitState = null;
4748: } else {
4749: texUnitState = ra.app.texUnitState;
4750: }
4751:
4752: currentBin = shaderBin.textureBinList;
4753: while (currentBin != null) {
4754: if (currentBin.equals(texUnitState, ra)) {
4755: //System.err.println("1: Equal");
4756: return (currentBin);
4757: }
4758: currentBin = currentBin.next;
4759: }
4760: // Check the "to-be-added" list of TextureBins for a match
4761: size = shaderBin.addTextureBins.size();
4762: for (i = 0; i < size; i++) {
4763: currentBin = (TextureBin) shaderBin.addTextureBins.get(i);
4764: if (currentBin.equals(texUnitState, ra)) {
4765: //System.err.println("2: Equal");
4766: return (currentBin);
4767: }
4768: }
4769: // get a new texture bin for this texture unit state
4770: currentBin = getTextureBin(texUnitState, ra.app);
4771: shaderBin.addTextureBin(currentBin, this , ra);
4772: return (currentBin);
4773: }
4774:
4775: /**
4776: * This finds or creates a RenderMolecule for a given RenderAtom.
4777: */
4778: private RenderMolecule findRenderMolecule(TextureBin textureBin,
4779: RenderAtom ra) {
4780:
4781: RenderMolecule currentBin;
4782: PolygonAttributesRetained polygonAttributes;
4783: LineAttributesRetained lineAttributes;
4784: PointAttributesRetained pointAttributes;
4785: MaterialRetained material;
4786: ColoringAttributesRetained coloringAttributes;
4787: TransparencyAttributesRetained transparencyAttributes;
4788: int i;
4789: ArrayList list;
4790: TextureUnitStateRetained texUnitState[];
4791: RenderingAttributesRetained renderingAttributes;
4792: HashMap rmap = null, addmap = null;
4793:
4794: if (ra.app == null) {
4795: polygonAttributes = null;
4796: lineAttributes = null;
4797: pointAttributes = null;
4798: material = null;
4799: coloringAttributes = null;
4800: transparencyAttributes = null;
4801: renderingAttributes = null;
4802: texUnitState = null;
4803: } else {
4804: polygonAttributes = ra.app.polygonAttributes;
4805: lineAttributes = ra.app.lineAttributes;
4806: pointAttributes = ra.app.pointAttributes;
4807: material = ra.app.material;
4808: coloringAttributes = ra.app.coloringAttributes;
4809: transparencyAttributes = ra.app.transparencyAttributes;
4810: renderingAttributes = ra.app.renderingAttributes;
4811: texUnitState = ra.app.texUnitState;
4812: }
4813:
4814: // Get the renderMoleculelist for this xform
4815: if (ra.isOpaque()) {
4816: rmap = textureBin.opaqueRenderMoleculeMap;
4817: addmap = textureBin.addOpaqueRMs;
4818: } else {
4819: rmap = textureBin.transparentRenderMoleculeMap;
4820: addmap = textureBin.addTransparentRMs;
4821: }
4822: currentBin = (RenderMolecule) rmap
4823: .get(ra.geometryAtom.source.localToVworld[0]);
4824:
4825: while (currentBin != null) {
4826: if (currentBin.equals(ra, polygonAttributes,
4827: lineAttributes, pointAttributes, material,
4828: coloringAttributes, transparencyAttributes,
4829: ra.geometryAtom.source.localToVworld[0])) {
4830:
4831: currentBin.addRenderAtom(ra, this );
4832: ra.envSet = ra.renderMolecule.textureBin.environmentSet;
4833: // If the locale has changed for an existing renderMolecule
4834: // handle the RmlocaleToVworld
4835: return (currentBin);
4836: }
4837: currentBin = currentBin.next;
4838: }
4839: // Check the "to-be-added" list of renderMolecules for a match
4840: if ((list = (ArrayList) addmap
4841: .get(ra.geometryAtom.source.localToVworld[0])) != null) {
4842: for (i = 0; i < list.size(); i++) {
4843: currentBin = (RenderMolecule) list.get(i);
4844: if (currentBin.equals(ra, polygonAttributes,
4845: lineAttributes, pointAttributes, material,
4846: coloringAttributes, transparencyAttributes,
4847: ra.geometryAtom.source.localToVworld[0])) {
4848: currentBin.addRenderAtom(ra, this );
4849: return (currentBin);
4850: }
4851: }
4852: }
4853:
4854: currentBin = getRenderMolecule(ra.geometryAtom,
4855: polygonAttributes, lineAttributes, pointAttributes,
4856: material, coloringAttributes, transparencyAttributes,
4857: renderingAttributes, texUnitState,
4858: ra.geometryAtom.source.localToVworld[0],
4859: ra.geometryAtom.source.localToVworldIndex[0]);
4860: textureBin.addRenderMolecule(currentBin, this );
4861: currentBin.addRenderAtom(ra, this );
4862: return (currentBin);
4863: }
4864:
4865: /**
4866: * This gets a new ShaderBin. It creates one if there are none
4867: * on the freelist.
4868: */
4869: private ShaderBin getShaderBin(ShaderAppearanceRetained sApp) {
4870: return new ShaderBin(sApp, this );
4871: }
4872:
4873: /**
4874: * This gets a new AttributeBin. It creates one if there are none
4875: * on the freelist.
4876: */
4877: private AttributeBin getAttributeBin(AppearanceRetained app,
4878: RenderingAttributesRetained ra) {
4879: return new AttributeBin(app, ra, this );
4880: }
4881:
4882: /**
4883: * This gets a new LightBin. It creates one if there are none
4884: * on the freelist.
4885: */
4886: private LightBin getLightBin(int maxLights, BackgroundRetained bg,
4887: boolean inOpaque) {
4888: LightBin lightBin;
4889:
4890: lightBin = new LightBin(maxLights, this , inOpaque);
4891:
4892: lightBin.geometryBackground = bg;
4893: return (lightBin);
4894: }
4895:
4896: /**
4897: * This gets a new TextureBin. It creates one if there are none
4898: * on the freelist.
4899: */
4900: private TextureBin getTextureBin(
4901: TextureUnitStateRetained texUnitState[],
4902: AppearanceRetained app) {
4903: return new TextureBin(texUnitState, app, this );
4904: }
4905:
4906: /**
4907: * This gets a new RenderMolecule. It creates one if there are none
4908: * on the freelist.
4909: */
4910: private RenderMolecule getRenderMolecule(GeometryAtom ga,
4911: PolygonAttributesRetained polya,
4912: LineAttributesRetained linea,
4913: PointAttributesRetained pointa, MaterialRetained material,
4914: ColoringAttributesRetained cola,
4915: TransparencyAttributesRetained transa,
4916: RenderingAttributesRetained ra,
4917: TextureUnitStateRetained[] texUnits,
4918: Transform3D[] transform, int[] transformIndex) {
4919:
4920: return new RenderMolecule(ga, polya, linea, pointa, material,
4921: cola, transa, ra, texUnits, transform, transformIndex,
4922: this );
4923: }
4924:
4925: /**
4926: * This finds or creates an EnviornmentSet for a given RenderAtom.
4927: * This also deals with empty LightBin lists.
4928: */
4929: private EnvironmentSet findEnvironmentSet(RenderAtom ra) {
4930: LightBin currentBin, lightBin;
4931: EnvironmentSet currentEnvSet, newBin;
4932: int i;
4933: LightBin addBin = null;
4934: OrderedCollection oc = null;
4935:
4936: if (ra.geometryAtom.source.geometryBackground == null) {
4937: if (ra.geometryAtom.source.orderedPath != null) {
4938: oc = findOrderedCollection(ra.geometryAtom, false);
4939: currentBin = oc.nextFrameLightBin;
4940: addBin = oc.addLightBins;
4941: } else {
4942: currentBin = opaqueBin;
4943: addBin = addOpaqueBin;
4944: }
4945: } else {
4946: if (ra.geometryAtom.source.orderedPath != null) {
4947: oc = findOrderedCollection(ra.geometryAtom, true);
4948: currentBin = oc.nextFrameLightBin;
4949: addBin = oc.addLightBins;
4950: } else {
4951: currentBin = bgOpaqueBin;
4952: addBin = bgAddOpaqueBin;
4953:
4954: }
4955: }
4956: lightBin = currentBin;
4957:
4958: ra.lights = universe.renderingEnvironmentStructure
4959: .getInfluencingLights(ra, view);
4960: ra.fog = universe.renderingEnvironmentStructure
4961: .getInfluencingFog(ra, view);
4962: ra.modelClip = universe.renderingEnvironmentStructure
4963: .getInfluencingModelClip(ra, view);
4964:
4965: while (currentBin != null) {
4966: // this test is always true for non-backgroundGeo bins
4967: if (currentBin.geometryBackground == ra.geometryAtom.source.geometryBackground) {
4968:
4969: currentEnvSet = currentBin.environmentSetList;
4970: while (currentEnvSet != null) {
4971: if (currentEnvSet.equals(ra, ra.lights, ra.fog,
4972: ra.modelClip)) {
4973: return (currentEnvSet);
4974: }
4975: currentEnvSet = currentEnvSet.next;
4976: }
4977: // Check the "to-be-added" list of environmentSets for a match
4978: for (i = 0; i < currentBin.insertEnvSet.size(); i++) {
4979: newBin = (EnvironmentSet) currentBin.insertEnvSet
4980: .get(i);
4981: if (newBin.equals(ra, ra.lights, ra.fog,
4982: ra.modelClip)) {
4983: return (newBin);
4984: }
4985: }
4986: }
4987: currentBin = currentBin.next;
4988: }
4989:
4990: // Now check the to-be added lightbins
4991: currentBin = addBin;
4992: while (currentBin != null) {
4993:
4994: // this following test is always true for non-backgroundGeo bins
4995: if (currentBin.geometryBackground == ra.geometryAtom.source.geometryBackground) {
4996:
4997: // Check the "to-be-added" list of environmentSets for a match
4998: for (i = 0; i < currentBin.insertEnvSet.size(); i++) {
4999: newBin = (EnvironmentSet) currentBin.insertEnvSet
5000: .get(i);
5001: if (newBin.equals(ra, ra.lights, ra.fog,
5002: ra.modelClip)) {
5003: return (newBin);
5004: }
5005: }
5006: }
5007: currentBin = currentBin.next;
5008: }
5009:
5010: // Need a new one
5011: currentEnvSet = getEnvironmentSet(ra, ra.lights, ra.fog,
5012: ra.modelClip);
5013: currentBin = lightBin;
5014:
5015: // Find a lightbin that envSet fits into
5016: while (currentBin != null) {
5017:
5018: // the first test is always true for non-backgroundGeo bins
5019: if (currentBin.geometryBackground == ra.geometryAtom.source.geometryBackground
5020: && currentBin.willEnvironmentSetFit(currentEnvSet)) {
5021: break;
5022: }
5023: currentBin = currentBin.next;
5024: }
5025:
5026: // Now check the to-be added lightbins
5027: if (currentBin == null) {
5028: currentBin = addBin;
5029: while (currentBin != null) {
5030:
5031: // the first test is always true for non-backgroundGeo bins
5032: if (currentBin.geometryBackground == ra.geometryAtom.source.geometryBackground
5033: && currentBin
5034: .willEnvironmentSetFit(currentEnvSet)) {
5035:
5036: break;
5037: }
5038: currentBin = currentBin.next;
5039: }
5040: }
5041:
5042: if (currentBin == null) {
5043: // Need a new lightbin
5044: currentBin = getLightBin(maxLights,
5045: ra.geometryAtom.source.geometryBackground, false);
5046: if (addBin != null) {
5047: currentBin.next = addBin;
5048: addBin.prev = currentBin;
5049: }
5050: if (ra.geometryAtom.source.orderedPath != null) {
5051: if (!oc.onUpdateList) {
5052: objUpdateList.add(oc);
5053: oc.onUpdateList = true;
5054: }
5055: oc.addLightBins = currentBin;
5056: } else {
5057: if (ra.geometryAtom.source.geometryBackground == null)
5058: addOpaqueBin = currentBin;
5059: else
5060: bgAddOpaqueBin = currentBin;
5061: }
5062: }
5063:
5064: currentBin.addEnvironmentSet(currentEnvSet, this );
5065: return (currentEnvSet);
5066: }
5067:
5068: void removeLightBin(LightBin lbin) {
5069: if (lbin.prev == null) { // At the head of the list
5070:
5071: if (lbin.orderedCollection != null)
5072: removeOrderedHeadLightBin(lbin);
5073:
5074: if (lbin.geometryBackground == null) {
5075: if (opaqueBin == lbin) {
5076: opaqueBin = lbin.next;
5077: }
5078: } else {
5079: if (bgOpaqueBin == lbin) {
5080: bgOpaqueBin = lbin.next;
5081: }
5082: }
5083: if (lbin.next != null) {
5084: lbin.next.prev = null;
5085: }
5086: } else { // In the middle or at the end.
5087: lbin.prev.next = lbin.next;
5088: if (lbin.next != null) {
5089: lbin.next.prev = lbin.prev;
5090: }
5091: }
5092: Canvas3D canvases[] = view.getCanvases();
5093: for (int i = 0; i < canvases.length; i++) {
5094: // Mark the environmentSet cached by all the canvases as null
5095: // to force to reEvaluate when it comes back from the freelist
5096: // During LightBin::render(), we only check for the pointers not
5097: // being the same, so we need to take care of the env set
5098: // gotten from the freelist from one frame to another
5099: canvases[i].lightBin = null;
5100: }
5101: lbin.prev = null;
5102: lbin.next = null;
5103: }
5104:
5105: void addDisplayListResourceFreeList(RenderMolecule rm) {
5106: displayListResourceFreeList.add(rm.displayListIdObj);
5107: }
5108:
5109: /**
5110: * This renders the background scene graph.
5111: */
5112: void renderBackground(Canvas3D cv) {
5113: LightBin currentBin;
5114: boolean savedDepthBufferWriteEnable;
5115:
5116: cv.setDepthBufferWriteEnableOverride(true);
5117: savedDepthBufferWriteEnable = cv.depthBufferWriteEnable;
5118: cv.setDepthBufferWriteEnable(false);
5119: // render background opaque
5120: currentBin = bgOpaqueBin;
5121: while (currentBin != null) {
5122: if (currentBin.geometryBackground == geometryBackground)
5123: currentBin.render(cv);
5124: currentBin = currentBin.next;
5125: }
5126:
5127: // render background ordered
5128: if (bgOrderedBins.size() > 0) {
5129: renderOrderedBins(cv, bgOrderedBins, true);
5130: }
5131:
5132: TransparentRenderingInfo tinfo = bgTransparentInfo;
5133: while (tinfo != null) {
5134: tinfo.render(cv);
5135: tinfo = tinfo.next;
5136: }
5137: cv.setDepthBufferWriteEnableOverride(false);
5138: cv.setDepthBufferWriteEnable(savedDepthBufferWriteEnable);
5139: }
5140:
5141: /**
5142: * This renders the opaque objects
5143: */
5144: void renderOpaque(Canvas3D cv) {
5145: LightBin currentBin = opaqueBin;
5146: //System.err.println("========> renderOpaque");
5147: while (currentBin != null) {
5148: //System.err.println("====> rendering Opaque Bin ");
5149: currentBin.render(cv);
5150: currentBin = currentBin.next;
5151: }
5152:
5153: }
5154:
5155: /**
5156: * This renders the transparent objects
5157: */
5158: void renderTransparent(Canvas3D cv) {
5159: boolean savedDepthBufferWriteEnable = true;
5160:
5161: //System.err.println("====> renderTransparent");
5162: TransparentRenderingInfo tinfo = transparentInfo;
5163: if (tinfo != null) {
5164: //System.err.println("====> rendering transparent Bin");
5165:
5166: if (cv.view.depthBufferFreezeTransparent) {
5167: cv.setDepthBufferWriteEnableOverride(true);
5168: savedDepthBufferWriteEnable = cv.depthBufferWriteEnable;
5169: cv.setDepthBufferWriteEnable(false);
5170: }
5171:
5172: if (transpSortMode == View.TRANSPARENCY_SORT_NONE) {
5173: while (tinfo != null) {
5174: tinfo.render(cv);
5175: tinfo = tinfo.next;
5176: }
5177: } else if (transpSortMode == View.TRANSPARENCY_SORT_GEOMETRY) {
5178: while (tinfo != null) {
5179: tinfo.sortRender(cv);
5180: tinfo = tinfo.next;
5181: }
5182: }
5183: if (cv.view.depthBufferFreezeTransparent) {
5184: cv.setDepthBufferWriteEnableOverride(false);
5185: cv
5186: .setDepthBufferWriteEnable(savedDepthBufferWriteEnable);
5187: }
5188: }
5189: }
5190:
5191: /**
5192: * This renders the ordered objects
5193: */
5194: void renderOrdered(Canvas3D cv) {
5195: // System.err.println("******renderOrdered, orderedBins.size() = "+orderedBins.size()+" RenderBin = "+this);
5196: if (orderedBins.size() > 0)
5197: renderOrderedBins(cv, orderedBins, false);
5198: }
5199:
5200: void renderOrderedBins(Canvas3D cv, ArrayList bins,
5201: boolean doInfinite) {
5202: int sz = bins.size();
5203:
5204: for (int i = 0; i < sz; i++) {
5205: renderOrderedBin(cv, (OrderedBin) bins.get(i), doInfinite);
5206: }
5207: }
5208:
5209: void renderOrderedBin(Canvas3D cv, OrderedBin orderedBin,
5210: boolean doInfinite) {
5211: int i, index;
5212: LightBin currentBin;
5213: OrderedCollection oc;
5214: boolean depthBufferEnable = true;
5215: OrderedGroupRetained og = orderedBin.source;
5216: boolean isDecal = (og instanceof DecalGroupRetained)
5217: && cv.systemStencilAvailable;
5218: int size = orderedBin.orderedCollections.size();
5219:
5220: // System.err.println("RB : orderedBin.orderedCollections.size() " + size);
5221: for (i = 0; i < size; i++) {
5222: if ((og != null) && (og.childIndexOrder != null)) {
5223: index = og.childIndexOrder[i];
5224: } else {
5225: index = i;
5226: }
5227: oc = (OrderedCollection) orderedBin.orderedCollections
5228: .get(index);
5229: if (isDecal) {
5230: if (index == 0) { // first child
5231: cv.setDepthBufferEnableOverride(true);
5232: depthBufferEnable = cv.decal1stChildSetup(cv.ctx);
5233: } else if (index == 1) { // second child
5234: // decalNthChildSetup will disable depth test
5235: cv.decalNthChildSetup(cv.ctx);
5236: }
5237: }
5238: if (oc != null) {
5239: currentBin = oc.lightBin;
5240: while (currentBin != null) {
5241: if (!doInfinite
5242: || currentBin.geometryBackground == geometryBackground) {
5243: currentBin.render(cv);
5244: }
5245: currentBin = currentBin.next;
5246: }
5247: renderOrderedBins(cv, oc.childOrderedBins, doInfinite);
5248: }
5249: }
5250: if (isDecal) { // reset
5251: cv.decalReset(cv.ctx, depthBufferEnable);
5252: cv.setDepthBufferEnableOverride(false);
5253: }
5254: }
5255:
5256: /**
5257: * Sets the new background color.
5258: */
5259: void setBackground(BackgroundRetained back) {
5260:
5261: boolean cvDirty = false;
5262: BackgroundRetained oldGeomBack = geometryBackground;
5263: geometryBackground = null;
5264:
5265: if (back != null) {
5266: background.initColor(back.color);
5267: background.initImageScaleMode(back.imageScaleMode);
5268: background.geometryBranch = back.geometryBranch;
5269: if (background.geometryBranch != null) {
5270: geometryBackground = back;
5271: }
5272: // Release resources associated with old BG and initialize new BG
5273: // if the old and new BG images are different or if the
5274: // reloadBgTexture flag is set.
5275: if (background.image != back.image || reloadBgTexture) {
5276: if (background.image != null) {
5277: assert background.texture != null;
5278: addTextureResourceFreeList(background.texture);
5279: removeNodeComponent(background.image);
5280: }
5281: if (back.image != null) {
5282: // May need to optimize later
5283: background
5284: .initImage((ImageComponent2D) back.image.source);
5285: addNodeComponent(back.image);
5286: } else {
5287: background.initImage(null);
5288: }
5289: }
5290: if (oldGeomBack == null) {
5291: cvDirty = true;
5292: }
5293: } else {
5294: background.initColor(black);
5295: background.geometryBranch = null;
5296: if (background.image != null) {
5297: assert background.texture != null;
5298: addTextureResourceFreeList(background.texture);
5299: removeNodeComponent(background.image);
5300: }
5301: background.initImage(null);
5302: if (oldGeomBack != null) {
5303: cvDirty = true;
5304: }
5305: }
5306:
5307: // Need to reEvaluate View cache since doInfinite
5308: // flag is changed in Renderer.updateViewCache()
5309: Canvas3D canvases[] = view.getCanvases();
5310: for (int i = 0; i < canvases.length; i++) {
5311: Canvas3D canvas = canvases[i];
5312: synchronized (canvas.dirtyMaskLock) {
5313: if (cvDirty) {
5314: canvas.cvDirtyMask[0] |= Canvas3D.BACKGROUND_DIRTY;
5315: canvas.cvDirtyMask[1] |= Canvas3D.BACKGROUND_DIRTY;
5316: }
5317: canvas.cvDirtyMask[0] |= Canvas3D.BACKGROUND_IMAGE_DIRTY;
5318: canvas.cvDirtyMask[1] |= Canvas3D.BACKGROUND_IMAGE_DIRTY;
5319: }
5320: }
5321: }
5322:
5323: void reEvaluateFog(ArrayList fogs, boolean updateDirty,
5324: boolean altAppDirty) {
5325: EnvironmentSet e;
5326: RenderAtom ra;
5327: FogRetained newfog;
5328: int i, j, n;
5329: AppearanceRetained app;
5330: Object[] retVal;
5331:
5332: int sz = renderAtoms.size();
5333: for (i = 0; i < sz; i++) {
5334: ra = (RenderAtom) renderAtoms.get(i);
5335: if (!ra.inRenderBin())
5336: continue;
5337:
5338: newfog = universe.renderingEnvironmentStructure
5339: .getInfluencingFog(ra, view);
5340: // If the fog of the render atom is the same
5341: // as the old fog, then move on to the
5342: // next renderAtom
5343: if (altAppDirty
5344: && ra.geometryAtom.source.appearanceOverrideEnable) {
5345: retVal = universe.renderingEnvironmentStructure
5346: .getInfluencingAppearance(ra, view);
5347: if (retVal[0] == Boolean.TRUE) {
5348: app = (AppearanceRetained) retVal[1];
5349: } else {
5350: app = ra.geometryAtom.source.appearance;
5351: }
5352:
5353: if (app == ra.app) {
5354: if (ra.envSet.fog == newfog)
5355: continue;
5356: else {
5357: getNewEnvironment(ra, ra.lights, newfog,
5358: ra.modelClip, ra.app);
5359: }
5360: } else {
5361: if (ra.geometryAtom.source.otherAppearance != app) {
5362: if (ra.geometryAtom.source.otherAppearance != null)
5363: ra.geometryAtom.source.otherAppearance.sgApp
5364: .removeAMirrorUser(ra.geometryAtom.source);
5365: if (app != ra.geometryAtom.source.appearance) {
5366: if (app != null) {
5367: app.sgApp
5368: .addAMirrorUser(ra.geometryAtom.source);
5369: }
5370: ra.geometryAtom.source.otherAppearance = app;
5371: } else {
5372: ra.geometryAtom.source.otherAppearance = null;
5373: }
5374: }
5375:
5376: if (ra.envSet.fog == newfog) {
5377: ra.app = app;
5378: e = ra.envSet;
5379: ra.renderMolecule.removeRenderAtom(ra);
5380: reInsertAttributeBin(e, ra);
5381: } else {
5382: getNewEnvironment(ra, ra.lights, newfog,
5383: ra.modelClip, app);
5384: }
5385: }
5386: } else {
5387: if (ra.envSet.fog == newfog)
5388: continue;
5389: getNewEnvironment(ra, ra.lights, newfog, ra.modelClip,
5390: ra.app);
5391: }
5392: ;
5393: }
5394:
5395: // Only done for new fogs added to the system
5396: if (updateDirty)
5397: updateCanvasForDirtyFog(fogs);
5398: }
5399:
5400: void updateCanvasForDirtyFog(ArrayList fogs) {
5401: int i, j;
5402: EnvironmentSet e;
5403: UnorderList list;
5404: EnvironmentSet envsets[];
5405: int envsize;
5406: int sz = fogs.size();
5407:
5408: for (i = 0; i < sz; i++) {
5409: FogRetained fog = (FogRetained) fogs.get(i);
5410: list = fog.environmentSets;
5411: synchronized (list) {
5412: envsize = list.size();
5413: envsets = (EnvironmentSet[]) list.toArray(false);
5414: for (j = 0; j < envsize; j++) {
5415: e = envsets[j];
5416: e.canvasDirty |= Canvas3D.FOG_DIRTY;
5417: if (!e.onUpdateList) {
5418: objUpdateList.add(e);
5419: e.onUpdateList = true;
5420: }
5421: }
5422: }
5423: }
5424: }
5425:
5426: void reEvaluateModelClip(ArrayList modelClips, boolean updateDirty,
5427: boolean altAppDirty) {
5428: EnvironmentSet e;
5429: RenderAtom ra;
5430: ModelClipRetained newModelClip;
5431: int i, j, n;
5432: AppearanceRetained app;
5433: Object[] retVal;
5434: int sz = renderAtoms.size();
5435: for (i = 0; i < sz; i++) {
5436: ra = (RenderAtom) renderAtoms.get(i);
5437: if (!ra.inRenderBin())
5438: continue;
5439:
5440: newModelClip = universe.renderingEnvironmentStructure
5441: .getInfluencingModelClip(ra, view);
5442:
5443: // If the model clip of the render atom is the same
5444: // as the old model clip, then move on to the
5445: // next renderAtom
5446: if (altAppDirty
5447: && ra.geometryAtom.source.appearanceOverrideEnable) {
5448: retVal = universe.renderingEnvironmentStructure
5449: .getInfluencingAppearance(ra, view);
5450: if (retVal[0] == Boolean.TRUE) {
5451: app = (AppearanceRetained) retVal[1];
5452: } else {
5453: app = ra.geometryAtom.source.appearance;
5454: }
5455:
5456: if (app == ra.app) {
5457: if (ra.envSet.modelClip == newModelClip)
5458: continue;
5459: else {
5460: getNewEnvironment(ra, ra.lights, ra.fog,
5461: ra.envSet.modelClip, ra.app);
5462: }
5463: } else {
5464: if (ra.geometryAtom.source.otherAppearance != app) {
5465: if (ra.geometryAtom.source.otherAppearance != null)
5466: ra.geometryAtom.source.otherAppearance.sgApp
5467: .removeAMirrorUser(ra.geometryAtom.source);
5468: if (app != ra.geometryAtom.source.appearance) {
5469: if (app != null) {
5470: app.sgApp
5471: .addAMirrorUser(ra.geometryAtom.source);
5472: }
5473: ra.geometryAtom.source.otherAppearance = app;
5474: } else {
5475: ra.geometryAtom.source.otherAppearance = null;
5476: }
5477: }
5478: if (ra.envSet.modelClip == newModelClip) {
5479: ra.app = app;
5480: e = ra.envSet;
5481: ra.renderMolecule.removeRenderAtom(ra);
5482: reInsertAttributeBin(e, ra);
5483: } else {
5484:
5485: getNewEnvironment(ra, ra.lights, ra.fog,
5486: newModelClip, app);
5487: }
5488: }
5489: } else {
5490: if (ra.envSet.modelClip == newModelClip)
5491: continue;
5492: getNewEnvironment(ra, ra.lights, ra.fog, newModelClip,
5493: ra.app);
5494: }
5495: ;
5496: }
5497:
5498: // Only done for new modelClip added to the system
5499: if (updateDirty)
5500: updateCanvasForDirtyModelClip(modelClips);
5501: }
5502:
5503: void updateCanvasForDirtyModelClip(ArrayList modelClips) {
5504: int i, j;
5505: EnvironmentSet e;
5506: int enableMCMaskCache = 0;
5507: UnorderList list;
5508: EnvironmentSet envsets[];
5509: int sz = modelClips.size();
5510: int envsize;
5511:
5512: for (i = 0; i < sz; i++) {
5513: ModelClipRetained modelClip = (ModelClipRetained) modelClips
5514: .get(i);
5515:
5516: // evaluate the modelClip enable mask
5517: enableMCMaskCache = 0;
5518: for (j = 0; j < 6; j++) {
5519: if (modelClip.enables[j])
5520: enableMCMaskCache |= 1 << j;
5521: }
5522: list = modelClip.environmentSets;
5523: synchronized (list) {
5524: envsize = list.size();
5525: envsets = (EnvironmentSet[]) list.toArray(false);
5526: for (j = 0; j < envsize; j++) {
5527: e = envsets[j];
5528: e.canvasDirty |= Canvas3D.MODELCLIP_DIRTY;
5529: e.enableMCMaskCache = enableMCMaskCache;
5530: if (!e.onUpdateList) {
5531: objUpdateList.add(e);
5532: e.onUpdateList = true;
5533: }
5534: }
5535: }
5536: }
5537: }
5538:
5539: void reEvaluateLights(boolean altAppDirty) {
5540: EnvironmentSet e;
5541: RenderAtom ra;
5542: LightRetained[] lights;
5543: int i, n;
5544: AppearanceRetained app;
5545: Object[] retVal;
5546: int sz = renderAtoms.size();
5547: for (i = 0; i < sz; i++) {
5548: ra = (RenderAtom) renderAtoms.get(i);
5549: if (!ra.inRenderBin())
5550: continue;
5551:
5552: lights = universe.renderingEnvironmentStructure
5553: .getInfluencingLights(ra, view);
5554: // If the lights of the render atom is the same
5555: // as the old set of lights, then move on to the
5556: // next renderAtom
5557: if (altAppDirty
5558: && ra.geometryAtom.source.appearanceOverrideEnable) {
5559: retVal = universe.renderingEnvironmentStructure
5560: .getInfluencingAppearance(ra, view);
5561: if (retVal[0] == Boolean.TRUE) {
5562: app = (AppearanceRetained) retVal[1];
5563: } else {
5564: app = ra.geometryAtom.source.appearance;
5565: }
5566:
5567: if (app == ra.app) {
5568: if (ra.lights == lights
5569: || ra.envSet.equalLights(lights))
5570: continue;
5571: else {
5572: getNewEnvironment(ra, lights, ra.fog,
5573: ra.modelClip, ra.app);
5574: }
5575: } else {
5576: if (ra.geometryAtom.source.otherAppearance != app) {
5577: if (ra.geometryAtom.source.otherAppearance != null)
5578: ra.geometryAtom.source.otherAppearance.sgApp
5579: .removeAMirrorUser(ra.geometryAtom.source);
5580: if (app != ra.geometryAtom.source.appearance) {
5581: if (app != null) {
5582: app.sgApp
5583: .addAMirrorUser(ra.geometryAtom.source);
5584: }
5585: ra.geometryAtom.source.otherAppearance = app;
5586: } else {
5587: ra.geometryAtom.source.otherAppearance = null;
5588: }
5589: }
5590: if (ra.lights == lights
5591: || ra.envSet.equalLights(lights)) {
5592: ra.app = app;
5593: e = ra.envSet;
5594: ra.renderMolecule.removeRenderAtom(ra);
5595: reInsertAttributeBin(e, ra);
5596: } else {
5597: getNewEnvironment(ra, lights, ra.fog,
5598: ra.modelClip, app);
5599: }
5600: }
5601: } else {
5602: if (ra.lights == lights
5603: || ra.envSet.equalLights(lights))
5604: continue;
5605: getNewEnvironment(ra, lights, ra.fog, ra.modelClip,
5606: ra.app);
5607: }
5608: }
5609: // Only done for new lights added to the system
5610: if (changedLts.size() > 0)
5611: updateCanvasForDirtyLights(changedLts);
5612:
5613: }
5614:
5615: void updateCanvasForDirtyLights(ArrayList mLts) {
5616: int n, i, j, lmask;
5617: EnvironmentSet e;
5618: UnorderList list;
5619: EnvironmentSet envsets[];
5620: int sz = mLts.size();
5621: int envsize;
5622: int ltsize;
5623:
5624: for (n = 0; n < sz; n++) {
5625: LightRetained lt = (LightRetained) mLts.get(n);
5626: list = lt.environmentSets;
5627: synchronized (list) {
5628: envsets = (EnvironmentSet[]) list.toArray(false);
5629: envsize = list.size();
5630:
5631: if (lt.nodeType == LightRetained.AMBIENTLIGHT) {
5632: for (i = 0; i < envsize; i++) {
5633: e = envsets[i];
5634: e.canvasDirty |= Canvas3D.AMBIENTLIGHT_DIRTY;
5635: if (!e.onUpdateList) {
5636: objUpdateList.add(e);
5637: e.onUpdateList = true;
5638: }
5639: }
5640: } else {
5641: for (i = 0; i < envsize; i++) {
5642: e = envsets[i];
5643: lmask = 0;
5644: ltsize = e.lights.size();
5645: for (j = 0; j < ltsize; j++) {
5646: LightRetained curLt = (LightRetained) e.lights
5647: .get(j);
5648: if (lt == curLt) {
5649: lmask = (1 << e.ltPos[j]);
5650: if (curLt.lightOn == true) {
5651: e.enableMaskCache |= (1 << e.ltPos[j]);
5652: } else {
5653: e.enableMaskCache &= (1 << e.ltPos[j]);
5654: }
5655: break;
5656: }
5657: }
5658: e.canvasDirty |= Canvas3D.LIGHTENABLES_DIRTY;
5659: if (!e.onUpdateList) {
5660: objUpdateList.add(e);
5661: e.onUpdateList = true;
5662: }
5663: if (e.lightBin != null) {
5664: e.lightBin.canvasDirty |= Canvas3D.LIGHTBIN_DIRTY;
5665: e.lightBin.lightDirtyMaskCache |= lmask;
5666: if (!e.lightBin.onUpdateList) {
5667: e.lightBin.onUpdateList = true;
5668: objUpdateList.add(e.lightBin);
5669: }
5670: }
5671: }
5672: }
5673: }
5674: }
5675: }
5676:
5677: void addTextureResourceFreeList(TextureRetained tex) {
5678: toBeAddedTextureResourceFreeList.add(tex);
5679: }
5680:
5681: void reEvaluateEnv(ArrayList mLts, ArrayList fogs,
5682: ArrayList modelClips, boolean updateDirty,
5683: boolean altAppDirty) {
5684:
5685: reEvaluateAllRenderAtoms(altAppDirty);
5686:
5687: // Done only for xform changes, not for bounding leaf change
5688: if (updateDirty) {
5689: // Update canvases for dirty lights and fog
5690: if (mLts.size() > 0)
5691: updateCanvasForDirtyLights(mLts);
5692: if (fogs.size() > 0)
5693: updateCanvasForDirtyFog(fogs);
5694: if (modelClips.size() > 0)
5695: updateCanvasForDirtyModelClip(modelClips);
5696: }
5697:
5698: }
5699:
5700: void updateInfVworldToVpc() {
5701: vworldToVpc.getRotation(infVworldToVpc);
5702: }
5703:
5704: // Lock all geometry before rendering into the any canvas
5705: // in the case of display list, for each renderer,
5706: // release after building the display list (which happens
5707: // for the first canvas rendered)
5708: void lockGeometry() {
5709: GeometryRetained geo;
5710: int i, size;
5711:
5712: // Vertex array is locked for every time renderer is run
5713: size = lockGeometryList.size();
5714: for (i = 0; i < size; i++) {
5715: geo = (GeometryRetained) lockGeometryList.get(i);
5716: geo.geomLock.getLock();
5717:
5718: }
5719:
5720: // dlist is locked only when they are rebuilt
5721: size = dlistLockList.size();
5722: for (i = 0; i < size; i++) {
5723: geo = (GeometryRetained) dlistLockList.get(i);
5724: geo.geomLock.getLock();
5725:
5726: }
5727:
5728: // Lock all the by reference image components
5729: size = nodeComponentList.size();
5730: for (i = 0; i < size; i++) {
5731: ImageComponentRetained nc = (ImageComponentRetained) nodeComponentList
5732: .get(i);
5733: nc.geomLock.getLock();
5734: }
5735: }
5736:
5737: // Release all geometry after rendering to the last canvas
5738: void releaseGeometry() {
5739: GeometryRetained geo;
5740: int i, size;
5741:
5742: size = lockGeometryList.size();
5743: for (i = 0; i < size; i++) {
5744: geo = (GeometryRetained) lockGeometryList.get(i);
5745: geo.geomLock.unLock();
5746: }
5747:
5748: size = dlistLockList.size();
5749: for (i = 0; i < size; i++) {
5750: geo = (GeometryRetained) dlistLockList.get(i);
5751: geo.geomLock.unLock();
5752: }
5753: // Clear the display list clear list
5754: dlistLockList.clear();
5755: // Lock all the by reference image components
5756: size = nodeComponentList.size();
5757: for (i = 0; i < size; i++) {
5758: ImageComponentRetained nc = (ImageComponentRetained) nodeComponentList
5759: .get(i);
5760: nc.geomLock.unLock();
5761: }
5762: }
5763:
5764: void addGeometryToLockList(Object geo) {
5765: // just add it to the list, if its a shared geometry
5766: // it may be added more than once, thats OK since we
5767: // now have nested locks!
5768: lockGeometryList.add(geo);
5769: }
5770:
5771: void removeGeometryFromLockList(Object geo) {
5772: lockGeometryList.remove(geo);
5773:
5774: }
5775:
5776: void addDirtyReferenceGeometry(Object geo) {
5777: // just add it to the list, if its a shared geometry
5778: // it may be added more than once, thats OK since we
5779: // now have nested locks!
5780: dirtyReferenceGeomList.add(geo);
5781: }
5782:
5783: void addNodeComponent(Object nc) {
5784: newNodeComponentList.add(nc);
5785: }
5786:
5787: void removeNodeComponent(Object nc) {
5788: removeNodeComponentList.add(nc);
5789: }
5790:
5791: void addDirtyNodeComponent(Object nc) {
5792: dirtyNodeComponentList.add(nc);
5793: }
5794:
5795: void clearDirtyOrientedRAs() {
5796: int i, nRAs;
5797: Canvas3D cv;
5798: RenderAtom ra;
5799: OrientedShape3DRetained os;
5800: nRAs = dirtyOrientedRAs.size();
5801:
5802: // clear the dirtyMask
5803: for (i = 0; i < nRAs; i++) {
5804: ra = (RenderAtom) dirtyOrientedRAs.get(i);
5805: ra.dirtyMask &= ~RenderAtom.IN_DIRTY_ORIENTED_RAs;
5806: }
5807: dirtyOrientedRAs.clear();
5808: }
5809:
5810: // Called from MasterControl when viewCache changes or if there are
5811: // dirtyOrientedShapes
5812: void updateOrientedRAs() {
5813: int i, nRAs;
5814: Canvas3D cv = null;
5815: RenderAtom ra;
5816: OrientedShape3DRetained os;
5817:
5818: // Issue 562 : use cached list of canvases to avoid index OOB exception
5819: Canvas3D[] canvases = view.getCanvases();
5820: if (canvases.length > 0) {
5821: cv = canvases[0];
5822: }
5823:
5824: if (cv != null) {
5825: if (view.viewCache.vcDirtyMask != 0) {
5826: nRAs = orientedRAs.size();
5827:
5828: // Update ra's localToVworld given orientedTransform
5829: // Mark Oriented shape as dirty, since multiple ra could point
5830: // to the same OrientShape3D, compute the xform only once
5831: for (i = 0; i < nRAs; i++) {
5832: ra = (RenderAtom) orientedRAs.get(i);
5833: os = (OrientedShape3DRetained) ra.geometryAtom.source;
5834: os.orientedTransformDirty = true;
5835: }
5836: // Update ra's localToVworld given orientedTransform
5837: for (i = 0; i < nRAs; i++) {
5838: ra = (RenderAtom) orientedRAs.get(i);
5839: os = (OrientedShape3DRetained) ra.geometryAtom.source;
5840: if (os.orientedTransformDirty) {
5841: os.updateOrientedTransform(cv, view.viewIndex);
5842: os.orientedTransformDirty = false;
5843: }
5844: ra.updateOrientedTransform();
5845: }
5846: } else {
5847: nRAs = cachedDirtyOrientedRAs.size();
5848: // Update ra's localToVworld given orientedTransform
5849: // Mark Oriented shape as dirty, since multiple ra could point
5850: // to the same OrientShape3D, compute the xform only once
5851: for (i = 0; i < nRAs; i++) {
5852: ra = (RenderAtom) cachedDirtyOrientedRAs.get(i);
5853: os = (OrientedShape3DRetained) ra.geometryAtom.source;
5854: os.orientedTransformDirty = true;
5855: }
5856: // Update ra's localToVworld given orientedTransform
5857: for (i = 0; i < nRAs; i++) {
5858: ra = (RenderAtom) cachedDirtyOrientedRAs.get(i);
5859: os = (OrientedShape3DRetained) ra.geometryAtom.source;
5860: if (os.orientedTransformDirty) {
5861: os.updateOrientedTransform(cv, view.viewIndex);
5862: os.orientedTransformDirty = false;
5863:
5864: }
5865: ra.updateOrientedTransform();
5866: }
5867: }
5868: }
5869: cachedDirtyOrientedRAs.clear();
5870:
5871: }
5872:
5873: // This removes a renderAtom and also does the necessary changes
5874: // for a orientShape3D
5875: void removeARenderAtom(RenderAtom ra) {
5876: // System.err.println("===> remove ga = "+ra.geometryAtom);
5877: ra.setRenderBin(false);
5878: ra.renderMolecule.removeRenderAtom(ra);
5879: if (ra.inDirtyOrientedRAs()) {
5880: dirtyOrientedRAs.remove(dirtyOrientedRAs.indexOf(ra));
5881: ra.dirtyMask &= ~RenderAtom.IN_DIRTY_ORIENTED_RAs;
5882: }
5883: if (ra.inDepthSortList()) {
5884: dirtyDepthSortRenderAtom.remove(ra);
5885: ra.dirtyMask &= ~RenderAtom.IN_SORTED_POS_DIRTY_TRANSP_LIST;
5886: numDirtyTinfo -= ra.rListInfo.length;
5887: }
5888:
5889: // Assertion check in debug mode
5890: if (VersionInfo.isDebug
5891: && dirtyDepthSortRenderAtom.contains(ra)) {
5892: System.err
5893: .println("removeARenderAtom: ERROR: RenderAtom not removed from dirty list");
5894: }
5895: }
5896:
5897: void removeAllRenderAtoms() {
5898: int i;
5899: J3dMessage m;
5900: RenderAtom ra;
5901: RenderMolecule rm;
5902: int sz = renderAtoms.size();
5903:
5904: for (i = 0; i < sz; i++) {
5905: ra = (RenderAtom) renderAtoms.get(i);
5906: rm = ra.renderMolecule;
5907: removeARenderAtom(ra);
5908: rm.updateRemoveRenderAtoms();
5909: }
5910: renderAtoms.clear();
5911:
5912: clearAllUpdateObjectState();
5913:
5914: // Clear the arrayList that are kept from one frame to another
5915: renderMoleculeList.clear();
5916: sharedDList.clear();
5917: lockGeometryList.clear();
5918: // clear out this orderedBin's entry in the orderedGroup
5919: for (i = 0; i < orderedBins.size(); i++) {
5920: removeOrderedBin((OrderedBin) orderedBins.get(i));
5921: }
5922: orderedBins.clear();
5923: bgOrderedBins.clear();
5924: nodeComponentList.clear();
5925: orientedRAs.clear();
5926:
5927: // clean up any messages that are queued up, since they are
5928: // irrelevant
5929: // clearMessages();
5930: geometryBackground = null;
5931: }
5932:
5933: void removeOrderedBin(OrderedBin ob) {
5934: int i, k;
5935: for (i = 0; i < ob.orderedCollections.size(); i++) {
5936: OrderedCollection oc = (OrderedCollection) ob.orderedCollections
5937: .get(i);
5938: if (oc == null)
5939: continue;
5940:
5941: for (k = 0; k < oc.childOrderedBins.size(); k++) {
5942: removeOrderedBin((OrderedBin) (oc.childOrderedBins
5943: .get(k)));
5944: }
5945: }
5946: if (ob.source != null) {
5947: ob.source.setOrderedBin(null, view.viewIndex);
5948: ob.source = null;
5949: }
5950: }
5951:
5952: void removeGeometryDlist(RenderAtomListInfo ra) {
5953: removeDlist.add(ra);
5954: }
5955:
5956: void addGeometryDlist(RenderAtomListInfo ra) {
5957: addDlist.add(ra);
5958: }
5959:
5960: void dumpBin(LightBin bin) {
5961: LightBin obin = bin;
5962: while (obin != null) {
5963: System.err.println("LightBin = " + obin);
5964: EnvironmentSet envSet = obin.environmentSetList;
5965: while (envSet != null) {
5966: System.err.println(" EnvSet = " + envSet);
5967: AttributeBin abin = envSet.attributeBinList;
5968: while (abin != null) {
5969: System.err.println(" ABin = " + abin);
5970: ShaderBin sbin = abin.shaderBinList;
5971: while (sbin != null) {
5972: System.err.println(" SBin = " + sbin);
5973: TextureBin tbin = sbin.textureBinList;
5974: while (tbin != null) {
5975: System.err.println(" Tbin = "
5976: + tbin);
5977: RenderMolecule rm = tbin.opaqueRMList;
5978: System.err
5979: .println("===> Begin Dumping OpaqueBin");
5980: dumpRM(rm);
5981: System.err
5982: .println("===> End Dumping OpaqueBin");
5983: rm = tbin.transparentRMList;
5984: System.err
5985: .println("===> Begin Dumping transparentBin");
5986: dumpRM(rm);
5987: System.err
5988: .println("===> End Dumping transparentBin");
5989: tbin = tbin.next;
5990: }
5991: sbin = sbin.next;
5992: }
5993: abin = abin.next;
5994: }
5995: envSet = envSet.next;
5996: }
5997: obin = obin.next;
5998: }
5999:
6000: }
6001:
6002: void dumpRM(RenderMolecule rm) {
6003: while (rm != null) {
6004: System.err.println(" rm = " + rm + " numRAs = "
6005: + rm.numRenderAtoms);
6006: System.err.println(" primaryRenderAtomList = "
6007: + rm.primaryRenderAtomList);
6008: RenderAtomListInfo rinfo = rm.primaryRenderAtomList;
6009: while (rinfo != null) {
6010: System.err.println(" rinfo = " + rinfo);
6011: System.err
6012: .println(" rinfo.ra.localeVwcBounds = "
6013: + rinfo.renderAtom.localeVwcBounds);
6014: System.err
6015: .println(" rinfo.ra.ga.so.vwcBounds = "
6016: + rinfo.renderAtom.geometryAtom.source.vwcBounds);
6017: System.err.println(" geometry = "
6018: + rinfo.geometry());
6019:
6020: rinfo = rinfo.next;
6021: }
6022: System.err
6023: .println(" separateDlistRenderAtomList = "
6024: + rm.separateDlistRenderAtomList);
6025: rinfo = rm.separateDlistRenderAtomList;
6026: while (rinfo != null) {
6027: System.err.println(" rinfo = " + rinfo);
6028: System.err
6029: .println(" rinfo.ra.localeVwcBounds = "
6030: + rinfo.renderAtom.localeVwcBounds);
6031: System.err
6032: .println(" rinfo.ra.ga.so.vwcBounds = "
6033: + rinfo.renderAtom.geometryAtom.source.vwcBounds);
6034: System.err.println(" geometry = "
6035: + rinfo.geometry());
6036: rinfo = rinfo.next;
6037: }
6038: System.err
6039: .println(" vertexArrayRenderAtomList = "
6040: + rm.vertexArrayRenderAtomList);
6041: if (rm.next == null) {
6042: rm = rm.nextMap;
6043: } else {
6044: rm = rm.next;
6045: }
6046: }
6047: }
6048:
6049: void removeTransparentObject(Object obj) {
6050: // System.err.println("&&&&&&&&&&&&removeTransparentObject r = "+obj);
6051: if (obj instanceof TextureBin) {
6052: TextureBin tb = (TextureBin) obj;
6053: if (tb.environmentSet.lightBin.geometryBackground != null) {
6054: TransparentRenderingInfo t = tb.parentTInfo;
6055:
6056: // Remove the element from the transparentInfo struct
6057: if (t == bgTransparentInfo) {
6058: bgTransparentInfo = bgTransparentInfo.next;
6059: if (bgTransparentInfo != null)
6060: bgTransparentInfo.prev = null;
6061: } else {
6062: t.prev.next = t.next;
6063: if (t.next != null)
6064: t.next.prev = t.prev;
6065: }
6066: t.prev = null;
6067: t.next = null;
6068: tb.parentTInfo = null;
6069: } else {
6070: int index = allTransparentObjects.indexOf(obj);
6071: if (index == -1) {
6072: // System.err.println("==> DEBUG1: Should never come here!");
6073: return;
6074: }
6075: allTransparentObjects.remove(index);
6076:
6077: TransparentRenderingInfo t = tb.parentTInfo;
6078:
6079: // Remove the element from the transparentInfo struct
6080: if (t == transparentInfo) {
6081: transparentInfo = transparentInfo.next;
6082: if (transparentInfo != null)
6083: transparentInfo.prev = null;
6084: } else {
6085: t.prev.next = t.next;
6086: if (t.next != null)
6087: t.next.prev = t.prev;
6088: }
6089: t.prev = null;
6090: t.next = null;
6091: tb.parentTInfo = null;
6092: }
6093:
6094: } else {
6095: int index = allTransparentObjects.indexOf(obj);
6096: if (index == -1) {
6097: // System.err.println("==> DEBUG2: Should never come here!");
6098: return;
6099: }
6100:
6101: allTransparentObjects.remove(index);
6102: RenderAtom r = (RenderAtom) obj;
6103: for (int i = 0; i < r.parentTInfo.length; i++) {
6104: // Remove the element from the transparentInfo struct
6105: TransparentRenderingInfo t = r.parentTInfo[i];
6106: // This corresponds to null geometry
6107: if (t == null)
6108: continue;
6109:
6110: // Remove the element from the transparentInfo struct
6111: if (t == transparentInfo) {
6112: transparentInfo = transparentInfo.next;
6113: if (transparentInfo != null)
6114: transparentInfo.prev = null;
6115: } else {
6116: t.prev.next = t.next;
6117: if (t.next != null)
6118: t.next.prev = t.prev;
6119: }
6120: t.prev = null;
6121: t.next = null;
6122: nElements--;
6123: r.parentTInfo[i] = null;
6124: }
6125: }
6126:
6127: }
6128:
6129: void updateTransparentInfo(RenderAtom r) {
6130: // System.err.println("===> update transparent Info");
6131: for (int i = 0; i < r.parentTInfo.length; i++) {
6132:
6133: if (r.parentTInfo[i] == null)
6134: continue;
6135: /*
6136: r.parentTInfo[i].lightBin = r.envSet.lightBin;
6137: r.parentTInfo[i].envSet = r.envSet;
6138: r.parentTInfo[i].aBin = r.renderMolecule.textureBin.attributeBin;
6139: */
6140: r.parentTInfo[i].rm = r.renderMolecule;
6141: }
6142: }
6143:
6144: void addTransparentObject(Object obj) {
6145: // System.err.println("&&&&&&&&&&&&addTransparentObject r = "+obj);
6146: if (obj instanceof TextureBin) {
6147: TextureBin tb = (TextureBin) obj;
6148: // Background geometry
6149: if (tb.environmentSet.lightBin.geometryBackground != null) {
6150: bgTransparentInfo = computeDirtyAcrossTransparentBins(
6151: tb, bgTransparentInfo);
6152: } else {
6153: allTransparentObjects.add(obj);
6154: transparentInfo = computeDirtyAcrossTransparentBins(tb,
6155: transparentInfo);
6156: }
6157: } else {
6158: allTransparentObjects.add(obj);
6159: RenderAtom r = (RenderAtom) obj;
6160: if (r.parentTInfo == null) {
6161: r.parentTInfo = new TransparentRenderingInfo[r.rListInfo.length];
6162: }
6163: computeDirtyAcrossTransparentBins(r);
6164: // System.err.println("update Centroid 2, ga = "+r.geometryAtom);
6165: r.geometryAtom.updateCentroid();
6166: if (dirtyDepthSortRenderAtom.add(r)) {
6167: numDirtyTinfo += r.rListInfo.length;
6168: }
6169: /*
6170: else {
6171: System.err.println("addTransparentObject: attempt to add RenderAtom already in dirty list");
6172: }
6173: */
6174: r.dirtyMask |= RenderAtom.IN_SORTED_POS_DIRTY_TRANSP_LIST;
6175: // System.err.println("transparentInfo ="+transparentInfo);
6176: }
6177: }
6178:
6179: TransparentRenderingInfo getTransparentInfo() {
6180: return new TransparentRenderingInfo();
6181: }
6182:
6183: TransparentRenderingInfo computeDirtyAcrossTransparentBins(
6184: TextureBin tb, TransparentRenderingInfo startinfo) {
6185: TransparentRenderingInfo tinfo = getTransparentInfo();
6186: /*
6187: tinfo.lightBin = tb.environmentSet.lightBin;
6188: tinfo.envSet = tb.environmentSet;
6189: tinfo.aBin = tb.attributeBin;
6190: */
6191: tinfo.rm = tb.transparentRMList;
6192: tb.parentTInfo = tinfo;
6193: if (startinfo == null) {
6194: startinfo = tinfo;
6195: tinfo.prev = null;
6196: tinfo.next = null;
6197:
6198: } else {
6199: tinfo.next = startinfo;
6200: startinfo.prev = tinfo;
6201: startinfo = tinfo;
6202: }
6203: return startinfo;
6204: }
6205:
6206: void computeDirtyAcrossTransparentBins(RenderAtom r) {
6207:
6208: for (int i = 0; i < r.parentTInfo.length; i++) {
6209: if (r.rListInfo[i].geometry() == null) {
6210: r.parentTInfo[i] = null;
6211: continue;
6212: }
6213: nElements++;
6214: TransparentRenderingInfo tinfo = getTransparentInfo();
6215: /*
6216: tinfo.lightBin = r.envSet.lightBin;
6217: tinfo.envSet = r.envSet;
6218: tinfo.aBin = r.renderMolecule.textureBin.attributeBin;
6219: */
6220: tinfo.rm = r.renderMolecule;
6221: tinfo.rInfo = r.rListInfo[i];
6222: r.parentTInfo[i] = tinfo;
6223: if (transparentInfo == null) {
6224: transparentInfo = tinfo;
6225: tinfo.prev = null;
6226: tinfo.next = null;
6227: } else {
6228: tinfo.prev = null;
6229: tinfo.next = transparentInfo;
6230: transparentInfo.prev = tinfo;
6231: transparentInfo = tinfo;
6232: }
6233:
6234: }
6235:
6236: }
6237:
6238: void processRenderAtomTransparentInfo(RenderAtomListInfo rinfo,
6239: ArrayList newList) {
6240: while (rinfo != null) {
6241: // If either the renderAtom has never been in transparent mode
6242: // or if it was previously in that mode and now going back
6243: // to that mode
6244: if (rinfo.renderAtom.parentTInfo == null) {
6245: rinfo.renderAtom.parentTInfo = new TransparentRenderingInfo[rinfo.renderAtom.rListInfo.length];
6246: computeDirtyAcrossTransparentBins(rinfo.renderAtom);
6247: rinfo.renderAtom.geometryAtom.updateCentroid();
6248: newList.add(rinfo.renderAtom);
6249: } else {
6250: GeometryRetained geo = null;
6251: int i = 0;
6252: while (geo == null
6253: && i < rinfo.renderAtom.rListInfo.length) {
6254: geo = rinfo.renderAtom.rListInfo[i].geometry();
6255: i++;
6256: }
6257: // If there is atleast one non-null geometry in this renderAtom
6258: if (geo != null) {
6259: if (rinfo.renderAtom.parentTInfo[i - 1] == null) {
6260: computeDirtyAcrossTransparentBins(rinfo.renderAtom);
6261: rinfo.renderAtom.geometryAtom.updateCentroid();
6262: newList.add(rinfo.renderAtom);
6263: }
6264: }
6265: }
6266: rinfo = rinfo.next;
6267:
6268: }
6269: }
6270:
6271: void convertTransparentRenderingStruct(int oldMode, int newMode) {
6272: int i, size;
6273: ArrayList newList = new ArrayList(5);
6274: RenderAtomListInfo rinfo;
6275: // Reset the transparentInfo;
6276: transparentInfo = null;
6277: if (oldMode == View.TRANSPARENCY_SORT_NONE
6278: && newMode == View.TRANSPARENCY_SORT_GEOMETRY) {
6279: size = allTransparentObjects.size();
6280:
6281: for (i = 0; i < size; i++) {
6282: TextureBin tb = (TextureBin) allTransparentObjects
6283: .get(i);
6284: tb.parentTInfo = null;
6285: RenderMolecule r = tb.transparentRMList;
6286: // For each renderMolecule
6287: while (r != null) {
6288: // If this was a dlist molecule, since we will be rendering
6289: // as separate dlist per rinfo, destroy the display list
6290: if ((r.primaryMoleculeType & RenderMolecule.DLIST_MOLECULE) != 0) {
6291: // System.err.println("&&&&&&&&& changing from dlist to dlist_per_rinfo");
6292: addDisplayListResourceFreeList(r);
6293: removeDirtyRenderMolecule(r);
6294:
6295: r.vwcBounds.set(null);
6296: r.displayListId = 0;
6297: r.displayListIdObj = null;
6298: // Change the group type for all the rlistInfo in the primaryList
6299: rinfo = r.primaryRenderAtomList;
6300: while (rinfo != null) {
6301: rinfo.groupType = RenderAtom.SEPARATE_DLIST_PER_RINFO;
6302: if (rinfo.renderAtom.dlistIds == null) {
6303: rinfo.renderAtom.dlistIds = new int[rinfo.renderAtom.rListInfo.length];
6304:
6305: for (int k = 0; k < rinfo.renderAtom.dlistIds.length; k++) {
6306: rinfo.renderAtom.dlistIds[k] = -1;
6307: }
6308: }
6309: if (rinfo.renderAtom.dlistIds[rinfo.index] == -1) {
6310: rinfo.renderAtom.dlistIds[rinfo.index] = VirtualUniverse.mc
6311: .getDisplayListId().intValue();
6312: addDlistPerRinfo.add(rinfo);
6313: }
6314: rinfo = rinfo.next;
6315: }
6316: r.primaryMoleculeType = RenderMolecule.SEPARATE_DLIST_PER_RINFO_MOLECULE;
6317: }
6318: // Get all the renderAtoms in the list
6319: processRenderAtomTransparentInfo(
6320: r.primaryRenderAtomList, newList);
6321: processRenderAtomTransparentInfo(
6322: r.vertexArrayRenderAtomList, newList);
6323: processRenderAtomTransparentInfo(
6324: r.separateDlistRenderAtomList, newList);
6325: if (r.next == null) {
6326: r = r.nextMap;
6327: } else {
6328: r = r.next;
6329: }
6330: }
6331: }
6332: allTransparentObjects = newList;
6333: } else if (oldMode == View.TRANSPARENCY_SORT_GEOMETRY
6334: && newMode == View.TRANSPARENCY_SORT_NONE) {
6335: // System.err.println("oldMode = TRANSPARENCY_SORT_GEOMETRY, newMode = TRANSPARENCY_SORT_NONE");
6336: size = allTransparentObjects.size();
6337: for (i = 0; i < size; i++) {
6338: RenderAtom r = (RenderAtom) allTransparentObjects
6339: .get(i);
6340: r.dirtyMask &= ~RenderAtom.IN_SORTED_POS_DIRTY_TRANSP_LIST;
6341: for (int j = 0; j < r.parentTInfo.length; j++) {
6342: // Corresponds to null geometry
6343: if (r.parentTInfo[j] == null)
6344: continue;
6345:
6346: r.parentTInfo[j] = null;
6347: }
6348: if (r.renderMolecule.textureBin.parentTInfo == null) {
6349: transparentInfo = computeDirtyAcrossTransparentBins(
6350: r.renderMolecule.textureBin,
6351: transparentInfo);
6352: newList.add(r.renderMolecule.textureBin);
6353: }
6354: }
6355: allTransparentObjects = newList;
6356: dirtyDepthSortRenderAtom.clear();
6357: numDirtyTinfo = 0;
6358: }
6359: }
6360:
6361: TransparentRenderingInfo mergeDepthSort(
6362: TransparentRenderingInfo oldList,
6363: TransparentRenderingInfo newList) {
6364: TransparentRenderingInfo input1 = oldList, input2 = newList, nextN;
6365: TransparentRenderingInfo lastInput1 = oldList;
6366: double zval1, zval2;
6367: // System.err.println("&&&&&&&&mergeDepthSort");
6368: /*
6369: TransparentRenderingInfo t = oldList;
6370: System.err.println("");
6371: while (t != null) {
6372: System.err.println("==> old t = "+t);
6373: t = t.next;
6374: }
6375: System.err.println("");
6376: t = newList;
6377: while (t != null) {
6378: System.err.println("==> new t = "+t);
6379: t = t.next;
6380: }
6381: */
6382:
6383: while (input1 != null && input2 != null) {
6384: lastInput1 = input1;
6385: nextN = input2.next;
6386: zval1 = input1.zVal;
6387: zval2 = input2.zVal;
6388: // Put the newList before the current one
6389:
6390: // System.err.print("Code path 1 ");
6391: // if (transparencySortComparator!=null)
6392: // if (zval2 > zval1 && (transparencySortComparator.compare(input2, input1)>0))
6393: // System.err.println("PASS");
6394: // else
6395: // System.err.println("FAIL");
6396:
6397: if ((transparencySortComparator == null && zval2 > zval1)
6398: || (transparencySortComparator != null && (transparencySortComparator
6399: .compare(input2, input1) > 0))) {
6400: // System.err.println("===> path1");
6401: if (input1.prev == null) {
6402: input1.prev = input2;
6403: input2.prev = null;
6404: input2.next = oldList;
6405: oldList = input2;
6406: } else {
6407: // System.err.println("===> path2");
6408: input2.prev = input1.prev;
6409: input1.prev.next = input2;
6410: input2.next = input1;
6411: input1.prev = input2;
6412: }
6413: input2 = nextN;
6414: } else {
6415: // System.err.println("===> path3");
6416: input1 = input1.next;
6417: }
6418: }
6419: if (input1 == null && input2 != null) {
6420: // add at then end
6421: if (lastInput1 == null) {
6422: oldList = input2;
6423: input2.prev = null;
6424: } else {
6425: lastInput1.next = input2;
6426: input2.prev = lastInput1;
6427: }
6428: }
6429: return oldList;
6430: }
6431:
6432: // void insertDepthSort(RenderAtom r) {
6433: // TransparentRenderingInfo tinfo = null;
6434: // // System.err.println("&&&&&&&&insertDepthSort");
6435: // for (int i = 0; i < r.rListInfo.length; i++) {
6436: // if (r.parentTInfo[i] == null)
6437: // continue;
6438: //
6439: // if (transparentInfo == null) {
6440: // transparentInfo = r.parentTInfo[i];
6441: // transparentInfo.prev = null;
6442: // transparentInfo.next = null;
6443: // }
6444: // else {
6445: // tinfo = transparentInfo;
6446: // TransparentRenderingInfo prevInfo = transparentInfo;
6447: // if (transparencySortComparator==null)
6448: // while (tinfo != null && r.parentTInfo[i].zVal < tinfo.zVal) {
6449: // prevInfo = tinfo;
6450: // tinfo = tinfo.next;
6451: // }
6452: // else {
6453: // System.err.println("Code Path 2 ");
6454: // if (tinfo!=null && (transparencySortComparator.compare(r.parentTInfo[i], tinfo)<0)==r.parentTInfo[i].zVal < tinfo.zVal)
6455: // System.err.println("PASS");
6456: // else
6457: // System.err.println("FAIL");
6458: // while (tinfo != null && transparencySortComparator.compare(r.parentTInfo[i], tinfo)<0) {
6459: // prevInfo = tinfo;
6460: // tinfo = tinfo.next;
6461: // }
6462: // }
6463: // r.parentTInfo[i].prev = prevInfo;
6464: // if (prevInfo.next != null) {
6465: // prevInfo.next.prev = r.parentTInfo[i];
6466: // }
6467: // r.parentTInfo[i].next = prevInfo.next;
6468: // prevInfo.next = r.parentTInfo[i];
6469: //
6470: // }
6471: //
6472: // }
6473: // }
6474:
6475: TransparentRenderingInfo collectDirtyTRInfo(
6476: TransparentRenderingInfo dirtyList, RenderAtom r) {
6477:
6478: for (int i = 0; i < r.rListInfo.length; i++) {
6479: TransparentRenderingInfo t = r.parentTInfo[i];
6480: if (t == null)
6481: continue;
6482: if (t == transparentInfo) {
6483: transparentInfo = transparentInfo.next;
6484: if (transparentInfo != null)
6485: transparentInfo.prev = null;
6486: } else {
6487: if (t == dirtyList) {
6488: // This means that the the item has already been
6489: // added to the dirtyList and is at the head of
6490: // the list; since we ensure no duplicate
6491: // renderAtoms, this should never happen. If it
6492: // does, don't try to add it again.
6493: System.err
6494: .println("collectDirtyTRInfo: ERROR: t == dirtyList");
6495: continue;
6496: }
6497:
6498: // assert(t.prev != null);
6499: t.prev.next = t.next;
6500: if (t.next != null)
6501: t.next.prev = t.prev;
6502: }
6503: if (dirtyList == null) {
6504: dirtyList = t;
6505: t.prev = null;
6506: t.next = null;
6507: } else {
6508: t.next = dirtyList;
6509: t.prev = null;
6510: dirtyList.prev = t;
6511: dirtyList = t;
6512: }
6513: }
6514:
6515: return dirtyList;
6516: }
6517:
6518: TransparentRenderingInfo depthSortAll(
6519: TransparentRenderingInfo startinfo) {
6520: transparencySortComparator = com.sun.j3d.utils.scenegraph.transparency.TransparencySortController
6521: .getComparator(view);
6522: TransparentRenderingInfo tinfo, previnfo, nextinfo;
6523: double curZ;
6524: // System.err.println("&&&&&&&&&&&depthSortAll");
6525: // Do insertion sort
6526: /*
6527: tinfo = startinfo;
6528: while (tinfo != null) {
6529: System.err.println("Soreted tinfo= "+tinfo+" tinfo.prev = "+tinfo.prev+" tinfo.next = "+tinfo.next);
6530: tinfo = tinfo.next;
6531: }
6532: */
6533: tinfo = startinfo.next;
6534: while (tinfo != null) {
6535: // System.err.println("====> Doing tinfo = "+tinfo);
6536: nextinfo = tinfo.next;
6537: curZ = tinfo.zVal;
6538: previnfo = tinfo.prev;
6539: // Find the correct location for tinfo
6540:
6541: if (transparencySortComparator == null) {
6542: while (previnfo != null && previnfo.zVal < curZ) {
6543: previnfo = previnfo.prev;
6544: }
6545: } else {
6546: // System.err.println("Code Path 3 ");
6547: // if (tinfo!=null && (transparencySortComparator.compare(previnfo, tinfo)<0)==previnfo.zVal < curZ)
6548: // System.err.println("PASS");
6549: // else
6550: // System.err.println("FAIL");
6551: while (previnfo != null
6552: && transparencySortComparator.compare(previnfo,
6553: tinfo) < 0) {
6554: previnfo = previnfo.prev;
6555: }
6556: }
6557:
6558: if (tinfo.prev != previnfo) {
6559: if (previnfo == null) {
6560: if (tinfo.next != null) {
6561: tinfo.next.prev = tinfo.prev;
6562: }
6563: // tinfo.prev is not null
6564: tinfo.prev.next = tinfo.next;
6565: tinfo.next = startinfo;
6566: startinfo.prev = tinfo;
6567: startinfo = tinfo;
6568: tinfo.prev = null;
6569: } else {
6570: if (tinfo.next != null) {
6571: tinfo.next.prev = tinfo.prev;
6572: }
6573: if (tinfo.prev != null) {
6574: tinfo.prev.next = tinfo.next;
6575: }
6576: tinfo.next = previnfo.next;
6577: if (previnfo.next != null)
6578: previnfo.next.prev = tinfo;
6579: tinfo.prev = previnfo;
6580: previnfo.next = tinfo;
6581: // System.err.println("path2, tinfo.prev = "+tinfo.prev);
6582: // System.err.println("path2, tinfo.next = "+tinfo.next);
6583: }
6584:
6585: }
6586: /*
6587: TransparentRenderingInfo tmp = startinfo;
6588: while (tmp != null) {
6589: System.err.println("Soreted tmp= "+tmp+" tmp.prev = "+tmp.prev+" tmp.next = "+tmp.next);
6590: tmp = tmp.next;
6591: }
6592: */
6593:
6594: tinfo = nextinfo;
6595:
6596: }
6597: /*
6598: tinfo = startinfo;
6599: double prevZ = 0.0;
6600: while (tinfo != null) {
6601: tinfo.render = false;
6602: curZ = ((double[])distMap.get(tinfo.rInfo.renderAtom))[tinfo.rInfo.index];
6603: nextinfo = tinfo.next;
6604: if (nextinfo != null) {
6605: double nextZ = ((double[])distMap.get(nextinfo.rInfo.renderAtom))[tinfo.rInfo.index];
6606: if (Math.abs(curZ - nextZ) < 1.0e-6 && curZ < 400) {
6607: tinfo.render = true;
6608: }
6609: }
6610:
6611: if (Math.abs(curZ - prevZ) < 1.0e-6 && curZ < 400) {
6612: tinfo.render = true;
6613: }
6614:
6615: prevZ = curZ;
6616: tinfo = tinfo.next;
6617:
6618: }
6619: tinfo = startinfo;
6620: while (tinfo != null) {
6621: System.err.println("z = "+((double[])distMap.get(tinfo.rInfo.renderAtom))[tinfo.rInfo.index]+" ga = "+tinfo.rInfo.renderAtom.geometryAtom);
6622: tinfo = tinfo.next;
6623: }
6624: System.err.println("\n\n");
6625: tinfo = startinfo;
6626: while (tinfo != null) {
6627: if (tinfo.render) {
6628: System.err.println("same z = "+((double[])distMap.get(tinfo.rInfo.renderAtom))[tinfo.rInfo.index]+" ga = "+tinfo.rInfo.renderAtom.geometryAtom);
6629: GeometryAtom ga = tinfo.rInfo.renderAtom.geometryAtom;
6630: System.err.println("ga.geometryArray.length = "+ga.geometryArray.length);
6631: for (int k = 0; k < ga.geometryArray.length; k++) {
6632: System.err.println("geometry "+k+" = "+ga.geometryArray[k]);
6633: if (ga.geometryArray[k] != null) {
6634: System.err.println(" vcount = "+((GeometryArrayRetained)ga.geometryArray[k]).getVertexCount());
6635: ((GeometryArrayRetained)ga.geometryArray[k]).printCoordinates();
6636: }
6637: }
6638: }
6639: tinfo = tinfo.next;
6640: }
6641: */
6642: return startinfo;
6643: }
6644:
6645: void processViewSpecificGroupChanged(J3dMessage m) {
6646: int component = ((Integer) m.args[0]).intValue();
6647: Object[] objAry = (Object[]) m.args[1];
6648: if (((component & ViewSpecificGroupRetained.ADD_VIEW) != 0)
6649: || ((component & ViewSpecificGroupRetained.SET_VIEW) != 0)) {
6650: int i;
6651: Object obj;
6652: View v = (View) objAry[0];
6653: ArrayList leafList = (ArrayList) objAry[2];
6654: // View being added is this view
6655: if (v == view) {
6656: int size = leafList.size();
6657: for (i = 0; i < size; i++) {
6658: obj = leafList.get(i);
6659: if (obj instanceof LightRetained) {
6660: envDirty |= REEVALUATE_LIGHTS;
6661: if (!changedLts.contains(obj))
6662: changedLts.add(obj);
6663: } else if (obj instanceof FogRetained) {
6664: envDirty |= REEVALUATE_FOG;
6665: if (!changedFogs.contains(obj))
6666: changedFogs.add(obj);
6667: } else if (obj instanceof AlternateAppearanceRetained) {
6668: altAppearanceDirty = true;
6669:
6670: } else if (obj instanceof ModelClipRetained) {
6671: envDirty |= REEVALUATE_MCLIP;
6672: if (!changedModelClips.contains(obj))
6673: changedModelClips.add(obj);
6674: } else if (obj instanceof BackgroundRetained) {
6675: reEvaluateBg = true;
6676: }
6677:
6678: else if (obj instanceof ClipRetained) {
6679: reEvaluateClip = true;
6680:
6681: } else if (obj instanceof GeometryAtom) {
6682: visGAIsDirty = true;
6683: visQuery = true;
6684: }
6685: }
6686:
6687: }
6688:
6689: }
6690: if (((component & ViewSpecificGroupRetained.REMOVE_VIEW) != 0)
6691: || ((component & ViewSpecificGroupRetained.SET_VIEW) != 0)) {
6692: int i;
6693: Object obj;
6694: ArrayList leafList;
6695: View v;
6696:
6697: if ((component & ViewSpecificGroupRetained.REMOVE_VIEW) != 0) {
6698: v = (View) objAry[0];
6699: leafList = (ArrayList) objAry[2];
6700: } else {
6701: v = (View) objAry[4];
6702: leafList = (ArrayList) objAry[6];
6703: }
6704: if (v == view) {
6705: int size = leafList.size();
6706: for (i = 0; i < size; i++) {
6707: obj = leafList.get(i);
6708: if (obj instanceof GeometryAtom) {
6709: RenderAtom ra = ((GeometryAtom) obj)
6710: .getRenderAtom(view);
6711: if (ra != null && ra.inRenderBin()) {
6712: renderAtoms.remove(renderAtoms.indexOf(ra));
6713: removeARenderAtom(ra);
6714: }
6715: } else if (obj instanceof LightRetained) {
6716: envDirty |= REEVALUATE_LIGHTS;
6717: } else if (obj instanceof FogRetained) {
6718: envDirty |= REEVALUATE_FOG;
6719: } else if (obj instanceof AlternateAppearanceRetained) {
6720: altAppearanceDirty = true;
6721:
6722: } else if (obj instanceof ModelClipRetained) {
6723: envDirty |= REEVALUATE_MCLIP;
6724:
6725: } else if (obj instanceof BackgroundRetained) {
6726: reEvaluateBg = true;
6727: }
6728:
6729: else if (obj instanceof ClipRetained) {
6730: reEvaluateClip = true;
6731:
6732: }
6733: }
6734: }
6735: }
6736:
6737: }
6738:
6739: void insertNodes(J3dMessage m) {
6740: Object nodes[];
6741: ArrayList viewScopedNodes = (ArrayList) m.args[3];
6742: ArrayList scopedNodesViewList = (ArrayList) m.args[4];
6743: int i, j;
6744: Object n;
6745: nodes = (Object[]) m.args[0];
6746: for (j = 0; j < nodes.length; j++) {
6747: if (nodes[j] instanceof LightRetained) {
6748: envDirty |= REEVALUATE_LIGHTS;
6749: if (!changedLts.contains(nodes[j]))
6750: changedLts.add(nodes[j]);
6751: } else if (nodes[j] instanceof FogRetained) {
6752: envDirty |= REEVALUATE_FOG;
6753: if (!changedFogs.contains(nodes[j]))
6754: changedFogs.add(nodes[j]);
6755: } else if (nodes[j] instanceof BackgroundRetained) {
6756: // If a new background is inserted, then
6757: // re_evaluate to determine if this background
6758: // should be used
6759: reEvaluateBg = true;
6760: } else if (nodes[j] instanceof ClipRetained) {
6761: reEvaluateClip = true;
6762: } else if (nodes[j] instanceof ModelClipRetained) {
6763: envDirty |= REEVALUATE_MCLIP;
6764: if (!changedModelClips.contains(nodes[j]))
6765: changedModelClips.add(nodes[j]);
6766: } else if (nodes[j] instanceof GeometryAtom) {
6767: visGAIsDirty = true;
6768: visQuery = true;
6769: } else if (nodes[j] instanceof AlternateAppearanceRetained) {
6770: altAppearanceDirty = true;
6771: }
6772: }
6773:
6774: // Handle ViewScoped Nodes
6775: if (viewScopedNodes != null) {
6776: int size = viewScopedNodes.size();
6777: int vlsize;
6778: for (i = 0; i < size; i++) {
6779: n = (NodeRetained) viewScopedNodes.get(i);
6780: ArrayList vl = (ArrayList) scopedNodesViewList.get(i);
6781: // If the node object is scoped to this view, then ..
6782: if (vl.contains(view)) {
6783: if (n instanceof LightRetained) {
6784: envDirty |= REEVALUATE_LIGHTS;
6785: if (!changedLts.contains(n))
6786: changedLts.add(n);
6787: } else if (n instanceof FogRetained) {
6788: envDirty |= REEVALUATE_FOG;
6789: if (!changedFogs.contains(n))
6790: changedFogs.add(n);
6791: } else if (n instanceof BackgroundRetained) {
6792: // If a new background is inserted, then
6793: // re_evaluate to determine if this backgrouns
6794: // should be used
6795: reEvaluateBg = true;
6796: } else if (n instanceof ClipRetained) {
6797: reEvaluateClip = true;
6798: } else if (n instanceof ModelClipRetained) {
6799: envDirty |= REEVALUATE_MCLIP;
6800: if (!changedModelClips.contains(n))
6801: changedModelClips.add(n);
6802: } else if (n instanceof AlternateAppearanceRetained) {
6803: altAppearanceDirty = true;
6804: }
6805: }
6806: // Note: geometryAtom is not part of viewScopedNodes
6807: // Its a part of orginal nodes even if scoped
6808:
6809: }
6810: }
6811: }
6812:
6813: void removeNodes(J3dMessage m) {
6814: Object[] nodes;
6815: ArrayList viewScopedNodes = (ArrayList) m.args[3];
6816: ArrayList scopedNodesViewList = (ArrayList) m.args[4];
6817: int i, j;
6818: nodes = (Object[]) m.args[0];
6819: for (int n = 0; n < nodes.length; n++) {
6820: if (nodes[n] instanceof GeometryAtom) {
6821: visGAIsDirty = true;
6822: visQuery = true;
6823: RenderAtom ra = ((GeometryAtom) nodes[n])
6824: .getRenderAtom(view);
6825: if (ra != null && ra.inRenderBin()) {
6826: renderAtoms.remove(renderAtoms.indexOf(ra));
6827: removeARenderAtom(ra);
6828: }
6829:
6830: // This code segment is to handle the texture resource cleanup
6831: // for Raster object.
6832: GeometryAtom geomAtom = (GeometryAtom) nodes[n];
6833: if (geomAtom.geometryArray != null) {
6834: for (int ii = 0; ii < geomAtom.geometryArray.length; ii++) {
6835: GeometryRetained geomRetained = geomAtom.geometryArray[ii];
6836: if ((geomRetained != null)
6837: && (geomRetained instanceof RasterRetained)) {
6838: addTextureResourceFreeList(((RasterRetained) geomRetained).texture);
6839: }
6840: }
6841: }
6842: } else if (nodes[n] instanceof AlternateAppearanceRetained) {
6843: altAppearanceDirty = true;
6844: } else if (nodes[n] instanceof BackgroundRetained) {
6845: reEvaluateBg = true;
6846: } else if (nodes[n] instanceof ClipRetained) {
6847: reEvaluateClip = true;
6848: } else if (nodes[n] instanceof ModelClipRetained) {
6849: envDirty |= REEVALUATE_MCLIP;
6850: } else if (nodes[n] instanceof FogRetained) {
6851: envDirty |= REEVALUATE_FOG;
6852: }
6853: if (nodes[n] instanceof LightRetained) {
6854: envDirty |= REEVALUATE_LIGHTS;
6855: }
6856: }
6857: // Handle ViewScoped Nodes
6858: if (viewScopedNodes != null) {
6859: int size = viewScopedNodes.size();
6860: int vlsize;
6861: Object node;
6862: for (i = 0; i < size; i++) {
6863: node = (NodeRetained) viewScopedNodes.get(i);
6864: ArrayList vl = (ArrayList) scopedNodesViewList.get(i);
6865: // If the node object is scoped to this view, then ..
6866: if (vl.contains(view)) {
6867: if (node instanceof LightRetained) {
6868: envDirty |= REEVALUATE_LIGHTS;
6869: } else if (node instanceof FogRetained) {
6870: envDirty |= REEVALUATE_FOG;
6871: } else if (node instanceof BackgroundRetained) {
6872: // If a new background is inserted, then
6873: // re_evaluate to determine if this backgrouns
6874: // should be used
6875: reEvaluateBg = true;
6876: } else if (node instanceof ClipRetained) {
6877: reEvaluateClip = true;
6878: } else if (node instanceof ModelClipRetained) {
6879: envDirty |= REEVALUATE_MCLIP;
6880:
6881: } else if (node instanceof AlternateAppearanceRetained) {
6882: altAppearanceDirty = true;
6883: }
6884: // Note: geometryAtom is not part of viewScopedNodes
6885: // Its a part of orginal nodes even if scoped
6886: }
6887:
6888: }
6889: }
6890: }
6891:
6892: void cleanup() {
6893: releaseAllDisplayListID();
6894: removeAllRenderAtoms();
6895: }
6896:
6897: void freeAllDisplayListResources(Canvas3D cv, Context ctx) {
6898:
6899: assert ctx != null;
6900:
6901: int i;
6902: int size = renderMoleculeList.size();
6903: Renderer rdr = cv.screen.renderer;
6904:
6905: if (size > 0) {
6906: RenderMolecule[] rmArr = (RenderMolecule[]) renderMoleculeList
6907: .toArray(false);
6908:
6909: for (i = 0; i < size; i++) {
6910: rmArr[i].releaseAllPrimaryDisplayListResources(cv, ctx);
6911: }
6912: }
6913:
6914: size = sharedDList.size();
6915: if (size > 0) {
6916: RenderAtomListInfo arr[] = new RenderAtomListInfo[size];
6917: arr = (RenderAtomListInfo[]) sharedDList.toArray(arr);
6918:
6919: GeometryArrayRetained geo;
6920: int mask = (cv.useSharedCtx ? rdr.rendererBit
6921: : cv.canvasBit);
6922:
6923: for (i = 0; i < size; i++) {
6924: geo = (GeometryArrayRetained) arr[i].geometry();
6925: // Fix for Issue 5: free all native display lists and clear the
6926: // context creation bits for this canvas, but don't do anything
6927: // with the geo's user list.
6928: if (geo.dlistId > 0) {
6929: // XXXX: for the shared ctx case, we really should
6930: // only free the display lists if this is the last
6931: // Canvas in the renderer. However, since the
6932: // display lists will be recreated, it doesn't
6933: // really matter.
6934: cv.freeDisplayList(ctx, geo.dlistId);
6935: geo.resourceCreationMask &= ~mask;
6936: }
6937: }
6938: }
6939: }
6940:
6941: // put displayListID back to MC
6942: void releaseAllDisplayListID() {
6943: int i;
6944: int size = renderMoleculeList.size();
6945:
6946: if (size > 0) {
6947: RenderMolecule[] rmArr = (RenderMolecule[]) renderMoleculeList
6948: .toArray(false);
6949:
6950: for (i = 0; i < size; i++) {
6951: rmArr[i].releaseAllPrimaryDisplayListID();
6952: }
6953: }
6954:
6955: size = sharedDList.size();
6956: if (size > 0) {
6957: RenderAtomListInfo arr[] = new RenderAtomListInfo[size];
6958: arr = (RenderAtomListInfo[]) sharedDList.toArray(arr);
6959: GeometryArrayRetained geo;
6960:
6961: for (i = 0; i < size; i++) {
6962: geo = (GeometryArrayRetained) arr[i].geometry();
6963: if (geo.resourceCreationMask == 0) {
6964: geo.freeDlistId();
6965: }
6966: }
6967: }
6968: }
6969:
6970: /*
6971: void handleFrequencyBitChanged(J3dMessage m) {
6972: NodeComponentRetained nc = (NodeComponentRetained)m.args[0];
6973: GeometryAtom[] gaArr = (GeometryAtom[])m.args[3];
6974: int i;
6975: RenderAtom ra;
6976: Boolean value = (Boolean)m.args[1];
6977: int mask = ((Integer)m.args[2]).intValue();
6978:
6979: // Currently, we do not handle the case of
6980: // going from frequent to infrequent
6981: if (value == Boolean.FALSE)
6982: return;
6983:
6984: ra = null;
6985: // Get the first ra that is visible
6986: for (i = 0; i < gaArr.length; i++) {
6987: ra = gaArr[i].getRenderAtom(view);
6988: if (ra== null || !ra.inRenderBin())
6989: continue;
6990: }
6991:
6992: if (ra == null)
6993: return;
6994:
6995: int start = i;
6996: // Check if the removed renderAtom is already in
6997: // a separate bin - this is to handle the case
6998: // when it has been changed to frequent, then to
6999: // infrequent and then to frequent again!
7000: if ((nc instanceof MaterialRetained && ra.renderMolecule.definingMaterial != ra.renderMolecule.material) ||
7001: (nc instanceof AppearanceRetained && ((ra.renderMolecule.soleUser & AppearanceRetained.MATERIAL) == 0))) {
7002: for (i = start; i < gaArr.length; i++) {
7003: ra = gaArr[i].getRenderAtom(view);
7004: if (ra== null || !ra.inRenderBin())
7005: continue;
7006:
7007: TextureBin tb = ra.renderMolecule.textureBin;
7008: ra.renderMolecule.removeRenderAtom(ra);
7009: reInsertRenderAtom(tb, ra);
7010: }
7011: }
7012: else if ((nc instanceof PolygonAttributesRetained && ra.renderMolecule.definingPolygonAttributes != ra.renderMolecule.polygonAttributes) ||
7013: (nc instanceof AppearanceRetained && ((ra.renderMolecule.soleUser & AppearanceRetained.POLYGON) == 0))) {
7014: // Check if the removed renderAtom is already in
7015: // a separate bin - this is to handle the case
7016: // when it has been changed to frequent, then to
7017: // infrequent and then to frequent again!
7018: for (i = start; i < gaArr.length; i++) {
7019: ra = gaArr[i].getRenderAtom(view);
7020: if (ra== null || !ra.inRenderBin())
7021: continue;
7022:
7023: TextureBin tb = ra.renderMolecule.textureBin;
7024: ra.renderMolecule.removeRenderAtom(ra);
7025: reInsertRenderAtom(tb, ra);
7026: }
7027: }
7028: else if ((nc instanceof PointAttributesRetained && ra.renderMolecule.definingPointAttributes != ra.renderMolecule.pointAttributes) ||
7029: (nc instanceof AppearanceRetained && ((ra.renderMolecule.soleUser & AppearanceRetained.POINT) == 0))) {
7030: // Check if the removed renderAtom is already in
7031: // a separate bin - this is to handle the case
7032: // when it has been changed to frequent, then to
7033: // infrequent and then to frequent again!
7034: for (i = start; i < gaArr.length; i++) {
7035: ra = gaArr[i].getRenderAtom(view);
7036: if (ra== null || !ra.inRenderBin())
7037: continue;
7038:
7039: TextureBin tb = ra.renderMolecule.textureBin;
7040: ra.renderMolecule.removeRenderAtom(ra);
7041: reInsertRenderAtom(tb, ra);
7042: }
7043: }
7044: else if ((nc instanceof LineAttributesRetained && ra.renderMolecule.definingLineAttributes != ra.renderMolecule.lineAttributes) ||
7045: (nc instanceof AppearanceRetained && ((ra.renderMolecule.soleUser & AppearanceRetained.LINE) == 0))) {
7046: // Check if the removed renderAtom is already in
7047: // a separate bin - this is to handle the case
7048: // when it has been changed to frequent, then to
7049: // infrequent and then to frequent again!
7050: for (i = start; i < gaArr.length; i++) {
7051: ra = gaArr[i].getRenderAtom(view);
7052: if (ra== null || !ra.inRenderBin())
7053: continue;
7054:
7055: TextureBin tb = ra.renderMolecule.textureBin;
7056: ra.renderMolecule.removeRenderAtom(ra);
7057: reInsertRenderAtom(tb, ra);
7058: }
7059: }
7060: else if((nc instanceof TransparencyAttributesRetained&& ra.renderMolecule.definingTransparency != ra.renderMolecule.transparency) ||
7061: (nc instanceof AppearanceRetained && ((ra.renderMolecule.soleUser & AppearanceRetained.TRANSPARENCY) == 0))) {
7062: // Check if the removed renderAtom is already in
7063: // a separate bin - this is to handle the case
7064: // when it has been changed to frequent, then to
7065: // infrequent and then to frequent again!
7066: for (i = start; i < gaArr.length; i++) {
7067: ra = gaArr[i].getRenderAtom(view);
7068: if (ra== null || !ra.inRenderBin())
7069: continue;
7070:
7071: TextureBin tb = ra.renderMolecule.textureBin;
7072: ra.renderMolecule.removeRenderAtom(ra);
7073: reInsertRenderAtom(tb, ra);
7074: }
7075: }
7076: else if ((nc instanceof ColoringAttributesRetained&& ra.renderMolecule.definingColoringAttributes != ra.renderMolecule.coloringAttributes) ||
7077: (nc instanceof AppearanceRetained && ((ra.renderMolecule.soleUser & AppearanceRetained.COLOR) == 0))) {
7078: // Check if the removed renderAtom is already in
7079: // a separate bin - this is to handle the case
7080: // when it has been changed to frequent, then to
7081: // infrequent and then to frequent again!
7082: for (i = start; i < gaArr.length; i++) {
7083: ra = gaArr[i].getRenderAtom(view);
7084: if (ra== null || !ra.inRenderBin())
7085: continue;
7086:
7087: TextureBin tb = ra.renderMolecule.textureBin;
7088: ra.renderMolecule.removeRenderAtom(ra);
7089: reInsertRenderAtom(tb, ra);
7090: }
7091: }
7092: else if ((nc instanceof RenderingAttributesRetained && ra.renderMolecule.textureBin.attributeBin.definingRenderingAttributes != ra.renderMolecule.textureBin.attributeBin.renderingAttrs) ||
7093: (nc instanceof AppearanceRetained && ((ra.renderMolecule.textureBin.attributeBin.soleUser & AppearanceRetained.RENDER) == 0))) {
7094: for (i = start; i < gaArr.length; i++) {
7095: ra = gaArr[i].getRenderAtom(view);
7096: if (ra== null || !ra.inRenderBin())
7097: continue;
7098:
7099: EnvironmentSet e= ra.renderMolecule.textureBin.environmentSet;
7100: ra.renderMolecule.removeRenderAtom(ra);
7101: reInsertAttributeBin(e, ra);
7102: }
7103: }
7104: else {
7105:
7106: // XXXX: handle texture
7107: }
7108:
7109:
7110: }
7111: */
7112:
7113: }
|