Source Code Cross Referenced for RenderBin.java in  » 6.0-JDK-Modules » java-3d » javax » media » j3d » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » java 3d » javax.media.j3d 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.