Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

11991 Posts in 1587 Topics- by 3508 Members - Latest Member: NevilleKemp

26. May 2012, 03:53:53 pm
Xith3D CommunityGeneral CategorySupport (Moderator: Marvin Fröhlich)[SOLVED] Mouse capturing and tabbed view disappearances
Pages: [1] 2
Print
Author Topic: [SOLVED] Mouse capturing and tabbed view disappearances  (Read 1250 times)
ChrisE
Becoming dependent
**
Offline Offline

Posts: 104


View Profile
« on: 15. November 2010, 04:23:25 pm »

I've got Xith up and running in my Swing application, and need to do the following two things:

1. Keep mouse centered in the viewport such that it doesn't wander off into other panels.
2. Hide mouse while this is happening.

To do 1, I thought about using the setPosition() method to undo any dx,dy from the mouse after processing movements. This is how I'd normally handle it in my own applications. However, would this in fact keep the mouse in the panel?

To do 2, I haven't the faintest idea. Is there a way to hide the mouse cursor in Xith?

Many thanks,
-Chris
« Last Edit: 18. November 2010, 08:47:31 pm by ChrisE » Logged
ChrisE
Becoming dependent
**
Offline Offline

Posts: 104


View Profile
« Reply #1 on: 15. November 2010, 04:27:37 pm »

Update: Possible answer to 2.

So, you can apparently use swing to do the following:

Code:
setCursor(getToolkit().createCustomCursor(new BufferedImage(3, 3, BufferedImage.TYPE_INT_ARGB), new Point(0, 0), "null"));

This makes an empty cursor for use in that component hierarchy, it would appear.

This seems kind of hackish to me, so any other ideas are welcome.

EDIT: Nope, this works absolutely correctly. The question remains for 1, though: how to keep the mouse centered?
« Last Edit: 15. November 2010, 05:16:12 pm by ChrisE » Logged
Marvin Fröhlich
Xith Lord
Administrator
Guru
*****
Offline Offline

Posts: 4381


May the 4th, be with you...


View Profile
« Reply #2 on: 15. November 2010, 06:03:43 pm »

This works out of the box in Xith. All you need to do is to register a new mouse on the InputSystem and set that mouse to "relative" or non "absolute" (IIRC this was the name). Then the cursor will be automatically hidden and the position will be sticked to the center.

Just have a look at the FirstPersonInputHandlerTest. If you hold the CTRL key, the mouse is shown and if you release the key, the mouse is hidden. Should be exactly, what you need.

Marvin
Logged
ChrisE
Becoming dependent
**
Offline Offline

Posts: 104


View Profile
« Reply #3 on: 15. November 2010, 07:45:36 pm »

Marvin,

It doesn't appear to hide the cursor (might be an artifact of our Swing setup; has some *interesting* quirks), but otherwise works as advertised. Thank you very much.

EDIT: Eek! So, this somehow prevents the setCursor trick from working, no matter if the trick is applied before or after the setAbsolute call. Any ideas?
« Last Edit: 15. November 2010, 08:16:52 pm by ChrisE » Logged
Marvin Fröhlich
Xith Lord
Administrator
Guru
*****
Offline Offline

Posts: 4381


May the 4th, be with you...


View Profile
« Reply #4 on: 15. November 2010, 09:12:08 pm »

The setAbsolute() method toggles the setCursor() method. So don't do that yourself, but let the InputSystem deal with it for you.

Marvin
Logged
ChrisE
Becoming dependent
**
Offline Offline

Posts: 104


View Profile
« Reply #5 on: 15. November 2010, 11:19:54 pm »

So, removed the setCursor code and used only setAbsolute. Sadly, the mouse cursor remains cheerfully affixed to the center of the screen and visible.

Another problem I'm having is that only intermittently does anything render; I'm using RenderLoop.begin(RenderLoop.RunMode.RUN_IN_SEPARATE_THREAD) if that helps. I'm adding the scene perspective branch before calling begin, if that helps (still doesn't seem to work if called after begin). It was running fine at one point, and then I left my desk and came back to find that it no longer rendered.

I'm sure that the render thread is running, as an updateable will spam stderr each draw frame.

Any ideas?
Logged
Marvin Fröhlich
Xith Lord
Administrator
Guru
*****
Offline Offline

Posts: 4381


May the 4th, be with you...


