//
// MouseBehaviorJ3D.java
//
/*
VisAD system for interactive analysis and visualization of numerical
data. Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom
Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and
Tommy Jasmin.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA
*/
package visad.java3d;
import visad.*;
import java.lang.reflect.*;
import java.awt.event.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import java.awt.*;
import java.util.*;
/**
MouseBehaviorJ3D is the VisAD class for mouse behaviors for Java3D
*/
/*
On MOUSE_PRESSED event with left button,
((InputEvent) events[i]).getModifiers() returns 0 and
should return 16 ( = InputEvent.BUTTON1_MASK ).
((InputEvent) events[i]).getModifiers() correctly
returns 16 on MOUSE_RELEASED with left button.
*/
public class MouseBehaviorJ3D extends Behavior
implements MouseBehavior {
/** wakeup condition for MouseBehaviorJ3D */
private WakeupOr wakeup;
/** DisplayRenderer for Display */
DisplayRendererJ3D display_renderer;
DisplayImpl display;
MouseHelper helper = null;
/**
* Default Constructor
*/
public MouseBehaviorJ3D() {
}
/**
* Construct a MouseBehavior for the DisplayRenderer specified
* @param r DisplayRenderer to use
*/
public MouseBehaviorJ3D(DisplayRendererJ3D r) {
this(r, MouseHelper.class);
}
/**
* Construct a MouseBehavior for the DisplayRenderer specified
* @param r DisplayRenderer to use
* @param mhClass MouseHelper subclass to use
*/
public MouseBehaviorJ3D(DisplayRendererJ3D r, Class mhClass) {
try {
Class[] param = new Class[] {DisplayRenderer.class, MouseBehavior.class};
Constructor mhConstructor =
mhClass.getConstructor(param);
helper = (MouseHelper) mhConstructor.newInstance(new Object[] {r, this});
}
catch (Exception e) {
throw new VisADError("cannot construct " + mhClass);
}
// helper = new MouseHelper(r, this);
display_renderer = r;
display = display_renderer.getDisplay();
WakeupCriterion[] conditions = new WakeupCriterion[6];
conditions[0] = new WakeupOnAWTEvent(MouseEvent.MOUSE_DRAGGED);
conditions[1] = new WakeupOnAWTEvent(MouseEvent.MOUSE_ENTERED);
conditions[2] = new WakeupOnAWTEvent(MouseEvent.MOUSE_EXITED);
conditions[3] = new WakeupOnAWTEvent(MouseEvent.MOUSE_PRESSED);
conditions[4] = new WakeupOnAWTEvent(MouseEvent.MOUSE_RELEASED);
conditions[5] = new WakeupOnAWTEvent(MouseEvent.MOUSE_MOVED);
wakeup = new WakeupOr(conditions);
}
// WLH 17 Dec 2001
public void destroy() {
helper = null;
display = null;
display_renderer = null;
}
/**
* Get the helper class used by this MouseBehavior.
* The MouseHelper defines the actions taken based
* on MouseEvents.
* @return MouseHelper being used.
*/
public MouseHelper getMouseHelper() {
return helper;
}
/**
* Initialize this behavior. NOTE: Applications should not call
* this method. It is called by the Java 3D behavior scheduler.
*/
public void initialize() {
setWakeup();
}
/**
* Process a stimulus meant for this behavior. This method is
* invoked when a key is pressed. NOTE: Applications should not
* call this method. It is called by the Java 3D behavior scheduler.
* @param criteria an enumeration of triggered wakeup criteria
*/
public void processStimulus(Enumeration criteria) {
while (criteria.hasMoreElements()) {
WakeupCriterion wakeup = (WakeupCriterion) criteria.nextElement();
if (!(wakeup instanceof WakeupOnAWTEvent)) {
System.out.println("MouseBehaviorJ3D.processStimulus: non-" +
"WakeupOnAWTEvent");
}
else {
AWTEvent[] events = ((WakeupOnAWTEvent) wakeup).getAWTEvent();
for (int i=0; iinstance_unmake_matrix .
* @param rot array to hold x,y,z rotation values
* @param scale array to hold scale value(s). If length == 1, assumes
* uniform scaling.
* @param trans array to hold x,y,z translation values
*/
public static void unmake_matrix(double[] rot, double[] scale,
double[] trans, double[] matrix) {
double sx, sy, sz, cx, cy, cz;
int i, j;
double[][] mat = new double[4][4];
double[][] nat = new double[4][4];
double scalex, scaley, scalez, cxa, cxb, cxinv;
double[] scaleinv = new double[3];
if (rot == null || rot.length != 3) return;
if (scale == null || !(scale.length == 1 || scale.length == 3)) return;
if (trans == null || trans.length != 3) return;
if (matrix == null || matrix.length != 16) return;
int k = 0;
for (i=0; i<4; i++) {
for (j=0; j<4; j++) {
mat[i][j] = matrix[k];
k++;
}
}
/* translation */
/* WLH 24 March 2000, for consistency with change
of 22 Dec 97 in static_make_matrix
trans[0] = mat[3][0];
trans[1] = mat[3][1];
trans[2] = mat[3][2];
*/
trans[0] = mat[0][3];
trans[1] = mat[1][3];
trans[2] = mat[2][3];
/* scale */
scalex = scaley = scalez = 0.0;
for (i=0; i<3; i++) {
scalex += mat[0][i] * mat[0][i];
scaley += mat[1][i] * mat[1][i];
scalez += mat[2][i] * mat[2][i];
}
if (Math.abs(scalex - scaley) > EPS || Math.abs(scalex - scalez) > EPS) {
// System.out.println("problem " + scalex + " " + scaley + " " + scalez);
}
if (scale.length == 1) {
scale[0] = Math.sqrt((scalex + scaley + scalez)/3.0);
scaleinv[0] = Math.abs(scale[0]) > EPS ? 1.0 / scale[0] : 1.0 / EPS;
scaleinv[1] = scaleinv[2] = scaleinv[0];
} else {
scale[0] = Math.sqrt(scalex);
scale[1] = Math.sqrt(scaley);
scale[2] = Math.sqrt(scalez);
for (i=0; i<3; i++) {
scaleinv[i] = Math.abs(scale[i]) > EPS ? 1.0 / scale[i] : 1.0 / EPS;
}
}
for (i=0; i<3; i++) {
for (j=0; j<3; j++) {
nat[j][i] = scaleinv[j] * mat[j][i];
}
}
/* rotation */
sx = -nat[2][1];
cxa = Math.sqrt(nat[2][0]*nat[2][0] + nat[2][2]*nat[2][2]);
cxb = Math.sqrt(nat[0][1]*nat[0][1] + nat[1][1]*nat[1][1]);
if (Math.abs(cxa - cxb) > EPS) {
// System.out.println("problem2 " + cxa + " " + cxb);
}
/* the sign of cx does not matter;
it is an ambiguity in 3-D rotations:
(rotz, rotx, roty) = (180+rotz, 180-rotx, 180+roty) */
cx = (cxa + cxb) / 2.0;
if (Math.abs(cx) > EPS) {
cxinv = 1.0 / cx;
sy = nat[2][0] * cxinv;
cy = nat[2][2] * cxinv;
sz = nat[0][1] * cxinv;
cz = nat[1][1] * cxinv;
}
else {
/* if cx == 0 then roty and rotz are ambiguous:
assume rotx = 0.0 */
sy = 0.0;
cy = 1.0;
sz = nat[0][2];
cz = nat[1][2];
}
rot[0] = 57.2957 * Math.atan2(sx, cx);
rot[1] = 57.2957 * Math.atan2(sy, cy);
rot[2] = 57.2957 * Math.atan2(sz, cz);
return;
}
/*
homogeneous coordinates:
point (x, y, z) is represented as (w*x, w*y, w*z, w) for w != 0
point (x, y, z, 1) transforms to
x' = x*mat[0] + y*mat[1] + z*mat[2] + mat[3]
y' = x*mat[4] + y*mat[5] + z*mat[6] + mat[7]
z' = x*mat[8] + y*mat[9] + z*mat[10] + mat[11]
w' = x*mat[12] + y*mat[13] + z*mat[14] + mat[15]
*/
/*
see ViewPlatform.TransformGroup in UniverseBuilderJ3D constructor
View.setProjectionPolicy
default is View.PERSPECTIVE_PROJECTION (vs PARALLEL_PROJECTION)
View.getVpcToEc(Transform3D vpcToEc)
"Compatibility mode method that retrieves the current ViewPlatform
Coordinates (VPC) system to Eye Coordinates (EC) transform and copies
it into the specified object."
View.getLeftProjection(Transform3D projection)
View.getRightProjection(Transform3D projection)
default is View.CYCLOPEAN_EYE_VIEW
require:
View.setCompatibilityModeEnable(true)
default is disabled
View.getLeftProjection(Transform3D projection)
"Compatibility mode method that specifies a viewing frustum for the
left eye that transforms points in Eye Coordinates (EC) to Clipping
Coordinates (CC)."
NOTE have View in UniverseBuilderJ3D
Canvas3D.getImagePlateToVworld(Transform3D t)
Canvas3D.getPixelLocationInImagePlate(int x, int y, Point3d position)
Canvas3D.getVworldToImagePlate(Transform3D t)
Canvas3D.getCenterEyeInImagePlate(Point3d position)
spec page 176: "final transform for rendering shapes to Canvas3D is
P * E * inv(ViewPlatform.TransformGroup) * trans
use Transform3D.invert for inv
where P = projection matrix from eye coords to clipping coords
i.e., projection
and E = matrix from ViewPlatform to eye coords
i.e., vpcToEc
*/
/*
is the mouse a Sensor or InputDevice?
if so, see spec page 369 for sensor to World transform
*/
/*
import javax.vecmath.*;
import javax.media.j3d.*;
public class TestTransform3D extends Object {
public static void main(String args[]) {
Transform3D trans_frustum = new Transform3D();
Transform3D trans_perspective = new Transform3D();
Transform3D trans_ortho = new Transform3D();
Transform3D trans_ortho2 = new Transform3D();
System.out.println("initial trans_frustum =\n" + trans_frustum);
trans_frustum.frustum(-1.0, 1.0, -1.0, 1.0, 1.0, 2.0);
System.out.println("trans_frustum =\n" + trans_frustum);
trans_perspective.perspective(0.5, 1.0, 1.0, 2.0);
System.out.println("trans_perspective =\n" + trans_perspective);
trans_ortho.ortho(-1.0, 1.0, -1.0, 1.0, 1.0, 2.0);
System.out.println("trans_ortho =\n" + trans_ortho);
trans_ortho2.ortho(-1.0, 1.0, -1.0, 1.0, 1.0, 3.0);
System.out.println("trans_ortho2 =\n" + trans_ortho2);
Transform3D trans_translate_scale =
new Transform3D(new Matrix3d(1.0, 1.1, 1.2,
1.3, 1.4, 1.5,
1.6, 1.7, 1.8),
new Vector3d(2.1, 2.2, 2.3), 3.0);
System.out.println("trans_translate_scale =\n" + trans_translate_scale);
double[] matrix = {1.0, 1.1, 1.2, 1.3,
1.4, 1.5, 1.6, 1.7,
1.8, 1.9, 2.0, 2.1,
2.2, 2.3, 2.4, 2.5};
Transform3D trans_matrix = new Transform3D(matrix);
System.out.println("trans_matrix =\n" + trans_matrix);
}
// here's the output:
verner 25% java TestTransform3D
initial trans_frustum =
1.0, 0.0, 0.0, 0.0
0.0, 1.0, 0.0, 0.0
0.0, 0.0, 1.0, 0.0
0.0, 0.0, 0.0, 1.0
trans_frustum =
1.0, 0.0, 0.0, 0.0
0.0, 1.0, 0.0, 0.0
0.0, 0.0, 3.0, 4.0
0.0, 0.0, -1.0, 0.0
trans_perspective =
3.91631736464594, 0.0, 0.0, 0.0
0.0, 3.91631736464594, 0.0, 0.0
0.0, 0.0, 3.0, 4.0
0.0, 0.0, -1.0, 0.0
trans_ortho =
1.0, 0.0, 0.0, -0.0
0.0, 1.0, 0.0, -0.0
0.0, 0.0, 2.0, 3.0
0.0, 0.0, 0.0, 1.0
trans_ortho2 =
1.0, 0.0, 0.0, -0.0
0.0, 1.0, 0.0, -0.0
0.0, 0.0, 1.0, 2.0
0.0, 0.0, 0.0, 1.0
trans_translate_scale =
3.0, 3.3000000000000003, 3.5999999999999996, 2.1
3.9000000000000004, 4.199999999999999, 4.5, 2.2
4.800000000000001, 5.1, 5.4, 2.3
0.0, 0.0, 0.0, 1.0
trans_matrix =
1.0, 1.1, 1.2, 1.3
1.4, 1.5, 1.6, 1.7
1.8, 1.9, 2.0, 2.1
2.2, 2.3, 2.4, 2.5
verner 26%
//
}
*/
}
Ads help maintain this website.