Input handler for strategy games

Im not sure how you are setting the the world coordinates…

There are two vectors that define "UP" behaviour: one that controls the offset from the scrolling plane and another that defines worldUp for the camera (they can be different). Maybe you are setting one of them and not setting the other.



If you are trying to map the scrolling to a sphere, then you are making the handler do something it was not originally intended to do… which means it will take some tinkering before everything starts working.



If the used scrolling/rotation model is not compatible with your application domain, you could take a different approach by designing your own scrolling/rotation model and using handler as an example and reusing some code.

Actually I am not trying to do anything else besides change the world orientation. I do it by adding only these lines:



final Vector3f DEFAULT_SCROLL_XVEC = Vector3f.UNIT_X;
final Vector3f DEFAULT_SCROLL_YVEC = Vector3f.UNIT_Y;
final Vector3f DEFAULT_WORLD_UP = Vector3f.UNIT_Z;
final Vector3f DEFAULT_DIRECTION = Vector3f.UNIT_Z;
final Vector3f DEFAULT_WORLD_LEFT = Vector3f.UNIT_X.negate();
      
strategicHandler.getRotationSphere().setVectors(
   DEFAULT_DIRECTION,
   DEFAULT_WORLD_UP,
   DEFAULT_WORLD_LEFT);
      
strategicHandler.getScrollingPlane().setPlane(
   DEFAULT_SCROLL_XVEC,
   DEFAULT_SCROLL_YVEC,
   DEFAULT_WORLD_UP);



All camera movement and scrolling seems to work correctly with these setting therefore I assume that I have changed all the necessary variables. Only problem is that when changing the vertical rotation, it does not stop at 89.9 but goes to 90 and blanks out the screen. This also happens with the example SimpleSetup that comes inside the package. These seem to be the only vectors I can and should set for the handler as I look at the default constants in the StrategicHandler class.

Is there perhaps an additional variable I must set that I am missing? I guess I can go on and develop using the default world orientation of the StrategicHandler as it is a really helpful library, but I am just hoping here.. that there is a different way.

Short: double check the handler default vectors and your vectors.



Long:


final Vector3f DEFAULT_WORLD_UP = Vector3f.UNIT_Z;
final Vector3f DEFAULT_DIRECTION = Vector3f.UNIT_Z;



Your direction and world up are the same vector. In your case, direction should probably be either X or Y (on the plane). In your case 0 angle is causing the problem, not 90, because 90 never happens due to max = 89.9. Flipping the direction from scrolling plane to the worldUp changes the angles.

The way rotation works is taking the inverse of the direction, rotating it around worldLeft by verticalDegree, then rotation the result around worldUp by horizontalDegree.

This is exactly what happens:
1) direction UNIT_Z becomes -UNIT_Z
2) direction is rotated by 0 degrees, around worldLeft, so it stays at -UNIT_Z
3) then it is rotated by an X degrees around worldUp, which happens to be UNIT_Z, but -UNIT_Z rotated around UNIT_Z by any amount of degress stays at -UNIT_Z
4) your direction is now parallel to the worldUp, causing the problem described in the previous post (camera direction parralel to the worldUp).

You could:
a) try a different values for direction.
b) try different ranges for min and max rotation.

Sorry for digging up and old post, but this seems like a relevant place.

I want the camera to stop moving once it reaches the edge of the terrain. I'm completely missing if or how this can be done with the strategichandler. Any ideas?



Thanks

JWar

I do not know how one is supposed to do it with default code. I modified the ScrollingPlane class to support this functionality. This is the new ScrollinPlane:



public class ScrollingPlane extends GeometricPlane {

   private Camera camera;
   private float scrollMinX;
   private float scrollMaxX;
   private float scrollMinY;
   private float scrollMaxY;
   private boolean alwaysScroll=true;
   
   /** temp vector */
   private Vector2f delta = new Vector2f();
   
   public ScrollingPlane(Camera camera) {
      super();
      this.camera = camera;
   }
   
   /**
    * xVec and yVec can be any two orthonormal vectors.
    * (These vectors have to be normalized and orthogonal to each other).
    *
    * These vectors will define a scrolling plane, and the camera orientation
    * will define the scrolling direction.
    *
    * The up vector is required to define the height offset via setHeight().
    * The height offset will affect the worldTranslation of the point on
    * the scrolling plane.
    *
    * @param xVec
    * @param yVec
    * @param up is needed to define the height offset
    * @param camera
    */
   public ScrollingPlane(Camera camera,
         Vector3f xVec, Vector3f yVec, Vector3f up)
   {
      super(xVec, yVec, up);
      this.camera = camera;
   }
   
