|
ChrisE
|
 |
« 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
|
 |
« 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: 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
Posts: 4381
May the 4th, be with you...
|
 |
« 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
|
 |
« 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
Posts: 4381
May the 4th, be with you...
|
 |
« 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
|
 |
« 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
Posts: 4381
May the 4th, be with you...
|
 |
« Reply #6 on: 16. November 2010, 01:22:25 am » |
|
Could you please send a small testcase?
Marvin
|
|
|
|
|
Logged
|
|
|
|
|
ChrisE
|
 |
« 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): 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: 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: @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
|
 |
« 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
|
 |
« 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
Posts: 4381
May the 4th, be with you...
|
 |
« 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  . 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: 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
|
 |
« Reply #11 on: 16. November 2010, 10:24:48 pm » |
|
No, but they not designed to be used that way either  . 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. 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? If the XithPanel extends JPanel, I don't understand this line: 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. 
|
|
|
|
|
Logged
|
|
|
|
|
ChrisE
|
 |
« 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
|
 |
« 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
Posts: 4381
May the 4th, be with you...
|
 |
« 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
|
|
|
|
|