I send the file to you for reference, the demo is given at
http://vlab.ee.nus.edu.sg/~ccd/VR
Cheng Chang Dong
----- Original Message -----
From: "LeW on Yahoo" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Monday, January 28, 2002 5:30 AM
Subject: [JAVA3D] custom MouseBehavior: catching MouseEntered
> hello,
> .confused with custom MouseBehavior writing.
>
> I have situation like this:
>
> -BranchGroup
> --TransformGroup1
> ----Sphere1
> --TransformGroup2
> ----Sphere2
>
> how catch mouse pointer events (for example MouseEntered, MouseExited,
MouseClicked)
> for TransformGroups or Spheres?
> any ideas, demos, working examples?
>
> thanks, LeW.
>
> p.s.
> ;) ..I don't have problems with such units as MouseRotate or
PickRotateBehavior, its
> working..
>
>
>
>
>
> _________________________________________________________
> Do You Yahoo!?
> Get your free @yahoo.com address at http://mail.yahoo.com
>
>
>
===========================================================================
> To unsubscribe, send email to [EMAIL PROTECTED] and include in the
body
> of the message "signoff JAVA3D-INTEREST". For general help, send email to
> [EMAIL PROTECTED] and include in the body of the message "help".
import javax.media.j3d.*;
import javax.vecmath.*;
import java.awt.event.*;
import java.awt.AWTEvent;
import java.util.Enumeration;
import javax.swing.event.*;
import javax.swing.*;
public class NavigatorBehavior extends Behavior implements MouseListener,
MouseMotionListener, ActionListener, ItemListener, ChangeListener
{
private TransformGroup viewTrans;
private TransformGroup bodyTrans;
private TransformGroup outsideTrans;
private Matrix3f comMat = new Matrix3f();
private Shape3D bodyshape;
private int direction;
private WakeupCriterion eventsCondition[] = new WakeupCriterion[3];
private WakeupOr allEvents;
private String buttonvalue = new String();
private boolean poststop = false;
private float turningAngle = 0.0f;
private float pitchAngle = 0.0f;
private Point3f viewposi = new Point3f();
private Point3f firstviewposi = new Point3f();
private Point3f outsideposi = new Point3f();
private boolean ticked = false;
private int delay = 20;
private JSlider FrameDelay;
private Animation animator; //for animating thread;
private boolean animating = false;
private BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 0.1);
private static final float PAI = 3.14159f;
private static final float ANGLEPAI = 2.0f*PAI/360.0f;
private static final float SPAN = 0.02f;
private static final float ANGLESTEP = 0.01f;
private static final float Outsidescale = 0.4f;
private static final int VIEWMOTION = 5001;
private static final int DOOROPEN = 401;
private static final int DOORCLOSE = 402;
private static final int ANIMATION = 501;
private static final int INTERACTION = 502;
private static final int Forward = KeyEvent.VK_UP;
private static final int Backward = KeyEvent.VK_DOWN;
private static final int LEFT = KeyEvent.VK_LEFT;
private static final int RIGHT = KeyEvent.VK_RIGHT;
private static final int SHIFTRIGHT = KeyEvent.VK_R;
private static final int SHIFTLEFT = KeyEvent.VK_L;
private static final int Up = KeyEvent.VK_U;
private static final int Down = KeyEvent.VK_D;
NavigatorBehavior(TransformGroup viewTrans, TransformGroup bodyTrans, Shape3D bodyshape)
{
this.bodyshape = bodyshape;
this.viewTrans = viewTrans;
this.bodyTrans = bodyTrans;
}
public void initPosition(Point3f initposi)
{
this.viewposi = new Point3f(initposi);
firstviewposi = new Point3f(initposi);
init();
}
public void setOutside(TransformGroup outsideTrans, Point3f outsideposi)
{
this.outsideTrans = outsideTrans;
this.outsideposi = new Point3f(outsideposi);
}
public void setObject(JSlider FrameDelay)
{
this.FrameDelay = FrameDelay;
}
private void init()
{
comMat.m00 = 1.0f;
comMat.m01 = 0.0f;
comMat.m02 = 0.0f;
comMat.m10 = 0.0f;
comMat.m11 = 1.0f;
comMat.m12 = 0.0f;
comMat.m20 = 0.0f;
comMat.m21 = 0.0f;
comMat.m22 = 1.0f;
}
private Matrix3f coMatrix(int mode, float angle)
{
Matrix3f tempMat = new Matrix3f();
switch (mode)
{
case 1:
tempMat.m00 = (float)(Math.cos(angle));
tempMat.m01 = 0.0f;
tempMat.m02 = (float)(Math.sin(angle));
tempMat.m10 = 0.0f;
tempMat.m11 = 1.0f;
tempMat.m12 = 0.0f;
tempMat.m20 = (float)(-Math.sin(angle));
tempMat.m21 = 0.0f;
tempMat.m22 = (float)(Math.cos(angle));
break;
case 2:
tempMat.m00 = 1.0f;
tempMat.m01 = 0.0f;
tempMat.m02 = 0.0f;
tempMat.m10 = 0.0f;
tempMat.m11 = (float)(Math.cos(angle));
tempMat.m12 = (float)(Math.sin(angle));
tempMat.m20 = 0.0f;
tempMat.m21 = (float)(-Math.sin(angle));
tempMat.m22 = (float)(Math.cos(angle));
break;
case 3:
tempMat.m00 = (float)(Math.cos(angle));
tempMat.m01 = (float)(-Math.sin(angle));
tempMat.m02 = 0.0f;
tempMat.m10 = (float)(Math.sin(angle));
tempMat.m11 = (float)(Math.cos(angle));
tempMat.m12 = 0.0f;
tempMat.m20 = 0.0f;
tempMat.m21 = 0.0f;
tempMat.m22 = 1.0f;
break;
default:
}
return tempMat;
}
private void setRotation(TransformGroup Trans, float angle, Matrix3f rotMat, int mode)
{
Transform3D rt3d = new Transform3D();
Trans.getTransform(rt3d);
rotMat.transpose();
rotMat.invert();
rotMat.mul(rotMat, coMatrix(mode, angle));
rt3d.setRotation(rotMat);
Trans.setTransform(rt3d);
}
private Point3f setTranslation(Matrix3f rotMat, Point3f posi)
{
Point3f tempposi = new Point3f();
tempposi.x = rotMat.m00*posi.x + rotMat.m01*posi.y + rotMat.m02*(posi.z+0.01f);
tempposi.y = rotMat.m10*posi.x + rotMat.m11*posi.y + rotMat.m12*(posi.z+0.01f);
tempposi.z = rotMat.m20*posi.x + rotMat.m21*posi.y + rotMat.m22*(posi.z+0.01f);
return tempposi;
}
private void setPosition(TransformGroup Trans, Point3f point)
{
Transform3D t3d = new Transform3D();
Trans.getTransform(t3d);
t3d.setTranslation(new Vector3d(point));
Trans.setTransform(t3d);
}
public void initialize()
{
eventsCondition[0] = new WakeupOnAWTEvent(KeyEvent.KEY_PRESSED);
eventsCondition[1] = new WakeupOnCollisionEntry(bodyshape);
eventsCondition[2] = new WakeupOnBehaviorPost(null, VIEWMOTION);
allEvents = new WakeupOr(eventsCondition);
wakeupOn(allEvents);
}
private void processKeyEvent(KeyEvent e)
{
int key = e.getKeyCode();
direction = key;
switch(key)
{
case Forward:
direction = Forward;
viewposi.x = viewposi.x-SPAN*(float)Math.sin(turningAngle);
viewposi.z = viewposi.z-SPAN*(float)Math.cos(turningAngle);
setPosition(bodyTrans, viewposi);
setPosition(viewTrans, viewposi);
if (outsideTrans!=null)
setPosition(outsideTrans, new Point3f(Outsidescale*viewposi.x, outsideposi.y, outsideposi.z));
break;
case Backward:
direction = Backward;
viewposi.x = viewposi.x+SPAN*(float)Math.sin(turningAngle);
viewposi.z = viewposi.z+SPAN*(float)Math.cos(turningAngle);
setPosition(bodyTrans, viewposi);
setPosition(viewTrans, viewposi);
if (outsideTrans!=null)
setPosition(outsideTrans, new Point3f(Outsidescale*viewposi.x, outsideposi.y, outsideposi.z));
break;
case LEFT:
setRotation(viewTrans, ANGLESTEP, comMat, 1);
turningAngle += ANGLESTEP;
break;
case RIGHT:
setRotation(viewTrans, -ANGLESTEP, comMat, 1);
turningAngle -= ANGLESTEP;
break;
case Up:
if (viewposi.y<1.7f)
{
viewposi.y = viewposi.y+SPAN/2.0f;
setPosition(viewTrans, viewposi);
setPosition(bodyTrans, viewposi);
}
break;
case Down:
if (viewposi.y>1.0f)
{
viewposi.y = viewposi.y-SPAN/2.0f;
setPosition(viewTrans, viewposi);
setPosition(bodyTrans, viewposi);
}
break;
case SHIFTLEFT:
direction = SHIFTLEFT;
viewposi.x = viewposi.x-SPAN*(float)Math.sin(turningAngle+Math.PI/2.0);
viewposi.z = viewposi.z-SPAN*(float)Math.cos(turningAngle+Math.PI/2.0);
setPosition(bodyTrans, viewposi);
setPosition(viewTrans, viewposi);
if (outsideTrans!=null)
setPosition(outsideTrans, new Point3f(Outsidescale*viewposi.x, outsideposi.y, outsideposi.z));
break;
case SHIFTRIGHT:
direction = SHIFTRIGHT;
viewposi.x = viewposi.x+SPAN*(float)Math.sin(turningAngle+Math.PI/2.0);
viewposi.z = viewposi.z+SPAN*(float)Math.cos(turningAngle+Math.PI/2.0);
setPosition(bodyTrans, viewposi);
setPosition(viewTrans, viewposi);
if (outsideTrans!=null)
setPosition(outsideTrans, new Point3f(Outsidescale*viewposi.x, outsideposi.y, outsideposi.z));
break;
default:
}
}
public void processStimulus(Enumeration criteria)
{
WakeupCriterion wakeup;
AWTEvent[] event;
int eventId;
if (!animating)
{
while (criteria.hasMoreElements())
{
wakeup = (WakeupCriterion) criteria.nextElement();
if (wakeup instanceof WakeupOnAWTEvent)
{
event = ((WakeupOnAWTEvent)wakeup).getAWTEvent();
for (int i=0; i<event.length; i++)
{
processKeyEvent((KeyEvent) event[i]);
}
}
if (wakeup instanceof WakeupOnBehaviorPost)
{
try {
Thread.sleep(delay);
} catch (Exception ie) {
System.out.println("Interrupted Exception!");
}
if (buttonvalue.indexOf("Forward") != -1)
{
direction = Forward;
viewposi.x = viewposi.x-SPAN*(float)Math.sin(turningAngle);
viewposi.z = viewposi.z-SPAN*(float)Math.cos(turningAngle);
setPosition(bodyTrans, viewposi);
setPosition(viewTrans, viewposi);
if (outsideTrans!=null)
setPosition(outsideTrans, new Point3f(Outsidescale*viewposi.x, outsideposi.y, outsideposi.z));
}
else if (buttonvalue.indexOf("Backward") != -1)
{
direction = Backward;
viewposi.x = viewposi.x+SPAN*(float)Math.sin(turningAngle);
viewposi.z = viewposi.z+SPAN*(float)Math.cos(turningAngle);
setPosition(bodyTrans, viewposi);
setPosition(viewTrans, viewposi);
if (outsideTrans!=null)
setPosition(outsideTrans, new Point3f(Outsidescale*viewposi.x, outsideposi.y, outsideposi.z));
}
else if (buttonvalue.indexOf("Turnleft") != -1)
{
if (pitchAngle!=0)
{
setRotation(viewTrans, -pitchAngle, comMat, 2);
pitchAngle = 0.0f;
}
setRotation(viewTrans, ANGLESTEP, comMat, 1);
turningAngle += ANGLESTEP;
}
else if (buttonvalue.indexOf("Turnright") != -1)
{
if (pitchAngle!=0)
{
setRotation(viewTrans, -pitchAngle, comMat, 2);
pitchAngle = 0.0f;
}
setRotation(viewTrans, -pitchAngle, comMat, 2);
pitchAngle = 0.0f;
setRotation(viewTrans, -ANGLESTEP, comMat, 1);
turningAngle -= ANGLESTEP;
}
else if (buttonvalue.indexOf("Pitchup") != -1)
{
if (pitchAngle>-10.0f*ANGLEPAI)
{
setRotation(viewTrans, -ANGLESTEP, comMat, 2);
pitchAngle -= ANGLESTEP;
}
}
else if (buttonvalue.indexOf("Pitchdown") != -1)
{
if (pitchAngle<10.0f*ANGLEPAI)
{
setRotation(viewTrans, ANGLESTEP, comMat, 2);
pitchAngle += ANGLESTEP;
}
}
else if (buttonvalue.indexOf("Yawleft") != -1)
{
}
else if (buttonvalue.indexOf("Yawright") != -1)
{
}
else if (buttonvalue.indexOf("Horizontal") != -1)
{
if (pitchAngle!=0)
{
setRotation(viewTrans, -pitchAngle, comMat, 2);
pitchAngle = 0.0f;
}
}
else if (buttonvalue.indexOf("Original") != -1)
{
viewposi = new Point3f(firstviewposi);
if (pitchAngle!=0)
{
setRotation(viewTrans, -pitchAngle, comMat, 2);
pitchAngle = 0.0f;
}
if (turningAngle!=0)
{
setRotation(viewTrans, -turningAngle, comMat, 1);
turningAngle = 0.0f;
}
setPosition(bodyTrans, viewposi);
setPosition(viewTrans, viewposi);
if (outsideTrans!=null)
setPosition(outsideTrans, new Point3f(Outsidescale*viewposi.x, outsideposi.y, outsideposi.z));
}
else if (buttonvalue.indexOf("Up") != -1)
{
if (viewposi.y<1.7f)
{
viewposi.y = viewposi.y+SPAN/2.0f;
setPosition(viewTrans, viewposi);
setPosition(bodyTrans, viewposi);
}
}
else if (buttonvalue.indexOf("Down") != -1)
{
if (viewposi.y>1.0f)
{
viewposi.y = viewposi.y-SPAN/2.0f;
setPosition(viewTrans, viewposi);
setPosition(bodyTrans, viewposi);
}
}
else if (buttonvalue.indexOf("Shiftleft") != -1)
{
direction = SHIFTLEFT;
viewposi.x = viewposi.x-SPAN*(float)Math.sin(turningAngle+Math.PI/2.0);
viewposi.z = viewposi.z-SPAN*(float)Math.cos(turningAngle+Math.PI/2.0);
setPosition(bodyTrans, viewposi);
setPosition(viewTrans, viewposi);
if (outsideTrans!=null)
setPosition(outsideTrans, new Point3f(Outsidescale*viewposi.x, outsideposi.y, outsideposi.z));
}
else if (buttonvalue.indexOf("Shiftright") != -1)
{
direction = SHIFTRIGHT;
viewposi.x = viewposi.x+SPAN*(float)Math.sin(turningAngle+Math.PI/2.0);
viewposi.z = viewposi.z+SPAN*(float)Math.cos(turningAngle+Math.PI/2.0);
setPosition(bodyTrans, viewposi);
setPosition(viewTrans, viewposi);
if (outsideTrans!=null)
setPosition(outsideTrans, new Point3f(Outsidescale*viewposi.x, outsideposi.y, outsideposi.z));
}
if (poststop) postId(VIEWMOTION);
}
if (wakeup instanceof WakeupOnCollisionEntry)
{
// The implememtation of the collision function, go back two step when
// the collision occurs in order to obtain the next collision ability
switch (direction)
{
case Forward:
viewposi.x = viewposi.x+2.0f*SPAN*(float)Math.sin(turningAngle);
viewposi.z = viewposi.z+2.0f*SPAN*(float)Math.cos(turningAngle);
setPosition(bodyTrans, viewposi);
setPosition(viewTrans, viewposi);
if (outsideTrans!=null)
setPosition(outsideTrans, new Point3f(Outsidescale*viewposi.x, outsideposi.y, outsideposi.z));
break;
case Backward:
viewposi.x = viewposi.x-2.0f*SPAN*(float)Math.sin(turningAngle);
viewposi.z = viewposi.z-2.0f*SPAN*(float)Math.cos(turningAngle);
setPosition(bodyTrans, viewposi);
setPosition(viewTrans, viewposi);
if (outsideTrans!=null)
setPosition(outsideTrans, new Point3f(Outsidescale*viewposi.x, outsideposi.y, outsideposi.z));
break;
case SHIFTLEFT:
viewposi.x = viewposi.x+2.0f*SPAN*(float)Math.sin(turningAngle+Math.PI/2.0);
viewposi.z = viewposi.z+2.0f*SPAN*(float)Math.cos(turningAngle+Math.PI/2.0);
setPosition(bodyTrans, viewposi);
setPosition(viewTrans, viewposi);
if (outsideTrans!=null)
setPosition(outsideTrans, new Point3f(Outsidescale*viewposi.x, outsideposi.y, outsideposi.z));
break;
case SHIFTRIGHT:
viewposi.x = viewposi.x-2.0f*SPAN*(float)Math.sin(turningAngle+Math.PI/2.0);
viewposi.z = viewposi.z-2.0f*SPAN*(float)Math.cos(turningAngle+Math.PI/2.0);
setPosition(bodyTrans, viewposi);
setPosition(viewTrans, viewposi);
if (outsideTrans!=null)
setPosition(outsideTrans, new Point3f(Outsidescale*viewposi.x, outsideposi.y, outsideposi.z));
break;
default:
}
//System.out.println("Collision!");
}
}
}
this.wakeupOn(allEvents);
}
public void actionPerformed(ActionEvent e)
{
//String name = ((Component)e.getSource()).getName();
String radiobutton = e.getActionCommand();
//System.out.println(" buttonvalue = " + radiobutton);
if (radiobutton.indexOf("Animation")!=-1)
{
animating = true;
viewposi = new Point3f(firstviewposi);
if (pitchAngle!=0)
{
setRotation(viewTrans, -pitchAngle, comMat, 2);
pitchAngle = 0.0f;
}
if (turningAngle!=0)
{
setRotation(viewTrans, -turningAngle, comMat, 1);
turningAngle = 0.0f;
}
setPosition(bodyTrans, viewposi);
setPosition(viewTrans, viewposi);
if (outsideTrans!=null)
setPosition(outsideTrans, new Point3f(Outsidescale*viewposi.x, outsideposi.y, outsideposi.z));
postId(DOOROPEN);
if (animator == null)
{
animator = new Animation();
animator.running = true;
}
else if (!animator.running)
{
animator.running = true;
}
postId(ANIMATION);
}
else if (radiobutton.indexOf("Interaction")!=-1)
{
animating = false;
viewposi = new Point3f(firstviewposi);
if (pitchAngle!=0)
{
setRotation(viewTrans, -pitchAngle, comMat, 2);
pitchAngle = 0.0f;
}
if (turningAngle!=0)
{
setRotation(viewTrans, -turningAngle, comMat, 1);
turningAngle = 0.0f;
}
setPosition(bodyTrans, viewposi);
setPosition(viewTrans, viewposi);
if (outsideTrans!=null)
setPosition(outsideTrans, new Point3f(Outsidescale*viewposi.x, outsideposi.y, outsideposi.z));
postId(DOORCLOSE);
if (animator != null)
{
if (animator.AnimationThread.isAlive())
{
animator.running = false; //quit the measuring loop
}
}
animator = null;
postId(INTERACTION);
}
}
public void mouseReleased(MouseEvent e)
{
poststop = false;
}
public void mousePressed(MouseEvent e)
{
// buttonvalue = e.getSource().toString();
buttonvalue = null;
int positionX = e.getX();
int positionY = e.getY();
// System.out.println(positionX+" "+positionY);//to be removed in the final program
if(positionX>722 && positionX<734 && positionY>58 && positionY<71)
{
buttonvalue = "Shiftleft";
}
else if(positionX>826 && positionX<839 && positionY>55 && positionY<69)
{
buttonvalue = "Shiftright";
}
else if(positionX>772 && positionX<788 && positionY>7 && positionY<21)
{
buttonvalue = "Up";
}
else if(positionX>772 && positionX<788 && positionY>102 && positionY<114)
{
buttonvalue = "Down";
}
else if(positionX>785 && positionX<798 && positionY>40 && positionY<52)
{
buttonvalue = "Forward";
}
else if(positionX>758 && positionX<771 && positionY>74 && positionY<86)
{
buttonvalue = "Backward";
}
else if(positionX>767 && positionX<791 && positionY>52 && positionY<64)
{
buttonvalue = "Original";
}
else if(positionX>883 && positionX<896 && positionY>53 && positionY<73)
{
buttonvalue = "Turnleft";
}
else if(positionX>974 && positionX<985 && positionY>52 && positionY<75)
{
buttonvalue = "Turnright";
}
else if(positionX>922 && positionX<944 && positionY>14 && positionY<22)
{
buttonvalue = "Pitchup";
}
else if(positionX>922 && positionX<942 && positionY>100 && positionY<113)
{
buttonvalue = "Pitchdown";
}
else if(positionX>925 && positionX<942 && positionY>57 && positionY<77)
{
buttonvalue = "Horizontal";
}
if (buttonvalue != null)
{
poststop = true;
postId(VIEWMOTION);
}
}
public void mouseExited(MouseEvent e)
{
}
public void mouseEntered(MouseEvent e)
{
}
public void mouseClicked(MouseEvent e)
{
}
public void mouseMoved(MouseEvent e)
{
}
public void mouseDragged(MouseEvent e)
{
}
public void stateChanged(ChangeEvent e)
{
if (e.getSource().toString().indexOf("majorTickSpacing=30")!=-1)
{
delay = FrameDelay.getValue();
}
}
public void itemStateChanged(ItemEvent e)
{
if (e.getSource().toString().indexOf("Keyboard")!=-1)
{
if (e.getStateChange() == ItemEvent.DESELECTED)
{
ticked = false;
}
else ticked = true;
//System.out.println(ticked);
}
}
class Animation implements Runnable
{
boolean running = false;
Thread AnimationThread;
public Animation()
{
AnimationThread = new Thread(this);
AnimationThread.start(); //call function run() to begin to measure
}
public void run()
{
try {
AnimationThread.sleep(1000);
} catch (Exception ie) {
System.out.println("Interrupted Exception!");
}
while (running)
{
if (viewposi.z>-2.0f)
{
viewposi.z = viewposi.z - 2.0f*SPAN;
setPosition(bodyTrans, viewposi);
setPosition(viewTrans, viewposi);
if (outsideTrans!=null)
setPosition(outsideTrans, new Point3f(Outsidescale*viewposi.x, outsideposi.y, outsideposi.z));
}
else
{
viewposi.z=-2.0f;
setRotation(viewTrans, ANGLESTEP, comMat, 1);
turningAngle += ANGLESTEP;
}
try {
AnimationThread.sleep(80);
} catch (Exception ie) {
System.out.println("Interrupted Exception!");
}
}
AnimationThread.interrupt(); //stop measuring
}
}
} // end of class NavigatorBehavior