ThirdPersonHandler / ChaseCamera / RenControlEditor

Hey folks,

I've posted some prelim information on the new third person control and camera system for version .10 but here's the official posting because version 1.0 is done and ready for testing by the general public.  The system consists of the following classes:

com.jme.input.ThirdPersonHandler  The main handler for controlling a target (eg. a model, a box, a car, whatever) in the third person.

com.jme.input.ChaseCamera  A "smart" camera controller and input handler that basically instructs the camera to follow a given target.

com.jme.input.thirdperson.ThirdPersonMouseLook  A mouse input class that allows manipulation of the camera via the mouse in conjunction with a ChaseCamera.

com.jme.input.thirdperson.ThirdPerson*Action  Classes used to enact key commands for the ThirdPersonHandler.

com.jme.input.thirdperson.MovementPermitter  An interface used to allow/disallow movement on a frame by frame basis.  (think - can't moved due to stunned, sleeping, etc.)

There are a great many configuration options available on this system and to highlight those options and make it easy to play with them, I've developed the RenControlEditor.  Similar to the RenParticleEditor, this application allows you to quickly configure in real time all of the options in these classes and also immediately get a copy of the exact code required to bring your creation into your own app.  Have a play with it and see what you think.

Known about the RenParticleEditor:

  1. There are no example configurations in the examples tab.  I know.  :)  Play with the editor and send me your configs with a catchy name and I'll put them in!
  2. The pull downs in the Test Scene tab only have 1 item to select.  Yes.  Sorry, I want to expand this, but I really needed to move on to MultiPass.  When you see shadows in jME finally, you'll be glad I did.
  3. The AWT input is a bit more touchy (specifically the mouse) than the pure lwjgl inputs in your game.  Yes I know this.  It should be close enough to work with though.  I wanted to add a button that flips you into full screen non-awt mode, but again with the reasons from #2.  Sorry.

    And now for the curious, here's the feature list for the system itself:


  • Properties can be set either directly via accessor methods or via a HashMap of properties.  When setting via properties, all primitive values should be represented as Strings.

  • Movement can be relative to the camera's frame or the targets current rotation.

  • All movement keys can be reconfigured.

  • Left/Right movement can either be rotation in place or gradual rotation over time as the target moves forward (think turning radius)  Speed of turning (radians per second) is configurable.

  • Custom movement permission class can be supplied to allow/disallow movement.

  • Customizeable up vector (in case you don't want to follow jME's y axis up model.

  • Lockable back motion (think backing up in a car vs. turning around your avatar to move backwards.)

  • Strafe movement support - can be independently set to target-aligned even if other movement is camera aligned.


  • Autocreates ThirdPersonMouseLook and passes the properties HashMap from the constructor to it.

  • MouseLook can be disabled if only ChaseCamera function is desired.

  • Camera motion is (by default) smoothed by a spring system.  The spring constants are configurable - most easily by the editor.

  • Spring smoothing can be disabled if desired.

  • Camera can be configured to always come to rest behind the target.  By default it comes to rest in a line straight towards the target regardless of the target's orientation - allowing you to swivel around and view the target from the front.

  • A maximum and minimum camera distance can be configured to keep the camera from getting too close or too far from the target (if your springs are too stretchy for example.)

  • Camera can be configured to look at an offset to the target's location.  This is useful for things like moving the camera's center of view from a character's waist - where the worldlocation point may be - to their shoulders.

  • Initial spherical coordinates are configurable.


  • camera's max ascent (how much of an angle it can make with the ground) is configurable and even lockable.

  • Max/min zoom (using mousewheel) is configurable.

  • Mouse speed is seperately configurable - horizontal acceleration, vertical, zoom.

  • Vertical control can be inverted - for those who prefer "pilot controls"

Things it doesn't have that would be nice in a 2.0 version:

  • Ability to handle non-planar movement.  This would enable controlling of airplanes, space ships, etc.  (maybe moved into a 1.1 version if enough people need it now.)

  • Expanded support for interacting with animations.

Anyhow, please play and make comments.  And send me those configs!

PS: A snapshot of the editor is viewable on my blog if you're too lazy to check it out of cvs.  :wink:


there is a little mistake in (1.13): it concerns the Camera and Mouse Panels

Actually, it only shows the Camera panel for non-Mac.

I would like to suggest:

        final JPanel camPanel = new JPanel();


        camPanel.setLayout(new GridBagLayout());

        if (!isMac) { // we need to use vertical label

            VTextIcon icon = new VTextIcon(tabbedPane, "Camera");

            tabbedPane.addTab(null, icon, camPanel, null);

        } else

            tabbedPane.addTab("Camera", null, camPanel, null);

        final JPanel mousePanel = new JPanel();


        mousePanel.setLayout(new GridBagLayout());

        if (!isMac) { // we need to use vertical label

            VTextIcon icon = new VTextIcon(tabbedPane, "Mouse");

            tabbedPane.addTab(null, icon, mousePanel, null);

        } else

            tabbedPane.addTab("Mouse", null, mousePanel, null);


Meh, that's what I get for using an editor and doing changes by hand.  Thanks!

agian nice work, works like a charm still tweaking but having fun doing it

one requst though when time allows that is rather then new scene how about the ability to load and orient a model


Ok, I'll look into that.  Models can be flakey though so support may be a pain.  Thanks for the compliments, nice to hear after a few weeks of work and tweaking (had to invent AWT input support and other such side things just to get this working right!)

Also, please send me those examples people so I can plug them into the example tab.

My Payne

HashMap handlerProps = new HashMap();

handlerProps.put(ThirdPersonHandler.PROP_ROTATEONLY, "true");

handlerProps.put(ThirdPersonHandler.PROP_DOGRADUAL, "true");

handlerProps.put(ThirdPersonHandler.PROP_TURNSPEED, "3.1415");

handlerProps.put(ThirdPersonHandler.PROP_LOCKBACKWARDS, "true");

handlerProps.put(ThirdPersonHandler.PROP_CAMERAALIGNEDMOVE, "false");

handlerProps.put(ThirdPersonHandler.PROP_ROTATEONLY, "true");

handlerProps.put(ThirdPersonHandler.PROP_STRAFETARGETALIGN, "true");

handlerProps.put(ThirdPersonHandler.PROP_KEY_FORWARD, KeyInput.KEY_W);

handlerProps.put(ThirdPersonHandler.PROP_KEY_LEFT, KeyInput.KEY_A);

handlerProps.put(ThirdPersonHandler.PROP_KEY_BACKWARD, KeyInput.KEY_S);

handlerProps.put(ThirdPersonHandler.PROP_KEY_RIGHT, KeyInput.KEY_D);

handlerProps.put(ThirdPersonHandler.PROP_KEY_STRAFELEFT, KeyInput.KEY_Q);

handlerProps.put(ThirdPersonHandler.PROP_KEY_STRAFERIGHT, KeyInput.KEY_E);

input = new ThirdPersonHandler(m_character, cam, handlerProps);


HashMap chaserProps = new HashMap();

chaserProps.put(ChaseCamera.PROP_ENABLESPRING, "true");

chaserProps.put(ChaseCamera.PROP_DAMPINGK, "55");

chaserProps.put(ChaseCamera.PROP_SPRINGK, "756.25");

chaserProps.put(ChaseCamera.PROP_MAXDISTANCE, "0");

chaserProps.put(ChaseCamera.PROP_MINDISTANCE, "0");

chaserProps.put(ChaseCamera.PROP_INITIALSPHERECOORDS, new Vector3f(65, 0, 12));

chaserProps.put(ChaseCamera.PROP_STAYBEHINDTARGET, "true");

chaserProps.put(ChaseCamera.PROP_TARGETOFFSET,  new Vector3f(0, ((BoundingBox) myTarget.getWorldBound()).yExtent * 1.6f, 0));

chaserProps.put(ThirdPersonMouseLook.PROP_ENABLED, "true");

chaserProps.put(ThirdPersonMouseLook.PROP_MAXASCENT, "85");

chaserProps.put(ThirdPersonMouseLook.PROP_INVERTEDY, "false");

chaserProps.put(ThirdPersonMouseLook.PROP_MINROLLOUT, "30");

chaserProps.put(ThirdPersonMouseLook.PROP_MAXROLLOUT, "240.0");

chaserProps.put(ThirdPersonMouseLook.PROP_MOUSEXMULT, "2.0");

chaserProps.put(ThirdPersonMouseLook.PROP_MOUSEYMULT, "30.0");

chaserProps.put(ThirdPersonMouseLook.PROP_MOUSEROLLMULT, "50.0");

chaserProps.put(ThirdPersonMouseLook.PROP_LOCKASCENT, "true");

chaser = new ChaseCamera(cam, m_character, chaserProps);


this is a setting I'm planning to use for my little game thing it works nicely in the editor but when I plug a quick and dirty into a copy of Testthirdperson get some issues incated in bold in those  settings


setActionSpeed and yextent multiple should be float (fixed in my test)

The method put(Object, Object) in the type HashMap is not applicable for the arguments (String, int)

seems specific to key bindings,  I didn't do something but what? :?

I just swapped your props with mine

Ah, it's my fault in the code generation.  ://  I'll get it cleaned up.  Thanks for the sample, I'll get that in soon too!


on a side note speak of strafing, you know the other thread, I have seen arc rotating strafing but for bots u know ai patterns,  utilizes the player/target as the origin and updated the bot to maintain the radius have never seen it on the player side though

Example is in as is a "plumber" example… and the code generation bugs are fixed (also fixed an additional one concerning radians and degrees.)