001    /*
002     * $RCSfile: MouseZoom.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    /**
057     * MouseZoom is a Java3D behavior object that lets users control the
058     * Z axis translation of an object via a mouse drag motion with the second
059     * mouse button. See MouseRotate for similar usage info.
060     */
061    
062    public class CustomMouseZoom extends MouseZoom {
063    
064        double z_factor = .04;
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 zoom behavior given the transform group.
073         * @param transformGroup The transformGroup to operate on.
074         */
075        public CustomMouseZoom(TransformGroup transformGroup,
076                               Canvas3D haut, Canvas3D droite,
077                               Canvas3D gauche, Canvas3D face, 
078                               Canvas3D big) {
079    
080          super(transformGroup);
081          this.haut   = haut;
082          this.droite = droite;
083          this.gauche = gauche;
084          this.face   =  face;
085          this.big   =  big;
086        }
087    
088        /**
089         * Creates a default mouse zoom behavior.
090         **/
091        public CustomMouseZoom(){
092            super(0);
093        }
094    
095        /**
096         * Creates a zoom behavior.
097         * Note that this behavior still needs a transform
098         * group to work on (use setTransformGroup(tg)) and
099         * the transform group must add this behavior.
100         * @param flags
101         */
102        public CustomMouseZoom(int flags) {
103            super(flags);
104        }
105    
106        /**
107         * Creates a zoom behavior that uses AWT listeners and behavior
108         * posts rather than WakeupOnAWTEvent.  The behavior is added to the
109         * specified Component.  A null component can be passed to specify
110         * the behavior should use listeners.  Components can then be added
111         * to the behavior with the addListener(Component c) method.
112         * @param c The Component to add the MouseListener
113         * and MouseMotionListener to.
114         * @since Java 3D 1.2.1
115         */
116        public CustomMouseZoom(Component c) {
117            super(c, 0);
118        }
119    
120        /**
121         * Creates a zoom behavior that uses AWT listeners and behavior
122         * posts rather than WakeupOnAWTEvent.  The behaviors is added to
123         * the specified Component and works on the given TransformGroup.
124         * @param c The Component to add the MouseListener and
125         * MouseMotionListener to.  A null component can be passed to specify
126         * the behavior should use listeners.  Components can then be added
127         * to the behavior with the addListener(Component c) method.
128         * @param transformGroup The TransformGroup to operate on.
129         * @since Java 3D 1.2.1
130         */
131        public CustomMouseZoom(Component c, TransformGroup transformGroup) {
132            super(c, transformGroup);
133        }
134    
135        /**
136         * Creates a zoom 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
140         * to 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 CustomMouseZoom(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                z_factor *= -1;
155                invert = true;
156            }
157        }
158    
159        /**
160         * Return the y-axis movement multipler.
161         **/
162        public double getFactor() {
163            return z_factor;
164        }
165    
166        /**
167         * Set the y-axis movement multipler with factor.
168         **/
169        public void setFactor( double factor) {
170            z_factor = factor;
171        }
172    
173    
174        public void processStimulus (Enumeration criteria) {
175            WakeupCriterion wakeup;
176            AWTEvent[] events;
177            MouseEvent evt;
178    //      int id;
179    //      int dx, dy;
180    
181            while (criteria.hasMoreElements()) {
182                wakeup = (WakeupCriterion) criteria.nextElement();
183                if (wakeup instanceof WakeupOnAWTEvent) {
184                    events = ((WakeupOnAWTEvent)wakeup).getAWTEvent();
185                    if (events.length > 0) {
186                        evt = (MouseEvent) events[events.length-1];
187                        doProcess(evt);
188                    }
189                }
190    
191                else if (wakeup instanceof WakeupOnBehaviorPost) {
192                    while (true) {
193                        synchronized (mouseq) {
194                            if (mouseq.isEmpty()) break;
195                            evt = (MouseEvent)mouseq.remove(0);
196                            // consolodate MOUSE_DRAG events
197                            while((evt.getID() == MouseEvent.MOUSE_DRAGGED) &&
198                                  !mouseq.isEmpty() &&
199                                  (((MouseEvent)mouseq.get(0)).getID() ==
200                                   MouseEvent.MOUSE_DRAGGED)) {
201                                evt = (MouseEvent)mouseq.remove(0);
202                            }
203                        }
204                        doProcess(evt);
205                    }
206                }
207    
208            }
209            wakeupOn (mouseCriterion);
210        }
211    
212        void doProcess(MouseEvent evt) {
213            int id;
214            int dx, dy;
215    
216            processMouseEvent(evt);
217    
218            if (((buttonPress)&&((flags & MANUAL_WAKEUP) == 0)) ||
219                ((wakeUp)&&((flags & MANUAL_WAKEUP) != 0))){
220                id = evt.getID();
221                if ((id == MouseEvent.MOUSE_DRAGGED) &&
222                    evt.isAltDown() && !evt.isMetaDown()){
223    
224                    x = evt.getX();
225                    y = evt.getY();
226    
227                    dx = x - x_last;
228                    dy = y - y_last;
229    
230                    if (!reset){
231                      transformGroup.getTransform(currXform);
232    
233                      // Transformations specifiques a chaque canvas 3D
234                      if (evt.getSource().equals(haut)) {
235                        translation.x = 0;
236                        translation.y = dy*z_factor;
237                        translation.z = 0;
238                      }
239                      else if (evt.getSource().equals(droite)) {
240                        translation.x = -dy*z_factor;
241                        translation.y = 0;
242                        translation.z = 0;
243                      }
244                      else if (evt.getSource().equals(gauche)) {
245                        translation.x = dy*z_factor;
246                        translation.y = 0;
247                        translation.z = 0;
248                      }
249                      else if (evt.getSource().equals(face)) {
250                        translation.x = 0;
251                        translation.y = 0;
252                        translation.z = dy*z_factor;
253                      }
254                      else if (evt.getSource().equals(big)) {
255                          translation.x = 0;
256                          translation.y = 0;
257                          translation.z = dy*z_factor;
258                      }
259    
260                      transformX.set(translation);
261    
262                      if (invert) {
263                        currXform.mul(currXform, transformX);
264                      } else {
265                        currXform.mul(transformX, currXform);
266                      }
267    
268                        transformGroup.setTransform(currXform);
269    
270                        transformChanged( currXform );
271    
272                        if (callback!=null)
273                            callback.transformChanged( MouseBehaviorCallback.ZOOM,
274                                                       currXform );
275    
276                    }
277                    else {
278                        reset = false;
279                    }
280    
281                    x_last = x;
282                    y_last = y;
283                }
284                else if (id == MouseEvent.MOUSE_PRESSED) {
285                    x_last = evt.getX();
286                    y_last = evt.getY();
287                }
288            }
289        }
290    
291    
292      /**
293        * Users can overload this method  which is called every time
294        * the Behavior updates the transform
295        *
296        * Default implementation does nothing
297        */
298      public void transformChanged( Transform3D transform ) {
299      }
300    
301      /**
302        * The transformChanged method in the callback class will
303        * be called every time the transform is updated
304        */
305      public void setupCallback( MouseBehaviorCallback callback ) {
306          this.callback = callback;
307      }
308    }
309