Source Code Cross Referenced for NodeRetained.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) 


001:        /*
002:         * $RCSfile: NodeRetained.java,v $
003:         *
004:         * Copyright 1996-2008 Sun Microsystems, Inc.  All Rights Reserved.
005:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
006:         *
007:         * This code is free software; you can redistribute it and/or modify it
008:         * under the terms of the GNU General Public License version 2 only, as
009:         * published by the Free Software Foundation.  Sun designates this
010:         * particular file as subject to the "Classpath" exception as provided
011:         * by Sun in the LICENSE file that accompanied this code.
012:         *
013:         * This code is distributed in the hope that it will be useful, but WITHOUT
014:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
015:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
016:         * version 2 for more details (a copy is included in the LICENSE file that
017:         * accompanied this code).
018:         *
019:         * You should have received a copy of the GNU General Public License version
020:         * 2 along with this work; if not, write to the Free Software Foundation,
021:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
022:         *
023:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
024:         * CA 95054 USA or visit www.sun.com if you need additional information or
025:         * have any questions.
026:         *
027:         * $Revision: 1.10 $
028:         * $Date: 2008/02/28 20:17:26 $
029:         * $State: Exp $
030:         */
031:
032:        package javax.media.j3d;
033:
034:        import java.util.Vector;
035:        import java.util.Hashtable;
036:        import java.util.ArrayList;
037:
038:        /**
039:         * The Node class provides an abstract class for all Group and Leaf
040:         * Nodes.  It provides a common framework for constructing a Java 3D
041:         * scene graph, including bounding volumes and parent pointers.
042:         */
043:        abstract class NodeRetained extends SceneGraphObjectRetained implements 
044:                NnuId {
045:
046:            // All the node types in the scene graph
047:            static final int BACKGROUND = 1;
048:            static final int CLIP = 2;
049:            static final int LINEARFOG = 3;
050:            static final int EXPONENTIALFOG = 4;
051:            static final int AMBIENTLIGHT = 5;
052:            static final int DIRECTIONALLIGHT = 6;
053:            static final int POINTLIGHT = 7;
054:            static final int SPOTLIGHT = 8;
055:            static final int LINK = 9;
056:            static final int MORPH = 10;
057:            static final int SHAPE = 11;
058:            static final int BACKGROUNDSOUND = 12;
059:            static final int POINTSOUND = 13;
060:            static final int CONESOUND = 14;
061:            static final int SOUNDSCAPE = 15;
062:            static final int VIEWPLATFORM = 16;
063:            static final int BEHAVIOR = 17;
064:
065:            static final int SWITCH = 18;
066:            static final int BRANCHGROUP = 19;
067:            static final int ORDEREDGROUP = 20;
068:            static final int DECALGROUP = 21;
069:            static final int SHAREDGROUP = 22;
070:            static final int GROUP = 23;
071:            static final int TRANSFORMGROUP = 24;
072:            static final int BOUNDINGLEAF = 25;
073:            static final int MODELCLIP = 26;
074:            static final int ALTERNATEAPPEARANCE = 27;
075:            static final int ORIENTEDSHAPE3D = 28;
076:            static final int VIEWSPECIFICGROUP = 29;
077:            static final int NUMNODES = 29;
078:
079:            // traverse flags
080:            static final int CONTAINS_VIEWPLATFORM = 0x1;
081:
082:            /**
083:             * The universe that we are in
084:             */
085:            VirtualUniverse universe = null;
086:
087:            /** 
088:             * The locale that this node is attatched to.  This is only non-null
089:             * if this instance is directly linked into a locale.
090:             */
091:            Locale locale = null;
092:
093:            /**
094:             * The node's parent.
095:             */
096:            NodeRetained parent = null;
097:
098:            /**
099:             * The node's internal identifier.
100:             */
101:            String nodeId = null;
102:
103:            /**
104:             * An int that represents the nodes type.  Used for quick if tests 
105:             * in the traverser.
106:             */
107:            int nodeType;
108:
109:            // This keeps track of how many times this Node is refernced, refCount > 1
110:            // if node is in a shared group
111:            int refCount = 0;
112:
113:            /**
114:             * This is the index for the child, as seen by its parent.
115:             */
116:            int childIndex = -1;
117:
118:            /**
119:             * This boolean is true when the node is in a sharedGroup
120:             */
121:            boolean inSharedGroup = false;
122:
123:            /**
124:             * This indicates if the node is pickable. If this node is not
125:             * pickable then neither are any children
126:             */
127:            boolean pickable = true;
128:
129:            /**
130:             * The collidable setting; see getCollidable and setCollidable.
131:             */
132:            boolean collidable = true;
133:
134:            // A list of localToVworld transforms. If inSharedGroup is false,
135:            // then only localToVworld[0][] is valid.
136:            // Note: this contains reference to the actual transforms in the
137:            //		TransformGroupRetained
138:            Transform3D localToVworld[][] = null;
139:            int localToVworldIndex[][] = null;
140:
141:            static final int LAST_LOCAL_TO_VWORLD = 0;
142:            static final int CURRENT_LOCAL_TO_VWORLD = 1;
143:
144:            // A parallel array to localToVworld.  This is the keys for 
145:            // localToVworld transforms in shared groups.
146:            HashKey localToVworldKeys[] = null;
147:
148:            /**
149:             * This boolean is true when the geometric bounds for the node is 
150:             * automatically updated 
151:             */
152:            boolean boundsAutoCompute = true;
153:
154:            // "effective" bounds in local coordinate if boundsAutoCompute == F,
155:            // used for internal operations, not used if boundsAutoCompute == T
156:            Bounds localBounds;
157:
158:            // Bounds set by the API
159:            Bounds apiBounds;
160:
161:            protected Bounds cachedBounds = null; // Cached auto compute bounds, could we use localBounds ?
162:            protected boolean validCachedBounds = false; // Fix to Issue 514
163:            /**
164:             * Each element, p, of branchGroupPaths is a list of BranchGroup from
165:             * root of the tree to this.
166:             * For BranchGroup under a non-shared group this size of
167:             * branchGroupPaths is always 1. Otherwise, the size is equal to
168:             * the number of possible paths to reach this node.
169:             * This variable is used to cached BranchGroup for fast picking. 
170:             * For non BranchGroupRetained class this is a reference to
171:             * the previous BranchGroupRetained branchGroupPaths.
172:             */
173:            ArrayList branchGroupPaths = new ArrayList(1);
174:
175:            // background node whose geometry branch contains this node 
176:            BackgroundRetained geometryBackground = null;
177:
178:            // closest parent which is a TransformGroupRetained or sharedGroupRetained
179:            GroupRetained parentTransformLink = null;
180:
181:            // closest parent which is a SwitchRetained or sharedGroupRetained
182:            GroupRetained parentSwitchLink = null;
183:
184:            // static transform if a parent transform group is merged during compile.
185:            TransformGroupRetained staticTransform = null;
186:
187:            // orderedId assigned by OrderedGroup parent
188:            Integer orderedId = null;
189:
190:            // Id use for quick search.
191:            int nnuId;
192:
193:            NodeRetained() {
194:                // Get a not necessary unique Id.
195:                nnuId = NnuIdManager.getId();
196:
197:                localBounds = new BoundingBox();
198:                ((BoundingBox) localBounds).setUpper(-1.0, -1.0, -1.0);
199:                ((BoundingBox) localBounds).setLower(1.0, 1.0, 1.0);
200:            }
201:
202:            public int getId() {
203:                return nnuId;
204:            }
205:
206:            public int equal(NnuId obj) {
207:                int keyId = obj.getId();
208:                if (nnuId < keyId) {
209:                    return -1;
210:                } else if (nnuId > keyId) {
211:                    return 1;
212:                } else { // Found it!
213:                    return 0;
214:                }
215:            }
216:
217:            Bounds getLocalBounds(Bounds bounds) {
218:                return (Bounds) bounds.clone();
219:            }
220:
221:            /**
222:             * Sets the geometric bounds of a node.
223:             * @param bounds the bounding object for the node
224:             */
225:            void setBounds(Bounds bounds) {
226:                apiBounds = bounds;
227:                if (source.isLive()) {
228:                    if (!boundsAutoCompute) {
229:                        if (bounds != null) {
230:                            localBounds = getLocalBounds(bounds);
231:                            if (staticTransform != null) {
232:                                localBounds
233:                                        .transform(staticTransform.transform);
234:                            }
235:                        } else {
236:                            if (localBounds != null) {
237:                                localBounds.set((Bounds) null);
238:                            } else {
239:                                localBounds = new BoundingBox((Bounds) null);
240:                            }
241:                        }
242:                    }
243:                } else {
244:                    if (bounds != null) {
245:                        localBounds = getLocalBounds(bounds);
246:                        if (staticTransform != null) {
247:                            localBounds.transform(staticTransform.transform);
248:                        }
249:                    } else {
250:                        if (localBounds != null) {
251:                            localBounds.set((Bounds) null);
252:                        } else {
253:                            localBounds = new BoundingBox((Bounds) null);
254:                        }
255:                    }
256:                }
257:            }
258:
259:            /**
260:             * Gets the bounding object of a node.
261:             * @return the node's bounding object
262:             */
263:            Bounds getEffectiveBounds() {
264:                Bounds b = null;
265:                if (localBounds != null && !localBounds.isEmpty()) {
266:                    b = (Bounds) localBounds.clone();
267:                    if (staticTransform != null) {
268:                        Transform3D invTransform = staticTransform
269:                                .getInvTransform();
270:                        b.transform(invTransform);
271:                    }
272:                }
273:                return b;
274:            }
275:
276:            Bounds getBounds() {
277:                return apiBounds;
278:            }
279:
280:            /**
281:             * ONLY needed for SHAPE, MORPH, and LINK node type.
282:             * Compute the combine bounds of bounds and its localBounds.
283:             */
284:            void computeCombineBounds(Bounds bounds) {
285:                // Do nothing except for Group, Shape3D, Morph, and Link node.
286:            }
287:
288:            /**
289:             * Sets the automatic calcuation of geometric bounds of a node.
290:             * @param autoCompute is a boolean value indicating if automatic calcuation 
291:             * of bounds 
292:             */
293:            void setBoundsAutoCompute(boolean autoCompute) {
294:                if (this .boundsAutoCompute == autoCompute) {
295:                    return;
296:                }
297:
298:                this .boundsAutoCompute = autoCompute;
299:                dirtyBoundsCache();
300:            }
301:
302:            /**
303:             * Gets the auto Compute flag for the geometric bounds.
304:             * @return the node's auto Compute flag for the geometric bounding object
305:             */
306:            boolean getBoundsAutoCompute() {
307:                return boundsAutoCompute;
308:            }
309:
310:            /**
311:             * Replaces the specified parent by a new parent.
312:             * @param parent the new parent
313:             */
314:            void setParent(NodeRetained parent) {
315:                this .parent = parent;
316:            }
317:
318:            /**
319:             * Returns the parent of the node.
320:             * @return the parent.
321:             */
322:            NodeRetained getParent() {
323:                return (NodeRetained) parent;
324:            }
325:
326:            // Transform the input bound by the current LocalToVWorld
327:            void transformBounds(SceneGraphPath path, Bounds bound) {
328:                if (!((NodeRetained) path.item.retained).inSharedGroup) {
329:                    bound.transform(getCurrentLocalToVworld());
330:                } else {
331:                    HashKey key = new HashKey("");
332:                    path.getHashKey(key);
333:                    bound.transform(getCurrentLocalToVworld(key));
334:                }
335:            }
336:
337:            // Note : key will get modified in this method.   
338:            private void computeLocalToVworld(NodeRetained caller,
339:                    NodeRetained nodeR, HashKey key, Transform3D l2Vw) {
340:                int i;
341:
342:                //  To handle localToVworld under a SG.
343:                if (nodeR instanceof  SharedGroupRetained) {
344:                    // Get the immediate parent's id and remove last id from key.
345:                    String nodeId = key.getLastNodeId();
346:
347:                    SharedGroupRetained sgRetained = (SharedGroupRetained) nodeR;
348:
349:                    // Search for the right parent.
350:                    for (i = 0; i < sgRetained.parents.size(); i++) {
351:
352:                        if (nodeId
353:                                .equals((String) (((NodeRetained) (sgRetained.parents
354:                                        .elementAt(i))).nodeId))) {
355:                            // Found the right link. Now traverse upward.
356:
357:                            computeLocalToVworld(caller,
358:                                    (NodeRetained) (sgRetained.parents
359:                                            .elementAt(i)), key, l2Vw);
360:                            return;
361:                        }
362:                    }
363:                    // Problem !
364:                    throw new RuntimeException(J3dI18N
365:                            .getString("NodeRetained4"));
366:                } else {
367:
368:                    NodeRetained nodeParentR = (NodeRetained) nodeR.getParent();
369:
370:                    if (nodeParentR == null) {
371:                        // Base case. It has to be a BG attached to a locale.
372:                        if (((BranchGroupRetained) (nodeR)).locale != null) {
373:                            l2Vw.setIdentity();
374:                        } else {
375:                            throw new RuntimeException(J3dI18N
376:                                    .getString("NodeRetained5"));
377:                        }
378:                    } else {
379:                        computeLocalToVworld(caller,
380:                                (NodeRetained) nodeParentR, key, l2Vw);
381:
382:                    }
383:
384:                }
385:
386:                if ((nodeR instanceof  TransformGroupRetained)
387:                        && (nodeR != caller)) {
388:                    Transform3D t1 = new Transform3D();
389:                    ((TransformGroupRetained) (nodeR)).transform
390:                            .getWithLock(t1);
391:                    l2Vw.mul(t1);
392:                } else if ((nodeR == caller) && (staticTransform != null)) {
393:                    l2Vw.mul(staticTransform.transform);
394:                }
395:
396:                return;
397:            }
398:
399:            /**
400:             * Compute the LocalToVworld of this node even though it is not live. We
401:             * assume the graph is attached at the origin of a locale
402:             */
403:            void computeNonLiveLocalToVworld(Transform3D t, Node caller) {
404:                NodeRetained n = getParent();
405:
406:                if (n == null)
407:                    t.setIdentity();
408:                else
409:                    n.computeNonLiveLocalToVworld(t, caller);
410:
411:                if (this  instanceof  TransformGroupRetained
412:                        && this .source != caller) {
413:                    Transform3D trans = new Transform3D();
414:                    ((TransformGroupRetained) this ).getTransform(trans);
415:                    t.mul(trans);
416:                }
417:
418:            }
419:
420:            /**
421:             * Get the localToVworld transform for a node.
422:             */
423:            void getLocalToVworld(Transform3D t) {
424:                if (inSharedGroup) {
425:                    throw new IllegalSharingException(J3dI18N
426:                            .getString("NodeRetained0"));
427:                }
428:
429:                // Lock the object while writing into t.
430:                if (localToVworld == null) {
431:                    t.setIdentity();
432:                } else {
433:                    computeLocalToVworld(this , this , null, t);
434:                }
435:            }
436:
437:            /**
438:             * Get the localToVworld transform for a node.
439:             */
440:            void getLocalToVworld(SceneGraphPath path, Transform3D t) {
441:                HashKey key = new HashKey("");
442:
443:                if (inSharedGroup == false) {
444:                    throw new IllegalSharingException(J3dI18N
445:                            .getString("NodeRetained1"));
446:                }
447:                path.validate(key);
448:                computeLocalToVworld(this , this , key, t);
449:
450:            }
451:
452:            /**
453:             * Get the localToVworld transform for a node
454:             */
455:            void getLocalToVworld(Transform3D t, HashKey key) {
456:                HashKey newKey = new HashKey(key);
457:                computeLocalToVworld(this , this , newKey, t);
458:            }
459:
460:            /**
461:             * Get the Locale to which the node is attached
462:             */
463:            Locale getLocale() {
464:                if (inSharedGroup) {
465:                    throw new IllegalSharingException(J3dI18N
466:                            .getString("NodeRetained0"));
467:                }
468:
469:                return locale;
470:            }
471:
472:            /**
473:             * Get the current localToVworld transform for a node
474:             */
475:            Transform3D getCurrentLocalToVworld() {
476:
477:                if (localToVworld != null) {
478:                    return localToVworld[0][localToVworldIndex[0][CURRENT_LOCAL_TO_VWORLD]];
479:                } else {
480:                    return new Transform3D();
481:                }
482:            }
483:
484:            // this method expects that localToVworld is not null
485:
486:            Transform3D getCurrentLocalToVworld(int index) {
487:                return localToVworld[index][localToVworldIndex[index][CURRENT_LOCAL_TO_VWORLD]];
488:            }
489:
490:            Transform3D getCurrentLocalToVworld(HashKey key) {
491:
492:                if (localToVworld != null) {
493:                    if (!inSharedGroup) {
494:                        return localToVworld[0][localToVworldIndex[0][CURRENT_LOCAL_TO_VWORLD]];
495:                    } else {
496:                        int i = key.equals(localToVworldKeys, 0,
497:                                localToVworldKeys.length);
498:                        if (i >= 0) {
499:                            return localToVworld[i][localToVworldIndex[i][CURRENT_LOCAL_TO_VWORLD]];
500:                        }
501:                    }
502:                }
503:                return new Transform3D();
504:            }
505:
506:            /**
507:             * Get the last localToVworld transform for a node
508:             */
509:            Transform3D getLastLocalToVworld() {
510:
511:                if (localToVworld != null) {
512:                    return localToVworld[0][localToVworldIndex[0][LAST_LOCAL_TO_VWORLD]];
513:                } else {
514:                    return new Transform3D();
515:                }
516:            }
517:
518:            Transform3D getLastLocalToVworld(int index) {
519:                return localToVworld[index][localToVworldIndex[index][LAST_LOCAL_TO_VWORLD]];
520:            }
521:
522:            Transform3D getLastLocalToVworld(HashKey key) {
523:
524:                if (localToVworld != null) {
525:                    if (!inSharedGroup) {
526:                        return localToVworld[0][localToVworldIndex[0][LAST_LOCAL_TO_VWORLD]];
527:                    } else {
528:                        int i = key.equals(localToVworldKeys, 0,
529:                                localToVworldKeys.length);
530:                        if (i >= 0) {
531:                            return localToVworld[i][localToVworldIndex[i][LAST_LOCAL_TO_VWORLD]];
532:                        }
533:                    }
534:                }
535:                return new Transform3D();
536:            }
537:
538:            // Do nothing for NodeRetained.
539:            void setAuxData(SetLiveState s, int index, int hkIndex) {
540:
541:            }
542:
543:            void setNodeData(SetLiveState s) {
544:                localToVworld = s.localToVworld;
545:                localToVworldIndex = s.localToVworldIndex;
546:                localToVworldKeys = s.localToVworldKeys;
547:
548:                // reference to the last branchGroupPaths
549:                branchGroupPaths = s.parentBranchGroupPaths;
550:
551:                parentTransformLink = s.parentTransformLink;
552:                parentSwitchLink = s.parentSwitchLink;
553:            }
554:
555:            // set pickable, recursively update cache result
556:            void setPickable(boolean pickable) {
557:                if (this .pickable == pickable)
558:                    return;
559:
560:                this .pickable = pickable;
561:
562:                if (source.isLive()) {
563:                    synchronized (universe.sceneGraphLock) {
564:                        boolean pick[];
565:                        if (!inSharedGroup) {
566:                            pick = new boolean[1];
567:                        } else {
568:                            pick = new boolean[localToVworldKeys.length];
569:                        }
570:
571:                        findPickableFlags(pick);
572:                        updatePickable(localToVworldKeys, pick);
573:                    }
574:                }
575:            }
576:
577:            void updatePickable(HashKey pickKeys[], boolean pick[]) {
578:                for (int i = 0; i < pick.length; i++) {
579:                    if (!pickable) {
580:                        pick[i] = false;
581:                    }
582:                }
583:            }
584:
585:            // get pickable
586:            boolean getPickable() {
587:                return pickable;
588:            }
589:
590:            // set collidable, recursively update cache result
591:            void setCollidable(boolean collidable) {
592:                if (this .collidable == collidable)
593:                    return;
594:
595:                this .collidable = collidable;
596:
597:                if (source.isLive()) {
598:                    synchronized (universe.sceneGraphLock) {
599:                        boolean collide[];
600:                        if (!inSharedGroup) {
601:                            collide = new boolean[1];
602:                        } else {
603:                            collide = new boolean[localToVworldKeys.length];
604:                        }
605:
606:                        findCollidableFlags(collide);
607:                        updateCollidable(localToVworldKeys, collide);
608:                    }
609:                }
610:            }
611:
612:            // get collidable
613:            boolean getCollidable() {
614:                return collidable;
615:            }
616:
617:            void updateCollidable(HashKey keys[], boolean collide[]) {
618:                for (int i = 0; i < collide.length; i++) {
619:                    if (!collidable) {
620:                        collide[i] = false;
621:                    }
622:                }
623:            }
624:
625:            /**
626:             * For the default, just pass up to parent
627:             */
628:            void notifySceneGraphChanged(boolean globalTraverse) {
629:            }
630:
631:            void recombineAbove() {
632:            }
633:
634:            synchronized void updateLocalToVworld() {
635:            }
636:
637:            void setLive(SetLiveState s) {
638:                int oldrefCount = refCount;
639:
640:                doSetLive(s);
641:                if (oldrefCount <= 0)
642:                    super .markAsLive();
643:            }
644:
645:            // The default set of setLive actions.
646:            void doSetLive(SetLiveState s) {
647:                int i;
648:                int oldrefCount = refCount;
649:
650:                refCount += s.refCount;
651:                if (!(locale == null || universe == s.universe))
652:                    throw new IllegalSharingException(J3dI18N
653:                            .getString("NodeRetained3"));
654:                if (s.locale == null)
655:                    System.err.println("NodeRetained.setLive() locale is null");
656:
657:                locale = s.locale;
658:                inSharedGroup = s.inSharedGroup;
659:
660:                if (oldrefCount <= 0) {
661:                    if (listIdx == null) {
662:                        universe = s.universe;
663:                    } else {
664:                        // sync with getIdxUsed()
665:                        if (s.universe != universe) {
666:                            synchronized (this ) {
667:                                universe = s.universe;
668:                                incIdxUsed();
669:                            }
670:                        }
671:                    }
672:                }
673:                s.universe.numNodes++;
674:
675:                //  pickable & collidable array have the same length
676:                for (i = 0; i < s.pickable.length; i++) {
677:                    if (!pickable) {
678:                        s.pickable[i] = false;
679:                    }
680:                    if (!collidable) {
681:                        s.collidable[i] = false;
682:                    }
683:                }
684:
685:                if (oldrefCount <= 0)
686:                    super .doSetLive(s);
687:
688:                if (inBackgroundGroup) {
689:                    geometryBackground = s.geometryBackground;
690:                }
691:
692:                setNodeData(s);
693:            }
694:
695:            /**
696:             * remove the localToVworld transform for this node.
697:             */
698:            void removeNodeData(SetLiveState s) {
699:
700:                if (refCount <= 0) {
701:                    localToVworld = null;
702:                    localToVworldIndex = null;
703:                    localToVworldKeys = null;
704:                    // restore to default and avoid calling clear() 
705:                    // that may clear parent reference branchGroupPaths
706:                    branchGroupPaths = new ArrayList(1);
707:                    parentTransformLink = null;
708:                    parentSwitchLink = null;
709:                } else {
710:                    // Set it back to its parent localToVworld data. This is b/c the parent has
711:                    // changed it localToVworld data arrays.
712:                    localToVworld = s.localToVworld;
713:                    localToVworldIndex = s.localToVworldIndex;
714:                    localToVworldKeys = s.localToVworldKeys;
715:
716:                    // Reference of parent branchGroupPaths will not change
717:
718:                    // no need to reset parentSwitchLink or parentTransformLink 
719:                    // because there are not per path data
720:                }
721:
722:            }
723:
724:            // The default set of clearLive actions
725:            void clearLive(SetLiveState s) {
726:
727:                refCount -= s.refCount;
728:
729:                if (refCount <= 0) {
730:                    super .clearLive();
731:
732:                    // don't remove the nodeId unless there are no more references
733:                    if (nodeId != null) {
734:                        universe.nodeIdFreeList.addElement(nodeId);
735:                        nodeId = null;
736:                    }
737:                }
738:
739:                universe.numNodes--;
740:
741:                removeNodeData(s);
742:
743:                if (refCount <= 0) {
744:                    locale = null;
745:                    geometryBackground = null;
746:                }
747:            }
748:
749:            // search up the parent to determine if this node is pickable
750:            void findPickableFlags(boolean pick[]) {
751:                NodeRetained nodeR = this ;
752:
753:                if (!inSharedGroup) {
754:                    pick[0] = true;
755:                    nodeR = nodeR.parent;
756:                    while (nodeR != null) {
757:                        if (!nodeR.pickable) {
758:                            pick[0] = false;
759:                            break;
760:                        }
761:                        nodeR = nodeR.parent;
762:                    }
763:                } else {
764:                    HashKey key;
765:                    for (int i = 0; i < pick.length; i++) {
766:                        nodeR = this ;
767:                        pick[i] = true;
768:                        key = new HashKey(localToVworldKeys[i]);
769:
770:                        do {
771:                            if (nodeR instanceof  SharedGroupRetained) {
772:                                String nodeId = key.getLastNodeId();
773:                                Vector parents = ((SharedGroupRetained) nodeR).parents;
774:                                int sz = parents.size();
775:                                NodeRetained prevNodeR = nodeR;
776:                                for (int j = 0; j < sz; j++) {
777:                                    NodeRetained linkR = (NodeRetained) parents
778:                                            .elementAt(j);
779:                                    if (linkR.nodeId.equals(nodeId)) {
780:                                        nodeR = linkR;
781:                                        break;
782:                                    }
783:                                }
784:                                if (prevNodeR == nodeR) {
785:                                    // branch is already detach
786:                                    return;
787:                                }
788:                            } else {
789:                                nodeR = nodeR.parent;
790:                            }
791:                            if (nodeR == null)
792:                                break;
793:                            if (!nodeR.pickable) {
794:                                pick[i] = false;
795:                                break;
796:                            }
797:                        } while (true);
798:                    }
799:                }
800:            }
801:
802:            // search up the parent to determine if this node is collidable
803:            void findCollidableFlags(boolean collide[]) {
804:                NodeRetained nodeR = this ;
805:
806:                if (!inSharedGroup) {
807:                    collide[0] = true;
808:                    nodeR = nodeR.parent;
809:                    while (nodeR != null) {
810:                        if (!nodeR.collidable) {
811:                            collide[0] = false;
812:                            break;
813:                        }
814:                        nodeR = nodeR.parent;
815:                    }
816:                } else {
817:                    HashKey key;
818:                    for (int i = 0; i < collide.length; i++) {
819:                        nodeR = this ;
820:                        collide[i] = true;
821:                        key = new HashKey(localToVworldKeys[i]);
822:
823:                        do {
824:                            if (nodeR instanceof  SharedGroupRetained) {
825:                                String nodeId = key.getLastNodeId();
826:                                Vector parents = ((SharedGroupRetained) nodeR).parents;
827:                                int sz = parents.size();
828:                                NodeRetained prevNodeR = nodeR;
829:                                for (int j = 0; j < sz; j++) {
830:                                    NodeRetained linkR = (NodeRetained) parents
831:                                            .elementAt(j);
832:                                    if (linkR.nodeId.equals(nodeId)) {
833:                                        nodeR = linkR;
834:                                        break;
835:                                    }
836:                                }
837:                                if (nodeR == prevNodeR) {
838:                                    return;
839:                                }
840:                            } else {
841:                                nodeR = nodeR.parent;
842:                            }
843:                            if (nodeR == null)
844:                                break;
845:                            if (!nodeR.collidable) {
846:                                collide[i] = false;
847:                                break;
848:                            }
849:                        } while (true);
850:                    }
851:                }
852:            }
853:
854:            void findTransformLevels(int transformLevels[]) {
855:                NodeRetained nodeR = this ;
856:                TransformGroupRetained tg;
857:
858:                if (!inSharedGroup) {
859:                    transformLevels[0] = -1;
860:                    while (nodeR != null) {
861:                        if (nodeR.nodeType == NodeRetained.TRANSFORMGROUP) {
862:                            tg = (TransformGroupRetained) nodeR;
863:                            transformLevels[0] = tg.transformLevels[0];
864:                            break;
865:                        }
866:                        nodeR = nodeR.parent;
867:                    }
868:                } else {
869:                    HashKey key;
870:                    int i, j;
871:                    for (i = 0; i < transformLevels.length; i++) {
872:                        nodeR = this ;
873:                        transformLevels[i] = -1;
874:                        key = new HashKey(localToVworldKeys[i]);
875:
876:                        do {
877:                            if (nodeR == null)
878:                                break;
879:                            else if (nodeR instanceof  SharedGroupRetained) {
880:                                // note that key is truncated after getLastNodeId
881:                                String nodeId = key.getLastNodeId();
882:                                Vector parents = ((SharedGroupRetained) nodeR).parents;
883:                                int sz = parents.size();
884:                                NodeRetained prevNodeR = nodeR;
885:                                for (j = 0; j < sz; j++) {
886:                                    NodeRetained linkR = (NodeRetained) parents
887:                                            .elementAt(j);
888:                                    if (linkR.nodeId.equals(nodeId)) {
889:                                        nodeR = linkR;
890:                                        break;
891:                                    }
892:                                }
893:                                if (prevNodeR == nodeR) {
894:                                    // branch is already detach
895:                                    return;
896:                                }
897:                            } else if (nodeR.nodeType == NodeRetained.TRANSFORMGROUP) {
898:                                tg = (TransformGroupRetained) nodeR;
899:                                if (tg.inSharedGroup) {
900:
901:                                    j = key.equals(tg.localToVworldKeys, 0,
902:                                            tg.localToVworldKeys.length);
903:
904:                                    transformLevels[i] = tg.transformLevels[j];
905:                                } else {
906:                                    transformLevels[i] = tg.transformLevels[0];
907:                                }
908:                                break;
909:                            }
910:
911:                            nodeR = nodeR.parent;
912:                        } while (true);
913:                    }
914:                }
915:            }
916:
917:            boolean isStatic() {
918:                if (source.getCapability(Node.ALLOW_LOCAL_TO_VWORLD_READ)
919:                        || source.getCapability(Node.ALLOW_PARENT_READ)
920:                        || source.getCapability(Node.ENABLE_PICK_REPORTING)
921:                        || source
922:                                .getCapability(Node.ENABLE_COLLISION_REPORTING)
923:                        || source.getCapability(Node.ALLOW_BOUNDS_READ)
924:                        || source.getCapability(Node.ALLOW_BOUNDS_WRITE)
925:                        || source.getCapability(Node.ALLOW_PICKABLE_READ)
926:                        || source.getCapability(Node.ALLOW_PICKABLE_WRITE)
927:                        || source.getCapability(Node.ALLOW_COLLIDABLE_READ)
928:                        || source.getCapability(Node.ALLOW_COLLIDABLE_WRITE)
929:                        || source
930:                                .getCapability(Node.ALLOW_AUTO_COMPUTE_BOUNDS_READ)
931:                        || source
932:                                .getCapability(Node.ALLOW_AUTO_COMPUTE_BOUNDS_WRITE)) {
933:                    return false;
934:                }
935:                return true;
936:            }
937:
938:            void merge(CompileState compState) {
939:                staticTransform = compState.staticTransform;
940:                if (compState.parentGroup != null) {
941:                    compState.parentGroup.compiledChildrenList.add(this );
942:                }
943:                parent = compState.parentGroup;
944:                if (staticTransform != null) {
945:                    mergeTransform(staticTransform);
946:                }
947:            }
948:
949:            void mergeTransform(TransformGroupRetained xform) {
950:                if (localBounds != null) {
951:                    localBounds.transform(xform.transform);
952:                }
953:            }
954:
955:            int[] processViewSpecificInfo(int mode, HashKey k, View v,
956:                    ArrayList vsgList, int[] keyList, ArrayList leafList) {
957:                return keyList;
958:
959:            }
960:
961:            VirtualUniverse getVirtualUniverse() {
962:                return universe;
963:            }
964:
965:            void searchGeometryAtoms(UnorderList list) {
966:            }
967:
968:            /** 
969:             * Make the boundsCache of this node and all its parents dirty
970:             */
971:            void dirtyBoundsCache() {
972:                // Possible optimisation is to not traverse up the tree
973:                // if the cachedBounds==null. However this is not the case
974:                // if the node is the child of a SharedGroup
975:                if (VirtualUniverse.mc.cacheAutoComputedBounds) {
976:                    // Issue 514 : NPE in Wonderland : triggered in cached bounds computation
977:                    validCachedBounds = false;
978:                    if (parent != null) {
979:                        parent.dirtyBoundsCache();
980:                    }
981:                }
982:            }
983:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.