   public void scrollUp(float distance) {
      Vector3f direction = camera.getDirection();
      delta.x = xVector.dot(direction);
      delta.y = yVector.dot(direction);
      delta.normalizeLocal();
      delta.multLocal(distance);
      if (alwaysScroll || (
            (delta.y > 0 && getWorldTranslation().y < scrollMaxY) ||
            (delta.y < 0 && getWorldTranslation().y > scrollMinY))){
         location.addLocal(delta);
         updateWorldTranslation();
      }
   }
   
   public void scrollRight(float distance) {
      Vector3f direction = camera.getLeft();
      delta.x = -1*xVector.dot(direction);
      delta.y = -1*yVector.dot(direction);
      delta.normalizeLocal();
      delta.multLocal(distance);
      if (alwaysScroll || (
            (delta.x > 0 && getWorldTranslation().x < scrollMaxX) ||
            (delta.x < 0 && getWorldTranslation().x > scrollMinX))){
         location.addLocal(delta);
         updateWorldTranslation();
      }
   }
   
   /**
    * @return camera
    */
   public Camera getCamera() {
      return camera;
   }
   
   public void setCamera(Camera camera) {
      this.camera = camera;
   }
   
   /**
    * Sets the limits for the ScrollingPlane where scrolling will stop.
    * @param minX
    * @param maxX
    * @param minY
    * @param maxY
    */
   public void setScrollLimits(float minX, float maxX, float minY, float maxY){
      alwaysScroll = false;
      scrollMinX = minX;
      scrollMaxX = maxX;
      scrollMinY = minY;
      scrollMaxY = maxY;
   }
   
}



Then after initializing StrategicHandler I call:


strategicHandler.getScrollingPlane().setScrollLimits(minX, maxX, minY, maxY);



hi,





i've just startet to port my code from jme1 to jme2.



is there a version of the strategyhandler and the mousemanager for jme2?



or when will they be evailable??




I do not know when and if lex will release a jME 2.0 version… so here you go :)  - the refactor was quite easy… StrategicHandler itself needed only 2 lines of code changed + the examples… MouseManager was a bit more work. In the end I removed the FengGUI integration class and example as I do not have a working FengGUI on my computer and I do not use it at this point.



Anyways if this is the state that satisfies you, here are the src and jars (made with Java 6)

MouseManager src

MouseManager jar

StrategicHandler src

StrategicHandler jar



Let us know if you have any problems with these - I have not used them myself actually, but the tests work…

thanks,





they works great.



the only problem was:



terrain = new TerrainPage("Terrain", 33,

    heightMap.getSize(), terrainScale,

    heightMap.getHeightMap(), false);



must be

terrain = new TerrainPage("Terrain", 33,

    heightMap.getSize(), terrainScale,

    heightMap.getHeightMap());



in org.lex.game.Demo and org.lex.game.SimpleSetup.

Thanks… my jME was over a week old and ren just worked on the TerrainPage.



jar and src files updated

Hey! Thanx for the update, Mindgamer!



Currently I don't have much time to look into this myself. Would you be interested in contributing the changes? If so, just add your name to the the copyright notice in the modified files and add the credit in the readme file and I'll put the updates on the goolgecode page.

Naah its ok… but thanks for the offer.



Putting them up on google-code is a good idea though. But as I said - it comes without the link with FengGUI for now.

please don't replace the jme1 version at least not yet, jme 1 and 2 projects can exist in the same repo it is donefor the md5 loader

I have question, how can I change maximum camera hight when I zoom out (without chagnig in src if possible)?? I found how to set minimum height/offset.

Micz said:

I have question, how can I change maximum camera hight when I zoom out (without chagnig in src if possible)?? I found how to set minimum height/offset.


That's easy... In the method where you init your StrategicHandler... add a line, something like this:

strategicHandler.getRotationSphere().getZoom().setMax(StrategicHandler.DEFAULT_ZOOM_DISTANCE_MAX * 4);



