Source Code Cross Referenced for RenderMolecule.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: RenderMolecule.java,v $
0003:         *
0004:         * Copyright 1999-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.9 $
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 RenderMolecule manages a collection of RenderAtoms.
0039:         */
0040:
0041:        class RenderMolecule extends IndexedObject implements  ObjectUpdate,
0042:                NodeComponentUpdate {
0043:
0044:            // different types of IndexedUnorderedSet that store RenderMolecule
0045:            static final int REMOVE_RENDER_ATOM_IN_RM_LIST = 0;
0046:            static final int RENDER_MOLECULE_LIST = 1;
0047:
0048:            // total number of different IndexedUnorderedSet types
0049:            static final int TOTAL_INDEXED_UNORDER_SET_TYPES = 2;
0050:
0051:            /**
0052:             * Values for the geometryType field
0053:             */
0054:            static final int POINT = 0x01;
0055:            static final int LINE = 0x02;
0056:            static final int SURFACE = 0x04;
0057:            static final int RASTER = 0x08;
0058:            static final int COMPRESSED = 0x10;
0059:
0060:            static int RM_COMPONENTS = (AppearanceRetained.POLYGON
0061:                    | AppearanceRetained.LINE | AppearanceRetained.POINT
0062:                    | AppearanceRetained.MATERIAL
0063:                    | AppearanceRetained.TRANSPARENCY | AppearanceRetained.COLOR);
0064:
0065:            // XXXX: use definingMaterial etc. instead of these
0066:            // when sole user is completely implement
0067:            PolygonAttributesRetained polygonAttributes = null;
0068:            LineAttributesRetained lineAttributes = null;
0069:            PointAttributesRetained pointAttributes = null;
0070:            MaterialRetained material = null;
0071:            ColoringAttributesRetained coloringAttributes = null;
0072:            TransparencyAttributesRetained transparency = null;
0073:
0074:            // Use Object instead of AppearanceRetained class for 
0075:            // state caching optimation memory performance
0076:
0077:            boolean normalPresent = true;
0078:
0079:            // Equivalent bits
0080:            static final int POINTATTRS_DIRTY = AppearanceRetained.POINT;
0081:            static final int LINEATTRS_DIRTY = AppearanceRetained.LINE;
0082:            static final int POLYGONATTRS_DIRTY = AppearanceRetained.POLYGON;
0083:            static final int MATERIAL_DIRTY = AppearanceRetained.MATERIAL;
0084:            static final int TRANSPARENCY_DIRTY = AppearanceRetained.TRANSPARENCY;
0085:            static final int COLORINGATTRS_DIRTY = AppearanceRetained.COLOR;
0086:
0087:            static final int ALL_DIRTY_BITS = POINTATTRS_DIRTY
0088:                    | LINEATTRS_DIRTY | POLYGONATTRS_DIRTY | MATERIAL_DIRTY
0089:                    | TRANSPARENCY_DIRTY | COLORINGATTRS_DIRTY;
0090:
0091:            /** 
0092:             * bit mask of all attr fields that are equivalent across 
0093:             * renderMolecules
0094:             */
0095:            int dirtyAttrsAcrossRms = ALL_DIRTY_BITS;
0096:
0097:            // Mask set to true is any of the component have changed
0098:            int soleUserCompDirty = 0;
0099:
0100:            /**
0101:             * The PolygonAttributes for this RenderMolecule
0102:             */
0103:            PolygonAttributesRetained definingPolygonAttributes = null;
0104:
0105:            /**
0106:             * The LineAttributes for this RenderMolecule
0107:             */
0108:            LineAttributesRetained definingLineAttributes = null;
0109:
0110:            /**
0111:             * The PointAttributes for this RenderMolecule
0112:             */
0113:            PointAttributesRetained definingPointAttributes = null;
0114:
0115:            /**
0116:             * The TextureBin that this RenderMolecule resides
0117:             */
0118:            TextureBin textureBin = null;
0119:
0120:            /**
0121:             * The localToVworld for this RenderMolecule
0122:             */
0123:            Transform3D[] localToVworld = null;
0124:            int[] localToVworldIndex = null;
0125:
0126:            /**
0127:             * The Material reference for this RenderMolecule
0128:             */
0129:            MaterialRetained definingMaterial = null;
0130:
0131:            /**
0132:             * The ColoringAttribute reference for this RenderMolecule
0133:             */
0134:            ColoringAttributesRetained definingColoringAttributes = null;
0135:
0136:            /**
0137:             * The Transparency reference for this RenderMolecule
0138:             */
0139:            TransparencyAttributesRetained definingTransparency = null;
0140:
0141:            /**
0142:             * Transform3D - point to the right one based on bg or not
0143:             */
0144:            Transform3D[] trans = null;
0145:
0146:            /**
0147:             * specify whether scale is nonuniform
0148:             */
0149:            boolean isNonUniformScale = false;
0150:
0151:            /**
0152:             * number of renderAtoms to be rendered in this RenderMolecule
0153:             */
0154:            int numRenderAtoms = 0;
0155:
0156:            /**
0157:             * number of render atoms, used during the renderBin update time
0158:             */
0159:            int numEditingRenderAtoms = 0;
0160:
0161:            RenderAtom addRAs = null;
0162:            RenderAtom removeRAs = null;
0163:
0164:            /** 
0165:             * The cached ColoringAttributes color value.  It is
0166:             * 1.0, 1.0, 1.0 if there is no ColoringAttributes.
0167:             */
0168:            float red = 1.0f;
0169:            float green = 1.0f;
0170:            float blue = 1.0f;
0171:
0172:            /**
0173:             * Cached diffuse color value
0174:             */
0175:            float dRed = 1.0f;
0176:            float dGreen = 1.0f;
0177:            float dBlue = 1.0f;
0178:
0179:            /** 
0180:             * The cached TransparencyAttributes transparency value.  It is
0181:             * 0.0 if there is no TransparencyAttributes.
0182:             */
0183:            float alpha = 0.0f;
0184:
0185:            /**
0186:             * The geometry type for this RenderMolecule
0187:             */
0188:            int geometryType = -1;
0189:
0190:            /** 
0191:             * A boolean indicating whether or not lighting should be on.
0192:             */
0193:            boolean enableLighting = false;
0194:
0195:            /** 
0196:             * A boolean indicating whether or not this molecule rendered Text3D
0197:             */
0198:
0199:            int primaryMoleculeType = 0;
0200:            static int COMPRESSED_MOLECULE = 0x1;
0201:            static int TEXT3D_MOLECULE = 0x2;
0202:            static int DLIST_MOLECULE = 0x4;
0203:            static int RASTER_MOLECULE = 0x8;
0204:            static int ORIENTEDSHAPE3D_MOLECULE = 0x10;
0205:            static int SEPARATE_DLIST_PER_RINFO_MOLECULE = 0x20;
0206:
0207:            /** 
0208:             * Cached values for polygonMode, line antialiasing, and point antialiasing
0209:             */
0210:            int polygonMode = PolygonAttributes.POLYGON_FILL;
0211:            boolean lineAA = false;
0212:            boolean pointAA = false;
0213:
0214:            /**
0215:             * The vertex format for this RenderMolecule.  Only looked
0216:             * at for GeometryArray and CompressedGeometry objects.
0217:             */
0218:            int vertexFormat = -1;
0219:
0220:            /**
0221:             * The texCoordSetMap length for this RenderMolecule.
0222:             */
0223:            int texCoordSetMapLen = 0;
0224:
0225:            /**
0226:             * The primary renderMethod object for this RenderMolecule 
0227:             * this is either a Text3D, display list, or compressed geometry renderer.
0228:             */
0229:            RenderMethod primaryRenderMethod = null;
0230:
0231:            /**
0232:             * The secondary renderMethod object for this RenderMolecule
0233:             * this is used for geometry that is shared
0234:             */
0235:            RenderMethod secondaryRenderMethod = null;
0236:
0237:            /**
0238:             * The RenderBino for this molecule
0239:             */
0240:            RenderBin renderBin = null;
0241:
0242:            /**
0243:             * The references to the next and previous RenderMolecule in the
0244:             * list.
0245:             */
0246:            RenderMolecule next = null;
0247:            RenderMolecule prev = null;
0248:
0249:            /**
0250:             * The list of RenderAtoms in this RenderMolecule that are not using
0251:             * vertex arrays.
0252:             */
0253:            RenderAtomListInfo primaryRenderAtomList = null;
0254:
0255:            /**
0256:             * The list of RenderAtoms in this RenderMolecule that are using
0257:             * separte dlist .
0258:             */
0259:            RenderAtomListInfo separateDlistRenderAtomList = null;
0260:
0261:            /**
0262:             * The list of RenderAtoms in this RenderMolecule that are using vertex
0263:             * arrays.
0264:             */
0265:            RenderAtomListInfo vertexArrayRenderAtomList = null;
0266:
0267:            /**
0268:             * This BoundingBox is used for View Frustum culling on the primary
0269:             * list
0270:             */
0271:            BoundingBox vwcBounds = null;
0272:
0273:            /**
0274:             * If this is end of the linked list for this xform, then
0275:             * this field is non-null, if there is a map after this
0276:             */
0277:            RenderMolecule nextMap = null;
0278:            RenderMolecule prevMap = null;
0279:
0280:            /**
0281:             * If the any of the node component of the appearance in RM will be changed
0282:             * frequently, then confine it to a separate bin
0283:             */
0284:            boolean soleUser = false;
0285:            Object appHandle = null;
0286:
0287:            VertexArrayRenderMethod cachedVertexArrayRenderMethod = (VertexArrayRenderMethod) VirtualUniverse.mc
0288:                    .getVertexArrayRenderMethod();
0289:
0290:            // In D3D separate Quad/Triangle Geometry with others in RenderMolecule
0291:            // Since we need to dynamically switch whether to use DisplayList
0292:            // or not in render() as a group.
0293:            boolean isQuadGeometryArray = false;
0294:            boolean isTriGeometryArray = false;
0295:
0296:            // display list id, valid id starts from 1
0297:            int displayListId = 0;
0298:            Integer displayListIdObj = null;
0299:
0300:            int onUpdateList = 0;
0301:            static int NEW_RENDERATOMS_UPDATE = 0x1;
0302:            static int BOUNDS_RECOMPUTE_UPDATE = 0x2;
0303:            static int LOCALE_TRANSLATION = 0x4;
0304:            static int UPDATE_BACKGROUND_TRANSFORM = 0x8;
0305:            static int IN_DIRTY_RENDERMOLECULE_LIST = 0x10;
0306:            static int LOCALE_CHANGED = 0x20;
0307:            static int ON_UPDATE_CHECK_LIST = 0x40;
0308:
0309:            // background geometry rendering
0310:            boolean doInfinite;
0311:            Transform3D[] infLocalToVworld;
0312:
0313:            // Whether alpha is used in this renderMolecule
0314:            boolean useAlpha = false;
0315:
0316:            // Support for multiple locales
0317:            Locale locale = null;
0318:
0319:            // Transform when locale is different from the view's locale
0320:            Transform3D[] localeLocalToVworld = null;
0321:
0322:            // Vector used for locale translation
0323:            Vector3d localeTranslation = null;
0324:
0325:            boolean primaryChanged = false;
0326:
0327:            boolean isOpaqueOrInOG = true;
0328:            boolean inOrderedGroup = false;
0329:
0330:            // closest switch parent
0331:            SwitchRetained closestSwitchParent = null;
0332:
0333:            // the child index from the closest switch parent
0334:            int closestSwitchIndex = -1;
0335:
0336:            RenderMolecule(GeometryAtom ga,
0337:                    PolygonAttributesRetained polygonAttributes,
0338:                    LineAttributesRetained lineAttributes,
0339:                    PointAttributesRetained pointAttributes,
0340:                    MaterialRetained material,
0341:                    ColoringAttributesRetained coloringAttributes,
0342:                    TransparencyAttributesRetained transparency,
0343:                    RenderingAttributesRetained renderAttrs,
0344:                    TextureUnitStateRetained[] texUnits,
0345:                    Transform3D[] transform, int[] transformIndex, RenderBin rb) {
0346:                renderBin = rb;
0347:                IndexedUnorderSet.init(this , TOTAL_INDEXED_UNORDER_SET_TYPES);
0348:
0349:                reset(ga, polygonAttributes, lineAttributes, pointAttributes,
0350:                        material, coloringAttributes, transparency,
0351:                        renderAttrs, texUnits, transform, transformIndex);
0352:            }
0353:
0354:            void reset(GeometryAtom ga,
0355:                    PolygonAttributesRetained polygonAttributes,
0356:                    LineAttributesRetained lineAttributes,
0357:                    PointAttributesRetained pointAttributes,
0358:                    MaterialRetained material,
0359:                    ColoringAttributesRetained coloringAttributes,
0360:                    TransparencyAttributesRetained transparency,
0361:                    RenderingAttributesRetained renderAttrs,
0362:                    TextureUnitStateRetained[] texUnits,
0363:                    Transform3D[] transform, int[] transformIndex) {
0364:                primaryMoleculeType = 0;
0365:                numRenderAtoms = 0;
0366:                numEditingRenderAtoms = 0;
0367:                onUpdateList = 0;
0368:                dirtyAttrsAcrossRms = ALL_DIRTY_BITS;
0369:                primaryRenderMethod = null;
0370:                isNonUniformScale = false;
0371:                primaryChanged = false;
0372:                this .material = material;
0373:                this .polygonAttributes = polygonAttributes;
0374:                this .lineAttributes = lineAttributes;
0375:                this .pointAttributes = pointAttributes;
0376:                this .coloringAttributes = coloringAttributes;
0377:                this .transparency = transparency;
0378:
0379:                closestSwitchParent = ga.source.closestSwitchParent;
0380:                closestSwitchIndex = ga.source.closestSwitchIndex;
0381:
0382:                int i1;
0383:                // Find the first non-null geometey
0384:                GeometryRetained geo = null;
0385:                int k = 0;
0386:                isOpaqueOrInOG = true;
0387:                inOrderedGroup = false;
0388:                while (geo == null && (k < ga.geometryArray.length)) {
0389:                    geo = ga.geometryArray[k];
0390:                    k++;
0391:                }
0392:
0393:                // Issue 249 - check for sole user only if property is set
0394:                soleUser = false;
0395:                if (VirtualUniverse.mc.allowSoleUser) {
0396:                    if (ga.source.appearance != null) {
0397:                        soleUser = ((ga.source.appearance.changedFrequent & RM_COMPONENTS) != 0);
0398:                    }
0399:                }
0400:
0401:                // Set the appearance only for soleUser case
0402:                if (soleUser)
0403:                    appHandle = ga.source.appearance;
0404:                else
0405:                    appHandle = (Object) this ;
0406:
0407:                // If its of type GeometryArrayRetained 
0408:                if (ga.geoType <= GeometryRetained.GEO_TYPE_GEOMETRYARRAY
0409:                        || ga.geoType == GeometryRetained.GEO_TYPE_TEXT3D) {
0410:
0411:                    if (ga.source instanceof  OrientedShape3DRetained) {
0412:                        primaryRenderMethod = VirtualUniverse.mc
0413:                                .getOrientedShape3DRenderMethod();
0414:                        primaryMoleculeType = ORIENTEDSHAPE3D_MOLECULE;
0415:                    } else if (ga.geoType == GeometryRetained.GEO_TYPE_TEXT3D) {
0416:                        primaryRenderMethod = VirtualUniverse.mc
0417:                                .getText3DRenderMethod();
0418:                        primaryMoleculeType = TEXT3D_MOLECULE;
0419:                    } else {
0420:                        // Make determination of dlist or not during addRenderAtom
0421:                        secondaryRenderMethod = cachedVertexArrayRenderMethod;
0422:                    }
0423:                } else {
0424:                    if (ga.geoType == GeometryRetained.GEO_TYPE_COMPRESSED) {
0425:                        primaryRenderMethod = VirtualUniverse.mc
0426:                                .getCompressedGeometryRenderMethod();
0427:                        primaryMoleculeType = COMPRESSED_MOLECULE;
0428:                    } else if (geo instanceof  RasterRetained) {
0429:                        primaryRenderMethod = VirtualUniverse.mc
0430:                                .getDefaultRenderMethod();
0431:                        primaryMoleculeType = RASTER_MOLECULE;
0432:                    }
0433:                }
0434:
0435:                prev = null;
0436:                next = null;
0437:                prevMap = null;
0438:                nextMap = null;
0439:
0440:                primaryRenderAtomList = null;
0441:                vertexArrayRenderAtomList = null;
0442:
0443:                switch (ga.geoType) {
0444:                case GeometryRetained.GEO_TYPE_POINT_SET:
0445:                case GeometryRetained.GEO_TYPE_INDEXED_POINT_SET:
0446:                    this .geometryType = POINT;
0447:                    break;
0448:                case GeometryRetained.GEO_TYPE_LINE_SET:
0449:                case GeometryRetained.GEO_TYPE_LINE_STRIP_SET:
0450:                case GeometryRetained.GEO_TYPE_INDEXED_LINE_SET:
0451:                case GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET:
0452:                    this .geometryType = LINE;
0453:                    break;
0454:                case GeometryRetained.GEO_TYPE_RASTER:
0455:                    this .geometryType = RASTER;
0456:                    break;
0457:                case GeometryRetained.GEO_TYPE_COMPRESSED:
0458:                    this .geometryType = COMPRESSED;
0459:
0460:                    switch (((CompressedGeometryRetained) geo).getBufferType()) {
0461:                    case CompressedGeometryHeader.POINT_BUFFER:
0462:                        this .geometryType |= POINT;
0463:                        break;
0464:                    case CompressedGeometryHeader.LINE_BUFFER:
0465:                        this .geometryType |= LINE;
0466:                        break;
0467:                    default:
0468:                    case CompressedGeometryHeader.TRIANGLE_BUFFER:
0469:                        this .geometryType |= SURFACE;
0470:                        if (polygonAttributes != null) {
0471:                            if (polygonAttributes.polygonMode == PolygonAttributes.POLYGON_POINT) {
0472:                                this .geometryType |= POINT;
0473:                            } else if (polygonAttributes.polygonMode == PolygonAttributes.POLYGON_LINE) {
0474:                                this .geometryType |= LINE;
0475:                            }
0476:                        }
0477:                        break;
0478:                    }
0479:                    break;
0480:                default:
0481:                    this .geometryType = SURFACE;
0482:                    if (polygonAttributes != null) {
0483:                        if (polygonAttributes.polygonMode == PolygonAttributes.POLYGON_POINT) {
0484:                            this .geometryType |= POINT;
0485:                        } else if (polygonAttributes.polygonMode == PolygonAttributes.POLYGON_LINE) {
0486:                            this .geometryType |= LINE;
0487:                        }
0488:                    }
0489:                    break;
0490:                }
0491:
0492:                isQuadGeometryArray = (geo.getClassType() == GeometryRetained.QUAD_TYPE);
0493:                isTriGeometryArray = (geo.getClassType() == GeometryRetained.TRIANGLE_TYPE);
0494:
0495:                this .localToVworld = transform;
0496:                this .localToVworldIndex = transformIndex;
0497:                doInfinite = ga.source.inBackgroundGroup;
0498:                if (doInfinite) {
0499:                    if (infLocalToVworld == null) {
0500:                        infLocalToVworld = new Transform3D[2];
0501:                        infLocalToVworld[0] = infLocalToVworld[1] = new Transform3D();
0502:                    }
0503:                    localToVworld[0].getRotation(infLocalToVworld[0]);
0504:                }
0505:                int mask = 0;
0506:                if (polygonAttributes != null) {
0507:                    if (polygonAttributes.changedFrequent != 0) {
0508:                        definingPolygonAttributes = polygonAttributes;
0509:
0510:                        mask |= POLYGONATTRS_DIRTY;
0511:                    } else {
0512:                        if (definingPolygonAttributes != null) {
0513:                            definingPolygonAttributes.set(polygonAttributes);
0514:                        } else {
0515:                            definingPolygonAttributes = (PolygonAttributesRetained) polygonAttributes
0516:                                    .clone();
0517:                        }
0518:                    }
0519:                    polygonMode = definingPolygonAttributes.polygonMode;
0520:                } else {
0521:                    polygonMode = PolygonAttributes.POLYGON_FILL;
0522:                    definingPolygonAttributes = null;
0523:                }
0524:
0525:                if (lineAttributes != null) {
0526:                    if (lineAttributes.changedFrequent != 0) {
0527:                        definingLineAttributes = lineAttributes;
0528:                        mask |= LINEATTRS_DIRTY;
0529:                    } else {
0530:                        if (definingLineAttributes != null) {
0531:                            definingLineAttributes.set(lineAttributes);
0532:                        } else {
0533:                            definingLineAttributes = (LineAttributesRetained) lineAttributes
0534:                                    .clone();
0535:                        }
0536:                    }
0537:                    lineAA = definingLineAttributes.lineAntialiasing;
0538:                } else {
0539:                    lineAA = false;
0540:                    definingLineAttributes = null;
0541:                }
0542:
0543:                if (pointAttributes != null) {
0544:                    if (pointAttributes.changedFrequent != 0) {
0545:                        definingPointAttributes = pointAttributes;
0546:                        mask |= POINTATTRS_DIRTY;
0547:
0548:                    } else {
0549:                        if (definingPointAttributes != null) {
0550:                            definingPointAttributes.set(pointAttributes);
0551:                        } else {
0552:                            definingPointAttributes = (PointAttributesRetained) pointAttributes
0553:                                    .clone();
0554:                        }
0555:                    }
0556:                    pointAA = definingPointAttributes.pointAntialiasing;
0557:                } else {
0558:                    pointAA = false;
0559:                    definingPointAttributes = null;
0560:                }
0561:
0562:                normalPresent = true;
0563:                if (geo instanceof  GeometryArrayRetained) {
0564:                    GeometryArrayRetained gr = (GeometryArrayRetained) geo;
0565:                    this .vertexFormat = gr.vertexFormat;
0566:
0567:                    if (gr.texCoordSetMap != null) {
0568:                        this .texCoordSetMapLen = gr.texCoordSetMap.length;
0569:                    } else {
0570:                        this .texCoordSetMapLen = 0;
0571:                    }
0572:
0573:                    // Throw an exception if lighting is enabled, but no normals defined
0574:                    if ((vertexFormat & GeometryArray.NORMALS) == 0) {
0575:                        // Force lighting to false
0576:                        normalPresent = false;
0577:                    }
0578:
0579:                } else if (geo instanceof  CompressedGeometryRetained) {
0580:                    this .vertexFormat = ((CompressedGeometryRetained) geo)
0581:                            .getVertexFormat();
0582:                    // Throw an exception if lighting is enabled, but no normals defined
0583:                    if ((vertexFormat & GeometryArray.NORMALS) == 0) {
0584:                        // Force lighting to false
0585:                        normalPresent = false;
0586:                    }
0587:
0588:                    this .texCoordSetMapLen = 0;
0589:
0590:                } else {
0591:                    this .vertexFormat = -1;
0592:                    this .texCoordSetMapLen = 0;
0593:                }
0594:
0595:                if (material != null) {
0596:                    if (material.changedFrequent != 0) {
0597:                        definingMaterial = material;
0598:                        mask |= MATERIAL_DIRTY;
0599:                    } else {
0600:                        if (definingMaterial != null)
0601:                            definingMaterial.set(material);
0602:                        else {
0603:                            definingMaterial = (MaterialRetained) material
0604:                                    .clone();
0605:                        }
0606:                    }
0607:
0608:                } else {
0609:                    definingMaterial = null;
0610:                }
0611:                evalMaterialCachedState();
0612:                if (coloringAttributes != null) {
0613:                    if (coloringAttributes.changedFrequent != 0) {
0614:                        definingColoringAttributes = coloringAttributes;
0615:                        mask |= COLORINGATTRS_DIRTY;
0616:                    } else {
0617:                        if (definingColoringAttributes != null) {
0618:                            definingColoringAttributes.set(coloringAttributes);
0619:                        } else {
0620:                            definingColoringAttributes = (ColoringAttributesRetained) coloringAttributes
0621:                                    .clone();
0622:                        }
0623:                    }
0624:                    red = coloringAttributes.color.x;
0625:                    green = coloringAttributes.color.y;
0626:                    blue = coloringAttributes.color.z;
0627:                } else {
0628:                    red = 1.0f;
0629:                    green = 1.0f;
0630:                    blue = 1.0f;
0631:                    definingColoringAttributes = null;
0632:                }
0633:
0634:                if (transparency != null) {
0635:
0636:                    if (transparency.changedFrequent != 0) {
0637:                        definingTransparency = transparency;
0638:                        mask |= TRANSPARENCY_DIRTY;
0639:                    } else {
0640:                        if (definingTransparency != null) {
0641:                            definingTransparency.set(transparency);
0642:                        } else {
0643:                            definingTransparency = (TransparencyAttributesRetained) transparency
0644:                                    .clone();
0645:                        }
0646:                    }
0647:                    alpha = 1.0f - transparency.transparency;
0648:
0649:                } else {
0650:                    alpha = 1.0f;
0651:                    definingTransparency = null;
0652:
0653:                }
0654:
0655:                locale = ga.source.locale;
0656:                if (locale != renderBin.locale) {
0657:                    if (localeLocalToVworld == null) {
0658:                        localeLocalToVworld = new Transform3D[2];
0659:                    }
0660:                    localeLocalToVworld[0] = new Transform3D();
0661:                    localeLocalToVworld[1] = new Transform3D();
0662:                    localeTranslation = new Vector3d();
0663:                    ga.locale.hiRes.difference(renderBin.locale.hiRes,
0664:                            localeTranslation);
0665:                    translate();
0666:                } else {
0667:                    localeLocalToVworld = localToVworld;
0668:                }
0669:
0670:                if (doInfinite) {
0671:                    trans = infLocalToVworld;
0672:                } else {
0673:                    trans = localeLocalToVworld;
0674:                }
0675:
0676:                evalAlphaUsage(renderAttrs, texUnits);
0677:                isOpaqueOrInOG = isOpaque() || (ga.source.orderedPath != null);
0678:                inOrderedGroup = (ga.source.orderedPath != null);
0679:                //	System.err.println("isOpaque = "+isOpaque() +" OrInOG = "+isOpaqueOrInOG);
0680:                if (mask != 0) {
0681:                    if ((soleUserCompDirty & ALL_DIRTY_BITS) == 0) {
0682:                        renderBin.rmUpdateList.add(this );
0683:                    }
0684:                    soleUserCompDirty |= mask;
0685:                }
0686:            }
0687:
0688:            /**
0689:             * This tests if the given attributes matches this TextureBin
0690:             */
0691:            boolean equals(RenderAtom ra,
0692:                    PolygonAttributesRetained polygonAttributes,
0693:                    LineAttributesRetained lineAttributes,
0694:                    PointAttributesRetained pointAttributes,
0695:                    MaterialRetained material,
0696:                    ColoringAttributesRetained coloringAttributes,
0697:                    TransparencyAttributesRetained transparency,
0698:                    Transform3D[] transform) {
0699:                int geoType = 0;
0700:                GeometryAtom ga = ra.geometryAtom;
0701:                int eAttrs = 0;
0702:
0703:                if (this .localToVworld != transform) {
0704:                    return (false);
0705:                }
0706:
0707:                if (locale != ra.geometryAtom.source.locale) {
0708:                    return (false);
0709:                }
0710:
0711:                if (ra.geometryAtom.source.closestSwitchParent != closestSwitchParent
0712:                        || ra.geometryAtom.source.closestSwitchIndex != closestSwitchIndex) {
0713:                    return (false);
0714:                }
0715:
0716:                // Find the first non-null geometey
0717:                GeometryRetained geo = null;
0718:                int k = 0;
0719:                while (geo == null && (k < ga.geometryArray.length)) {
0720:                    geo = ga.geometryArray[k];
0721:                    k++;
0722:                }
0723:
0724:                // XXXX: Add tags
0725:                switch (ga.geoType) {
0726:                case GeometryRetained.GEO_TYPE_POINT_SET:
0727:                case GeometryRetained.GEO_TYPE_INDEXED_POINT_SET:
0728:                    geoType = POINT;
0729:                    break;
0730:                case GeometryRetained.GEO_TYPE_LINE_SET:
0731:                case GeometryRetained.GEO_TYPE_LINE_STRIP_SET:
0732:                case GeometryRetained.GEO_TYPE_INDEXED_LINE_SET:
0733:                case GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET:
0734:                    geoType = LINE;
0735:                    break;
0736:                case GeometryRetained.GEO_TYPE_RASTER:
0737:                    geoType = RASTER;
0738:                    break;
0739:                case GeometryRetained.GEO_TYPE_COMPRESSED:
0740:                    geoType = COMPRESSED;
0741:                    switch (((CompressedGeometryRetained) geo).getBufferType()) {
0742:                    case CompressedGeometryHeader.POINT_BUFFER:
0743:                        geoType |= POINT;
0744:                        break;
0745:                    case CompressedGeometryHeader.LINE_BUFFER:
0746:                        geoType |= LINE;
0747:                        break;
0748:                    default:
0749:                    case CompressedGeometryHeader.TRIANGLE_BUFFER:
0750:                        geoType |= SURFACE;
0751:                        break;
0752:                    }
0753:                    break;
0754:                default:
0755:                    geoType = SURFACE;
0756:                    if (polygonAttributes != null) {
0757:                        if (polygonAttributes.polygonMode == PolygonAttributes.POLYGON_POINT) {
0758:                            geoType |= POINT;
0759:                        } else if (polygonAttributes.polygonMode == PolygonAttributes.POLYGON_LINE) {
0760:                            geoType |= LINE;
0761:                        }
0762:                    }
0763:                    break;
0764:                }
0765:
0766:                if (this .geometryType != geoType) {
0767:                    return (false);
0768:                }
0769:                /*
0770:                // XXXX : Check this 
0771:                if (useDisplayList &&
0772:                    (ga.geometry.isEditable ||
0773:                     ga.geometry.refCount > 1 ||
0774:                     ((GroupRetained)ga.source.parent).switchLevel >= 0 ||
0775:                     ga.alphaEditable)) { 
0776:                    return (false);
0777:                }
0778:                 */
0779:                if (ga.geoType == GeometryRetained.GEO_TYPE_TEXT3D
0780:                        && primaryMoleculeType != 0
0781:                        && ((primaryMoleculeType & TEXT3D_MOLECULE) == 0)) {
0782:                    return (false);
0783:                }
0784:
0785:                if (!(ra.geometryAtom.source instanceof  OrientedShape3DRetained)
0786:                        && ((primaryMoleculeType & ORIENTEDSHAPE3D_MOLECULE) != 0)) {
0787:                    //System.err.println("RA's NOT a OrientedShape3DRetained and RM is a ORIENTEDSHAPE3D_MOLECULE ");
0788:
0789:                    return (false);
0790:                }
0791:
0792:                // XXXX: Its is necessary to have same vformat for dl,
0793:                // Howabout iteration, should we have 2 vformats in rm?
0794:                if (geo instanceof  GeometryArrayRetained) {
0795:                    GeometryArrayRetained gr = (GeometryArrayRetained) geo;
0796:                    if (this .vertexFormat != gr.vertexFormat) {
0797:                        return (false);
0798:                    }
0799:
0800:                    // we are requiring that texCoordSetMap length to be the same
0801:                    // so that we can either put all multi-tex ga to a display list,
0802:                    // or punt all to vertex array. And we don't need to worry
0803:                    // about some of the ga can be in display list for this canvas,
0804:                    // and some other can be in display list for the other canvas.
0805:                    if (((gr.texCoordSetMap != null) && (this .texCoordSetMapLen != gr.texCoordSetMap.length))
0806:                            || ((gr.texCoordSetMap == null) && (this .texCoordSetMapLen != 0))) {
0807:                        return (false);
0808:                    }
0809:
0810:                    if (VirtualUniverse.mc.isD3D()
0811:                            && (((geo.getClassType() == GeometryRetained.QUAD_TYPE) && !isQuadGeometryArray) || ((geo
0812:                                    .getClassType() == GeometryRetained.TRIANGLE_TYPE) && !isTriGeometryArray))) {
0813:                        return false;
0814:                    }
0815:
0816:                } else if (geo instanceof  CompressedGeometryRetained) {
0817:                    if (this .vertexFormat != ((CompressedGeometryRetained) geo)
0818:                            .getVertexFormat()) {
0819:                        return (false);
0820:                    }
0821:                } else {
0822:                    //XXXX: compare isEditable
0823:                    if (this .vertexFormat != -1) {
0824:                        return (false);
0825:                    }
0826:                }
0827:
0828:                // If the any reference to the appearance components  that is cached renderMolecule
0829:                // can change frequently, make a separate bin
0830:                if (soleUser
0831:                        || (ra.geometryAtom.source.appearance != null && ((ra.geometryAtom.source.appearance.changedFrequent & RM_COMPONENTS) != 0))) {
0832:                    if (appHandle == (Object) ra.geometryAtom.source.appearance) {
0833:
0834:                        // if this RenderMolecule is currently on a zombie state,
0835:                        // we'll need to put it on the update list to reevaluate
0836:                        // the state, because while it is on a zombie state,
0837:                        // state could have been changed. Example,
0838:                        // application could have detached an appearance,
0839:                        // made changes to the appearance state, and then
0840:                        // reattached the appearance. In this case, the 
0841:                        // changes would not have reflected to the RenderMolecule
0842:
0843:                        if (numEditingRenderAtoms == 0) {
0844:
0845:                            if ((soleUserCompDirty & ALL_DIRTY_BITS) == 0) {
0846:                                renderBin.rmUpdateList.add(this );
0847:                            }
0848:                            soleUserCompDirty |= ALL_DIRTY_BITS;
0849:                        }
0850:                        return true;
0851:                    } else {
0852:                        return false;
0853:                    }
0854:
0855:                }
0856:                // Assign the cloned value as the original value
0857:
0858:                // Either a changedFrequent or a null case
0859:                // and the incoming one is not equal or null
0860:                // then return;	
0861:                // This check also handles null == null case
0862:                if (definingPolygonAttributes != null) {
0863:                    if ((this .definingPolygonAttributes.changedFrequent != 0)
0864:                            || (polygonAttributes != null && polygonAttributes.changedFrequent != 0))
0865:                        if (definingPolygonAttributes == polygonAttributes) {
0866:                            if (definingPolygonAttributes.compChanged != 0) {
0867:                                if ((soleUserCompDirty & ALL_DIRTY_BITS) == 0) {
0868:                                    renderBin.rmUpdateList.add(this );
0869:                                }
0870:                                soleUserCompDirty |= POLYGONATTRS_DIRTY;
0871:                            }
0872:                        } else {
0873:                            return false;
0874:                        }
0875:                    else if (!definingPolygonAttributes
0876:                            .equivalent(polygonAttributes)) {
0877:                        return false;
0878:                    }
0879:                } else if (polygonAttributes != null) {
0880:                    return false;
0881:                }
0882:
0883:                if (definingLineAttributes != null) {
0884:                    if ((this .definingLineAttributes.changedFrequent != 0)
0885:                            || (lineAttributes != null && lineAttributes.changedFrequent != 0))
0886:                        if (definingLineAttributes == lineAttributes) {
0887:                            if (definingLineAttributes.compChanged != 0) {
0888:                                if ((soleUserCompDirty & ALL_DIRTY_BITS) == 0) {
0889:                                    renderBin.rmUpdateList.add(this );
0890:                                }
0891:                                soleUserCompDirty |= LINEATTRS_DIRTY;
0892:                            }
0893:                        } else {
0894:                            return false;
0895:                        }
0896:                    else if (!definingLineAttributes.equivalent(lineAttributes)) {
0897:                        return false;
0898:                    }
0899:                } else if (lineAttributes != null) {
0900:                    return false;
0901:                }
0902:
0903:                if (definingPointAttributes != null) {
0904:                    if ((this .definingPointAttributes.changedFrequent != 0)
0905:                            || (pointAttributes != null && pointAttributes.changedFrequent != 0))
0906:                        if (definingPointAttributes == pointAttributes) {
0907:                            if (definingPointAttributes.compChanged != 0) {
0908:                                if ((soleUserCompDirty & ALL_DIRTY_BITS) == 0) {
0909:                                    renderBin.rmUpdateList.add(this );
0910:                                }
0911:                                soleUserCompDirty |= POINTATTRS_DIRTY;
0912:                            }
0913:                        } else {
0914:                            return false;
0915:                        }
0916:                    else if (!definingPointAttributes
0917:                            .equivalent(pointAttributes)) {
0918:                        return false;
0919:                    }
0920:                } else if (pointAttributes != null) {
0921:                    return false;
0922:                }
0923:
0924:                if (definingMaterial != null) {
0925:                    if ((this .definingMaterial.changedFrequent != 0)
0926:                            || (material != null && material.changedFrequent != 0))
0927:                        if (definingMaterial == material) {
0928:                            if (definingMaterial.compChanged != 0) {
0929:                                if ((soleUserCompDirty & ALL_DIRTY_BITS) == 0) {
0930:                                    renderBin.rmUpdateList.add(this );
0931:                                }
0932:                                soleUserCompDirty |= MATERIAL_DIRTY;
0933:                            }
0934:                        } else {
0935:                            return false;
0936:                        }
0937:                    else if (!definingMaterial.equivalent(material)) {
0938:                        return false;
0939:                    }
0940:                } else if (material != null) {
0941:                    return false;
0942:                }
0943:
0944:                if (definingColoringAttributes != null) {
0945:                    if ((this .definingColoringAttributes.changedFrequent != 0)
0946:                            || (coloringAttributes != null && coloringAttributes.changedFrequent != 0))
0947:                        if (definingColoringAttributes == coloringAttributes) {
0948:                            if (definingColoringAttributes.compChanged != 0) {
0949:                                if ((soleUserCompDirty & ALL_DIRTY_BITS) == 0) {
0950:                                    renderBin.rmUpdateList.add(this );
0951:                                }
0952:                                soleUserCompDirty |= COLORINGATTRS_DIRTY;
0953:                            }
0954:                        } else {
0955:                            return false;
0956:                        }
0957:                    else if (!definingColoringAttributes
0958:                            .equivalent(coloringAttributes)) {
0959:                        return false;
0960:                    }
0961:                } else if (coloringAttributes != null) {
0962:                    return false;
0963:                }
0964:
0965:                // if the definingTransparency is a non cloned values and the incoming
0966:                // one is equivalent, then check if the component is dirty
0967:                // this happens when all the RAs from this RM have been removed
0968:                // but new ones are not added yet (rbin visibility) not run yet
0969:                // and when there is a change in nc based on the new RA, we wil;
0970:                // miss the change, doing this check will catch the change durin
0971:                // new RAs insertRenderAtom
0972:                if (definingTransparency != null) {
0973:                    if ((this .definingTransparency.changedFrequent != 0)
0974:                            || (transparency != null && transparency.changedFrequent != 0))
0975:                        if (definingTransparency == transparency) {
0976:                            if (definingTransparency.compChanged != 0) {
0977:                                if ((soleUserCompDirty & ALL_DIRTY_BITS) == 0) {
0978:                                    renderBin.rmUpdateList.add(this );
0979:                                }
0980:                                soleUserCompDirty |= TRANSPARENCY_DIRTY;
0981:                            }
0982:                        } else {
0983:                            return false;
0984:                        }
0985:                    else if (!definingTransparency.equivalent(transparency)) {
0986:                        return false;
0987:                    }
0988:                } else if (transparency != null) {
0989:                    return false;
0990:                }
0991:
0992:                return (true);
0993:            }
0994:
0995:            public void updateRemoveRenderAtoms() {
0996:                int i;
0997:                RenderAtom r;
0998:                RenderAtomListInfo rinfo;
0999:
1000:                // Check if this renderMolecule was created and destroyed this frame.
1001:                // so, no display list was created
1002:                if (numRenderAtoms == 0 && removeRAs == null && addRAs == null) {
1003:                    textureBin.removeRenderMolecule(this );
1004:                    return;
1005:                }
1006:
1007:                while (removeRAs != null) {
1008:                    r = (RenderAtom) removeRAs;
1009:                    r.removed = null;
1010:                    numRenderAtoms--;
1011:
1012:                    // Loop thru all geometries in the renderAtom, they could
1013:                    // potentially be in different buckets in the rendermoleulce
1014:                    for (int index = 0; index < r.rListInfo.length; index++) {
1015:                        rinfo = r.rListInfo[index];
1016:                        // Don't remove  null geo
1017:                        if (rinfo.geometry() == null)
1018:                            continue;
1019:
1020:                        if ((rinfo.groupType & RenderAtom.PRIMARY) != 0) {
1021:                            primaryChanged = true;
1022:                            if (rinfo.prev == null) { // At the head of the list
1023:                                primaryRenderAtomList = rinfo.next;
1024:                                if (rinfo.next != null) {
1025:                                    rinfo.next.prev = null;
1026:                                }
1027:                            } else { // In the middle or at the end.
1028:                                rinfo.prev.next = rinfo.next;
1029:                                if (rinfo.next != null) {
1030:                                    rinfo.next.prev = rinfo.prev;
1031:                                }
1032:                            }
1033:
1034:                            // If the molecule type is Raster, then add it to the lock list
1035:                            if (primaryMoleculeType == RASTER) {
1036:                                RasterRetained geo = (RasterRetained) rinfo
1037:                                        .geometry();
1038:                                renderBin.removeGeometryFromLockList(geo);
1039:                                if (geo.image != null)
1040:                                    renderBin.removeNodeComponent(geo.image);
1041:
1042:                            } else if ((rinfo.groupType & RenderAtom.SEPARATE_DLIST_PER_RINFO) != 0) {
1043:                                if (!rinfo.renderAtom.inRenderBin()) {
1044:                                    renderBin.removeDlistPerRinfo.add(rinfo);
1045:                                }
1046:                            }
1047:                        } else if ((rinfo.groupType & RenderAtom.SEPARATE_DLIST_PER_GEO) != 0) {
1048:                            if (rinfo.prev == null) { // At the head of the list
1049:                                separateDlistRenderAtomList = rinfo.next;
1050:                                if (rinfo.next != null) {
1051:                                    rinfo.next.prev = null;
1052:                                }
1053:                            } else { // In the middle or at the end.
1054:                                rinfo.prev.next = rinfo.next;
1055:                                if (rinfo.next != null) {
1056:                                    rinfo.next.prev = rinfo.prev;
1057:                                }
1058:                            }
1059:                            renderBin.removeGeometryDlist(rinfo);
1060:
1061:                        } else {
1062:                            if (rinfo.prev == null) { // At the head of the list
1063:                                vertexArrayRenderAtomList = rinfo.next;
1064:                                if (rinfo.next != null) {
1065:                                    rinfo.next.prev = null;
1066:                                }
1067:                            } else { // In the middle or at the end.
1068:                                rinfo.prev.next = rinfo.next;
1069:                                if (rinfo.next != null) {
1070:                                    rinfo.next.prev = rinfo.prev;
1071:                                }
1072:                            }
1073:                            // For indexed geometry there is no need to lock since
1074:                            // the mirror is changed only when the renderer is not
1075:                            // running
1076:                            // For indexed geometry, if use_coord is set, then either we
1077:                            // are using the index geometry as is or we will be unindexifying
1078:                            // on the fly, so its better to lock
1079:                            GeometryArrayRetained geo = (GeometryArrayRetained) rinfo
1080:                                    .geometry();
1081:                            if (!(geo instanceof  IndexedGeometryArrayRetained)
1082:                                    || ((geo.vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) != 0)) {
1083:                                renderBin.removeGeometryFromLockList(geo);
1084:                            }
1085:                        }
1086:                        rinfo.prev = null;
1087:                        rinfo.next = null;
1088:                    }
1089:                    removeRAs = removeRAs.nextRemove;
1090:                    r.nextRemove = null;
1091:                    r.prevRemove = null;
1092:                    if (r.isOriented()) {
1093:                        renderBin.orientedRAs.remove(renderBin.orientedRAs
1094:                                .indexOf(r));
1095:                    }
1096:
1097:                    if ((textureBin.environmentSet.lightBin.geometryBackground == null)
1098:                            && !isOpaqueOrInOG
1099:                            && renderBin.transpSortMode == View.TRANSPARENCY_SORT_GEOMETRY) {
1100:                        renderBin.removeTransparentObject(r);
1101:                    }
1102:                }
1103:                // If this renderMolecule will not be touched for adding new RenderAtoms
1104:                // then ..
1105:                if (addRAs == null) {
1106:                    // If there are no more renderAtoms and there will be no more
1107:                    // renderatoms added to this renderMolecule , then remove
1108:                    if (numRenderAtoms == 0) {
1109:                        // If both lists are empty remove this renderMolecule
1110:                        if ((primaryMoleculeType & DLIST_MOLECULE) != 0) {
1111:                            renderBin.addDisplayListResourceFreeList(this );
1112:                            vwcBounds.set(null);
1113:                            displayListId = 0;
1114:                            displayListIdObj = null;
1115:                        }
1116:                        if (locale != renderBin.locale) {
1117:                            localeLocalToVworld = null;
1118:                        }
1119:                        textureBin.removeRenderMolecule(this );
1120:                    } else {
1121:                        if ((primaryMoleculeType & DLIST_MOLECULE) != 0
1122:                                && primaryChanged) {
1123:
1124:                            // If a renderAtom is added to the display list
1125:                            // structure then add this to the dirty list of rm
1126:                            // for which the display list needs to be recreated
1127:                            renderBin.addDirtyRenderMolecule(this );
1128:                            vwcBounds.set(null);
1129:                            rinfo = primaryRenderAtomList;
1130:                            while (rinfo != null) {
1131:                                vwcBounds
1132:                                        .combine(rinfo.renderAtom.localeVwcBounds);
1133:                                rinfo = rinfo.next;
1134:                            }
1135:                            primaryChanged = false;
1136:                        }
1137:                    }
1138:                }
1139:                numEditingRenderAtoms = numRenderAtoms;
1140:            }
1141:
1142:            public void updateObject() {
1143:                int i;
1144:                RenderAtom renderAtom;
1145:                RenderAtomListInfo r;
1146:                if (textureBin == null) {
1147:                    return;
1148:                }
1149:
1150:                if (addRAs != null) {
1151:                    while (addRAs != null) {
1152:
1153:                        numRenderAtoms++;
1154:                        renderAtom = (RenderAtom) addRAs;
1155:                        renderAtom.renderMolecule = this ;
1156:                        renderAtom.added = null;
1157:                        for (int j = 0; j < renderAtom.rListInfo.length; j++) {
1158:                            r = (RenderAtomListInfo) renderAtom.rListInfo[j];
1159:                            // Don't add null geo
1160:                            if (r.geometry() == null)
1161:                                continue;
1162:                            r.groupType = evalRinfoGroupType(r);
1163:                            if ((r.groupType & RenderAtom.PRIMARY) != 0) {
1164:                                if ((r.groupType & RenderAtom.DLIST) != 0
1165:                                        && primaryRenderMethod == null) {
1166:                                    primaryMoleculeType = DLIST_MOLECULE;
1167:                                    renderBin.renderMoleculeList.add(this );
1168:
1169:                                    if (vwcBounds == null)
1170:                                        vwcBounds = new BoundingBox(
1171:                                                (BoundingBox) null);
1172:                                    primaryRenderMethod = VirtualUniverse.mc
1173:                                            .getDisplayListRenderMethod();
1174:                                    // Assign a displayListId for this renderMolecule
1175:                                    if (displayListId == 0) {
1176:                                        displayListIdObj = VirtualUniverse.mc
1177:                                                .getDisplayListId();
1178:                                        displayListId = displayListIdObj
1179:                                                .intValue();
1180:                                    }
1181:                                } else if ((r.groupType & RenderAtom.SEPARATE_DLIST_PER_RINFO) != 0
1182:                                        && primaryRenderMethod == null) {
1183:                                    primaryMoleculeType = SEPARATE_DLIST_PER_RINFO_MOLECULE;
1184:                                    renderBin.renderMoleculeList.add(this );
1185:                                    primaryRenderMethod = VirtualUniverse.mc
1186:                                            .getDisplayListRenderMethod();
1187:
1188:                                }
1189:                                primaryChanged = true;
1190:                                if (primaryRenderAtomList == null) {
1191:                                    primaryRenderAtomList = r;
1192:                                } else {
1193:                                    r.next = primaryRenderAtomList;
1194:                                    primaryRenderAtomList.prev = r;
1195:                                    primaryRenderAtomList = r;
1196:                                }
1197:                                if (primaryMoleculeType == SEPARATE_DLIST_PER_RINFO_MOLECULE) {
1198:                                    if (r.renderAtom.dlistIds == null) {
1199:                                        r.renderAtom.dlistIds = new int[r.renderAtom.rListInfo.length];
1200:
1201:                                        for (int k = 0; k < r.renderAtom.dlistIds.length; k++) {
1202:                                            r.renderAtom.dlistIds[k] = -1;
1203:                                        }
1204:                                    }
1205:                                    if (r.renderAtom.dlistIds[r.index] == -1) {
1206:                                        r.renderAtom.dlistIds[r.index] = VirtualUniverse.mc
1207:                                                .getDisplayListId().intValue();
1208:                                        renderBin.addDlistPerRinfo.add(r);
1209:                                    }
1210:                                }
1211:
1212:                                // If the molecule type is Raster, then add it to the lock list
1213:                                if (primaryMoleculeType == RASTER) {
1214:                                    RasterRetained geo = (RasterRetained) r
1215:                                            .geometry();
1216:                                    renderBin.addGeometryToLockList(geo);
1217:                                    if (geo.image != null)
1218:                                        renderBin.addNodeComponent(geo.image);
1219:                                }
1220:                            } else if ((r.groupType & RenderAtom.SEPARATE_DLIST_PER_GEO) != 0) {
1221:                                if (separateDlistRenderAtomList == null) {
1222:                                    separateDlistRenderAtomList = r;
1223:                                } else {
1224:                                    r.next = separateDlistRenderAtomList;
1225:                                    separateDlistRenderAtomList.prev = r;
1226:                                    separateDlistRenderAtomList = r;
1227:                                }
1228:                                ((GeometryArrayRetained) r.geometry())
1229:                                        .assignDlistId();
1230:                                renderBin.addGeometryDlist(r);
1231:                            } else {
1232:                                if (secondaryRenderMethod == null)
1233:                                    secondaryRenderMethod = cachedVertexArrayRenderMethod;
1234:                                if (vertexArrayRenderAtomList == null) {
1235:                                    vertexArrayRenderAtomList = r;
1236:                                } else {
1237:                                    r.next = vertexArrayRenderAtomList;
1238:                                    vertexArrayRenderAtomList.prev = r;
1239:                                    vertexArrayRenderAtomList = r;
1240:                                }
1241:                                // For indexed geometry there is no need to lock since
1242:                                // the mirror is changed only when the renderer is not
1243:                                // running
1244:                                // For indexed geometry, if use_coord is set, then either we
1245:                                // are using the index geometry as is or we will be unindexifying
1246:                                // on the fly, so its better to loc
1247:                                GeometryArrayRetained geo = (GeometryArrayRetained) r
1248:                                        .geometry();
1249:                                if (!(geo instanceof  IndexedGeometryArrayRetained)
1250:                                        || ((geo.vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) != 0)) {
1251:                                    renderBin.addGeometryToLockList(geo);
1252:                                    // Add the geometry to the dirty list only if the geometry is by
1253:                                    // refernce and there is color and we need to use alpha
1254:                                    // Issue 113 - ignore multiScreen
1255:                                    if (((geo.vertexFormat & GeometryArray.BY_REFERENCE) != 0)
1256:                                            && (geo.c4fAllocated == 0)
1257:                                            && ((geo.vertexFormat & GeometryArray.COLOR) != 0)
1258:                                            && useAlpha) {
1259:                                        renderBin
1260:                                                .addDirtyReferenceGeometry(geo);
1261:                                    }
1262:                                }
1263:                            }
1264:                        }
1265:                        addRAs = addRAs.nextAdd;
1266:                        renderAtom.nextAdd = null;
1267:                        renderAtom.prevAdd = null;
1268:                        if (renderAtom.isOriented()) {
1269:                            renderBin.orientedRAs.add(renderAtom);
1270:
1271:                        }
1272:                        // If transparent and not in bg geometry and is depth sorted transparency
1273:                        if (!isOpaqueOrInOG
1274:                                && (textureBin.environmentSet.lightBin.geometryBackground == null)
1275:                                && (renderBin.transpSortMode == View.TRANSPARENCY_SORT_GEOMETRY)) {
1276:                            GeometryRetained geo = null;
1277:                            int k = 0;
1278:                            while (geo == null
1279:                                    && k < renderAtom.rListInfo.length) {
1280:                                geo = renderAtom.rListInfo[k].geometry();
1281:                                k++;
1282:                            }
1283:                            if (geo != null) {
1284:                                if (renderAtom.parentTInfo != null
1285:                                        && renderAtom.parentTInfo[k - 1] != null) {
1286:                                    renderBin.updateTransparentInfo(renderAtom);
1287:                                }
1288:                                // Newly added renderAtom
1289:                                else {
1290:                                    renderBin.addTransparentObject(renderAtom);
1291:                                }
1292:                            }
1293:                            // Moving within the renderBin
1294:
1295:                        }
1296:                    }
1297:
1298:                    if ((primaryMoleculeType & DLIST_MOLECULE) != 0
1299:                            && primaryChanged) {
1300:
1301:                        // If a renderAtom is added to the display list
1302:                        // structure then add this to the dirty list of rm
1303:                        // for which the display list needs to be recreated
1304:                        renderBin.addDirtyRenderMolecule(this );
1305:                        vwcBounds.set(null);
1306:                        r = primaryRenderAtomList;
1307:                        while (r != null) {
1308:                            vwcBounds.combine(r.renderAtom.localeVwcBounds);
1309:                            r = r.next;
1310:                        }
1311:                        primaryChanged = false;
1312:                    }
1313:
1314:                    if ((onUpdateList & LOCALE_CHANGED) != 0) {
1315:                        handleLocaleChange();
1316:                    }
1317:
1318:                    if (locale != renderBin.locale) {
1319:                        translate();
1320:                    }
1321:                } else {
1322:                    // The flag LOCALE_CHANGED only gets sets when there is a new additon
1323:                    // There are cases when RM updateObject() get called (due to addition
1324:                    // in renderBin - see processTransformChanged()), we need to
1325:                    // evaluate locale change for this  case as well
1326:                    if (renderBin.localeChanged) {
1327:                        handleLocaleChange();
1328:                    }
1329:
1330:                    if (locale != renderBin.locale) {
1331:                        translate();
1332:                    }
1333:
1334:                    if ((onUpdateList & UPDATE_BACKGROUND_TRANSFORM) != 0) {
1335:                        i = localToVworldIndex[NodeRetained.LAST_LOCAL_TO_VWORLD];
1336:                        localeLocalToVworld[i].getRotation(infLocalToVworld[i]);
1337:                    }
1338:
1339:                    // No new renderAtoms were added, but need to	
1340:                    // recompute vwcBounds in response to xform change
1341:                    if ((onUpdateList & BOUNDS_RECOMPUTE_UPDATE) != 0) {
1342:                        vwcBounds.set(null);
1343:                        r = primaryRenderAtomList;
1344:                        while (r != null) {
1345:                            vwcBounds.combine(r.renderAtom.localeVwcBounds);
1346:                            r = r.next;
1347:                        }
1348:                    }
1349:                }
1350:
1351:                // Clear all bits except the IN_DIRTY_LIST
1352:                onUpdateList &= IN_DIRTY_RENDERMOLECULE_LIST;
1353:
1354:                numEditingRenderAtoms = numRenderAtoms;
1355:            }
1356:
1357:            boolean canBeInDisplayList(GeometryRetained geo, GeometryAtom ga) {
1358:                if (ga.source.sourceNode instanceof  MorphRetained) {
1359:                    return false;
1360:                }
1361:
1362:                return geo.canBeInDisplayList(ga.alphaEditable);
1363:            }
1364:
1365:            // If dlist will be altered due to alpha or ignoreVertexColors, then don't
1366:            // put in a separate dlist that can be shared ...
1367:            final boolean geoNotAltered(GeometryArrayRetained geo) {
1368:                return !(((geo.vertexFormat & GeometryArray.COLOR) != 0) && (textureBin.attributeBin.ignoreVertexColors || useAlpha));
1369:            }
1370:
1371:            int evalRinfoGroupType(RenderAtomListInfo r) {
1372:                int groupType = 0;
1373:
1374:                GeometryRetained geo = r.geometry();
1375:                if (geo == null)
1376:                    return groupType;
1377:
1378:                if ((primaryMoleculeType & (COMPRESSED_MOLECULE
1379:                        | RASTER_MOLECULE | TEXT3D_MOLECULE | ORIENTEDSHAPE3D_MOLECULE)) != 0) {
1380:                    groupType = RenderAtom.OTHER;
1381:                } else if (canBeInDisplayList(geo, r.renderAtom.geometryAtom)) {
1382:                    // if geometry is under share group we immediate set the
1383:                    // dlistID to something other than -1
1384:                    if (!((GeometryArrayRetained) geo).isShared ||
1385:                    // if we do a compiled and push the transform down to
1386:                            // Geometry, we can't share the displayList
1387:                            (r.renderAtom.geometryAtom.source.staticTransform != null)) {
1388:                        // If the molecule is already defined to be SEPARATE_DLIST_PER_RINFO_MOLECULE
1389:                        // continue adding in that mode even if it was switched back to
1390:                        // no depth sorted mode
1391:                        //		System.err.println("isOpaqueOrInOG ="+isOpaqueOrInOG+" primaryMoleculeType ="+primaryMoleculeType+" renderBin.transpSortMode ="+renderBin.transpSortMode);
1392:                        if (primaryMoleculeType == SEPARATE_DLIST_PER_RINFO_MOLECULE) {
1393:                            groupType = RenderAtom.SEPARATE_DLIST_PER_RINFO;
1394:                        } else {
1395:                            if (isOpaqueOrInOG
1396:                                    || renderBin.transpSortMode == View.TRANSPARENCY_SORT_NONE) {
1397:                                groupType = RenderAtom.DLIST;
1398:                            } else {
1399:                                groupType = RenderAtom.SEPARATE_DLIST_PER_RINFO;
1400:                            }
1401:                        }
1402:
1403:                    } else if (geoNotAltered((GeometryArrayRetained) r
1404:                            .geometry())) {
1405:                        groupType = RenderAtom.SEPARATE_DLIST_PER_GEO;
1406:                    } else {
1407:                        groupType = RenderAtom.VARRAY;
1408:                    }
1409:                } else {
1410:                    groupType = RenderAtom.VARRAY;
1411:                }
1412:                return groupType;
1413:            }
1414:
1415:            /**
1416:             * Adds the given RenderAtom to this RenderMolecule.
1417:             */
1418:            void addRenderAtom(RenderAtom renderAtom, RenderBin rb) {
1419:                int i, n;
1420:                RenderAtomListInfo r;
1421:                int index;
1422:
1423:                renderAtom.envSet = textureBin.environmentSet;
1424:                renderAtom.renderMolecule = this ;
1425:                renderAtom.dirtyMask &= ~RenderAtom.NEED_SEPARATE_LOCALE_VWC_BOUNDS;
1426:
1427:                AppearanceRetained raApp = renderAtom.geometryAtom.source.appearance;
1428:
1429:                MaterialRetained mat = (raApp == null) ? null : raApp.material;
1430:                if (!soleUser && material != mat) {
1431:                    // no longer sole user
1432:                    material = definingMaterial;
1433:                }
1434:
1435:                if ((geometryType & SURFACE) != 0) {
1436:                    PolygonAttributesRetained pgAttrs = (raApp == null) ? null
1437:                            : raApp.polygonAttributes;
1438:                    if (!soleUser && polygonAttributes != pgAttrs) {
1439:                        // no longer sole user 
1440:                        polygonAttributes = definingPolygonAttributes;
1441:                    }
1442:
1443:                }
1444:                if ((geometryType & LINE) != 0) {
1445:                    LineAttributesRetained lnAttrs = (raApp == null) ? null
1446:                            : raApp.lineAttributes;
1447:                    if (!soleUser && lineAttributes != lnAttrs) {
1448:                        // no longer sole user 
1449:                        lineAttributes = definingLineAttributes;
1450:                    }
1451:
1452:                }
1453:                if ((geometryType & POINT) != 0) {
1454:                    PointAttributesRetained pnAttrs = (raApp == null) ? null
1455:                            : raApp.pointAttributes;
1456:                    if (!soleUser && pointAttributes != pnAttrs) {
1457:                        // no longer sole user 
1458:                        pointAttributes = definingPointAttributes;
1459:                    }
1460:                }
1461:
1462:                ColoringAttributesRetained coAttrs = (raApp == null) ? null
1463:                        : raApp.coloringAttributes;
1464:                if (!soleUser && coloringAttributes != coAttrs) {
1465:                    // no longer sole user 
1466:                    coloringAttributes = definingColoringAttributes;
1467:                }
1468:
1469:                TransparencyAttributesRetained trAttrs = (raApp == null) ? null
1470:                        : raApp.transparencyAttributes;
1471:                if (!soleUser && transparency != trAttrs) {
1472:                    // no longer sole user 
1473:                    transparency = definingTransparency;
1474:                }
1475:
1476:                // If the renderAtom is being inserted first time, then evaluate
1477:                // the groupType to determine if need separate localeVwcBounds
1478:                if (!renderAtom.inRenderBin()) {
1479:                    for (i = 0; i < renderAtom.rListInfo.length; i++) {
1480:                        if (renderAtom.rListInfo[i].geometry() == null)
1481:                            continue;
1482:                        int groupType = evalRinfoGroupType(renderAtom.rListInfo[i]);
1483:                        if (groupType != RenderAtom.DLIST) {
1484:                            renderAtom.dirtyMask |= RenderAtom.NEED_SEPARATE_LOCALE_VWC_BOUNDS;
1485:                        }
1486:                    }
1487:                }
1488:                if (renderAtom.removed == this ) {
1489:                    // Remove the renderAtom from the list of removeRAs
1490:                    // If this is at the head of the list
1491:                    if (renderAtom == removeRAs) {
1492:                        removeRAs = renderAtom.nextRemove;
1493:                        if (removeRAs != null)
1494:                            removeRAs.prevRemove = null;
1495:                        renderAtom.nextRemove = null;
1496:                        renderAtom.prevRemove = null;
1497:                    }
1498:                    // Somewhere in the middle
1499:                    else {
1500:                        renderAtom.prevRemove.nextRemove = renderAtom.nextRemove;
1501:                        if (renderAtom.nextRemove != null)
1502:                            renderAtom.nextRemove.prevRemove = renderAtom.prevRemove;
1503:                        renderAtom.nextRemove = null;
1504:                        renderAtom.prevRemove = null;
1505:                    }
1506:
1507:                    renderAtom.removed = null;
1508:                    // Redo any dlist etc, because it has been added
1509:                    for (i = 0; i < renderAtom.rListInfo.length; i++) {
1510:                        if (renderAtom.rListInfo[i].geometry() == null)
1511:                            continue;
1512:                        if ((renderAtom.rListInfo[i].groupType & RenderAtom.DLIST) != 0)
1513:                            renderBin.addDirtyRenderMolecule(this );
1514:                        else if ((renderAtom.rListInfo[i].groupType & RenderAtom.SEPARATE_DLIST_PER_RINFO) != 0) {
1515:                            renderBin.addDlistPerRinfo
1516:                                    .add(renderAtom.rListInfo[i]);
1517:                        } else if ((renderAtom.rListInfo[i].groupType & RenderAtom.SEPARATE_DLIST_PER_GEO) != 0)
1518:                            renderBin.addGeometryDlist(renderAtom.rListInfo[i]);
1519:
1520:                    }
1521:                    if (removeRAs == null)
1522:                        rb.removeRenderAtomInRMList.remove(this );
1523:                } else {
1524:                    // Add this renderAtom to the addList
1525:                    if (addRAs == null) {
1526:                        addRAs = renderAtom;
1527:                        renderAtom.nextAdd = null;
1528:                        renderAtom.prevAdd = null;
1529:                    } else {
1530:                        renderAtom.nextAdd = addRAs;
1531:                        renderAtom.prevAdd = null;
1532:                        addRAs.prevAdd = renderAtom;
1533:                        addRAs = renderAtom;
1534:                    }
1535:                    renderAtom.added = this ;
1536:                    if (onUpdateList == 0)
1537:                        rb.objUpdateList.add(this );
1538:                    onUpdateList |= NEW_RENDERATOMS_UPDATE;
1539:
1540:                }
1541:                if (renderBin.localeChanged && !doInfinite) {
1542:                    if (onUpdateList == 0)
1543:                        rb.objUpdateList.add(this );
1544:                    onUpdateList |= LOCALE_CHANGED;
1545:                }
1546:
1547:                // inform the texture bin that this render molecule is no longer
1548:                // in zombie state
1549:
1550:                if (numEditingRenderAtoms == 0) {
1551:                    textureBin.incrActiveRenderMolecule();
1552:                }
1553:                numEditingRenderAtoms++;
1554:            }
1555:
1556:            /**
1557:             * Removes the given RenderAtom from this RenderMolecule.
1558:             */
1559:            void removeRenderAtom(RenderAtom r) {
1560:                int index;
1561:
1562:                r.renderMolecule = null;
1563:                if (r.added == this ) {
1564:                    //Remove this renderAtom from the addRAs list
1565:
1566:                    // If this is at the head of the list
1567:                    if (r == addRAs) {
1568:                        addRAs = r.nextAdd;
1569:                        if (addRAs != null)
1570:                            addRAs.prevAdd = null;
1571:                        r.nextAdd = null;
1572:                        r.prevAdd = null;
1573:                    }
1574:                    // Somewhere in the middle
1575:                    else {
1576:                        r.prevAdd.nextAdd = r.nextAdd;
1577:                        if (r.nextAdd != null)
1578:                            r.nextAdd.prevAdd = r.prevAdd;
1579:                        r.nextAdd = null;
1580:                        r.prevAdd = null;
1581:                    }
1582:
1583:                    r.added = null;
1584:                    r.envSet = null;
1585:                    // If the number of renderAtoms is zero, and it is on the
1586:                    // update list for adding new renderatroms only (not for
1587:                    // bounds update), then remove this rm from the update list
1588:
1589:                    // Might be expensive to remove this entry from the renderBin
1590:                    // objUpdateList, just let it call the renderMolecule
1591:                    /*
1592:                      if (addRAs == null) { 
1593:                      if (onUpdateList == NEW_RENDERATOMS_UPDATE){
1594:                      renderBin.objUpdateList.remove(renderBin.objUpdateList.indexOf(this));
1595:                      }
1596:                      onUpdateList &= ~NEW_RENDERATOMS_UPDATE;
1597:                      }
1598:                     */
1599:
1600:                } else {
1601:                    // Add this renderAtom to the remove list
1602:                    if (removeRAs == null) {
1603:                        removeRAs = r;
1604:                        r.nextRemove = null;
1605:                        r.prevRemove = null;
1606:                    } else {
1607:                        r.nextRemove = removeRAs;
1608:                        r.prevRemove = null;
1609:                        removeRAs.prevRemove = r;
1610:                        removeRAs = r;
1611:                    }
1612:                    r.removed = this ;
1613:                }
1614:
1615:                // Add it to the removeRenderAtom List , in case the renderMolecule
1616:                // needs to be removed
1617:                if (!renderBin.removeRenderAtomInRMList.contains(this )) {
1618:                    renderBin.removeRenderAtomInRMList.add(this );
1619:                }
1620:
1621:                // decrement the number of editing render atoms in this render molecule
1622:                numEditingRenderAtoms--;
1623:
1624:                // if there is no more editing render atoms, inform the texture bin
1625:                // that this render molecule is going to zombie state
1626:
1627:                if (numEditingRenderAtoms == 0) {
1628:                    textureBin.decrActiveRenderMolecule();
1629:                }
1630:            }
1631:
1632:            /**
1633:             * Recalculates the vwcBounds for a RenderMolecule
1634:             */
1635:            void recalcBounds() {
1636:                RenderAtomListInfo ra;
1637:
1638:                if (primaryRenderMethod == VirtualUniverse.mc
1639:                        .getDisplayListRenderMethod()) {
1640:                    vwcBounds.set(null);
1641:                    ra = primaryRenderAtomList;
1642:                    while (ra != null) {
1643:                        vwcBounds.combine(ra.renderAtom.localeVwcBounds);
1644:                        ra = ra.next;
1645:                    }
1646:                }
1647:            }
1648:
1649:            void evalAlphaUsage(RenderingAttributesRetained renderAttrs,
1650:                    TextureUnitStateRetained[] texUnits) {
1651:                boolean alphaBlend, alphaTest, textureBlend = false;
1652:
1653:                alphaBlend = definingTransparency != null
1654:                        && definingTransparency.transparencyMode != TransparencyAttributes.NONE
1655:                        && (VirtualUniverse.mc.isD3D() || !VirtualUniverse.mc
1656:                                .isD3D()
1657:                                && definingTransparency.transparencyMode != TransparencyAttributes.SCREEN_DOOR);
1658:
1659:                if (texUnits != null) {
1660:                    for (int i = 0; textureBlend == false
1661:                            && i < texUnits.length; i++) {
1662:                        if (texUnits[i] != null && texUnits[i].texAttrs != null) {
1663:                            textureBlend = textureBlend
1664:                                    || (texUnits[i].texAttrs.textureMode == TextureAttributes.BLEND);
1665:                        }
1666:                    }
1667:                }
1668:
1669:                alphaTest = renderAttrs != null
1670:                        && renderAttrs.alphaTestFunction != RenderingAttributes.ALWAYS;
1671:
1672:                boolean oldUseAlpha = useAlpha;
1673:                useAlpha = alphaBlend || alphaTest || textureBlend;
1674:
1675:                if (!oldUseAlpha && useAlpha) {
1676:                    GeometryArrayRetained geo = null;
1677:
1678:                    if (vertexArrayRenderAtomList != null)
1679:                        geo = (GeometryArrayRetained) vertexArrayRenderAtomList
1680:                                .geometry();
1681:
1682:                    if (geo != null) {
1683:                        if (!(geo instanceof  IndexedGeometryArrayRetained)
1684:                                || ((geo.vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) != 0)) {
1685:                            renderBin.addGeometryToLockList(geo);
1686:                            // Add the geometry to the dirty list only if the geometry is by
1687:                            // reference and there is color and we need to use alpha
1688:                            // Issue 113 - ignore multiScreen
1689:                            if (((geo.vertexFormat & GeometryArray.BY_REFERENCE) != 0)
1690:                                    && (geo.c4fAllocated == 0)
1691:                                    && ((geo.vertexFormat & GeometryArray.COLOR) != 0)
1692:                                    && useAlpha) {
1693:                                renderBin.addDirtyReferenceGeometry(geo);
1694:                            }
1695:                        }
1696:                    }
1697:                }
1698:            }
1699:
1700:            final boolean isSwitchOn() {
1701:                // The switchOn status of the entire RM can be determined
1702:                // by the switchOn status of any renderAtoms below.
1703:                // This is possible because renderAtoms generated from a common
1704:                // switch branch are placed in the same renderMolecule
1705:                if (primaryRenderAtomList != null) {
1706:                    return primaryRenderAtomList.renderAtom.geometryAtom.source.switchState.lastSwitchOn;
1707:
1708:                }
1709:
1710:                if (vertexArrayRenderAtomList != null) {
1711:                    return vertexArrayRenderAtomList.renderAtom.geometryAtom.source.switchState.lastSwitchOn;
1712:
1713:                }
1714:
1715:                if (separateDlistRenderAtomList != null) {
1716:                    return separateDlistRenderAtomList.renderAtom.geometryAtom.source.switchState.lastSwitchOn;
1717:                }
1718:                return false;
1719:            }
1720:
1721:            /**
1722:             * Renders this RenderMolecule
1723:             */
1724:            boolean render(Canvas3D cv, int pass, int dirtyBits) {
1725:                assert pass < 0;
1726:
1727:                boolean isVisible = isSwitchOn();
1728:
1729:                if (!isVisible) {
1730:                    return false;
1731:                }
1732:
1733:                isVisible = false;
1734:
1735:                // include this LightBin to the to-be-updated list in Canvas
1736:                cv.setStateToUpdate(Canvas3D.RENDERMOLECULE_BIT, this );
1737:
1738:                boolean modeSupportDL = true;
1739:                isNonUniformScale = !trans[localToVworldIndex[NodeRetained.LAST_LOCAL_TO_VWORLD]]
1740:                        .isCongruent();
1741:                // We have to dynamically switch between using displaymode
1742:                // mode or not instead of decide in canBeInDisplayList(), 
1743:                // since polygonAttribute can be change by editable Appearance
1744:                // or editable polygonAttribute which mode we can't take
1745:                // advantage of display list mode in many cases just because
1746:                // there are three special cases to handle.
1747:
1748:                // Another case for punting to vertex array is if pass specifies
1749:                // something other than -1. That means, we are in the
1750:                // multi-texturing multi-pass case. Then we'll use vertex array
1751:                // instead. Or the length of the texCoordSetMap is greater than
1752:                // the number of texture units supported by the Canvas, then
1753:                // we'll have to punt to vertex array as well.
1754:
1755:                if ((pass != TextureBin.USE_DISPLAYLIST)
1756:                        || (texCoordSetMapLen > cv.maxTexCoordSets)
1757:                        || (VirtualUniverse.mc.isD3D() && (((definingPolygonAttributes != null) && ((isQuadGeometryArray && (definingPolygonAttributes.polygonMode == PolygonAttributes.POLYGON_LINE)) || (isTriGeometryArray && (definingPolygonAttributes.polygonMode == PolygonAttributes.POLYGON_POINT)))) || cv.texLinearMode))) {
1758:                    modeSupportDL = false;
1759:                }
1760:
1761:                /*
1762:                System.err.println("texCoord " + texCoordSetMapLen + " " +
1763:                		   cv.maxTexCoordSets + " " + modeSupportDL);
1764:
1765:                System.err.println("primaryMoleculeType = "+primaryMoleculeType+" primaryRenderAtomList ="+primaryRenderAtomList+" separateDlistRenderAtomList ="+separateDlistRenderAtomList+" vertexArrayRenderAtomList ="+vertexArrayRenderAtomList);
1766:                 */
1767:                // Send down the model view only once, if its not of type text
1768:                if ((primaryMoleculeType & (TEXT3D_MOLECULE | ORIENTEDSHAPE3D_MOLECULE)) == 0) {
1769:
1770:                    if (primaryRenderAtomList != null) {
1771:                        if ((primaryRenderMethod != VirtualUniverse.mc
1772:                                .getDisplayListRenderMethod())
1773:                                || modeSupportDL) {
1774:                            if (primaryMoleculeType != SEPARATE_DLIST_PER_RINFO_MOLECULE) {
1775:
1776:                                if (primaryRenderMethod.render(this , cv,
1777:                                        primaryRenderAtomList, dirtyBits))
1778:                                    isVisible = true;
1779:                            } else {
1780:                                if (renderBin.dlistRenderMethod
1781:                                        .renderSeparateDlistPerRinfo(this , cv,
1782:                                                primaryRenderAtomList,
1783:                                                dirtyBits))
1784:                                    isVisible = true;
1785:
1786:                            }
1787:                        } else {
1788:                            if (cachedVertexArrayRenderMethod.render(this , cv,
1789:                                    primaryRenderAtomList, dirtyBits)) {
1790:                                isVisible = true;
1791:                            }
1792:                        }
1793:                    }
1794:                } else { // TEXT3D or ORIENTEDSHAPE3D    
1795:
1796:                    if (primaryRenderAtomList != null) {
1797:                        if (primaryRenderMethod.render(this , cv,
1798:                                primaryRenderAtomList, dirtyBits)) {
1799:                            isVisible = true;
1800:                        }
1801:                    }
1802:                }
1803:
1804:                if (separateDlistRenderAtomList != null) {
1805:                    if (modeSupportDL) {
1806:                        if (renderBin.dlistRenderMethod.renderSeparateDlists(
1807:                                this , cv, separateDlistRenderAtomList,
1808:                                dirtyBits)) {
1809:                            isVisible = true;
1810:                        }
1811:
1812:                    } else {
1813:                        if (cachedVertexArrayRenderMethod.render(this , cv,
1814:                                separateDlistRenderAtomList, dirtyBits)) {
1815:                            isVisible = true;
1816:                        }
1817:                    }
1818:
1819:                }
1820:
1821:                // XXXX: In the case of independent primitives such as quads,
1822:                // it would still be better to call multi draw arrays
1823:                if (vertexArrayRenderAtomList != null) {
1824:                    if (cachedVertexArrayRenderMethod.render(this , cv,
1825:                            vertexArrayRenderAtomList, dirtyBits)) {
1826:                        isVisible = true;
1827:                    }
1828:                }
1829:                return isVisible;
1830:            }
1831:
1832:            void updateAttributes(Canvas3D cv, int dirtyBits) {
1833:
1834:                boolean setTransparency = false;
1835:
1836:                // If this is a beginning of a frame OR diff. geometryType 
1837:                // then reload everything for the first rendermolecule
1838:                //	System.err.println("updateAttributes");
1839:                int bitMask = geometryType | Canvas3D.MATERIAL_DIRTY
1840:                        | Canvas3D.COLORINGATTRS_DIRTY
1841:                        | Canvas3D.TRANSPARENCYATTRS_DIRTY;
1842:
1843:                // If beginning of a frame then reload all the attributes
1844:                if ((cv.canvasDirty & bitMask) != 0) {
1845:                    if ((geometryType & SURFACE) != 0) {
1846:                        if (definingPolygonAttributes == null) {
1847:                            cv.resetPolygonAttributes(cv.ctx);
1848:                        } else {
1849:                            definingPolygonAttributes.updateNative(cv.ctx);
1850:                        }
1851:                        cv.polygonAttributes = polygonAttributes;
1852:                    }
1853:                    if ((geometryType & LINE) != 0) {
1854:                        if (definingLineAttributes == null) {
1855:                            cv.resetLineAttributes(cv.ctx);
1856:                        } else {
1857:                            definingLineAttributes.updateNative(cv.ctx);
1858:                        }
1859:                        cv.lineAttributes = lineAttributes;
1860:                    }
1861:                    if ((geometryType & POINT) != 0) {
1862:                        if (definingPointAttributes == null) {
1863:                            cv.resetPointAttributes(cv.ctx);
1864:                        } else {
1865:                            definingPointAttributes.updateNative(cv.ctx);
1866:                        }
1867:                        cv.pointAttributes = pointAttributes;
1868:                    }
1869:
1870:                    if (definingTransparency == null) {
1871:                        cv.resetTransparency(cv.ctx, geometryType, polygonMode,
1872:                                lineAA, pointAA);
1873:                    } else {
1874:                        definingTransparency.updateNative(cv.ctx, alpha,
1875:                                geometryType, polygonMode, lineAA, pointAA);
1876:                    }
1877:                    cv.transparency = transparency;
1878:
1879:                    if (definingMaterial == null) {
1880:                        cv.updateMaterial(cv.ctx, red, green, blue, alpha);
1881:                    } else {
1882:                        definingMaterial.updateNative(cv.ctx, red, green, blue,
1883:                                alpha, enableLighting);
1884:                    }
1885:                    cv.material = material;
1886:                    cv.enableLighting = enableLighting;
1887:
1888:                    if (definingColoringAttributes == null) {
1889:                        cv.resetColoringAttributes(cv.ctx, red, green, blue,
1890:                                alpha, enableLighting);
1891:                    } else {
1892:                        definingColoringAttributes.updateNative(cv.ctx, dRed,
1893:                                dBlue, dGreen, alpha, enableLighting);
1894:                    }
1895:                    cv.coloringAttributes = coloringAttributes;
1896:
1897:                    // Use Object instead of AppearanceRetained class for
1898:                    // state caching optimation for memory performance
1899:                    cv.appHandle = appHandle;
1900:                }
1901:
1902:                // assuming neighbor dirty bits ORing is implemented
1903:                // note that we need to set it to ALL_DIRTY at the
1904:                // begining of textureBin first and only do the ORing
1905:                // whenever encounter a non-visible rm
1906:
1907:                else if (cv.renderMolecule != this  && (dirtyBits != 0)) {
1908:
1909:                    // no need to download states if appHandle is the same
1910:                    if (cv.appHandle != appHandle) {
1911:
1912:                        // Check if the attribute bundle in the canvas is the same
1913:                        // as the attribute bundle in this renderMolecule
1914:
1915:                        if (cv.transparency != transparency
1916:                                && (dirtyBits & TRANSPARENCY_DIRTY) != 0) {
1917:                            setTransparency = true;
1918:                            if (definingTransparency == null) {
1919:
1920:                                cv.resetTransparency(cv.ctx, geometryType,
1921:                                        polygonMode, lineAA, pointAA);
1922:                            } else {
1923:                                definingTransparency.updateNative(cv.ctx,
1924:                                        alpha, geometryType, polygonMode,
1925:                                        lineAA, pointAA);
1926:                            }
1927:                            cv.transparency = transparency;
1928:                        }
1929:
1930:                        if (setTransparency
1931:                                || ((cv.enableLighting != enableLighting) || (cv.material != material)
1932:                                        && (dirtyBits & MATERIAL_DIRTY) != 0)) {
1933:                            if (definingMaterial == null) {
1934:                                cv.updateMaterial(cv.ctx, red, green, blue,
1935:                                        alpha);
1936:                            } else {
1937:                                definingMaterial.updateNative(cv.ctx, red,
1938:                                        green, blue, alpha, enableLighting);
1939:                            }
1940:                            cv.material = material;
1941:                            cv.enableLighting = enableLighting;
1942:                        }
1943:
1944:                        if (((geometryType & SURFACE) != 0)
1945:                                && cv.polygonAttributes != polygonAttributes
1946:                                && (dirtyBits & POLYGONATTRS_DIRTY) != 0) {
1947:
1948:                            if (definingPolygonAttributes == null) {
1949:                                cv.resetPolygonAttributes(cv.ctx);
1950:                            } else {
1951:                                definingPolygonAttributes.updateNative(cv.ctx);
1952:                            }
1953:                            cv.polygonAttributes = polygonAttributes;
1954:                        }
1955:
1956:                        if (((geometryType & LINE) != 0)
1957:                                && cv.lineAttributes != lineAttributes
1958:                                && (dirtyBits & LINEATTRS_DIRTY) != 0) {
1959:
1960:                            if (definingLineAttributes == null) {
1961:                                cv.resetLineAttributes(cv.ctx);
1962:                            } else {
1963:                                definingLineAttributes.updateNative(cv.ctx);
1964:                            }
1965:                            cv.lineAttributes = lineAttributes;
1966:                        }
1967:
1968:                        if (((geometryType & POINT) != 0)
1969:                                && cv.pointAttributes != pointAttributes
1970:                                && (dirtyBits & POINTATTRS_DIRTY) != 0) {
1971:
1972:                            if (definingPointAttributes == null) {
1973:                                cv.resetPointAttributes(cv.ctx);
1974:                            } else {
1975:                                definingPointAttributes.updateNative(cv.ctx);
1976:                            }
1977:                            cv.pointAttributes = pointAttributes;
1978:                        }
1979:
1980:                        // Use Object instead of AppearanceRetained class for
1981:                        // state caching optimation for memory performance
1982:                        cv.appHandle = appHandle;
1983:                    }
1984:                    // no state caching for color attrs, which can also be 
1985:                    // changed by primitive with colors
1986:                    if (setTransparency
1987:                            || ((dirtyBits & COLORINGATTRS_DIRTY) != 0)) {
1988:
1989:                        if (definingColoringAttributes == null) {
1990:                            cv.resetColoringAttributes(cv.ctx, red, green,
1991:                                    blue, alpha, enableLighting);
1992:                        } else {
1993:                            definingColoringAttributes.updateNative(cv.ctx,
1994:                                    dRed, dBlue, dGreen, alpha, enableLighting);
1995:
1996:                        }
1997:                        cv.coloringAttributes = coloringAttributes;
1998:                    }
1999:
2000:                }
2001:
2002:                if ((primaryMoleculeType & (TEXT3D_MOLECULE | ORIENTEDSHAPE3D_MOLECULE)) == 0) {
2003:                    /* System.err.println("updateAttributes  setModelViewMatrix (1)"); */
2004:
2005:                    Transform3D modelMatrix = trans[localToVworldIndex[NodeRetained.LAST_LOCAL_TO_VWORLD]];
2006:
2007:                    if (cv.modelMatrix != modelMatrix) {
2008:                        /* System.err.println("updateAttributes  setModelViewMatrix (2)"); */
2009:
2010:                        cv.setModelViewMatrix(cv.ctx, cv.vworldToEc.mat,
2011:                                modelMatrix);
2012:                    }
2013:                }
2014:
2015:                cv.canvasDirty &= ~bitMask;
2016:                cv.renderMolecule = this ;
2017:            }
2018:
2019:            void transparentSortRender(Canvas3D cv, int pass,
2020:                    TransparentRenderingInfo tinfo) {
2021:                assert pass < 0;
2022:
2023:                Transform3D modelMatrix = trans[localToVworldIndex[NodeRetained.LAST_LOCAL_TO_VWORLD]];
2024:
2025:                // include this LightBin to the to-be-updated list in Canvas
2026:                cv.setStateToUpdate(Canvas3D.RENDERMOLECULE_BIT, this );
2027:
2028:                boolean modeSupportDL = true;
2029:
2030:                // We have to dynamically switch between using displaymode
2031:                // mode or not instead of decide in canBeInDisplayList(), 
2032:                // since polygonAttribute can be change by editable Appearance
2033:                // or editable polygonAttribute which mode we can't take
2034:                // advantage of display list mode in many cases just because
2035:                // there are three special cases to handle.
2036:
2037:                // Another case for punting to vertex array is if pass specifies
2038:                // something other than -1. That means, we are in the
2039:                // multi-texturing multi-pass case. Then we'll use vertex array
2040:                // instead.
2041:
2042:                if ((pass != TextureBin.USE_DISPLAYLIST)
2043:                        || (texCoordSetMapLen > cv.maxTexCoordSets)
2044:                        || (VirtualUniverse.mc.isD3D() && (((definingPolygonAttributes != null) && ((isQuadGeometryArray && (definingPolygonAttributes.polygonMode == PolygonAttributes.POLYGON_LINE)) || (isTriGeometryArray && (definingPolygonAttributes.polygonMode == PolygonAttributes.POLYGON_POINT)))) || cv.texLinearMode))) {
2045:                    modeSupportDL = false;
2046:                }
2047:
2048:                //	System.err.println("r.isOpaque = "+isOpaque+" rinfo = "+tinfo.rInfo+" groupType = "+tinfo.rInfo.groupType);
2049:                // Only support individual dlist or varray
2050:                // If this rInfo is a part of a bigger dlist, render as VA
2051:                // XXXX: What to do with Text3D, Raster, CG?
2052:                if ((tinfo.rInfo.groupType & RenderAtom.SEPARATE_DLIST_PER_RINFO) != 0) {
2053:                    RenderAtomListInfo save = tinfo.rInfo.next;
2054:                    // Render only one geometry
2055:                    tinfo.rInfo.next = null;
2056:                    //	    System.err.println("cachedVertexArrayRenderMethod = "+cachedVertexArrayRenderMethod);
2057:                    //	    System.err.println("tinfo.rInfo = "+tinfo.rInfo);
2058:                    if (modeSupportDL) {
2059:                        renderBin.dlistRenderMethod
2060:                                .renderSeparateDlistPerRinfo(this , cv,
2061:                                        tinfo.rInfo, ALL_DIRTY_BITS);
2062:                    } else {
2063:                        cachedVertexArrayRenderMethod.render(this , cv,
2064:                                tinfo.rInfo, ALL_DIRTY_BITS);
2065:                    }
2066:                    tinfo.rInfo.next = save;
2067:                } else if ((tinfo.rInfo.groupType & (RenderAtom.VARRAY | RenderAtom.DLIST)) != 0) {
2068:                    RenderAtomListInfo save = tinfo.rInfo.next;
2069:                    // Render only one geometry
2070:                    tinfo.rInfo.next = null;
2071:                    //	    System.err.println("cachedVertexArrayRenderMethod = "+cachedVertexArrayRenderMethod);
2072:                    //	    System.err.println("tinfo.rInfo = "+tinfo.rInfo);
2073:                    cachedVertexArrayRenderMethod.render(this , cv, tinfo.rInfo,
2074:                            ALL_DIRTY_BITS);
2075:                    tinfo.rInfo.next = save;
2076:                }
2077:
2078:                // Only support individual dlist or varray
2079:                else if ((tinfo.rInfo.groupType & RenderAtom.SEPARATE_DLIST_PER_GEO) != 0) {
2080:                    RenderAtomListInfo save = tinfo.rInfo.next;
2081:                    tinfo.rInfo.next = null;
2082:                    if (modeSupportDL) {
2083:                        renderBin.dlistRenderMethod.renderSeparateDlists(this ,
2084:                                cv, tinfo.rInfo, ALL_DIRTY_BITS);
2085:                    } else {
2086:                        cachedVertexArrayRenderMethod.render(this , cv,
2087:                                tinfo.rInfo, ALL_DIRTY_BITS);
2088:                    }
2089:                    tinfo.rInfo.next = save;
2090:                } else {
2091:                    RenderAtomListInfo save = tinfo.rInfo.next;
2092:                    primaryRenderMethod.render(this , cv, primaryRenderAtomList,
2093:                            ALL_DIRTY_BITS);
2094:                    tinfo.rInfo.next = save;
2095:                }
2096:
2097:            }
2098:
2099:            /**
2100:             * This render method is used to render the transparency attributes.
2101:             * It is used in the multi-texture multi-pass case to reset the
2102:             * transparency attributes to what it was
2103:             */
2104:            void updateTransparencyAttributes(Canvas3D cv) {
2105:                if (definingTransparency == null) {
2106:                    cv.resetTransparency(cv.ctx, geometryType, polygonMode,
2107:                            lineAA, pointAA);
2108:                } else {
2109:                    definingTransparency.updateNative(cv.ctx, alpha,
2110:                            geometryType, polygonMode, lineAA, pointAA);
2111:                }
2112:            }
2113:
2114:            void updateDisplayList(Canvas3D cv) {
2115:                // This function only gets called when primaryRenderAtomsList are
2116:                if (primaryRenderAtomList != null) {
2117:                    ((DisplayListRenderMethod) primaryRenderMethod)
2118:                            .buildDisplayList(this , cv);
2119:                }
2120:            }
2121:
2122:            void releaseAllPrimaryDisplayListID() {
2123:
2124:                if (primaryRenderAtomList != null) {
2125:                    if (primaryMoleculeType == SEPARATE_DLIST_PER_RINFO_MOLECULE) {
2126:                        RenderAtomListInfo ra = primaryRenderAtomList;
2127:                        int id;
2128:
2129:                        while (ra != null) {
2130:                            id = ra.renderAtom.dlistIds[ra.index];
2131:
2132:                            if (id > 0) {
2133:                                VirtualUniverse.mc
2134:                                        .freeDisplayListId(new Integer(id));
2135:                                ra.renderAtom.dlistIds[ra.index] = -1;
2136:                            }
2137:                            ra = ra.next;
2138:                        }
2139:                    } else if (primaryMoleculeType == DLIST_MOLECULE) {
2140:                        if (displayListIdObj != null) {
2141:                            VirtualUniverse.mc
2142:                                    .freeDisplayListId(displayListIdObj);
2143:                            displayListIdObj = null;
2144:                            displayListId = -1;
2145:                        }
2146:                    }
2147:                }
2148:
2149:            }
2150:
2151:            void releaseAllPrimaryDisplayListResources(Canvas3D cv, Context ctx) {
2152:                if (primaryRenderAtomList != null) {
2153:                    if (primaryMoleculeType == SEPARATE_DLIST_PER_RINFO_MOLECULE) {
2154:                        RenderAtomListInfo ra = primaryRenderAtomList;
2155:                        int id;
2156:                        while (ra != null) {
2157:                            id = ra.renderAtom.dlistIds[ra.index];
2158:                            if (id > 0) {
2159:                                cv.freeDisplayList(ctx, id);
2160:                            }
2161:                            ra = ra.next;
2162:                        }
2163:                    } else if (primaryMoleculeType == DLIST_MOLECULE) {
2164:                        if (displayListId > 0) {
2165:                            cv.freeDisplayList(ctx, displayListId);
2166:                        }
2167:                    }
2168:                }
2169:            }
2170:
2171:            void updateAllPrimaryDisplayLists(Canvas3D cv) {
2172:                // This function only gets called when primaryRenderAtomsList are
2173:                if (primaryRenderAtomList != null) {
2174:                    if (primaryMoleculeType == SEPARATE_DLIST_PER_RINFO_MOLECULE) {
2175:                        RenderAtomListInfo ra = primaryRenderAtomList;
2176:                        while (ra != null) {
2177:                            renderBin.dlistRenderMethod.buildDlistPerRinfo(ra,
2178:                                    this , cv);
2179:                            ra = ra.next;
2180:                        }
2181:                    } else if (primaryMoleculeType == DLIST_MOLECULE) {
2182:                        ((DisplayListRenderMethod) primaryRenderMethod)
2183:                                .buildDisplayList(this , cv);
2184:                    }
2185:                }
2186:            }
2187:
2188:            void checkEquivalenceWithBothNeighbors(int dirtyBits) {
2189:                RenderMolecule leftRm = prev;
2190:                RenderMolecule rightRm = next;
2191:                dirtyAttrsAcrossRms = ALL_DIRTY_BITS;
2192:                boolean reload_color = true;
2193:
2194:                if (prev != null) {
2195:                    checkEquivalenceWithLeftNeighbor(prev, dirtyBits);
2196:                }
2197:                if (next != null) {
2198:                    next.checkEquivalenceWithLeftNeighbor(this , dirtyBits);
2199:                }
2200:            }
2201:
2202:            boolean reloadColor(RenderMolecule rm) {
2203:                if (((rm.vertexFormat & GeometryArray.COLOR) == 0)
2204:                        || (((rm.vertexFormat & GeometryArray.COLOR) != 0) && (vertexFormat & GeometryArray.COLOR) != 0)) {
2205:                    return false;
2206:                }
2207:                return true;
2208:            }
2209:
2210:            void checkEquivalenceWithLeftNeighbor(RenderMolecule rm,
2211:                    int dirtyBits) {
2212:                boolean reload_color = reloadColor(rm);
2213:                // XXXX : For now ignore the dirtyBits being sent in
2214:                dirtyAttrsAcrossRms = ALL_DIRTY_BITS;
2215:
2216:                // There is some interdepenency between the different components
2217:                // in the way it is sent down to the native code
2218:                // Material is affected by transparency and coloring attrs
2219:                // Transparency is affected by poly/line/pointAA
2220:                // ColoringAttrs is affected by material and transaparency
2221:                int materialColoringDirty = (MATERIAL_DIRTY
2222:                        | TRANSPARENCY_DIRTY | COLORINGATTRS_DIRTY);
2223:
2224:                int transparencyDirty = (TRANSPARENCY_DIRTY
2225:                        | POLYGONATTRS_DIRTY | LINEATTRS_DIRTY | POINTATTRS_DIRTY);
2226:
2227:                if ((dirtyAttrsAcrossRms & POLYGONATTRS_DIRTY) != 0) {
2228:                    if (rm.geometryType == geometryType
2229:                            && (rm.polygonAttributes == polygonAttributes || ((rm.definingPolygonAttributes != null) && (rm.definingPolygonAttributes
2230:                                    .equivalent(definingPolygonAttributes)))))
2231:                        dirtyAttrsAcrossRms &= ~POLYGONATTRS_DIRTY;
2232:
2233:                }
2234:
2235:                if ((dirtyAttrsAcrossRms & POINTATTRS_DIRTY) != 0) {
2236:                    if (rm.geometryType == geometryType
2237:                            && ((rm.pointAttributes == pointAttributes) || ((rm.definingPointAttributes != null) && (rm.definingPointAttributes
2238:                                    .equivalent(definingPointAttributes)))))
2239:                        dirtyAttrsAcrossRms &= ~POINTATTRS_DIRTY;
2240:
2241:                }
2242:
2243:                if ((dirtyAttrsAcrossRms & LINEATTRS_DIRTY) != 0) {
2244:                    if (rm.geometryType == geometryType
2245:                            && ((rm.lineAttributes == lineAttributes) || ((rm.definingLineAttributes != null) && (rm.definingLineAttributes
2246:                                    .equivalent(definingLineAttributes)))))
2247:                        dirtyAttrsAcrossRms &= ~LINEATTRS_DIRTY;
2248:                }
2249:
2250:                if ((dirtyAttrsAcrossRms & materialColoringDirty) != 0) {
2251:                    if (materialEquivalent(rm, reload_color)) {
2252:                        dirtyAttrsAcrossRms &= ~MATERIAL_DIRTY;
2253:                    } else {
2254:                        dirtyAttrsAcrossRms |= MATERIAL_DIRTY;
2255:                    }
2256:                }
2257:
2258:                if ((dirtyAttrsAcrossRms & materialColoringDirty) != 0) {
2259:                    if (coloringEquivalent(rm, reload_color)) {
2260:                        dirtyAttrsAcrossRms &= ~COLORINGATTRS_DIRTY;
2261:                    } else {
2262:                        dirtyAttrsAcrossRms |= COLORINGATTRS_DIRTY;
2263:                    }
2264:                }
2265:
2266:                if ((dirtyAttrsAcrossRms & transparencyDirty) != 0) {
2267:                    if (transparencyEquivalent(rm)) {
2268:                        dirtyAttrsAcrossRms &= ~TRANSPARENCY_DIRTY;
2269:                    } else {
2270:                        dirtyAttrsAcrossRms |= TRANSPARENCY_DIRTY;
2271:                    }
2272:                }
2273:            }
2274:
2275:            void translate() {
2276:                //	System.err.println("onUpdateList = "+onUpdateList+" renderBin.localeChanged = "+renderBin.localeChanged+" rm = "+this);
2277:                int i = localToVworldIndex[NodeRetained.LAST_LOCAL_TO_VWORLD];
2278:
2279:                localeLocalToVworld[i].mat[0] = localToVworld[i].mat[0];
2280:                localeLocalToVworld[i].mat[1] = localToVworld[i].mat[1];
2281:                localeLocalToVworld[i].mat[2] = localToVworld[i].mat[2];
2282:                localeLocalToVworld[i].mat[3] = localToVworld[i].mat[3]
2283:                        + localeTranslation.x;
2284:                localeLocalToVworld[i].mat[4] = localToVworld[i].mat[4];
2285:                localeLocalToVworld[i].mat[5] = localToVworld[i].mat[5];
2286:                localeLocalToVworld[i].mat[6] = localToVworld[i].mat[6];
2287:                localeLocalToVworld[i].mat[7] = localToVworld[i].mat[7]
2288:                        + localeTranslation.y;
2289:                localeLocalToVworld[i].mat[8] = localToVworld[i].mat[8];
2290:                localeLocalToVworld[i].mat[9] = localToVworld[i].mat[9];
2291:                localeLocalToVworld[i].mat[10] = localToVworld[i].mat[10];
2292:                localeLocalToVworld[i].mat[11] = localToVworld[i].mat[11]
2293:                        + localeTranslation.z;
2294:                localeLocalToVworld[i].mat[12] = localToVworld[i].mat[12];
2295:                localeLocalToVworld[i].mat[13] = localToVworld[i].mat[13];
2296:                localeLocalToVworld[i].mat[14] = localToVworld[i].mat[14];
2297:                localeLocalToVworld[i].mat[15] = localToVworld[i].mat[15];
2298:                //	System.err.println("rm = "+this+" localTovworld = "+localeLocalToVworld[i]+" localeTranslation = "+localeTranslation);
2299:            }
2300:
2301:            boolean isOpaque() {
2302:                if (!VirtualUniverse.mc.isD3D()) {
2303:                    // D3D doesn't support line/point antialiasing
2304:                    if ((geometryType & SURFACE) != 0) {
2305:                        if (definingPolygonAttributes != null) {
2306:                            if ((definingPolygonAttributes.polygonMode == PolygonAttributes.POLYGON_POINT)
2307:                                    && (definingPointAttributes != null)
2308:                                    && definingPointAttributes.pointAntialiasing) {
2309:                                return false;
2310:                            } else if ((definingPolygonAttributes.polygonMode == PolygonAttributes.POLYGON_LINE)
2311:                                    && (definingLineAttributes != null)
2312:                                    && definingLineAttributes.lineAntialiasing) {
2313:                                return false;
2314:                            }
2315:                        }
2316:                    } else if ((geometryType & POINT) != 0) {
2317:                        if ((definingPointAttributes != null)
2318:                                && definingPointAttributes.pointAntialiasing) {
2319:                            return false;
2320:                        }
2321:                    } else if ((geometryType & LINE) != 0) {
2322:                        if ((definingLineAttributes != null)
2323:                                && definingLineAttributes.lineAntialiasing) {
2324:                            return false;
2325:                        }
2326:                    }
2327:                    return ((definingTransparency == null)
2328:                            || (definingTransparency.transparencyMode == TransparencyAttributes.NONE) || (definingTransparency.transparencyMode == TransparencyAttributes.SCREEN_DOOR));
2329:                } else {
2330:                    return ((definingTransparency == null) || (definingTransparency.transparencyMode == TransparencyAttributes.NONE));
2331:                }
2332:            }
2333:
2334:            boolean updateNodeComponent() {
2335:                //	System.err.println("soleUser = "+soleUser+" rm = "+this);
2336:                if ((soleUserCompDirty & MATERIAL_DIRTY) != 0) {
2337:                    // Note: this RM is a soleUser(only then this function is called)
2338:                    // and if definingMaterial == material, then the material is freq
2339:                    // changed and therefore is not cloned, only other time it can be
2340:                    // same is when an equivalent material is added in and this can
2341:                    // never be true when a bin is a soleUser of a appearance
2342:
2343:                    // Evaluate before replacing the old Value
2344:                    if (soleUser) {
2345:                        boolean cloned = definingMaterial != null
2346:                                && definingMaterial != material;
2347:                        //		System.err.println("===>Rm = "+this);
2348:
2349:                        //		System.err.println("===> updating node component, cloned = "+cloned+" material.changedFrequent = "+material.changedFrequent);
2350:                        //		System.err.println("===> definingMaterial ="+definingMaterial+" material = "+material);
2351:
2352:                        material = ((AppearanceRetained) appHandle).material;
2353:                        if (material == null)
2354:                            definingMaterial = null;
2355:                        else {
2356:                            if (material.changedFrequent != 0) {
2357:                                definingMaterial = material;
2358:                            } else {
2359:                                // If the one replaced is a cloned copy, then ..
2360:                                if (cloned) {
2361:                                    definingMaterial.set(material);
2362:                                } else {
2363:                                    definingMaterial = (MaterialRetained) material
2364:                                            .clone();
2365:                                }
2366:                            }
2367:                        }
2368:                    }
2369:                    evalMaterialCachedState();
2370:                }
2371:                if ((soleUserCompDirty & LINEATTRS_DIRTY) != 0) {
2372:                    if (soleUser) {
2373:                        // Evaluate before replacing the old Value
2374:                        boolean cloned = definingLineAttributes != null
2375:                                && definingLineAttributes != lineAttributes;
2376:
2377:                        lineAttributes = ((AppearanceRetained) appHandle).lineAttributes;
2378:                        if (lineAttributes == null) {
2379:                            lineAA = false;
2380:                            definingLineAttributes = null;
2381:                        } else {
2382:                            if (lineAttributes.changedFrequent != 0) {
2383:                                definingLineAttributes = lineAttributes;
2384:                            } else {
2385:                                // If the one replaced is a cloned copy, then ..
2386:                                if (cloned) {
2387:                                    definingLineAttributes.set(lineAttributes);
2388:                                } else {
2389:                                    definingLineAttributes = (LineAttributesRetained) lineAttributes
2390:                                            .clone();
2391:                                }
2392:                            }
2393:                            lineAA = definingLineAttributes.lineAntialiasing;
2394:                        }
2395:                    } else {
2396:                        lineAA = definingLineAttributes.lineAntialiasing;
2397:                    }
2398:                }
2399:                if ((soleUserCompDirty & POINTATTRS_DIRTY) != 0) {
2400:                    if (soleUser) {
2401:                        // Evaluate before replacing the old Value
2402:                        boolean cloned = definingPointAttributes != null
2403:                                && definingPointAttributes != pointAttributes;
2404:
2405:                        pointAttributes = ((AppearanceRetained) appHandle).pointAttributes;
2406:                        if (pointAttributes == null) {
2407:                            pointAA = false;
2408:                            definingPointAttributes = null;
2409:                        } else {
2410:                            if (pointAttributes.changedFrequent != 0) {
2411:                                definingPointAttributes = pointAttributes;
2412:                            } else {
2413:                                // If the one replaced is a cloned copy, then ..
2414:                                if (cloned) {
2415:                                    definingPointAttributes
2416:                                            .set(pointAttributes);
2417:                                } else {
2418:                                    definingPointAttributes = (PointAttributesRetained) pointAttributes
2419:                                            .clone();
2420:                                }
2421:                            }
2422:                            pointAA = definingPointAttributes.pointAntialiasing;
2423:                        }
2424:                    } else {
2425:                        pointAA = definingPointAttributes.pointAntialiasing;
2426:                    }
2427:
2428:                }
2429:                if ((soleUserCompDirty & POLYGONATTRS_DIRTY) != 0) {
2430:                    if (soleUser) {
2431:                        // Evaluate before replacing the old Value
2432:                        boolean cloned = definingPolygonAttributes != null
2433:                                && definingPolygonAttributes != polygonAttributes;
2434:
2435:                        polygonAttributes = ((AppearanceRetained) appHandle).polygonAttributes;
2436:
2437:                        if (polygonAttributes == null) {
2438:                            polygonMode = PolygonAttributes.POLYGON_FILL;
2439:                            definingPolygonAttributes = null;
2440:                        } else {
2441:                            if (polygonAttributes.changedFrequent != 0) {
2442:                                definingPolygonAttributes = polygonAttributes;
2443:                            } else {
2444:                                // If the one replaced is a cloned copy, then ..
2445:                                if (cloned) {
2446:                                    definingPolygonAttributes
2447:                                            .set(polygonAttributes);
2448:                                } else {
2449:                                    definingPolygonAttributes = (PolygonAttributesRetained) polygonAttributes
2450:                                            .clone();
2451:                                }
2452:                            }
2453:
2454:                            polygonMode = definingPolygonAttributes.polygonMode;
2455:                        }
2456:                    } else {
2457:                        polygonMode = definingPolygonAttributes.polygonMode;
2458:                    }
2459:
2460:                    if (polygonMode == PolygonAttributes.POLYGON_LINE) {
2461:                        geometryType |= LINE;
2462:                    } else if (polygonMode == PolygonAttributes.POLYGON_POINT) {
2463:                        geometryType |= POINT;
2464:                    }
2465:                }
2466:
2467:                if ((soleUserCompDirty & TRANSPARENCY_DIRTY) != 0) {
2468:                    if (soleUser) {
2469:                        // Evaluate before replacing the old Value
2470:                        boolean cloned = definingTransparency != null
2471:                                && definingTransparency != transparency;
2472:                        transparency = ((AppearanceRetained) appHandle).transparencyAttributes;
2473:
2474:                        if (transparency == null) {
2475:                            alpha = 1.0f;
2476:                            definingTransparency = null;
2477:                        } else {
2478:                            if (transparency.changedFrequent != 0) {
2479:                                definingTransparency = transparency;
2480:                            } else {
2481:                                // If the one replaced is a cloned copy, then ..
2482:                                if (cloned) {
2483:                                    definingTransparency.set(transparency);
2484:                                } else {
2485:                                    definingTransparency = (TransparencyAttributesRetained) transparency
2486:                                            .clone();
2487:                                }
2488:                            }
2489:
2490:                            alpha = 1.0f - definingTransparency.transparency;
2491:                        }
2492:                    } else {
2493:                        alpha = 1.0f - definingTransparency.transparency;
2494:                    }
2495:                }
2496:
2497:                if ((soleUserCompDirty & COLORINGATTRS_DIRTY) != 0) {
2498:                    if (soleUser) {
2499:                        // Evaluate before replacing the old Value
2500:                        boolean cloned = definingColoringAttributes != null
2501:                                && definingColoringAttributes != coloringAttributes;
2502:
2503:                        coloringAttributes = ((AppearanceRetained) appHandle).coloringAttributes;
2504:                        //		System.err.println("coloringAttributes and soleUser");
2505:                        //		System.err.println("coloringAttributes ="+coloringAttributes);
2506:                        if (coloringAttributes == null) {
2507:                            definingColoringAttributes = null;
2508:                            red = 1.0f;
2509:                            green = 1.0f;
2510:                            blue = 1.0f;
2511:                        } else {
2512:                            //		    System.err.println("coloringAttributes.changedFrequent  = "+coloringAttributes.changedFrequent );
2513:                            if (coloringAttributes.changedFrequent != 0) {
2514:                                definingColoringAttributes = coloringAttributes;
2515:                            } else {
2516:                                // If the one replaced is a cloned copy, then ..
2517:                                if (cloned) {
2518:                                    definingColoringAttributes
2519:                                            .set(coloringAttributes);
2520:                                } else {
2521:                                    definingColoringAttributes = (ColoringAttributesRetained) coloringAttributes
2522:                                            .clone();
2523:                                }
2524:                            }
2525:                            red = definingColoringAttributes.color.x;
2526:                            green = definingColoringAttributes.color.y;
2527:                            blue = definingColoringAttributes.color.z;
2528:                        }
2529:                    } else {
2530:                        red = definingColoringAttributes.color.x;
2531:                        green = definingColoringAttributes.color.y;
2532:                        blue = definingColoringAttributes.color.z;
2533:                    }
2534:                }
2535:                //	System.err.println("rm = "+this+"red = "+red+" green = "+green+" blue = "+blue);
2536:                boolean newVal = isOpaque() || inOrderedGroup;
2537:                return (isOpaqueOrInOG != newVal);
2538:
2539:            }
2540:
2541:            // Issue 129: method to add or remove all rendering atoms in this
2542:            // RenderMolecule to or from the transparent info list when we are
2543:            // in depth sorted transparency mode and the RenderMolecule
2544:            // changes from opaque to transparent or vice versa.
2545:            void addRemoveTransparentObject(RenderBin renderBin, boolean add) {
2546:                addRemoveTransparentObject(renderBin, add,
2547:                        primaryRenderAtomList);
2548:                addRemoveTransparentObject(renderBin, add,
2549:                        separateDlistRenderAtomList);
2550:                addRemoveTransparentObject(renderBin, add,
2551:                        vertexArrayRenderAtomList);
2552:            }
2553:
2554:            private void addRemoveTransparentObject(RenderBin renderBin,
2555:                    boolean add, RenderAtomListInfo rinfo) {
2556:                while (rinfo != null) {
2557:                    if (add) {
2558:                        renderBin.addTransparentObject(rinfo.renderAtom);
2559:                    } else {
2560:                        renderBin.removeTransparentObject(rinfo.renderAtom);
2561:                    }
2562:                    rinfo = rinfo.next;
2563:                }
2564:            }
2565:
2566:            void evalMaterialCachedState() {
2567:                if (definingMaterial == null) {
2568:                    enableLighting = false;
2569:                    ;
2570:                    definingMaterial = null;
2571:                    dRed = 1.0f;
2572:                    dGreen = 1.0f;
2573:                    dBlue = 1.0f;
2574:                } else {
2575:                    if ((geometryType & RASTER) != 0) {
2576:                        enableLighting = false;
2577:                        dRed = 1.0f;
2578:                        dGreen = 1.0f;
2579:                        dBlue = 1.0f;
2580:                    } else {
2581:                        if (normalPresent)
2582:                            enableLighting = definingMaterial.lightingEnable;
2583:                        else
2584:                            enableLighting = false;
2585:                        dRed = definingMaterial.diffuseColor.x;
2586:                        dGreen = definingMaterial.diffuseColor.y;
2587:                        dBlue = definingMaterial.diffuseColor.z;
2588:                    }
2589:                }
2590:            }
2591:
2592:            void markBitsAsDirty(int leftBits, int rightBits) {
2593:                if (prev != null) {
2594:                    checkEquivalenceWithLeftNeighbor(prev, leftBits);
2595:                    prev.soleUserCompDirty &= ~ALL_DIRTY_BITS;
2596:                } else if (prevMap != null) {
2597:                    checkEquivalenceWithLeftNeighbor(prevMap, leftBits);
2598:                    prevMap.soleUserCompDirty &= ~ALL_DIRTY_BITS;
2599:                }
2600:                if (next != null) {
2601:                    if ((next.soleUserCompDirty & ALL_DIRTY_BITS) == 0) {
2602:                        next.checkEquivalenceWithLeftNeighbor(this , rightBits);
2603:                    } else {
2604:                        next.soleUserCompDirty = rightBits;
2605:                    }
2606:                } else if (nextMap != null) {
2607:                    if ((nextMap.soleUserCompDirty & ALL_DIRTY_BITS) == 0) {
2608:                        nextMap.checkEquivalenceWithLeftNeighbor(this ,
2609:                                rightBits);
2610:                    } else {
2611:                        nextMap.soleUserCompDirty = rightBits;
2612:                    }
2613:                }
2614:
2615:            }
2616:
2617:            void handleMaterialEquivalence() {
2618:                // Check if it has equivalent material to any of the "non-dirty"
2619:                // renderMolecules before this one
2620:                RenderMolecule curPrevRm = null;
2621:                RenderMolecule curNextRm = null;
2622:                boolean found = false;
2623:                int leftBits = ALL_DIRTY_BITS;
2624:                int rightBits = ALL_DIRTY_BITS;
2625:                if (prev != null) {
2626:                    curPrevRm = prev.prev;
2627:                    if (materialEquivalent(prev, reloadColor(prev))) {
2628:                        found = true;
2629:                        leftBits = (((soleUserCompDirty | prev.soleUserCompDirty) & ALL_DIRTY_BITS) & ~MATERIAL_DIRTY);
2630:                        rightBits = (soleUserCompDirty & ALL_DIRTY_BITS);
2631:                        markBitsAsDirty(leftBits, rightBits);
2632:                    }
2633:                } else if (!found && next != null) {
2634:                    curNextRm = next.next;
2635:
2636:                    if (materialEquivalent(next, reloadColor(next))) {
2637:                        found = true;
2638:                        int bits = 0;
2639:                        if (prev != null)
2640:                            bits = prev.soleUserCompDirty;
2641:                        else if (prevMap != null)
2642:                            bits = prevMap.soleUserCompDirty;
2643:
2644:                        leftBits = ((soleUserCompDirty | bits) & ALL_DIRTY_BITS);
2645:                        rightBits = ((soleUserCompDirty & ALL_DIRTY_BITS) & ~MATERIAL_DIRTY);
2646:                        markBitsAsDirty(leftBits, rightBits);
2647:
2648:                    }
2649:                }
2650:                // try place it next to a equivalent material on the left
2651:                while (!found && curPrevRm != null) {
2652:                    if (materialEquivalent(curPrevRm, reloadColor(curPrevRm))) {
2653:                        found = true;
2654:                        // Remove the renderMolecule from it place
2655:                        prev.next = next;
2656:                        prev.nextMap = nextMap;
2657:                        if (next != null) {
2658:                            next.prev = prev;
2659:                            if ((next.soleUserCompDirty & ALL_DIRTY_BITS) == 0) {
2660:                                next.checkEquivalenceWithLeftNeighbor(prev,
2661:                                        ALL_DIRTY_BITS);
2662:                            } else {
2663:                                next.soleUserCompDirty = ALL_DIRTY_BITS;
2664:                            }
2665:                        } else if (nextMap != null) {
2666:                            nextMap.prevMap = prev;
2667:                            if ((nextMap.soleUserCompDirty & ALL_DIRTY_BITS) == 0) {
2668:                                nextMap.checkEquivalenceWithLeftNeighbor(prev,
2669:                                        ALL_DIRTY_BITS);
2670:                            } else {
2671:                                nextMap.soleUserCompDirty |= ALL_DIRTY_BITS;
2672:                            }
2673:                        }
2674:
2675:                        // Insert it after the equivalent RM
2676:                        next = curPrevRm.next;
2677:                        nextMap = curPrevRm.nextMap;
2678:                        curPrevRm.nextMap = null;
2679:                        if (next != null) {
2680:                            next.prev = this ;
2681:                        } else if (nextMap != null) {
2682:                            nextMap.prevMap = this ;
2683:                        }
2684:                        prev = curPrevRm;
2685:                        curPrevRm.next = this ;
2686:                        leftBits = (ALL_DIRTY_BITS & ~MATERIAL_DIRTY);
2687:                        markBitsAsDirty(leftBits, ALL_DIRTY_BITS);
2688:                    }
2689:                    curPrevRm = curPrevRm.prev;
2690:                }
2691:
2692:                // Check if it has equivalent material to any of the renderMolecules after
2693:                // this one
2694:                while (!found && curNextRm != null) {
2695:                    if (materialEquivalent(curNextRm, reloadColor(curNextRm))) {
2696:                        found = true;
2697:                        // switch the pointers
2698:                        next.prev = prev;
2699:                        next.prevMap = prevMap;
2700:                        if (prev != null) {
2701:                            prev.next = next;
2702:                            if ((next.soleUserCompDirty & ALL_DIRTY_BITS) == 0) {
2703:                                next.checkEquivalenceWithLeftNeighbor(prev,
2704:                                        ALL_DIRTY_BITS);
2705:                            } else {
2706:                                next.soleUserCompDirty = ALL_DIRTY_BITS;
2707:                            }
2708:                        } else if (prevMap != null) {
2709:                            prevMap.nextMap = next;
2710:                            if ((next.soleUserCompDirty & ALL_DIRTY_BITS) == 0) {
2711:                                next.checkEquivalenceWithLeftNeighbor(prevMap,
2712:                                        ALL_DIRTY_BITS);
2713:                            } else {
2714:                                next.soleUserCompDirty = ALL_DIRTY_BITS;
2715:                            }
2716:                        }
2717:
2718:                        // Insert it before the equivalent RM
2719:                        prev = curNextRm.prev;
2720:                        prevMap = curNextRm.prevMap;
2721:                        curNextRm.prevMap = null;
2722:                        if (curNextRm.prev != null) {
2723:                            curNextRm.prev.next = this ;
2724:                        } else if (prevMap != null) {
2725:                            prevMap.nextMap = this ;
2726:                        }
2727:                        next = curNextRm;
2728:                        curNextRm.prev = this ;
2729:                        rightBits = (ALL_DIRTY_BITS & ~MATERIAL_DIRTY);
2730:                        markBitsAsDirty(ALL_DIRTY_BITS, rightBits);
2731:                    }
2732:                    curNextRm = curNextRm.next;
2733:                }
2734:                // If there are no equivalent ones, evaluate the dirty bits in the current place
2735:                if (!found) {
2736:                    if (prev != null) {
2737:                        leftBits = ((soleUserCompDirty | prev.soleUserCompDirty) & ALL_DIRTY_BITS);
2738:                    } else if (prevMap != null) {
2739:                        leftBits = ((soleUserCompDirty | prevMap.soleUserCompDirty) & ALL_DIRTY_BITS);
2740:                    }
2741:                    if (next != null) {
2742:                        rightBits = ((soleUserCompDirty | next.soleUserCompDirty) & ALL_DIRTY_BITS);
2743:                    } else if (nextMap != null) {
2744:                        rightBits = ((soleUserCompDirty | nextMap.soleUserCompDirty) & ALL_DIRTY_BITS);
2745:                    }
2746:                    markBitsAsDirty(leftBits, rightBits);
2747:                }
2748:
2749:            }
2750:
2751:            void reEvaluateEquivalence() {
2752:                // If Material changed, reInsert next to a equivalent material under
2753:                // the same transform group
2754:                // to prevent unnecessary material download
2755:                // This RM may have been evaluated due to an other RM is the same list
2756:                // If not, ...
2757:                if ((soleUserCompDirty & ALL_DIRTY_BITS) != 0) {
2758:                    if ((soleUserCompDirty & MATERIAL_DIRTY) != 0) {
2759:                        handleMaterialEquivalence();
2760:                    } else {
2761:                        int dirtyBits = (soleUserCompDirty & ALL_DIRTY_BITS);
2762:                        if (prev != null) {
2763:                            checkEquivalenceWithLeftNeighbor(
2764:                                    prev,
2765:                                    ((dirtyBits | prev.soleUserCompDirty) & ALL_DIRTY_BITS));
2766:                            prev.soleUserCompDirty = 0;
2767:                        } else if (prevMap != null) {
2768:                            checkEquivalenceWithLeftNeighbor(
2769:                                    prevMap,
2770:                                    ((dirtyBits | prevMap.soleUserCompDirty) & ALL_DIRTY_BITS));
2771:                            prevMap.soleUserCompDirty = 0;
2772:                        }
2773:                        if (next != null) {
2774:                            next
2775:                                    .checkEquivalenceWithLeftNeighbor(
2776:                                            this ,
2777:                                            ((next.soleUserCompDirty | soleUserCompDirty) & ALL_DIRTY_BITS));
2778:                        } else if (nextMap != null) {
2779:                            nextMap
2780:                                    .checkEquivalenceWithLeftNeighbor(
2781:                                            this ,
2782:                                            ((nextMap.soleUserCompDirty | soleUserCompDirty) & ALL_DIRTY_BITS));
2783:                        }
2784:                    }
2785:                }
2786:                soleUserCompDirty &= ~ALL_DIRTY_BITS;
2787:            }
2788:
2789:            boolean materialEquivalent(RenderMolecule rm, boolean reloadColor) {
2790:                if (!reloadColor) {
2791:                    if (((this .material == rm.material) || ((rm.definingMaterial != null) && (rm.definingMaterial
2792:                            .equivalent(definingMaterial))))
2793:                            && rm.alpha == alpha
2794:                            && enableLighting == rm.enableLighting
2795:                            && (enableLighting || (!enableLighting
2796:                                    && rm.red == red && rm.green == green && rm.blue == blue))) {
2797:                        return true;
2798:                    }
2799:                }
2800:                return false;
2801:            }
2802:
2803:            boolean coloringEquivalent(RenderMolecule rm, boolean reload_color) {
2804:                if (!reload_color) {
2805:                    if (((rm.coloringAttributes == coloringAttributes) || ((rm.definingColoringAttributes != null) && (rm.definingColoringAttributes
2806:                            .equivalent(definingColoringAttributes))))
2807:                            && (!enableLighting || (enableLighting && (dRed == rm.dRed
2808:                                    && dBlue == rm.dBlue && dGreen == rm.dGreen)))) {
2809:                        return true;
2810:                    }
2811:                }
2812:                return false;
2813:            }
2814:
2815:            boolean transparencyEquivalent(RenderMolecule rm) {
2816:                if (((rm.transparency == transparency) || ((rm.definingTransparency != null) && (rm.definingTransparency
2817:                        .equivalent(definingTransparency)))
2818:                        && (rm.definingTransparency.transparencyMode < TransparencyAttributes.SCREEN_DOOR && blendOn() == rm
2819:                                .blendOn()))) {
2820:                    return true;
2821:                }
2822:                return false;
2823:            }
2824:
2825:            boolean blendOn() {
2826:                if (lineAA
2827:                        && ((((geometryType & LINE) != 0) || polygonMode == PolygonAttributes.POLYGON_LINE))) {
2828:                    return true;
2829:                }
2830:                if (pointAA
2831:                        && ((((geometryType & POINT) != 0) || polygonMode == PolygonAttributes.POLYGON_POINT))) {
2832:                    return true;
2833:                }
2834:                return false;
2835:            }
2836:
2837:            VirtualUniverse getVirtualUniverse() {
2838:                return null;
2839:            }
2840:
2841:            void handleLocaleChange() {
2842:                if (locale == renderBin.locale) {
2843:                    if (localToVworld != localeLocalToVworld) {
2844:                        localeLocalToVworld = localToVworld;
2845:                        localeTranslation = null;
2846:                    }
2847:                } else {
2848:                    // Using the localToVworl then, go back to making a new copy
2849:                    if (localeTranslation == null) {
2850:                        localeLocalToVworld = new Transform3D[2];
2851:                        localeLocalToVworld[0] = new Transform3D();
2852:                        localeLocalToVworld[1] = new Transform3D();
2853:
2854:                        localeTranslation = new Vector3d();
2855:                        locale.hiRes.difference(renderBin.locale.hiRes,
2856:                                localeTranslation);
2857:                        translate();
2858:                        int i = localToVworldIndex[NodeRetained.CURRENT_LOCAL_TO_VWORLD];
2859:
2860:                        localeLocalToVworld[i].mat[0] = localToVworld[i].mat[0];
2861:                        localeLocalToVworld[i].mat[1] = localToVworld[i].mat[1];
2862:                        localeLocalToVworld[i].mat[2] = localToVworld[i].mat[2];
2863:                        localeLocalToVworld[i].mat[3] = localToVworld[i].mat[3]
2864:                                + localeTranslation.x;
2865:                        localeLocalToVworld[i].mat[4] = localToVworld[i].mat[4];
2866:                        localeLocalToVworld[i].mat[5] = localToVworld[i].mat[5];
2867:                        localeLocalToVworld[i].mat[6] = localToVworld[i].mat[6];
2868:                        localeLocalToVworld[i].mat[7] = localToVworld[i].mat[7]
2869:                                + localeTranslation.y;
2870:                        localeLocalToVworld[i].mat[8] = localToVworld[i].mat[8];
2871:                        localeLocalToVworld[i].mat[9] = localToVworld[i].mat[9];
2872:                        localeLocalToVworld[i].mat[10] = localToVworld[i].mat[10];
2873:                        localeLocalToVworld[i].mat[11] = localToVworld[i].mat[11]
2874:                                + localeTranslation.z;
2875:                        localeLocalToVworld[i].mat[12] = localToVworld[i].mat[12];
2876:                        localeLocalToVworld[i].mat[13] = localToVworld[i].mat[13];
2877:                        localeLocalToVworld[i].mat[14] = localToVworld[i].mat[14];
2878:                        localeLocalToVworld[i].mat[15] = localToVworld[i].mat[15];
2879:                    }
2880:                }
2881:
2882:                trans = localeLocalToVworld;
2883:            }
2884:
2885:            /**
2886:             * updateNodeComponentCheck is called for each soleUser RenderMolecule 
2887:             * into which new renderAtom has been added. This method is called before
2888:             * updateNodeComponent() to allow RenderMolecule to catch any node
2889:             * component changes that have been missed because the changes
2890:             * come when there is no active renderAtom associated with the
2891:             * TextureBin. See bug# 4503926 for details.
2892:             */
2893:            public void updateNodeComponentCheck() {
2894:
2895:                // If the renderMolecule has been removed, do nothing ..
2896:                if ((onUpdateList & ON_UPDATE_CHECK_LIST) == 0)
2897:                    return;
2898:
2899:                onUpdateList &= ~ON_UPDATE_CHECK_LIST;
2900:                NodeComponentRetained nc = (NodeComponentRetained) appHandle;
2901:                if ((nc.compChanged & RM_COMPONENTS) != 0) {
2902:                    if ((soleUserCompDirty & ALL_DIRTY_BITS) == 0) {
2903:                        renderBin.rmUpdateList.add(this );
2904:                    }
2905:                    soleUserCompDirty |= (nc.compChanged & RM_COMPONENTS);
2906:                }
2907:                if (definingPolygonAttributes != null
2908:                        && definingPolygonAttributes == polygonAttributes) {
2909:                    if (definingPolygonAttributes.compChanged != 0) {
2910:                        if ((soleUserCompDirty & ALL_DIRTY_BITS) == 0) {
2911:                            renderBin.rmUpdateList.add(this );
2912:                        }
2913:                        soleUserCompDirty |= POLYGONATTRS_DIRTY;
2914:                    }
2915:                }
2916:                if (definingLineAttributes != null
2917:                        && definingLineAttributes == lineAttributes) {
2918:                    if (definingLineAttributes.compChanged != 0) {
2919:                        if ((soleUserCompDirty & ALL_DIRTY_BITS) == 0) {
2920:                            renderBin.rmUpdateList.add(this );
2921:                        }
2922:                        soleUserCompDirty |= LINEATTRS_DIRTY;
2923:                    }
2924:                }
2925:                if (definingPointAttributes != null
2926:                        && definingPointAttributes.compChanged != 0) {
2927:                    if ((soleUserCompDirty & ALL_DIRTY_BITS) == 0) {
2928:                        renderBin.rmUpdateList.add(this );
2929:                    }
2930:                    soleUserCompDirty |= POINTATTRS_DIRTY;
2931:                }
2932:
2933:                if (definingMaterial != null && definingMaterial == material) {
2934:                    if (definingMaterial.compChanged != 0) {
2935:                        if ((soleUserCompDirty & ALL_DIRTY_BITS) == 0) {
2936:                            renderBin.rmUpdateList.add(this );
2937:                        }
2938:                        soleUserCompDirty |= MATERIAL_DIRTY;
2939:                    }
2940:                }
2941:
2942:                if (definingColoringAttributes != null
2943:                        && definingColoringAttributes == coloringAttributes) {
2944:                    if (definingColoringAttributes.compChanged != 0) {
2945:                        if ((soleUserCompDirty & ALL_DIRTY_BITS) == 0) {
2946:                            renderBin.rmUpdateList.add(this );
2947:                        }
2948:                        soleUserCompDirty |= COLORINGATTRS_DIRTY;
2949:                    }
2950:                }
2951:
2952:                if (definingTransparency != null
2953:                        && definingTransparency == transparency) {
2954:                    if (definingTransparency.compChanged != 0) {
2955:                        if ((soleUserCompDirty & ALL_DIRTY_BITS) == 0) {
2956:                            renderBin.rmUpdateList.add(this);
2957:                        }
2958:                        soleUserCompDirty |= TRANSPARENCY_DIRTY;
2959:                    }
2960:                }
2961:            }
2962:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.