View Profile
« Reply #6 on: 16. November 2010, 01:22:25 am »

Could you please send a small testcase?

Marvin
Logged
ChrisE
Becoming dependent
**
Offline Offline

Posts: 104


View Profile
« Reply #7 on: 16. November 2010, 04:11:39 pm »

Sure, would be my pleasure:

The code used to setup the XithPanel (what I'm calling it; the enclosing class extends a javax.swing.JPanel):

Code:
    private void setupXith()
    {
    Canvas3DPanel the3dPanel = new Canvas3DPanel();

    // allocate Xith
    this.xithRL = new InputAdapterRenderLoop(60);
    this.xithEnv = new Xith3DEnvironment (this.xithRL);
    this.xithEnv.getView().lookAt(eyePosition, viewFocus, vecUp);
   
    // bind Xith to our component
    this.getComponent().add(the3dPanel,null);
    this.xithEnv.addCanvas( the3dPanel);
   
    try
    {
    InputSystem.getInstance().registerNewKeyboardAndMouse(the3dPanel.getCanvas().getInputDeviceFactory());
    }
    catch (Exception e)
    {
    e.printStackTrace();
    }
    InputSystem.getInstance().addInputListener( new XPInputListener() );
   
    // start Xith
this.geomBG = this.createScene();
    this.xithEnv.addPerspectiveBranch(this.geomBG);
    this.xithRL.begin(RenderLoop.RunMode.RUN_IN_SEPARATE_THREAD);
    this.xithRL.pauseRendering();
    System.err.printf("setupXith");
    System.err.flush();
    }

The input listener used to rotate the camera left and right:

Code:
class XPInputListener implements InputListener
{
@Override
public void onMouseButtonClicked(
MouseButtonClickedEvent arg0, MouseButton arg1,
int arg2)
{
System.err.printf("mouse click");
System.err.flush();
}

@Override
public void onMouseButtonPressed(
MouseButtonPressedEvent arg0, MouseButton arg1)
{
try
{
InputSystem.getInstance().getMouse().setAbsolute(false);
}
catch (Exception e)
{
e.printStackTrace();
}
}

@Override
public void onMouseButtonReleased(
MouseButtonReleasedEvent arg0, MouseButton arg1)
{
try
{
InputSystem.getInstance().getMouse().setAbsolute(true);
}
catch (Exception e)
{
e.printStackTrace();
}
}

@Override
public void onMouseMoved(MouseMovedEvent arg0, int x,
int y, int dx, int dy)
{
Point3f tempPt = new Point3f();
Matrix3f rotMat = new Matrix3f();
rotMat.rotY(dx);
rotMat.mul(XithPanel.this.viewFocus, tempPt);
XithPanel.this.viewFocus = tempPt;
XithPanel.this.xithEnv.getView().lookAt(XithPanel.this.eyePosition,
XithPanel.this.viewFocus,
XithPanel.this.vecUp);
}

// other overrides left out for simplicity's sake
}

And finally, a visibility hook so other panels can hide us:

Code:
    @Override
    public void setVisible(boolean v)
    {
    System.err.printf("setVisible %d", (v)?1:0);
    System.err.flush();
    if (this.initOnce_ < 1)
    return;
    if (v)
    {
    if (!this.xithRL.isRunning())
    this.xithRL.resumeRendering();
    }
    else
    {
    this.xithRL.pauseRendering();
    }
    }

That help at all?
Logged
ChrisE
Becoming dependent
**
Offline Offline

Posts: 104


View Profile
« Reply #8 on: 16. November 2010, 05:03:10 pm »

UPDATE: So, it appears that calling resumeRendering() or pauseRendering() multiple times in a row makes Xith unhappy and it will start drawing? Or maybe I need to repaint the attach panel?

Either way, removing duplicate calls seems to alleviate that issue. However, now I've got a crash in my event queue when I switch away and come back, which then seems to make the renderer stop working. The exception (NullPointerException) occurs in the AWTEvent code, and after stepping through/resuming in the debugger, the renderer stops drawing anything other than a flat gray screen. It also reports a IllegalComponentStateException immediately prior to the NullPointerException.
This issue appears to have ceased.
UPDATE 2: So, calling repaint on the canvas (the Canvas3D bit) prior to calling resume rendering will cause nothing to be drawn. Not repainting the canvas will allow drawing to occur. A cycle of pauseRendering() and resumeRendering() seems to also cause drawing to cease.

UPDATE 3: Aaaaand it's gone back to not rendering at startup. gah.
« Last Edit: 16. November 2010, 06:36:09 pm by ChrisE » Logged
ChrisE
Becoming dependent
**
Offline Offline

Posts: 104


View Profile
« Reply #9 on: 16. November 2010, 09:49:24 pm »

So, it seems that the biggest problem here is that there is a feature (bug?) where Xith does not like redundant calls to begin, pause, resume, or similar calls. Are these functions intended to be so sensitive?
Logged
Marvin Fröhlich
Xith Lord
Administrator
Guru
*****
Offline Offline

Posts: 4381


May the 4th, be with you...


View Profile
« Reply #10 on: 16. November 2010, 10:15:48 pm »

Are these functions intended to be so sensitive?

No, but they not designed to be used that way either Wink.

Could you please setup a complete runnable testcase? You don't need to post it in code blocks. Just attach a zip archive or something containing a runnable testcase. I really don't have that much time and would prefer it that way.

As a first hint: Don't use InputAdapterRenderLoop, but RenderLoop. You already correctly use your own InputListener. Hint2: MouseButtonClickedEvent will give you the Mouse through the getMouse() method.

If the XithPanel extends JPanel, I don't understand this line:
Code:
this.getComponent().add(the3dPanel,null);
Canvas3DPanel already extends a Panel. Maybe it would be better to let your XithPanel extend Canvas3DPanel instead of wasting CPU time by wrapping it in another JPanel.

Marvin
Logged
ChrisE
Becoming dependent
**
Offline Offline

Posts: 104


View Profile
« Reply #11 on: 16. November 2010, 10:24:48 pm »


No, but they not designed to be used that way either Wink.

Could you please setup a complete runnable testcase? You don't need to post it in code blocks. Just attach a zip archive or something containing a runnable testcase. I really don't have that much time and would prefer it that way.


I'll see what I can do... extracting that code from the codebase was already a bit harrowing; we've got it interfaced with a good chunk of proprietary code.

Quote
As a first hint: Don't use InputAdapterRenderLoop, but RenderLoop. You already correctly use your own InputListener. Hint2: MouseButtonClickedEvent will give you the Mouse through the getMouse() method.

Out of curiosity, what is the intended purpose of InputAdapterRenderLoop?


Quote
If the XithPanel extends JPanel, I don't understand this line:
Code:
this.getComponent().add(the3dPanel,null);
Canvas3DPanel already extends a Panel. Maybe it would be better to let your XithPanel extend Canvas3DPanel instead of wasting CPU time by wrapping it in another JPanel.

So, in reality it extends one of our other classes used for interoperability, which handles some other things internal to our app, and in turn extends JPanel; removing that dependency could prove... entertaining.

Ah, the joys of large application development. Sad
Logged
ChrisE
Becoming dependent
**
Offline Offline

Posts: 104


View Profile
« Reply #12 on: 16. November 2010, 10:26:36 pm »

Changed to normal RenderLoop; no effect.

EDIT: I appreciate the help, Marvin. I understand that you're probably pretty busy with other stuff. Fellow apps dev?
« Last Edit: 16. November 2010, 10:28:24 pm by ChrisE » Logged
ChrisE
Becoming dependent
**
Offline Offline

Posts: 104


View Profile
« Reply #13 on: 16. November 2010, 11:33:05 pm »

So, fixed error where other parts of app were calling redundant pause() and resume(). Still have a problem where switching away to another panel and back (in a tabbed scheme) fails to draw. Do I need to call canvas.repaint() or somesuch?
Logged
Marvin Fröhlich
Xith Lord
Administrator
Guru
*****
Offline Offline

Posts: 4381


May the 4th, be with you...


View Profile
« Reply #14 on: 16. November 2010, 11:41:57 pm »

Changed to normal RenderLoop; no effect.

I didn't expect an effect. It was just the wrong class, which didn't harm though (except for unnecessary listeners to be called).

Fellow apps dev?

Yeah

Do I need to call canvas.repaint() or somesuch?

I don't think, this would have any effect. You would have to trigger the RenderLoop to render the next frame. But this is certainly not the solution. I need a working testcase to tell you more.

Marvin
Logged
Pages: [1] 2
Print
Jump to:  

Theme orange-lt created by panic