001 /* 002 * $RCSfile: MouseTranslate.java,v $ 003 * 004 * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. 005 * 006 * Redistribution and use in source and binary forms, with or without 007 * modification, are permitted provided that the following conditions 008 * are met: 009 * 010 * - Redistribution of source code must retain the above copyright 011 * notice, this list of conditions and the following disclaimer. 012 * 013 * - Redistribution in binary form must reproduce the above copyright 014 * notice, this list of conditions and the following disclaimer in 015 * the documentation and/or other materials provided with the 016 * distribution. 017 * 018 * Neither the name of Sun Microsystems, Inc. or the names of 019 * contributors may be used to endorse or promote products derived 020 * from this software without specific prior written permission. 021 * 022 * This software is provided "AS IS," without a warranty of any 023 * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND 024 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, 025 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY 026 * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL 027 * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF 028 * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS 029 * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR 030 * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, 031 * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND 032 * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR 033 * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE 034 * POSSIBILITY OF SUCH DAMAGES. 035 * 036 * You acknowledge that this software is not designed, licensed or 037 * intended for use in the design, construction, operation or 038 * maintenance of any nuclear facility. 039 * 040 * $Revision: 1.1 $ 041 * $Date: 2004/06/09 04:10:25 $ 042 * $State: Exp $ 043 */ 044 045 package com.appearance3Dchooser; 046 047 import java.awt.*; 048 import java.awt.event.*; 049 import java.util.*; 050 051 import com.sun.j3d.utils.behaviors.mouse.*; 052 import javax.media.j3d.*; 053 import javax.vecmath.*; 054 055 /** 056 * MouseTranslate is a Java3D behavior object that lets users control the 057 * translation (X, Y) of an object via a mouse drag motion with the third 058 * mouse button (alt-click on PC). See MouseRotate for similar usage info. 059 */ 060 061 public class CustomMouseTranslate extends MouseTranslate { 062 063 double x_factor = .02; 064 double y_factor = .02; 065 Vector3d translation = new Vector3d(); 066 067 private MouseBehaviorCallback callback = null; 068 069 private Canvas3D haut, droite, gauche, face, big = null; 070 071 /** 072 * Creates a mouse translate behavior given the transform group. 073 * @param transformGroup The transformGroup to operate on. 074 */ 075 public CustomMouseTranslate(TransformGroup transformGroup, 076 Canvas3D haut, Canvas3D droite, 077 Canvas3D gauche, Canvas3D face, 078 Canvas3D big) { 079 super(transformGroup); 080 this.haut = haut; 081 this.droite = droite; 082 this.gauche = gauche; 083 this.face = face; 084 this.big = big; 085 } 086 087 /** 088 * Creates a default translate behavior. 089 */ 090 public CustomMouseTranslate(){ 091 super(0); 092 } 093 094 /** 095 * Creates a translate behavior. 096 * Note that this behavior still needs a transform 097 * group to work on (use setTransformGroup(tg)) and 098 * the transform group must add this behavior. 099 * @param flags 100 */ 101 public CustomMouseTranslate(int flags) { 102 super(flags); 103 } 104 105 /** 106 * Creates a translate behavior that uses AWT listeners and behavior 107 * posts rather than WakeupOnAWTEvent. The behavior is added to the 108 * specified Component. A null component can be passed to specify 109 * the behavior should use listeners. Components can then be added 110 * to the behavior with the addListener(Component c) method. 111 * @param c The Component to add the MouseListener 112 * and MouseMotionListener to. 113 * @since Java 3D 1.2.1 114 */ 115 public CustomMouseTranslate(Component c) { 116 super(c, 0); 117 } 118 119 /** 120 * Creates a translate behavior that uses AWT listeners and behavior 121 * posts rather than WakeupOnAWTEvent. The behaviors is added to 122 * the specified Component and works on the given TransformGroup. 123 * A null component can be passed to specify the behavior should use 124 * listeners. Components can then be added to the behavior with the 125 * addListener(Component c) method. 126 * @param c The Component to add the MouseListener and 127 * MouseMotionListener to. 128 * @param transformGroup The TransformGroup to operate on. 129 * @since Java 3D 1.2.1 130 */ 131 public CustomMouseTranslate(Component c, TransformGroup transformGroup) { 132 super(c, transformGroup); 133 } 134 135 /** 136 * Creates a translate behavior that uses AWT listeners and behavior 137 * posts rather than WakeupOnAWTEvent. The behavior is added to the 138 * specified Component. A null component can be passed to specify 139 * the behavior should use listeners. Components can then be added to 140 * the behavior with the addListener(Component c) method. 141 * Note that this behavior still needs a transform 142 * group to work on (use setTransformGroup(tg)) and the transform 143 * group must add this behavior. 144 * @param flags interesting flags (wakeup conditions). 145 * @since Java 3D 1.2.1 146 */ 147 public CustomMouseTranslate(Component c, int flags) { 148 super(c, flags); 149 } 150 151 public void initialize() { 152 super.initialize(); 153 if ((flags & INVERT_INPUT) == INVERT_INPUT) { 154 invert = true; 155 x_factor *= -1; 156 y_factor *= -1; 157 } 158 } 159 160 /** 161 * Return the x-axis movement multipler. 162 **/ 163 public double getXFactor() { 164 return x_factor; 165 } 166 167 /** 168 * Return the y-axis movement multipler. 169 **/ 170 public double getYFactor() { 171 return y_factor; 172 } 173 174 /** 175 * Set the x-axis amd y-axis movement multipler with factor. 176 **/ 177 public void setFactor( double factor) { 178 x_factor = y_factor = factor; 179 } 180 181 /** 182 * Set the x-axis amd y-axis movement multipler with xFactor and yFactor 183 * respectively. 184 **/ 185 public void setFactor( double xFactor, double yFactor) { 186 x_factor = xFactor; 187 y_factor = yFactor; 188 } 189 190 public void processStimulus (Enumeration criteria) { 191 WakeupCriterion wakeup; 192 AWTEvent[] events; 193 MouseEvent evt; 194 // int id; 195 // int dx, dy; 196 197 while (criteria.hasMoreElements()) { 198 wakeup = (WakeupCriterion) criteria.nextElement(); 199 200 if (wakeup instanceof WakeupOnAWTEvent) { 201 events = ((WakeupOnAWTEvent)wakeup).getAWTEvent(); 202 if (events.length > 0) { 203 evt = (MouseEvent) events[events.length-1]; 204 doProcess(evt); 205 } 206 } 207 208 else if (wakeup instanceof WakeupOnBehaviorPost) { 209 while (true) { 210 // access to the queue must be synchronized 211 synchronized (mouseq) { 212 if (mouseq.isEmpty()) break; 213 evt = (MouseEvent)mouseq.remove(0); 214 // consolodate MOUSE_DRAG events 215 while ((evt.getID() == MouseEvent.MOUSE_DRAGGED) && 216 !mouseq.isEmpty() && 217 (((MouseEvent)mouseq.get(0)).getID() == 218 MouseEvent.MOUSE_DRAGGED)) { 219 evt = (MouseEvent)mouseq.remove(0); 220 } 221 } 222 doProcess(evt); 223 } 224 } 225 226 } 227 wakeupOn(mouseCriterion); 228 } 229 230 void doProcess(MouseEvent evt) { 231 int id; 232 int dx, dy; 233 234 processMouseEvent(evt); 235 236 if (((buttonPress)&&((flags & MANUAL_WAKEUP) == 0)) || 237 ((wakeUp)&&((flags & MANUAL_WAKEUP) != 0))){ 238 id = evt.getID(); 239 if ((id == MouseEvent.MOUSE_DRAGGED) && 240 !evt.isAltDown() && evt.isMetaDown()) { 241 242 x = evt.getX(); 243 y = evt.getY(); 244 245 dx = x - x_last; 246 dy = y - y_last; 247 248 if ((!reset) && ((Math.abs(dy) < 50) && (Math.abs(dx) < 50))) { 249 //System.out.println("dx " + dx + " dy " + dy); 250 transformGroup.getTransform(currXform); 251 252 // Transformations specifiques a chaque canvas 3D 253 if (evt.getSource().equals(haut)) { 254 translation.x = dx*x_factor; 255 translation.y = 0; 256 translation.z = dy*y_factor; 257 } 258 else if (evt.getSource().equals(droite)) { 259 translation.x = 0; 260 translation.y = -dy*y_factor; 261 translation.z = -dx*x_factor; 262 } 263 else if (evt.getSource().equals(gauche)) { 264 translation.x = 0; 265 translation.y = -dy*y_factor; 266 translation.z = dx*x_factor; 267 } 268 else if (evt.getSource().equals(face)) { 269 translation.x = dx*x_factor; 270 translation.y = -dy*y_factor; 271 translation.z = 0; 272 } 273 else if (evt.getSource().equals(big)) { 274 translation.x = dx*x_factor; 275 translation.y = -dy*y_factor; 276 translation.z = 0; 277 } 278 279 transformX.set(translation); 280 281 if (invert) { 282 currXform.mul(currXform, transformX); 283 } else { 284 currXform.mul(transformX, currXform); 285 } 286 287 transformGroup.setTransform(currXform); 288 289 transformChanged( currXform ); 290 291 if (callback!=null) 292 callback.transformChanged( MouseBehaviorCallback.TRANSLATE, 293 currXform ); 294 295 } 296 else { 297 reset = false; 298 } 299 x_last = x; 300 y_last = y; 301 } 302 else if (id == MouseEvent.MOUSE_PRESSED) { 303 x_last = evt.getX(); 304 y_last = evt.getY(); 305 } 306 } 307 } 308 309 /** 310 * Users can overload this method which is called every time 311 * the Behavior updates the transform 312 * 313 * Default implementation does nothing 314 */ 315 public void transformChanged( Transform3D transform ) { 316 } 317 318 /** 319 * The transformChanged method in the callback class will 320 * be called every time the transform is updated 321 */ 322 public void setupCallback( MouseBehaviorCallback callback ) { 323 this.callback = callback; 324 } 325 } 326