Source Code Cross Referenced for Billboard.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: Billboard.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.6 $
028:         * $Date: 2008/02/28 20:17:19 $
029:         * $State: Exp $
030:         */
031:
032:        package javax.media.j3d;
033:
034:        import java.util.Enumeration;
035:        import javax.vecmath.Point3f;
036:        import javax.vecmath.Point3d;
037:        import javax.vecmath.Vector3d;
038:        import javax.vecmath.Vector3f;
039:        import javax.vecmath.AxisAngle4d;
040:
041:        /**
042:         * The Billboard behavior node operates on the TransformGroup node
043:         * to cause the local +z axis of the TransformGroup to point at
044:         * the viewer's eye position. This is done  regardless of the transforms 
045:         * above the specified TransformGroup  node in the scene graph.
046:         *
047:         * <p>
048:         * If the alignment mode is ROTATE_ABOUT_AXIS, the rotation will be
049:         * around the specified axis.  If the alignment mode is
050:         * ROTATE_ABOUT_POINT, the rotation will be about the specified
051:         * point, with an additional rotation to align the +y axis of the
052:         * TransformGroup with the +y axis in the View.
053:         *
054:         * <p>
055:         * Note that in a multiple View system, the alignment is done to
056:         * the primary View only.
057:         *
058:         * <p>
059:         * Billboard nodes are ideal for drawing screen aligned-text or
060:         * for drawing roughly-symmetrical objects.  A typical use might
061:         * consist of a quadrilateral that contains a texture of a tree.
062:         *
063:         * @see OrientedShape3D
064:         */
065:        public class Billboard extends Behavior {
066:            /**
067:             * Specifies that rotation should be about the specified axis.
068:             */
069:            public static final int ROTATE_ABOUT_AXIS = 0;
070:
071:            /**
072:             * Specifies that rotation should be about the specified point and
073:             * that the children's Y-axis should match the view object's Y-axis.
074:             */
075:            public static final int ROTATE_ABOUT_POINT = 1;
076:
077:            // Wakeup condition for Billboard node
078:            WakeupOnElapsedFrames wakeupFrame = new WakeupOnElapsedFrames(0,
079:                    true);
080:
081:            // Specifies the billboard's mode of operation. One of ROTATE_AXIAL,
082:            // ROTATE_POINT_VIEW, or ROTATE_POINT_WORLD.
083:            int mode = ROTATE_ABOUT_AXIS;
084:
085:            // Axis about which to rotate.
086:            Vector3f axis = new Vector3f(0.0f, 1.0f, 0.0f);
087:            Point3f rotationPoint = new Point3f(0.0f, 0.0f, 1.0f);
088:            private Vector3d nAxis = new Vector3d(0.0, 1.0, 0.0); // normalized axis
089:
090:            // TransformGroup to operate on.
091:            TransformGroup tg = null;
092:
093:            // reused temporaries
094:            private Point3d viewPosition = new Point3d();
095:            private Point3d yUpPoint = new Point3d();
096:
097:            private Vector3d eyeVec = new Vector3d();
098:            private Vector3d yUp = new Vector3d();
099:            private Vector3d zAxis = new Vector3d();
100:            private Vector3d yAxis = new Vector3d();
101:            private Vector3d vector = new Vector3d();
102:
103:            private AxisAngle4d aa = new AxisAngle4d();
104:
105:            static final double EPSILON = 1.0e-6;
106:
107:            /**
108:             * Constructs a Billboard node with default parameters.
109:             * The default values are as follows:
110:             * <ul>
111:             * alignment mode : ROTATE_ABOUT_AXIS<br>
112:             * alignment axis : Y-axis (0,1,0)<br>
113:             * rotation point : (0,0,1)<br>
114:             * target transform group: null<br>
115:             *</ul>
116:             */
117:            public Billboard() {
118:                nAxis.x = 0.0;
119:                nAxis.y = 1.0;
120:                nAxis.z = 0.0;
121:            }
122:
123:            /**
124:             * Constructs a Billboard node with default parameters that operates
125:             * on the specified TransformGroup node.
126:             * The default alignment mode is ROTATE_ABOUT_AXIS rotation with the axis
127:             * pointing along the Y axis.
128:             * @param tg the TransformGroup node that this Billboard
129:             * node operates upon
130:             */
131:            public Billboard(TransformGroup tg) {
132:                this .tg = tg;
133:                nAxis.x = 0.0;
134:                nAxis.y = 1.0;
135:                nAxis.z = 0.0;
136:
137:            }
138:
139:            /**
140:             * Constructs a Billboard node with the specified axis and mode
141:             * that operates on the specified TransformGroup node.
142:             * The specified axis must not be parallel to the <i>Z</i>
143:             * axis--(0,0,<i>z</i>) for any value of <i>z</i>.  It is not
144:             * possible for the +<i>Z</i> axis to point at the viewer's eye
145:             * position by rotating about itself.  The target transform will
146:             * be set to the identity if the axis is (0,0,<i>z</i>).
147:             *
148:             * @param tg the TransformGroup node that this Billboard
149:             * node operates upon
150:             * @param mode alignment mode, one of ROTATE_ABOUT_AXIS or 
151:             * ROTATE_ABOUT_POINT
152:             * @param axis the ray about which the billboard rotates
153:             */
154:            public Billboard(TransformGroup tg, int mode, Vector3f axis) {
155:                this .tg = tg;
156:                this .mode = mode;
157:                this .axis.set(axis);
158:                double invMag;
159:                invMag = 1.0 / Math.sqrt(axis.x * axis.x + axis.y * axis.y
160:                        + axis.z * axis.z);
161:                nAxis.x = (double) axis.x * invMag;
162:                nAxis.y = (double) axis.y * invMag;
163:                nAxis.z = (double) axis.z * invMag;
164:
165:            }
166:
167:            /**
168:             * Constructs a Billboard node with the specified rotation point and mode
169:             * that operates on the specified TransformGroup node.
170:             * @param tg the TransformGroup node that this Billboard
171:             * node operates upon
172:             * @param mode alignment mode, one of ROTATE_ABOUT_AXIS or 
173:             * ROTATE_ABOUT_POINT
174:             * @param point the position about which the billboard rotates
175:             */
176:            public Billboard(TransformGroup tg, int mode, Point3f point) {
177:                this .tg = tg;
178:                this .mode = mode;
179:                this .rotationPoint.set(point);
180:            }
181:
182:            /**
183:             * Sets the alignment mode.
184:             * @param mode one of: ROTATE_ABOUT_AXIS or ROTATE_ABOUT_POINT
185:             */
186:            public void setAlignmentMode(int mode) {
187:                this .mode = mode;
188:            }
189:
190:            /**
191:             * Gets the alignment mode.
192:             * @return one of: ROTATE_ABOUT_AXIS or ROTATE_ABOUT_POINT
193:             */
194:            public int getAlignmentMode() {
195:                return this .mode;
196:            }
197:
198:            /**
199:             * Sets the alignment axis.
200:             * The specified axis must not be parallel to the <i>Z</i>
201:             * axis--(0,0,<i>z</i>) for any value of <i>z</i>.  It is not
202:             * possible for the +<i>Z</i> axis to point at the viewer's eye
203:             * position by rotating about itself.  The target transform will
204:             * be set to the identity if the axis is (0,0,<i>z</i>).
205:             *
206:             * @param axis the ray about which the billboard rotates
207:             */
208:            public void setAlignmentAxis(Vector3f axis) {
209:                this .axis.set(axis);
210:                double invMag;
211:                invMag = 1.0 / Math.sqrt(axis.x * axis.x + axis.y * axis.y
212:                        + axis.z * axis.z);
213:                nAxis.x = (double) axis.x * invMag;
214:                nAxis.y = (double) axis.y * invMag;
215:                nAxis.z = (double) axis.z * invMag;
216:
217:            }
218:
219:            /**
220:             * Sets the alignment axis.
221:             * The specified axis must not be parallel to the <i>Z</i>
222:             * axis--(0,0,<i>z</i>) for any value of <i>z</i>.  It is not
223:             * possible for the +<i>Z</i> axis to point at the viewer's eye
224:             * position by rotating about itself.  The target transform will
225:             * be set to the identity if the axis is (0,0,<i>z</i>).
226:             *
227:             * @param x the x component of the ray about which the billboard rotates
228:             * @param y the y component of the ray about which the billboard rotates
229:             * @param z the z component of the ray about which the billboard rotates
230:             */
231:            public void setAlignmentAxis(float x, float y, float z) {
232:                this .axis.set(x, y, z);
233:                this .axis.set(axis);
234:                double invMag;
235:                invMag = 1.0 / Math.sqrt(axis.x * axis.x + axis.y * axis.y
236:                        + axis.z * axis.z);
237:                nAxis.x = (double) axis.x * invMag;
238:                nAxis.y = (double) axis.y * invMag;
239:                nAxis.z = (double) axis.z * invMag;
240:
241:            }
242:
243:            /**
244:             * Gets the alignment axis and sets the parameter to this value.
245:             * @param axis the vector that will contain the ray about which
246:             * the billboard rotates
247:             */
248:            public void getAlignmentAxis(Vector3f axis) {
249:                axis.set(this .axis);
250:            }
251:
252:            /**
253:             * Sets the rotation point.
254:             * @param point the point about which the billboard rotates
255:             */
256:            public void setRotationPoint(Point3f point) {
257:                this .rotationPoint.set(point);
258:            }
259:
260:            /**
261:             * Sets the rotation point.
262:             * @param x the x component of the point about which the billboard rotates
263:             * @param y the y component of the point about which the billboard rotates
264:             * @param z the z component of the point about which the billboard rotates
265:             */
266:            public void setRotationPoint(float x, float y, float z) {
267:                this .rotationPoint.set(x, y, z);
268:            }
269:
270:            /**
271:             * Gets the rotation point and sets the parameter to this value.
272:             * @param point the position the Billboard rotates about
273:             */
274:            public void getRotationPoint(Point3f point) {
275:                point.set(this .rotationPoint);
276:            }
277:
278:            /**
279:             * Sets the tranformGroup for this Billboard object.
280:             * @param tg the transformGroup node which replaces the current
281:             * transformGroup node for this Billboard
282:             */
283:            public void setTarget(TransformGroup tg) {
284:                this .tg = tg;
285:            }
286:
287:            /**
288:             *  Returns a copy of the transformGroup associated with this Billboard.
289:             *  @return the TranformGroup for this Billboard 
290:             */
291:            public TransformGroup getTarget() {
292:                return (tg);
293:            }
294:
295:            /**
296:             * Initialize method that sets up initial wakeup criteria.
297:             */
298:            public void initialize() {
299:                // Insert wakeup condition into queue
300:                wakeupOn(wakeupFrame);
301:            }
302:
303:            /**
304:             * Process stimulus method that computes appropriate transform.
305:             * @param criteria an enumeration of the criteria that caused the
306:             * stimulus
307:             */
308:            public void processStimulus(Enumeration criteria) {
309:                double angle = 0.0;
310:                double mag, sign;
311:                double tx, ty, tz;
312:
313:                if (tg == null) {
314:                    wakeupOn(wakeupFrame);
315:                    return;
316:                }
317:
318:                //  get viewplatforms's location in virutal world
319:                View v = this .getView();
320:                if (v == null) {
321:                    wakeupOn(wakeupFrame);
322:                    return;
323:                }
324:                Canvas3D canvas = (Canvas3D) v.getCanvas3D(0);
325:                boolean status;
326:
327:                Transform3D xform = new Transform3D();
328:                Transform3D bbXform = new Transform3D();
329:                Transform3D prevTransform = new Transform3D();
330:
331:                ((TransformGroupRetained) tg.retained)
332:                        .getTransform(prevTransform);
333:
334:                if (mode == ROTATE_ABOUT_AXIS) { // rotate about axis
335:                    canvas.getCenterEyeInImagePlate(viewPosition);
336:                    canvas.getImagePlateToVworld(xform); // xform is imagePlateToLocal
337:                    xform.transform(viewPosition);
338:
339:                    // get billboard's transform
340:
341:                    // since we are using getTransform() to get the transform
342:                    // of the transformGroup, we need to use getLocalToVworld()
343:                    // to get the localToVworld which includes the static transform
344:
345:                    ((NodeRetained) tg.retained).getLocalToVworld(xform);
346:
347:                    xform.invert(); // xform is now vWorldToLocal
348:
349:                    // transform the eye position into the billboard's coordinate system
350:                    xform.transform(viewPosition);
351:
352:                    // eyeVec is a vector from the local origin to the eye pt in local
353:                    eyeVec.set(viewPosition);
354:                    eyeVec.normalize();
355:
356:                    // project the eye into the rotation plane
357:                    status = projectToPlane(eyeVec, nAxis);
358:
359:                    // If the first project was successful .. 
360:                    if (status) {
361:                        // project the z axis into the rotation plane
362:                        zAxis.x = 0.0;
363:                        zAxis.y = 0.0;
364:                        zAxis.z = 1.0;
365:                        status = projectToPlane(zAxis, nAxis);
366:                    }
367:
368:                    ((TransformGroupRetained) tg.retained).getTransform(xform);
369:                    if (status) {
370:                        // compute the sign of the angle by checking if the cross product 
371:                        // of the two vectors is in the same direction as the normal axis
372:                        vector.cross(eyeVec, zAxis);
373:                        if (vector.dot(nAxis) > 0.0) {
374:                            sign = 1.0;
375:                        } else {
376:                            sign = -1.0;
377:                        }
378:
379:                        // compute the angle between the projected eye vector and the 
380:                        // projected z
381:                        double dot = eyeVec.dot(zAxis);
382:
383:                        if (dot > 1.0f) {
384:                            dot = 1.0f;
385:                        } else if (dot < -1.0f) {
386:                            dot = -1.0f;
387:                        }
388:
389:                        angle = sign * Math.acos(dot);
390:
391:                        // use -angle because xform is to *undo* rotation by angle
392:                        aa.x = nAxis.x;
393:                        aa.y = nAxis.y;
394:                        aa.z = nAxis.z;
395:                        aa.angle = -angle;
396:                        bbXform.set(aa);
397:                        if (!prevTransform.epsilonEquals(bbXform, EPSILON)) {
398:                            // Optimization for Billboard since it use passive
399:                            // behavior
400:                            // set the transform on the Billboard TG
401:                            tg.setTransform(bbXform);
402:                        }
403:                    } else {
404:                        bbXform.setIdentity();
405:                        if (!prevTransform.epsilonEquals(bbXform, EPSILON)) {
406:                            tg.setTransform(bbXform);
407:                        }
408:                    }
409:
410:                } else { // rotate about point
411:                    // Need to rotate Z axis to point to eye, and Y axis to be 
412:                    // parallel to view platform Y axis, rotating around rotation pt 
413:
414:                    Transform3D zRotate = new Transform3D();
415:
416:                    // get the eye point 
417:                    canvas.getCenterEyeInImagePlate(viewPosition);
418:
419:                    // derive the yUp point
420:                    yUpPoint.set(viewPosition);
421:                    yUpPoint.y += 0.01; // one cm in Physical space
422:
423:                    // transform the points to the Billboard's space
424:                    canvas.getImagePlateToVworld(xform); // xform is ImagePlateToVworld
425:
426:                    xform.transform(viewPosition);
427:                    xform.transform(yUpPoint);
428:
429:                    // get billboard's transform
430:
431:                    // since we are using getTransform() to get the transform
432:                    // of the transformGroup, we need to use getLocalToVworld()
433:                    // to get the localToVworld which includes the static transform
434:
435:                    ((NodeRetained) tg.retained).getLocalToVworld(xform);
436:
437:                    xform.invert(); // xform is vWorldToLocal
438:
439:                    // transfom points to local coord sys
440:                    xform.transform(viewPosition);
441:                    xform.transform(yUpPoint);
442:
443:                    // Make a vector from viewPostion to 0,0,0 in the BB coord sys
444:                    eyeVec.set(viewPosition);
445:                    eyeVec.normalize();
446:
447:                    // create a yUp vector
448:                    yUp.set(yUpPoint);
449:                    yUp.sub(viewPosition);
450:                    yUp.normalize();
451:
452:                    // find the plane to rotate z
453:                    zAxis.x = 0.0;
454:                    zAxis.y = 0.0;
455:                    zAxis.z = 1.0;
456:
457:                    // rotation axis is cross product of eyeVec and zAxis
458:                    vector.cross(eyeVec, zAxis); // vector is cross product
459:
460:                    // if cross product is non-zero, vector is rotation axis and 
461:                    // rotation angle is acos(eyeVec.dot(zAxis)));
462:                    double length = vector.length();
463:
464:                    if (length > 0.0001) {
465:                        double dot = eyeVec.dot(zAxis);
466:
467:                        if (dot > 1.0f) {
468:                            dot = 1.0f;
469:                        } else if (dot < -1.0f) {
470:                            dot = -1.0f;
471:                        }
472:
473:                        angle = Math.acos(dot);
474:                        aa.x = vector.x;
475:                        aa.y = vector.y;
476:                        aa.z = vector.z;
477:                        aa.angle = -angle;
478:                        zRotate.set(aa);
479:                    } else {
480:                        // no rotation needed, set to identity (scale = 1.0)
481:                        zRotate.set(1.0);
482:                    }
483:
484:                    // Transform the yAxis by zRotate
485:                    yAxis.x = 0.0;
486:                    yAxis.y = 1.0;
487:                    yAxis.z = 0.0;
488:                    zRotate.transform(yAxis);
489:
490:                    // project the yAxis onto the plane perp to the eyeVec 
491:                    status = projectToPlane(yAxis, eyeVec);
492:
493:                    if (status) {
494:                        // project the yUp onto the plane perp to the eyeVec 
495:                        status = projectToPlane(yUp, eyeVec);
496:                    }
497:
498:                    ((TransformGroupRetained) tg.retained).getTransform(xform);
499:                    if (status) {
500:                        // rotation angle is acos(yUp.dot(yAxis));
501:                        double dot = yUp.dot(yAxis);
502:
503:                        // Fix numerical error, otherwise acos return NULL
504:                        if (dot > 1.0f) {
505:                            dot = 1.0f;
506:                        } else if (dot < -1.0f) {
507:                            dot = -1.0f;
508:                        }
509:
510:                        angle = Math.acos(dot);
511:
512:                        // check the sign by looking a the cross product vs the eyeVec 
513:                        vector.cross(yUp, yAxis); // vector is cross product
514:                        if (eyeVec.dot(vector) < 0) {
515:                            angle *= -1;
516:                        }
517:                        aa.x = eyeVec.x;
518:                        aa.y = eyeVec.y;
519:                        aa.z = eyeVec.z;
520:                        aa.angle = -angle;
521:
522:                        xform.set(aa); // xform is now yRotate
523:
524:                        // rotate around the rotation point
525:                        vector.x = rotationPoint.x;
526:                        vector.y = rotationPoint.y;
527:                        vector.z = rotationPoint.z; // vector to translate to RP
528:                        bbXform.set(vector); // translate to RP
529:                        bbXform.mul(xform); // yRotate
530:                        bbXform.mul(zRotate); // zRotate
531:                        vector.scale(-1.0); // vector to translate back
532:                        xform.set(vector); // xform to translate back 
533:                        bbXform.mul(xform); // translate back
534:
535:                        if (!prevTransform.epsilonEquals(bbXform, EPSILON)) {
536:                            // set the transform on the Billboard TG
537:                            tg.setTransform(bbXform);
538:                        }
539:                    } else {
540:                        bbXform.setIdentity();
541:                        if (!prevTransform.epsilonEquals(bbXform, EPSILON)) {
542:                            tg.setTransform(bbXform);
543:                        }
544:                    }
545:                }
546:
547:                // Insert wakeup condition into queue
548:                wakeupOn(wakeupFrame);
549:            }
550:
551:            private boolean projectToPlane(Vector3d projVec, Vector3d planeVec) {
552:                double dis = planeVec.dot(projVec);
553:                projVec.x = projVec.x - planeVec.x * dis;
554:                projVec.y = projVec.y - planeVec.y * dis;
555:                projVec.z = projVec.z - planeVec.z * dis;
556:
557:                double length = projVec.length();
558:
559:                if (length < EPSILON) {
560:                    return false;
561:                }
562:                projVec.scale(1 / length);
563:                return true;
564:            }
565:
566:            /**
567:             * Creates a new instance of the node.  This routine is called
568:             * by <code>cloneTree</code> to duplicate the current node.
569:             * @param forceDuplicate when set to <code>true</code>, causes the
570:             *  <code>duplicateOnCloneTree</code> flag to be ignored.  When
571:             *  <code>false</code>, the value of each node's
572:             *  <code>duplicateOnCloneTree</code> variable determines whether
573:             *  NodeComponent data is duplicated or copied.
574:             *
575:             * @see Node#cloneTree
576:             * @see Node#cloneNode
577:             * @see Node#duplicateNode
578:             * @see NodeComponent#setDuplicateOnCloneTree
579:             */
580:            public Node cloneNode(boolean forceDuplicate) {
581:                Billboard b = new Billboard();
582:                b.duplicateNode(this , forceDuplicate);
583:                return b;
584:            }
585:
586:            /**
587:             * Copies all Billboard information from
588:             * <code>originalNode</code> into
589:             * the current node.  This method is called from the
590:             * <code>cloneNode</code> method which is, in turn, called by the
591:             * <code>cloneTree</code> method.<P> 
592:             *
593:             * @param originalNode the original node to duplicate.
594:             * @param forceDuplicate when set to <code>true</code>, causes the
595:             *  <code>duplicateOnCloneTree</code> flag to be ignored.  When
596:             *  <code>false</code>, the value of each node's
597:             *  <code>duplicateOnCloneTree</code> variable determines whether
598:             *  NodeComponent data is duplicated or copied.
599:             *
600:             * @exception RestrictedAccessException if this object is part of a live
601:             *  or compiled scenegraph.
602:             *
603:             * @see Node#duplicateNode
604:             * @see Node#cloneTree
605:             * @see NodeComponent#setDuplicateOnCloneTree
606:             */
607:            void duplicateAttributes(Node originalNode, boolean forceDuplicate) {
608:                super .duplicateAttributes(originalNode, forceDuplicate);
609:
610:                Billboard bb = (Billboard) originalNode;
611:
612:                setAlignmentMode(bb.getAlignmentMode());
613:
614:                Vector3f v = new Vector3f();
615:                bb.getAlignmentAxis(v);
616:                setAlignmentAxis(v);
617:
618:                Point3f p = new Point3f();
619:                bb.getRotationPoint(p);
620:                setRotationPoint(p);
621:
622:                // this will be updated by updateNodeReferences() later
623:                setTarget(bb.getTarget());
624:            }
625:
626:            /**
627:             * Callback used to allow a node to check if any scene graph objects
628:             * referenced
629:             * by that node have been duplicated via a call to <code>cloneTree</code>.
630:             * This method is called by <code>cloneTree</code> after all nodes in
631:             * the sub-graph have been duplicated. The cloned Leaf node's method
632:             * will be called and the Leaf node can then look up any object references
633:             * by using the <code>getNewObjectReference</code> method found in the
634:             * <code>NodeReferenceTable</code> object.  If a match is found, a
635:             * reference to the corresponding object in the newly cloned sub-graph
636:             * is returned.  If no corresponding reference is found, either a
637:             * DanglingReferenceException is thrown or a reference to the original
638:             * object is returned depending on the value of the
639:             * <code>allowDanglingReferences</code> parameter passed in the
640:             * <code>cloneTree</code> call.
641:             * <p>
642:             * NOTE: Applications should <i>not</i> call this method directly.
643:             * It should only be called by the cloneTree method.
644:             *
645:             * @param referenceTable a NodeReferenceTableObject that contains the
646:             *  <code>getNewObjectReference</code> method needed to search for
647:             *  new object instances.
648:             * @see NodeReferenceTable
649:             * @see Node#cloneTree
650:             * @see DanglingReferenceException
651:             */
652:            public void updateNodeReferences(NodeReferenceTable referenceTable) {
653:                super .updateNodeReferences(referenceTable);
654:
655:                // check for new TransformGroup
656:                TransformGroup g = getTarget();
657:                if (g != null) {
658:                    setTarget((TransformGroup) referenceTable
659:                            .getNewObjectReference(g));
660:                }
661:            }
662:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.