001: /*
002: * $RCSfile: DragSensor.java,v $
003: *
004: * @(#)DragSensor.java 1.15 99/03/10 18:02:47
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:06:55 $
034: * $State: Exp $
035: */
036: /*
037: * @Author: Rick Goldberg
038: *
039: */
040: package org.jdesktop.j3d.loaders.vrml97.impl;
041:
042: import java.util.Vector;
043: import javax.media.j3d.Transform3D;
044: import javax.vecmath.*;
045:
046: // abstract base class for all drag sensors
047: /** Description of the Class */
048: public abstract class DragSensor extends Node implements VrmlSensor {
049:
050: // exposedField
051: SFBool enabled;
052: SFBool autoOffset;
053:
054: // Event outs
055: SFBool isActive;
056: SFVec3f trackPoint;
057:
058: // Scene graph reference
059: javax.media.j3d.Node parent;
060:
061: static double EPSILON = .00000001;
062: static double DELTA = .00001;
063:
064: /**
065: *Constructor for the DragSensor object
066: *
067: *@param loader Description of the Parameter
068: */
069: public DragSensor(Loader loader) {
070: super (loader);
071: enabled = new SFBool(true);
072: autoOffset = new SFBool(true);
073: isActive = new SFBool(true);
074: trackPoint = new SFVec3f(0.0f, 0.0f, 0.0f);
075: initFields();
076: }
077:
078: /**
079: *Constructor for the DragSensor object
080: *
081: *@param loader Description of the Parameter
082: *@param enabled Description of the Parameter
083: */
084: DragSensor(Loader loader, SFBool enabled) {
085: super (loader);
086: this .enabled = enabled;
087: isActive = new SFBool(true);
088: initFields();
089: }
090:
091: /**
092: * Description of the Method
093: *
094: *@param parentImpl Description of the Parameter
095: */
096: void updateParent(javax.media.j3d.Node parentImpl) {
097: Vector v = (Vector) (parentImpl.getUserData());
098: if (v == null) {
099: v = new Vector();
100: parentImpl.setUserData(v);
101: if (loader.debug) {
102: System.out.println("Drag Sensor parent: " + parentImpl
103: + " had no user data, added vector:" + v);
104: }
105: }
106: v.addElement(this );
107: // in case GroupBase did not hit this parent
108: parentImpl
109: .setCapability(javax.media.j3d.Node.ENABLE_PICK_REPORTING);
110: parentImpl
111: .setCapability(javax.media.j3d.Node.ALLOW_BOUNDS_READ);
112: parentImpl
113: .setCapability(javax.media.j3d.Node.ALLOW_LOCAL_TO_VWORLD_READ);
114: // bug: j3d: compiles away parentImpl losing pick info
115: parentImpl
116: .setCapability(javax.media.j3d.Group.ALLOW_CHILDREN_READ);
117: parentImpl
118: .setCapability(javax.media.j3d.Group.ALLOW_CHILDREN_WRITE);
119: parentImpl
120: .setCapability(javax.media.j3d.Group.ALLOW_CHILDREN_EXTEND);
121: if (parentImpl instanceof javax.media.j3d.TransformGroup) {
122: parentImpl
123: .setCapability(javax.media.j3d.TransformGroup.ALLOW_TRANSFORM_READ);
124: }
125: parentImpl.setPickable(true);
126: parent = parentImpl;
127: }
128:
129: /** Description of the Method */
130: void initFields() {
131: enabled.init(this , FieldSpec, Field.EXPOSED_FIELD, "enabled");
132: autoOffset.init(this , FieldSpec, Field.EXPOSED_FIELD,
133: "autoOffset");
134: isActive.init(this , FieldSpec, Field.EVENT_OUT, "isActive");
135: trackPoint.init(this , FieldSpec, Field.EVENT_OUT, "trackPoint");
136: }
137:
138: /** Description of the Method */
139: abstract void offset();
140:
141: /**
142: * Description of the Method
143: *
144: *@param t Description of the Parameter
145: */
146: abstract void simTick(double t);
147:
148: // Given the transformed pixel , the next pixel (if any), the node under the
149: // pick group, and the unique path incase of shared link , do something.
150: /**
151: * Description of the Method
152: *
153: *@param p1 Description of the Parameter
154: *@param p2 Description of the Parameter
155: *@param node Description of the Parameter
156: *@param unique Description of the Parameter
157: */
158: abstract void update(Point3d p1, Point3d p2,
159: javax.media.j3d.Node node,
160: javax.media.j3d.SceneGraphPath unique);
161:
162: // The following are adaptations of vecmath related methods, which have
163: // improved safety nets.
164:
165: /**
166: * Description of the Method
167: *
168: *@param n Description of the Parameter
169: *@exception ArithmeticException Description of the Exception
170: */
171: static void norm(Vector3d n) throws ArithmeticException {
172: double norml = (float) Math.sqrt(n.x * n.x + n.y * n.y + n.z
173: * n.z);
174: if (norml == 0.0) {
175: throw new ArithmeticException();
176: }
177:
178: n.x /= norml;
179: n.y /= norml;
180: n.z /= norml;
181: }
182:
183: /**
184: * Description of the Method
185: *
186: *@param t Description of the Parameter
187: *@param u Description of the Parameter
188: *@return Description of the Return Value
189: */
190: static double angle(Vector3d t, Vector3d u) {
191: double l1 = length(t);
192: double l2 = length(u);
193: double a;
194: if (l1 == 0.0 || l2 == 0.0) {
195: return 0.0;
196: }
197: // acos is returning a NAN
198: else {
199: a = Math.acos(dot(t, u) / (l1 * l2));
200: }
201: if (a < 0.0 || a > 0.0) {
202: return a;
203: } else {
204: return EPSILON;
205: }
206: }
207:
208: /**
209: * Description of the Method
210: *
211: *@param v Description of the Parameter
212: *@return Description of the Return Value
213: */
214: static double length(Vector3d v) {
215: double l = Math.sqrt(dot(v, v));
216: return l;
217: }
218:
219: /**
220: * Description of the Method
221: *
222: *@param v Description of the Parameter
223: *@param u Description of the Parameter
224: *@return Description of the Return Value
225: */
226: static double dot(Vector3d v, Vector3d u) {
227: return (v.x * u.x + v.y * u.y + v.z * u.z);
228: }
229:
230: // this function will corect for the Alice in Wonderland
231: // effect. No, not the white mice talking backwards...
232: /**
233: * Description of the Method
234: *
235: *@param tr Description of the Parameter
236: *@return Description of the Return Value
237: */
238: static double coorelate(Transform3D tr) {
239: double c = 0.0;
240: double COORELATION_FACTOR = 10.0;
241: if (c == 0.0) {
242: Point3d p1 = new Point3d(0.0, 0.0, 0.0);
243: Point3d p2 = new Point3d(0.0 + DELTA, 0.0, 0.0);
244:
245: tr.transform(p1);
246: tr.transform(p2);
247:
248: Vector3d v1 = new Vector3d(p1);
249: Vector3d v2 = new Vector3d(p2);
250:
251: norm(v1);
252: norm(v2);
253:
254: // increase or decrease COORELATION_FACTOR
255: // to taste
256: c = COORELATION_FACTOR * DELTA / angle(v1, v2);
257: }
258:
259: return c;
260: }
261:
262: }
|