001: /*
002: * $RCSfile: Viewpoint.java,v $
003: *
004: * @(#)Viewpoint.java 1.54 99/03/11 09:48:15
005: *
006: * Copyright (c) 1996-1998 Sun Microsystems, Inc. All Rights Reserved.
007: *
008: * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
009: * modify and redistribute this software in source and binary code form,
010: * provided that i) this copyright notice and license appear on all copies of
011: * the software; and ii) Licensee does not utilize the software in a manner
012: * which is disparaging to Sun.
013: *
014: * This software is provided "AS IS," without a warranty of any kind. ALL
015: * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
016: * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
017: * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
018: * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
019: * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
020: * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
021: * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
022: * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
023: * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
024: * POSSIBILITY OF SUCH DAMAGES.
025: *
026: * This software is not designed or intended for use in on-line control of
027: * aircraft, air traffic, aircraft navigation or aircraft communications; or in
028: * the design, construction, operation or maintenance of any nuclear
029: * facility. Licensee represents and warrants that it will not use or
030: * redistribute the Software for such purposes.
031: *
032: * $Revision: 1.2 $
033: * $Date: 2005/02/03 23:07:03 $
034: * $State: Exp $
035: */
036: /*
037: * @Author: Rick Goldberg
038: * @Author: Doug Gehringer
039: *
040: */
041: package org.jdesktop.j3d.loaders.vrml97.impl;
042:
043: import javax.media.j3d.BoundingLeaf;
044: import javax.media.j3d.BoundingSphere;
045: import javax.media.j3d.BranchGroup;
046: import javax.media.j3d.Transform3D;
047:
048: import javax.media.j3d.TransformGroup;
049: import javax.media.j3d.ViewPlatform;
050: import javax.vecmath.AxisAngle4d;
051: import javax.vecmath.Point3d;
052: import javax.vecmath.Quat4d;
053: import javax.vecmath.Vector3d;
054:
055: /** Description of the Class */
056: public class Viewpoint extends BindableNode {
057:
058: // If (loader.browser == null), the J3D structure will be:
059: //
060: // impl == implOrient: a TransformGroup with xform set by VP fields
061: // -->ViewPlatform
062:
063: // If (loader.browser == null), the J3D structure will be:
064: //
065: // impl is the detachable handle to this node.
066: // ->implWorld: a TransformGroup with browser conrolled xform
067: // ->->implOrient: a TransformGroup with xform set by VP fields
068: // ->->->implBrowser: a TransformGroup with browser controlled xform
069: // ->->->->ViewPlatform
070: // ->->->->Other RGroups used by browser
071:
072: BranchGroup impl;
073: TransformGroup implOrient;
074: TransformGroup implWorld;
075:
076: // From BindableNode;
077: //SFBool bind;
078: //SFBool isBound;
079: //SFTime bindTime;
080:
081: // exposedField
082: SFFloat fieldOfView;
083: SFBool jump;
084: SFRotation orientation;
085: SFVec3f position;
086: SFString description;
087:
088: SFRotation examine;// means just update the rotation without translation
089:
090: // impl objects
091: Transform3D implTrans, implBrowserTrans;//?implBrowserTrans?
092: TransformGroup implBrowser;
093: Transform3D examineViewpoint = new Transform3D();
094: Transform3D examineRotation = new Transform3D();
095: ViewPlatform implViewPlatform;
096: BoundingLeaf implBoundingLeaf;
097: AxisAngle4d axis = new AxisAngle4d();
098: Vector3d trans = new Vector3d();
099:
100: /**
101: *Constructor for the Viewpoint object
102: *
103: *@param loader Description of the Parameter
104: */
105: public Viewpoint(Loader loader) {
106: super (loader, loader.getViewpointStack());
107: fieldOfView = new SFFloat(.5398f);
108: jump = new SFBool(true);
109: orientation = new SFRotation(0.0f, 0.0f, 1.0f, 0.0f);
110: examine = new SFRotation(0.0f, 0.0f, 1.0f, 0.0f);
111: position = new SFVec3f(0.0f, 0.0f, 10.0f);
112: description = new SFString("");
113: loader.addViewpoint(this );
114: initFields();
115: }
116:
117: /**
118: *Constructor for the Viewpoint object
119: *
120: *@param loader Description of the Parameter
121: *@param bind Description of the Parameter
122: *@param bindTime Description of the Parameter
123: *@param isBound Description of the Parameter
124: *@param fieldOfView Description of the Parameter
125: *@param jump Description of the Parameter
126: *@param orientation Description of the Parameter
127: *@param position Description of the Parameter
128: *@param description Description of the Parameter
129: */
130: public Viewpoint(Loader loader, SFBool bind, SFTime bindTime,
131: SFBool isBound, SFFloat fieldOfView, SFBool jump,
132: SFRotation orientation, SFVec3f position,
133: SFString description) {
134: super (loader, loader.getViewpointStack(), bind, bindTime,
135: isBound);
136: this .fieldOfView = fieldOfView;
137: this .jump = jump;
138: this .orientation = orientation;
139: this .position = position;
140: this .description = description;
141: examine = new SFRotation(0.0f, 0.0f, 1.0f, 0.0f);
142: loader.addViewpoint(this );
143: initFields();
144: }
145:
146: /**
147: * Description of the Method
148: *
149: *@param eventInName Description of the Parameter
150: *@param time Description of the Parameter
151: */
152: public void notifyMethod(String eventInName, double time) {
153: if (eventInName.equals("position")
154: || eventInName.equals("orientation")) {
155: updateViewTrans();
156: } else if (eventInName.equals("examine")) {
157: updateViewTransExamine();
158: } else if (eventInName.equals("fieldOfView")
159: || eventInName.equals("description")
160: || eventInName.equals("jump")) {
161: updateBrowser();
162: } else if (eventInName.equals("bind")) {
163: // TODO: handle jumping
164: super .notifyMethod("bind", time);
165: } else if (eventInName.equals("route_position")
166: || eventInName.equals("route_orientation")
167: || eventInName.equals("route_fieldOfView")
168: || eventInName.equals("route_bind")
169: || eventInName.equals("route_description")) {
170: ;
171: } else if (eventInName.equals("route_examine")) {
172: updateViewTrans();
173: } else {
174: System.err.println("Viewpoint: unexpected notify "
175: + eventInName);
176: }
177: }
178:
179: /** Description of the Method */
180: void updateViewTrans() {
181: axis.x = orientation.rot[0];
182: axis.y = orientation.rot[1];
183: axis.z = orientation.rot[2];
184: double normalizer = Math.sqrt(axis.x * axis.x + axis.y * axis.y
185: + axis.z * axis.z);
186:
187: if (normalizer < .001) {// by about a millimeter
188: axis.x = 0.0;
189: axis.y = 1.0;
190: axis.z = 0.0;
191: } else {
192: axis.x /= normalizer;
193: axis.y /= normalizer;
194: axis.z /= normalizer;
195: }
196: axis.angle = Math.IEEEremainder(orientation.rot[3],
197: Math.PI * 2.0);
198: implTrans.setIdentity();
199: implTrans.set(axis);
200: trans.x = position.value[0];
201: trans.y = position.value[1];
202: trans.z = position.value[2];
203: implTrans.setTranslation(trans);
204: if ((implTrans.getType() & Transform3D.CONGRUENT) != 0) {
205: implOrient.setTransform(implTrans);
206: }
207:
208: }
209:
210: // obsolete see SceneTransform, but could go back
211: /** Description of the Method */
212: void updateViewTransExamine() {
213: axis.x = -examine.rot[0];
214: axis.y = -examine.rot[1];
215: axis.z = -examine.rot[2];
216: double normalizer = Math.sqrt(axis.x * axis.x + axis.y * axis.y
217: + axis.z * axis.z);
218:
219: if (normalizer < .001) {// by about a millimeter
220: axis.x = 0.0;
221: axis.y = 1.0;
222: axis.z = 0.0;
223: } else {
224: axis.x /= normalizer;
225: axis.y /= normalizer;
226: axis.z /= normalizer;
227: }
228: axis.angle = Math.IEEEremainder(examine.rot[3], Math.PI * 2.0);
229: examineRotation.set(axis);
230: examineViewpoint.mul(examineRotation, implTrans);
231: if ((examineViewpoint.getType() & Transform3D.CONGRUENT) != 0) {
232: implWorld.setTransform(examineViewpoint);
233: }
234:
235: }
236:
237: /** Description of the Method */
238: void updateBrowser() {
239: browser.viewChanged(this );
240: }
241:
242: /** Description of the Method */
243: void initImpl() {
244: if (loader.browser != null) {
245: // A TransformGroup above the Viewpoint's transforms. This is used
246: // by the browser to move the world relative to the viewpoint for
247: // "examine" mode
248: implWorld = new TransformGroup();
249: implWorld.setCapability(TransformGroup.ALLOW_CHILDREN_READ);
250: implWorld
251: .setCapability(TransformGroup.ALLOW_CHILDREN_WRITE);
252: implWorld
253: .setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND);
254: implWorld
255: .setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
256: implWorld
257: .setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
258: implWorld
259: .setCapability(TransformGroup.ALLOW_AUTO_COMPUTE_BOUNDS_READ);
260: implWorld
261: .setCapability(TransformGroup.ALLOW_AUTO_COMPUTE_BOUNDS_WRITE);
262: implWorld
263: .setCapability(javax.media.j3d.Node.ALLOW_BOUNDS_READ);
264: implWorld
265: .setCapability(javax.media.j3d.Node.ALLOW_BOUNDS_WRITE);
266: implWorld
267: .setCapability(javax.media.j3d.Group.ALLOW_COLLISION_BOUNDS_WRITE);
268:
269: // The Viewpoint itself. This part does not generally
270: // move.
271: implTrans = new Transform3D();
272: implOrient = new TransformGroup();
273: implOrient
274: .setCapability(TransformGroup.ALLOW_CHILDREN_READ);
275: implOrient
276: .setCapability(TransformGroup.ALLOW_CHILDREN_WRITE);
277: implOrient
278: .setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND);
279: implOrient
280: .setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
281: implOrient
282: .setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
283: implOrient
284: .setCapability(TransformGroup.ALLOW_AUTO_COMPUTE_BOUNDS_READ);
285: implOrient
286: .setCapability(TransformGroup.ALLOW_AUTO_COMPUTE_BOUNDS_WRITE);
287: implOrient
288: .setCapability(TransformGroup.ALLOW_AUTO_COMPUTE_BOUNDS_WRITE);
289: implOrient
290: .setCapability(javax.media.j3d.Node.ALLOW_BOUNDS_READ);
291: implOrient
292: .setCapability(javax.media.j3d.Node.ALLOW_BOUNDS_WRITE);
293: implOrient
294: .setCapability(javax.media.j3d.Group.ALLOW_COLLISION_BOUNDS_WRITE);
295: updateViewTrans();
296:
297: // The current position of the camera. This is the offset
298: // transform and group away from the viewpoint impl and implTrans.
299: // The BrowserBehavior will update this due to user interaction.
300: implBrowser = new TransformGroup();
301: implBrowserTrans = new Transform3D();
302: implBrowser.setTransform(implBrowserTrans);
303: implBrowser
304: .setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
305: implBrowser
306: .setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
307: implBrowser
308: .setCapability(TransformGroup.ALLOW_CHILDREN_READ);
309: implBrowser
310: .setCapability(TransformGroup.ALLOW_CHILDREN_WRITE);
311: implBrowser
312: .setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND);
313: implBrowser
314: .setCapability(TransformGroup.ALLOW_AUTO_COMPUTE_BOUNDS_READ);
315: implBrowser
316: .setCapability(TransformGroup.ALLOW_AUTO_COMPUTE_BOUNDS_WRITE);
317: implBrowser
318: .setCapability(javax.media.j3d.Node.ALLOW_BOUNDS_READ);
319: implBrowser
320: .setCapability(javax.media.j3d.Node.ALLOW_BOUNDS_WRITE);
321: implBrowser
322: .setCapability(javax.media.j3d.Group.ALLOW_COLLISION_BOUNDS_WRITE);
323:
324: // children of impl
325:
326: BranchGroup t = new RGroup();
327: t.addChild(implBrowser);
328:
329: // 0 browserGroup
330: // 1 fog
331: // 2 background
332: // 3 boundingLeaf
333: implOrient.addChild(t);
334: implOrient.addChild(new RGroup());
335: implOrient.addChild(new RGroup());
336: implOrient.addChild(new RGroup());
337: ((RGroup) implOrient.getChild(3))
338: .addChild(implBoundingLeaf = new BoundingLeaf(
339: new BoundingSphere((new Point3d(0.0, 0.0,
340: 0.0)), 100.0)));
341:
342: // children of implBrowser
343:
344: implViewPlatform = new ViewPlatform();
345: BranchGroup u = new RGroup();
346: u.addChild(implViewPlatform);
347: implViewPlatform
348: .setActivationRadius(Float.MAX_VALUE - 1.0f);
349: implViewPlatform
350: .setCapability(javax.media.j3d.Node.ALLOW_LOCAL_TO_VWORLD_READ);
351:
352: // leave room for
353: // 0 viewPlatform
354: // 1 headLights
355: // 2 browserBehavior
356: implBrowser.addChild(u);
357: implBrowser.addChild(new RGroup());
358: implBrowser.addChild(new RGroup());
359:
360: impl = new RGroup();
361: impl.addChild(implWorld);
362: implWorld.addChild(implOrient);
363:
364: if (loader.debug) {
365: System.out.println("Viewpoint impl = " + impl);
366: }
367:
368: implNode = impl;
369: } else {
370: // just set stuff up for the loader
371: implOrient = new TransformGroup();
372: implOrient
373: .setCapability(TransformGroup.ALLOW_CHILDREN_READ);
374: implOrient
375: .setCapability(TransformGroup.ALLOW_CHILDREN_WRITE);
376: implOrient
377: .setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND);
378: implOrient
379: .setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
380: implOrient
381: .setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
382: implOrient
383: .setCapability(TransformGroup.ALLOW_AUTO_COMPUTE_BOUNDS_READ);
384: implOrient
385: .setCapability(TransformGroup.ALLOW_AUTO_COMPUTE_BOUNDS_WRITE);
386: implOrient
387: .setCapability(javax.media.j3d.Node.ALLOW_BOUNDS_READ);
388: implOrient
389: .setCapability(javax.media.j3d.Node.ALLOW_BOUNDS_WRITE);
390: implOrient
391: .setCapability(javax.media.j3d.Group.ALLOW_COLLISION_BOUNDS_WRITE);
392: implTrans = new Transform3D();
393: updateViewTrans();
394:
395: implViewPlatform = new ViewPlatform();
396: implViewPlatform
397: .setActivationRadius(Float.MAX_VALUE - 1.0f);
398: implOrient.addChild(implViewPlatform);
399: implNode = implOrient;
400: }
401:
402: implReady = true;
403: }
404:
405: /**
406: * Description of the Method
407: *
408: *@param bounds Description of the Parameter
409: */
410: void frameObject(BoundingSphere bounds) {
411: Point3d p = new Point3d();
412: bounds.getCenter(p);
413: //System.out.println("frameObject "+ p + " " + bounds.getRadius());
414: position.value[0] = (float) p.x;
415: position.value[1] = (float) p.y / 1.05f;
416: position.value[2] = (float) p.z
417: + (3.14f * (float) (bounds.getRadius()));
418: updateViewTrans();
419: }
420:
421: /**
422: * Gets the viewPlatform attribute of the Viewpoint object
423: *
424: *@return The viewPlatform value
425: */
426: public javax.media.j3d.ViewPlatform getViewPlatform() {
427: return implViewPlatform;
428: }
429:
430: /**
431: * Gets the transformGroup attribute of the Viewpoint object
432: *
433: *@return The transformGroup value
434: */
435: public javax.media.j3d.TransformGroup getTransformGroup() {
436: return implOrient;
437: }
438:
439: /**
440: * Gets the fOV attribute of the Viewpoint object
441: *
442: *@return The fOV value
443: */
444: public float getFOV() {
445: return fieldOfView.value;
446: }
447:
448: /**
449: * Gets the description attribute of the Viewpoint object
450: *
451: *@return The description value
452: */
453: public String getDescription() {
454: return description.getValue();
455: }
456:
457: /**
458: * Gets the type attribute of the Viewpoint object
459: *
460: *@return The type value
461: */
462: public String getType() {
463: return "Viewpoint";
464: }
465:
466: /**
467: * Description of the Method
468: *
469: *@return Description of the Return Value
470: */
471: public Object clone() {
472: return new Viewpoint(loader, (SFBool) bind.clone(),
473: (SFTime) bindTime.clone(), (SFBool) isBound.clone(),
474: (SFFloat) fieldOfView.clone(), (SFBool) jump.clone(),
475: (SFRotation) orientation.clone(), (SFVec3f) position
476: .clone(), (SFString) description.clone());
477: }
478:
479: /** Description of the Method */
480: void initFields() {
481: initBindableFields();
482: fieldOfView.init(this , FieldSpec, Field.EXPOSED_FIELD,
483: "fieldOfView");
484: jump.init(this , FieldSpec, Field.EXPOSED_FIELD, "jump");
485: orientation.init(this , FieldSpec, Field.EXPOSED_FIELD,
486: "orientation");
487: position.init(this , FieldSpec, Field.EXPOSED_FIELD, "position");
488: description.init(this , FieldSpec, Field.FIELD, "description");
489: examine.init(this , FieldSpec, Field.EXPOSED_FIELD, "examine");
490: }
491:
492: /**
493: * Description of the Method
494: *
495: *@return Description of the Return Value
496: */
497: public vrml.BaseNode wrap() {
498: return new org.jdesktop.j3d.loaders.vrml97.node.Viewpoint(this);
499: }
500:
501: }
|