//
// MouseHelper.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;
import java.awt.event.*;
import java.rmi.*;
import java.awt.*;
import visad.browser.Convert;
/**
MouseHelper is the VisAD helper class for MouseBehaviorJ3D
and MouseBehaviorJ2D.<p>
MouseHelper is preferred by cats everywhere.<p>
*/
public class MouseHelper
implements RendererSourceListener
{
MouseBehavior behavior;
/** DisplayRenderer for Display */
DisplayRenderer display_renderer;
/** Display */
DisplayImpl display;
/** ProjectionControl for Display */
private ProjectionControl proj;
/** DataRenderer for direct manipulation */
protected DataRenderer direct_renderer = null;
/** matrix from ProjectionControl when mousePressed1 (left) */
protected double[] tstart;
/** screen location when mousePressed1 or mousePressed3 */
protected int start_x, start_y;
protected double xmul, ymul;
protected double xymul;
//protected double[] xtrans = new double[3];
//protected double[] ytrans = new double[3];
/** mouse in window (not used) */
private boolean mouseEntered;
/** ((InputEvent) event).getModifiers() when mouse pressed */
protected int mouseModifiers;
/** flag for 2-D mode */
private boolean mode2D;
// start of variables for table-driven mapping from mouse buttons and
// keys to functons
// index values for functions
public static final int NONE = -1, ROTATE = 0, ZOOM = 1, TRANSLATE = 2,
CURSOR_TRANSLATE = 3, CURSOR_ZOOM = 4, CURSOR_ROTATE = 5, DIRECT = 6;
/* Number of functions */
//protected int NFUNCTIONS = 7;
// index values for mouse buttons
public static final int LEFT = 0, CENTER = 1, RIGHT = 2;
// actual mouse buttons pressed
protected boolean[] actual_button = {false, false, false};
// mouse button pressed accounting for combos
protected int virtual_button = -1;
// array of enables for functions
protected boolean[] function = {false, false, false, false, false, false, false};
// save previous function to compute function change
protected boolean[] old_function = {false, false, false, false, false, false, false};
// enable any two mouse buttons = the third
private boolean enable_combos = true;
// mapping from buttons/keys to function
// function_map[button][CTRL][SHIFT] where
// button = 0, 1, 2
// CTRL = 0, 1
// SHIFT = 0, 1
// initialize with defaults
int[][][] function_map =
{{{ROTATE, ZOOM}, {TRANSLATE, NONE}},
{{CURSOR_TRANSLATE, CURSOR_ZOOM}, {CURSOR_ROTATE, NONE}},
{{DIRECT, DIRECT}, {DIRECT, DIRECT}}};
// end of variables for table-driven mapping from mouse buttons
// and keys to functons
public MouseHelper(DisplayRenderer r, MouseBehavior b) {
behavior = b;
display_renderer = r;
display = display_renderer.getDisplay();
proj = display.getProjectionControl();
mode2D = display_renderer.getMode2D();
// track Display's DataRenderers in case direct_renderer is removed
display.addRendererSourceListener(this);
//function =
// new boolean[] {false, false, false, false, false, false, false};
//enable_combos = true;
}
/**
* Get the MouseBehavior for this Helper
* @return MouseBehavior
*/
public MouseBehavior getMouseBehavior() { return behavior; }
/**
* Get the Display for this Helper
* @return Display
*/
public DisplayImpl getDisplay() { return display; }
/**
* Get the DisplayRenderer for this Helper
* @return DisplayRenderer
*/
public DisplayRenderer getDisplayRenderer() { return display_renderer; }
/**
* Get the ProjectionControl for this Helper
* @return ProjectionControl
*/
public ProjectionControl getProjectionControl() { return proj; }
/**
* Get whether we're in 2D mode
* @return true if 2D mode
*/
public boolean getMode2D() { return mode2D; }
/**
* Process the given event treating it as a local event.
* @param event event to process.
*/
public void processEvent(AWTEvent event) {
processEvent(event, VisADEvent.LOCAL_SOURCE);
}
// WLH 17 Aug 2000 (no longer used)
private boolean first = true;
/**
* Process the given event, treating it as coming from a remote source
* if remote flag is set.
* @param event event to process.
* @param remoteId id of remote source.
*/
public void processEvent(AWTEvent event, int remoteId) {
if (getMouseBehavior() == null) return;
// WLH 13 May 2003
// if (first) {
if (event instanceof MouseEvent &&
((MouseEvent) event).getID() == MouseEvent.MOUSE_PRESSED) {
start_x = 0;
start_y = 0;
VisADRay start_ray = getMouseBehavior().findRay(start_x, start_y);
VisADRay start_ray_x = getMouseBehavior().findRay(start_x + 1, start_y);
VisADRay start_ray_y = getMouseBehavior().findRay(start_x, start_y + 1);
if (start_ray != null && start_ray_x != null && start_ray_y != null) {
double[] tstart = getProjectionControl().getMatrix();
double[] rot = new double[3];
double[] scale = new double[3];
double[] trans = new double[3];
getMouseBehavior().instance_unmake_matrix(rot, scale, trans, tstart);
double[] trot = getMouseBehavior().make_matrix(rot[0], rot[1], rot[2],
scale[0], scale[1], scale[2],
0.0, 0.0, 0.0);
double[] xmat = getMouseBehavior().make_translate(
start_ray_x.position[0] - start_ray.position[0],
start_ray_x.position[1] - start_ray.position[1],
start_ray_x.position[2] - start_ray.position[2]);
double[] ymat = getMouseBehavior().make_translate(
start_ray_y.position[0] - start_ray.position[0],
start_ray_y.position[1] - start_ray.position[1],
start_ray_y.position[2] - start_ray.position[2]);
double[] xmatmul = getMouseBehavior().multiply_matrix(trot, xmat);
double[] ymatmul = getMouseBehavior().multiply_matrix(trot, ymat);
getMouseBehavior().instance_unmake_matrix(rot, scale, trans, xmatmul);
//double xmul = trans[0];
xmul = trans[0];
getMouseBehavior().instance_unmake_matrix(rot, scale, trans, ymatmul);
//double ymul = trans[1];
ymul = trans[1];
xymul = Math.sqrt(xmul * xmul + ymul * ymul);
// System.out.println("xymul = " + xymul);
first = false;
}
}
if (!(event instanceof MouseEvent)) {
System.out.println("MouseHelper.processStimulus: non-MouseEvent");
return;
}
MouseEvent mouse_event = (MouseEvent) event;
int event_id = event.getID();
if (event_id == MouseEvent.MOUSE_ENTERED) {
mouseEntered = true;
try {
DisplayEvent e = new DisplayEvent(getDisplay(),
DisplayEvent.MOUSE_ENTERED, mouse_event, remoteId);
getDisplay().notifyListeners(e);
}
catch (VisADException e) {
}
catch (RemoteException e) {
}
return;
}
else if (event_id == MouseEvent.MOUSE_EXITED) {
mouseEntered = false;
try {
DisplayEvent e = new DisplayEvent(getDisplay(),
DisplayEvent.MOUSE_EXITED, mouse_event, remoteId);
getDisplay().notifyListeners(e);
}
catch (VisADException e) {
}
catch (RemoteException e) {
}
return;
}
else if (event_id == MouseEvent.MOUSE_MOVED) {
try {
DisplayEvent e = new DisplayEvent(getDisplay(),
DisplayEvent.MOUSE_MOVED, mouse_event, remoteId);
getDisplay().notifyListeners(e);
}
catch (VisADException e) {
}
catch (RemoteException e) {
}
return;
}
else if (event_id == MouseEvent.MOUSE_PRESSED ||
event_id == MouseEvent.MOUSE_RELEASED) {
int m = ((InputEvent) event).getModifiers();
int m1 = m & InputEvent.BUTTON1_MASK;
int m2 = m & InputEvent.BUTTON2_MASK;
int m3 = m & InputEvent.BUTTON3_MASK;
int mctrl = m & InputEvent.CTRL_MASK;
int mshift = m & InputEvent.SHIFT_MASK;
if (event_id == MouseEvent.MOUSE_PRESSED) {
getDisplay().updateBusyStatus();
if (m1 != 0) {
actual_button[LEFT] = true;
}
if (m2 != 0) {
actual_button[CENTER] = true;
}
if (m3 != 0) {
actual_button[RIGHT] = true;
}
mouseModifiers = m;
}
else { // event_id == MouseEvent.MOUSE_RELEASED
getDisplay().updateBusyStatus();
if (m1 != 0) {
actual_button[LEFT] = false;
}
if (m2 != 0) {
actual_button[CENTER] = false;
}
if (m3 != 0) {
actual_button[RIGHT] = false;
}
mouseModifiers = 0;
}
// compute button combos
int n = 0, sum = 0;
for (int i=0; i<3; i++) {
if (actual_button[i]) {
n++;
sum += i;
}
}
if (n == 1) {
virtual_button = sum;
}
else if (n == 2 && getEnableCombos()) {
virtual_button = 3 - sum;
}
else { // n == 0 || n == 3 || (n == 2 && !getEnableCombos())
virtual_button = -1;
}
// compute old and new functions
for (int i=0; i<function.length; i++) {
old_function[i] = function[i];
function[i] = false;
}
int vctrl = (mctrl == 0) ? 0 : 1;
int vshift = (mshift == 0) ? 0 : 1;
int f = (virtual_button < 0) ? -1 :
function_map[virtual_button][vctrl][vshift];
if (f >= 0) function[f] = true;
boolean cursor_off = enableFunctions((MouseEvent) event);
if (event_id == MouseEvent.MOUSE_PRESSED) {
try {
DisplayEvent e = new DisplayEvent(getDisplay(),
DisplayEvent.MOUSE_PRESSED, mouse_event, remoteId);
getDisplay().notifyListeners(e);
}
catch (VisADException e) {
}
catch (RemoteException e) {
}
if (m1 != 0) {
try {
DisplayEvent e = new DisplayEvent(getDisplay(),
DisplayEvent.MOUSE_PRESSED_LEFT, mouse_event, remoteId);
getDisplay().notifyListeners(e);
}
catch (VisADException e) {
}
catch (RemoteException e) {
}
}
if (m2 != 0) {
try {
DisplayEvent e = new DisplayEvent(getDisplay(),
DisplayEvent.MOUSE_PRESSED_CENTER, mouse_event, remoteId);
getDisplay().notifyListeners(e);
}
catch (VisADException e) {
}
catch (RemoteException e) {
}
}
if (m3 != 0) {
try {
DisplayEvent e = new DisplayEvent(getDisplay(),
DisplayEvent.MOUSE_PRESSED_RIGHT, mouse_event, remoteId);
getDisplay().notifyListeners(e);
}
catch (VisADException e) {
}
catch (RemoteException e) {
}
}
}
else { // event_id == MouseEvent.MOUSE_RELEASED
try {
DisplayEvent e = new DisplayEvent(getDisplay(),
DisplayEvent.MOUSE_RELEASED, mouse_event, remoteId);
getDisplay().notifyListeners(e);
}
catch (VisADException e) {
}
catch (RemoteException e) {
}
if (m1 != 0) {
try {
DisplayEvent e = new DisplayEvent(getDisplay(),
DisplayEvent.MOUSE_RELEASED_LEFT, mouse_event, remoteId);
getDisplay().notifyListeners(e);
}
catch (VisADException e) {
}
catch (RemoteException e) {
}
}
if (m2 != 0) {
try {
DisplayEvent e = new DisplayEvent(getDisplay(),
DisplayEvent.MOUSE_RELEASED_CENTER, mouse_event, remoteId);
getDisplay().notifyListeners(e);
}
catch (VisADException e) {
}
catch (RemoteException e) {
}
}
if (m3 != 0) {
try {
DisplayEvent e = new DisplayEvent(getDisplay(),
DisplayEvent.MOUSE_RELEASED_RIGHT, mouse_event, remoteId);
getDisplay().notifyListeners(e);
}
catch (VisADException e) {
}
catch (RemoteException e) {
}
}
}
if (cursor_off) getDisplayRenderer().setCursorOn(false);
}
else if (event_id == MouseEvent.MOUSE_DRAGGED) {
handleMouseDragged(mouse_event, remoteId);
try {
DisplayEvent e = new DisplayEvent(getDisplay(),
DisplayEvent.MOUSE_DRAGGED, mouse_event, remoteId);
getDisplay().notifyListeners(e);
}
catch (VisADException e) {
}
catch (RemoteException e) {
}
}
}
protected void handleMouseDragged(MouseEvent event, int remoteId) {
MouseBehavior mouseBehavior = getMouseBehavior();
boolean cursor = function[CURSOR_TRANSLATE] ||
function[CURSOR_ZOOM] ||
function[CURSOR_ROTATE];
boolean matrix = function[ROTATE] ||
function[ZOOM] ||
function[TRANSLATE];
if (cursor || matrix || function[DIRECT]) {
getDisplay().updateBusyStatus();
Dimension d = event.getComponent().getSize();
int current_x = event.getX();
int current_y = event.getY();
if (matrix) {
double[] t1 = null;
double[] t2 = null;
if (function[ZOOM]) {
// current_y -> scale
double scale =
Math.exp((start_y-current_y) / (double) d.height);
t1 = getMouseBehavior().make_matrix(0.0, 0.0, 0.0, scale, 0.0, 0.0, 0.0);
}
if (function[TRANSLATE]) {
// current_x, current_y -> translate
// WLH 9 Aug 2000
double transx = xmul * (start_x - current_x);
double transy = ymul * (start_y - current_y);
// System.out.println("xmul = " + xmul + " ymul = " + ymul);
// System.out.println("transx = " + transx + " transy = " + transy);
t1 = getMouseBehavior().make_translate(-transx, -transy);
}
double [] myMatrix = tstart;
if (function[ROTATE]) {
if (getMode2D()) {
double transx = xmul * (start_x - current_x);
double transy = ymul * (start_y - current_y);
t1 = getMouseBehavior().make_translate(-transx, -transy);
}
else {
// don't do 3-D rotation in 2-D mode
double angley =
- (current_x - start_x) * 100.0 / (double) d.width;
double anglex =
- (current_y - start_y) * 100.0 / (double) d.height;
double[] transA = { 0.0, 0.0, 0.0 };
double[] rotA = { 0.0, 0.0, 0.0 };
double[] scaleA = { 0.0, 0.0, 0.0 };
mouseBehavior.instance_unmake_matrix(rotA, scaleA, transA, myMatrix);
if(display_renderer.getScaleRotation()) {
angley = angley/scaleA[0];
anglex = anglex/scaleA[0];
}
if(display_renderer.getRotateAboutCenter()) {
myMatrix = mouseBehavior.multiply_matrix(mouseBehavior.make_translate(-transA[0], -transA[1], -transA[2]), myMatrix);
t2 = mouseBehavior.make_translate(transA[0], transA[1], transA[2]);
}
t1 = mouseBehavior.make_matrix(anglex, angley,
0.0, 1.0, 0.0, 0.0, 0.0);
}
}
if (t1 != null) {
t1 = mouseBehavior.multiply_matrix(t1, myMatrix);
if(t2!=null) {
t1 = mouseBehavior.multiply_matrix(t2,t1);
}
try {
getProjectionControl().setMatrix(t1);
} catch (VisADException e) {}
catch (RemoteException e) {}
}
return;
} // end if (matrix)
if (function[CURSOR_ZOOM]) {
if (!getMode2D()) {
// don't do cursor Z in 2-D mode
// current_y -> 3-D cursor Z
float diff =
(start_y - current_y) * 4.0f / (float) d.height;
getDisplayRenderer().drag_depth(diff);
}
}
if (function[CURSOR_ROTATE]) {
if (!getMode2D()) {
// don't do 3-D rotation in 2-D mode
double angley =
- (current_x - start_x) * 100.0 / (double) d.width;
double anglex =
- (current_y - start_y) * 100.0 / (double) d.height;
double[] t1 = getMouseBehavior().make_matrix(anglex, angley,
0.0, 1.0, 0.0, 0.0, 0.0);
t1 = getMouseBehavior().multiply_matrix(t1, tstart);
try {
getProjectionControl().setMatrix(t1);
}
catch (VisADException e) {
}
catch (RemoteException e) {
}
}
}
if(function[CURSOR_TRANSLATE]) {
// current_x, current_y -> 3-D cursor X and Y
VisADRay cursor_ray = getMouseBehavior().findRay(current_x, current_y);
if (cursor_ray != null) {
getDisplayRenderer().drag_cursor(cursor_ray, false);
}
}
if (function[DIRECT]) {
if (direct_renderer != null) {
VisADRay direct_ray = getMouseBehavior().findRay(current_x, current_y);
if (direct_ray != null) {
direct_renderer.setLastMouseModifiers(mouseModifiers);
direct_renderer.drag_direct(direct_ray, false, mouseModifiers);
}
}
}
}
}
/**
* Enable the functions for this mouse helper
* @param event The MouseEvent
*/
protected boolean enableFunctions(MouseEvent event) {
boolean cursor_off = false;
if (event == null) {
for (int i=0; i<function.length; i++) {
old_function[i] = function[i];
function[i] = false;
}
}
// compute old and new cursor and matrix enables
boolean cursor = function[CURSOR_TRANSLATE] ||
function[CURSOR_ZOOM] ||
function[CURSOR_ROTATE];
boolean old_cursor = old_function[CURSOR_TRANSLATE] ||
old_function[CURSOR_ZOOM] ||
old_function[CURSOR_ROTATE];
boolean matrix = function[ROTATE] ||
function[ZOOM] ||
function[TRANSLATE];
boolean old_matrix = old_function[ROTATE] ||
old_function[ZOOM] ||
old_function[TRANSLATE];
// disable functions
if (old_cursor && !cursor) {
// getDisplayRenderer().setCursorOn(false);
cursor_off = true;
}
if (old_function[DIRECT] && !function[DIRECT]) {
getDisplayRenderer().setDirectOn(false);
if (direct_renderer != null) {
direct_renderer.release_direct();
direct_renderer = null;
}
}
// enable functions
if (matrix && !old_matrix) {
start_x = ((MouseEvent) event).getX();
start_y = ((MouseEvent) event).getY();
// WLH 9 Aug 2000
VisADRay start_ray = getMouseBehavior().findRay(start_x, start_y);
VisADRay start_ray_x = getMouseBehavior().findRay(start_x + 1, start_y);
VisADRay start_ray_y = getMouseBehavior().findRay(start_x, start_y + 1);
tstart = getProjectionControl().getMatrix();
// print_matrix("tstart", tstart);
double[] rot = new double[3];
double[] scale = new double[3];
double[] trans = new double[3];
getMouseBehavior().instance_unmake_matrix(rot, scale, trans, tstart);
double sts = scale[0];
double[] trot = getMouseBehavior().make_matrix(rot[0], rot[1], rot[2],
scale[0], scale[1], scale[2],
0.0, 0.0, 0.0);
// print_matrix("trot", trot);
// WLH 17 Aug 2000
double[] xmat = getMouseBehavior().make_translate(
start_ray_x.position[0] - start_ray.position[0],
start_ray_x.position[1] - start_ray.position[1],
start_ray_x.position[2] - start_ray.position[2]);
double[] ymat = getMouseBehavior().make_translate(
start_ray_y.position[0] - start_ray.position[0],
start_ray_y.position[1] - start_ray.position[1],
start_ray_y.position[2] - start_ray.position[2]);
double[] xmatmul = getMouseBehavior().multiply_matrix(trot, xmat);
double[] ymatmul = getMouseBehavior().multiply_matrix(trot, ymat);
/*
print_matrix("xmat", xmat);
print_matrix("ymat", ymat);
print_matrix("xmatmul", xmatmul);
print_matrix("ymatmul", ymatmul);
*/
getMouseBehavior().instance_unmake_matrix(rot, scale, trans, xmatmul);
xmul = trans[0];
getMouseBehavior().instance_unmake_matrix(rot, scale, trans, ymatmul);
ymul = trans[1];
// horrible hack, WLH 17 Aug 2000
if (getMouseBehavior() instanceof visad.java2d.MouseBehaviorJ2D) {
double factor = xymul / Math.sqrt(xmul * xmul + ymul * ymul);
xmul *= factor;
ymul *= factor;
xmul = Math.abs(xmul);
ymul = -Math.abs(ymul);
}
/*
System.out.println("xmul = " + Convert.shortString(xmul) +
" ymul = " + Convert.shortString(ymul) +
" scale = " + Convert.shortString(sts));
*/
} // end if (matrix && !old_matrix)
if (cursor && !old_cursor) {
// turn cursor on whenever mouse button2 pressed
getDisplayRenderer().setCursorOn(true);
start_x = ((MouseEvent) event).getX();
start_y = ((MouseEvent) event).getY();
tstart = getProjectionControl().getMatrix();
}
if (function[CURSOR_TRANSLATE] && !old_function[CURSOR_TRANSLATE]) {
VisADRay cursor_ray = getMouseBehavior().findRay(start_x, start_y);
if (cursor_ray != null) {
getDisplayRenderer().drag_cursor(cursor_ray, true);
}
}
if (function[CURSOR_ZOOM] && !old_function[CURSOR_ZOOM]) {
if (!getMode2D()) {
// don't do cursor Z in 2-D mode
// current_y -> 3-D cursor Z
VisADRay cursor_ray =
getMouseBehavior().cursorRay(getDisplayRenderer().getCursor());
getDisplayRenderer().depth_cursor(cursor_ray);
}
}
if (function[DIRECT] && !old_function[DIRECT]) {
if (getDisplayRenderer().anyDirects()) {
int current_x = ((MouseEvent) event).getX();
int current_y = ((MouseEvent) event).getY();
VisADRay direct_ray =
getMouseBehavior().findRay(current_x, current_y);
if (direct_ray != null) {
direct_renderer =
getDisplayRenderer().findDirect(direct_ray, mouseModifiers);
if (direct_renderer != null) {
getDisplayRenderer().setDirectOn(true);
direct_renderer.setLastMouseModifiers(mouseModifiers);
direct_renderer.drag_direct(direct_ray, true,
mouseModifiers);
}
}
}
}
return cursor_off;
}
/**
* Enable/disable the interpretation of any pair of mouse buttons
* as the third button.
* @param e enable/disable. If true (default), interpret any pair
* of mouse buttons as the third button.
*/
public void setEnableCombos(boolean e) {
enable_combos = e;
enableFunctions(null);
}
/**
* Get whether the mouse button combos are enabled
* @return true if any pair of mouse buttons is interpreted as the third
*/
public boolean getEnableCombos() { return enable_combos; }
/**
* Set mapping from (button, ctrl, shift) to function.
*
* <pre>
* map[button][ctrl][shift] =
* MouseHelper.NONE for no function
* MouseHelper.ROTATE for box rotate
* MouseHelper.ZOOM for box zoom
* MouseHelper.TRANSLATE for box translate
* MouseHelper.CURSOR_TRANSLATE for cursor translate
* MouseHelper.CURSOR_ZOOM for cursor on Z axis (3-D only)
* MouseHelper.CURSOR_ROTATE for box rotate with cursor
* MouseHelper.DIRECT for direct manipulate
* where button = 0 (left), 1 (center), 2 (right)
* ctrl = 0 (CTRL key not pressed), 1 (CTRL key pressed)
* shift = 0 (SHIFT key not pressed), 1 (SHIFT key pressed)
*
* Note some direct manipulation DataRenderers test the status of
* CTRL and SHIFT keys, so it is advisable that the DIRECT function
* be invariant to the state of ctrl and shift in the map array.
*
* For example, to set the left mouse button for direct
* manipulation, and the center button for box rotation
* (only without shift or control):
* mouse_helper.setFunctionMap(new int[][][]
* {{{MouseHelper.DIRECT, MouseHelper.DIRECT},
* {MouseHelper.DIRECT, MouseHelper.DIRECT}},
* {{MouseHelper.ROTATE, MouseHelper.NONE},
* {MouseHelper.NONE, MouseHelper.NONE}},
* {{MouseHelper.NONE, MouseHelper.NONE},
* {MouseHelper.NONE, MouseHelper.NONE}}});
* </pre>
* @param map map of functions. map must be int[3][2][2]
* @throws VisADException bad map
*/
public void setFunctionMap(int[][][] map) throws VisADException {
if (map == null || map.length != 3) {
throw new DisplayException("bad map array");
}
for (int i=0; i<3; i++) {
if (map[i] == null || map[i].length != 2) {
throw new DisplayException("bad map array");
}
for (int j=0; j<2; j++) {
if (map[i][j] == null || map[i][j].length != 2) {
throw new DisplayException("bad map array");
}
for (int k=0; k<2; k++) {
if (map[i][j][k] >= function.length) {
throw new DisplayException("bad map array value: " + map[i][j][k]);
}
}
}
}
for (int i=0; i<3; i++) {
for (int j=0; j<2; j++) {
for (int k=0; k<2; k++) {
function_map[i][j][k] = map[i][j][k];
}
}
}
enableFunctions(null);
}
/**
* Print out a readable form of a matrix. Useful for
* debugging.
* @param title title to prepend to output.
* @param m matrix to print.
*/
public void print_matrix(String title, double[] m) {
if (getMouseBehavior() == null) return;
double[] rot = new double[3];
double[] scale = new double[3];
double[] trans = new double[3];
getMouseBehavior().instance_unmake_matrix(rot, scale, trans, m);
StringBuffer buf = new StringBuffer(title);
buf.append(" = (");
buf.append(Convert.shortString(rot[0]));
buf.append(", ");
buf.append(Convert.shortString(rot[1]));
buf.append(", ");
buf.append(Convert.shortString(rot[2]));
buf.append("), ");
if (scale[0] == scale[1] && scale[0] == scale[2]) {
buf.append(Convert.shortString(scale[0]));
buf.append(", (");
} else {
buf.append("(");
buf.append(Convert.shortString(scale[0]));
buf.append(", ");
buf.append(Convert.shortString(scale[1]));
buf.append(", ");
buf.append(Convert.shortString(scale[2]));
buf.append("), (");
}
buf.append(Convert.shortString(trans[0]));
buf.append(", ");
buf.append(Convert.shortString(trans[1]));
buf.append(", ");
buf.append(Convert.shortString(trans[2]));
buf.append(")");
System.out.println(buf.toString());
}
/**
* Implementation for RendererSourceListener. Notifies that the
* renderer has been deleted.
* @param renderer DataRenderer that was deleted.
*/
public void rendererDeleted(DataRenderer renderer)
{
if (direct_renderer != null) {
if (direct_renderer == renderer || direct_renderer.equals(renderer)) {
direct_renderer = null;
}
}
}
}