The line posted above, will allow to zoom out 4 times the default distance. You can acually change every aspect of how StrategicHandler scrolls, rotates, zooms etc. This will probably be of only limited use for you, but check out how many settings I change when initializing StrategicHandler:


      /* Rotating the world into correct position and setting up Rotation */
      strategicHandler.getRotationSphere().setVectors(
            WorldConstants.INPUT_DEFAULT_DIRECTION,
            WorldConstants.INPUT_DEFAULT_WORLD_UP,
            WorldConstants.INPUT_DEFAULT_WORLD_LEFT);
      strategicHandler.getScrollingPlane().setPlane(
            WorldConstants.INPUT_DEFAULT_SCROLL_XVEC,
            WorldConstants.INPUT_DEFAULT_SCROLL_YVEC,
            WorldConstants.INPUT_DEFAULT_WORLD_UP);
      strategicHandler.getRotationSphere().rotateHorizontal(180f);
      strategicHandler.getRotationSphere().getVertical().setMax(
            WorldConstants.INPUT_DEFAULT_VERTICAL_ROTATION_MAX);
      // Default rotation is 45 degrees, but we want to be directly overhead
      strategicHandler.getRotationSphere().rotateVertical(45);                     
      /* Moving into the correct position on the map and setting up Scrolling */
      // Default location is at 0:0. We want to center on map / homeplanet
      strategicHandler.getScrollingPlane().setLocation(DEFAULT_START_X, DEFAULT_START_Y);   
      strategicHandler.getScrollingPlane().setScrollLimits(
            1, map.getMapDataWidth(), 1, map.getMapDataHeight());
      strategicHandler.getMouseScrollFilter().setForce(
            WorldConstants.INPUT_DEFAULT_MOUSE_SCROLL_FORCE);
      strategicHandler.getMouseScrollFilter().setDamping(
            WorldConstants.INPUT_DEFAULT_MOUSE_SCROLL_DAMPING);
      strategicHandler.getMouseScrollFilter().setMaxSpeed(
            WorldConstants.INPUT_DEFAULT_MOUSE_SCROLL_MAXSPEED);
      /* Setting up zooming */
      strategicHandler.getRotationSphere().getZoom().setMin(
            WorldConstants.INPUT_DEFAULT_ZOOM_DISTANCE_MIN);
      strategicHandler.getRotationSphere().getZoom().setMax(
            WorldConstants.INPUT_DEFAULT_ZOOM_DISTANCE_MAX);
      strategicHandler.getRotationSphere().getZoom().setCurrent(
            WorldConstants.INPUT_DEFAULT_ZOOM_DISTANCE_CURRENT);

How would I implement basic mouse picking using this input handler?

Petah said:

How would I implement basic mouse picking using this input handler?
For your information, lex has not been active on this forum since 29 March 2009. I have however contacted him by e-mail, both regarding this thread as well as his collection of jmeaddons, so I do hope we will hear from him sooner than later. It could be that you are better off just looking at the code and trying to figure it out yourself though, as opposed to waiting around hoping for him to take the time to come by and answer.
erlend_sh said:

Petah said:

How would I implement basic mouse picking using this input handler?
For your information, lex has not been active on this forum since 29 March 2009. I have however contacted him by e-mail, both regarding this thread as well as his collection of jmeaddons, so I do hope we will hear from him sooner than later. It could be that you are better off just looking at the code and trying to figure it out yourself though, as opposed to waiting around hoping for him to take the time to come by and answer.


hehe, yea i pretty much figured. I got it working now, had to do a few hackish type things to his addon to make it work.
Petah said:

erlend_sh said:

Petah said:

How would I implement basic mouse picking using this input handler?
For your information, lex has not been active on this forum since 29 March 2009. I have however contacted him by e-mail, both regarding this thread as well as his collection of jmeaddons, so I do hope we will hear from him sooner than later. It could be that you are better off just looking at the code and trying to figure it out yourself though, as opposed to waiting around hoping for him to take the time to come by and answer.


hehe, yea i pretty much figured. I got it working now, had to do a few hackish type things to his addon to make it work.


hackish :? like what, for my learning education, I use it as s base for thirdperson handler, jme's built solution has issues
mcbeth said:

hackish :? like what, for my learning education, I use it as s base for thirdperson handler, jme's built solution has issues


For one in order to make it work with a JME Desktop I had to use both a CombinedMouse and a HardwareMouse at once because  it wouldn't draw the hardware mouse, and it would interact with GUI with the software mouse.
Also I had issues getting it to draw cursors, like the rotation one I have to detect manually and update the cursor image.

Hey!



Firs, to address the issues:

There are problems integrating the mouse cursors with some GUI framework because those frameworks try to set the mouse cursors by themselves, essentially hijacking the control of the mouse state from the mouse manager. The only way around it is to intercept cursor change events from the framework and run your own code that changes the cursor via the mouse manager instead.

Also if the system does not support animated cursors with hardware mouse pointer, nothing can be done without excessive amount of expensive calls. Changing the hardware cursor can be very costly and causes visual artifacts on some systems.



Finally, I'm happy to see strategic handler being used. I will do a complete rewrite for jme3 when i get the chance.