001: /*
002: * $Header: /cvs/j3dfly/J3dFly/src/org/jdesktop/j3dfly/utils/vpbehaviors/ViewUtils.java,v 1.1 2005/04/20 21:05:15 paulby Exp $
003: *
004: * Sun Public License Notice
005: *
006: * The contents of this file are subject to the Sun Public License Version
007: * 1.0 (the "License"). You may not use this file except in compliance with
008: * the License. A copy of the License is available at http://www.sun.com/
009: *
010: * The Original Code is Java 3D(tm) Fly Through.
011: * The Initial Developer of the Original Code is Paul Byrne.
012: * Portions created by Paul Byrne are Copyright (C) 2002.
013: * All Rights Reserved.
014: *
015: * Contributor(s): Paul Byrne.
016: *
017: **/
018: package org.jdesktop.j3dfly.utils.vpbehaviors;
019:
020: import javax.media.j3d.TransformGroup;
021: import javax.media.j3d.Transform3D;
022: import javax.media.j3d.Bounds;
023: import javax.media.j3d.BoundingSphere;
024:
025: import javax.vecmath.Point3d;
026: import javax.vecmath.Vector3d;
027: import javax.vecmath.Matrix3d;
028:
029: /**
030: * Utility functions for manipulating the View
031: *
032: * @author Paul Byrne
033: * @version $Id: ViewUtils.java,v 1.1 2005/04/20 21:05:15 paulby Exp $
034: */
035: public class ViewUtils extends Object {
036:
037: public static final int POSITIVE_X_AXIS = 0;
038: public static final int POSITIVE_Y_AXIS = 1;
039: public static final int POSITIVE_Z_AXIS = 2;
040: public static final int NEGATIVE_X_AXIS = 3;
041: public static final int NEGATIVE_Y_AXIS = 4;
042: public static final int NEGATIVE_Z_AXIS = 5;
043:
044: private static Vector3d zAxis = new Vector3d(0, 0, -1);
045: private static Vector3d yAxis = new Vector3d(0, 1, 0);
046: private static Vector3d xAxis = new Vector3d(1, 0, 0);
047:
048: /**
049: * Set the transform so that everything inside the Bounds is
050: * visible within the view frustum. Return the views distance from
051: * center of the scene after transformation
052: *
053: * @param tg The transform to change
054: * @param sceneBounds The bounds of the scene to fit inside the view frustum
055: * @param fieldOfView The fieldOfView
056: * @param axis The axis along which to view the scene, this must be one of
057: * POSITIVE_X_AXIS, POSITIVE_Y_AXIS, POSITIVE_Z_AXIS, NEGATIVE_X_AXIS, NEGATIVE_Y_AXIS or NEGATIVE_Z_AXIS
058: * @return The distance the eye is from the center of the scene bounds.
059: */
060: public static double setViewpoint(TransformGroup tg,
061: Bounds sceneBounds, double fieldOfView, int axis) {
062:
063: if (sceneBounds instanceof BoundingSphere)
064: return setViewpoint(tg, (BoundingSphere) sceneBounds,
065: fieldOfView, axis);
066:
067: return setViewpoint(tg, new BoundingSphere(sceneBounds),
068: fieldOfView, axis);
069: }
070:
071: private static double setViewpoint(TransformGroup tg,
072: BoundingSphere sceneBounds, double fieldOfView, int axis) {
073: Transform3D viewTrans = new Transform3D();
074: Transform3D eyeTrans = new Transform3D();
075:
076: // point the view at the center of the object
077: Point3d center = new Point3d();
078: sceneBounds.getCenter(center);
079: double radius = sceneBounds.getRadius();
080: Point3d eyePos = new Point3d(center);
081: Vector3d up = new Vector3d();
082:
083: // pull the eye back far enough to see the whole object
084: double eyeDist = radius / Math.tan(fieldOfView / 2.0);
085: switch (axis) {
086: case POSITIVE_X_AXIS:
087: eyePos.x += eyeDist;
088: up.y = 1;
089: break;
090: case POSITIVE_Y_AXIS:
091: eyePos.y += eyeDist;
092: up.z = -1;
093: break;
094: case POSITIVE_Z_AXIS:
095: eyePos.z += eyeDist;
096: up.y = 1;
097: break;
098: case NEGATIVE_X_AXIS:
099: eyePos.x -= eyeDist;
100: up.y = 1;
101: break;
102: case NEGATIVE_Y_AXIS:
103: eyePos.y -= eyeDist;
104: up.z = -1;
105: break;
106: case NEGATIVE_Z_AXIS:
107: eyePos.z -= eyeDist;
108: up.y = 1;
109: break;
110: }
111:
112: viewTrans.setIdentity();
113: viewTrans.lookAt(eyePos, center, up);
114: viewTrans.invert();
115: // set the view transform
116: tg.setTransform(viewTrans);
117:
118: return eyeDist;
119: }
120:
121: /**
122: * Converts the Matrix into Euler angles (roll, pitch, yaw )
123: */
124: public static void toEuler(Matrix3d matrix, Vector3d euler) {
125: Vector3d v3d = new Vector3d();
126:
127: v3d.set(xAxis);
128: matrix.transform(v3d);
129: v3d.x = Math.abs(v3d.x);
130: v3d.z = 0;
131: v3d.normalize();
132:
133: euler.x = xAxis.angle(v3d);
134:
135: v3d.set(yAxis);
136: matrix.transform(v3d);
137: v3d.z = Math.abs(v3d.z);
138: v3d.x = 0;
139: v3d.normalize();
140:
141: euler.y = yAxis.angle(v3d);
142:
143: v3d.set(zAxis);
144: matrix.transform(v3d);
145: v3d.y = 0;
146: v3d.normalize();
147:
148: euler.z = zAxis.angle(v3d);
149: if (v3d.x < 0)
150: euler.z = 2 * Math.PI - euler.z;
151: }
152: }
|