The "Driven manipulator system" is a way for PVLE to separate the controlling system (on GFX thread) from the effective movement (on physics thread).
This system is called "driven manipulator" because the manipulator is actually only a relay for the two subsystems (contols and movement) : the manipulator is "driven" from outside. SplitManipulator is the class of PVLE that does this separation.
Differences between OSG standard and PVLE's driven manipulator system
The first important thing is that the system allows an total abstraction of the controls for the movement part. This is achieved by using a delegate handler for the
SplitManipulator that is able to map inputs to controls.
Inputs are direct events from the OS that are passed to the app, through OpenProducer library. Inputs in that case are event-based, so nothing is recorded over time.
Controls, on the other hand, are PVLE's specific. They refer to an action (Jump, move forward, etc.), not a specific key (Second mouse button, Z, etc.). ControlMapper in PVLE is a class that maps inputs to controls, and that saves control events (which are the equivalent of input events). Moreover, controls current state is recorded this class, so you can at any time know the state of any key, button or axis. Note that in PVLE, buttons inputs (mouse/joystick) and keys inputs (keyboard) are strictly interpreted the same way, and are mapped to switches controls.
Movement part is, for the driven manipulator system, only a way to get a matrix : the matrix getter is a delegate for
SplitManipulator. Of course, the class that matches this goal may know about the
ControlMapper and use controls to update its matrix.
For instance, a unit (Let's say UnpilotedUnit, as it is PVLE's base class for units) is a matrix getter : it knows about a control mapper and updates its position and orientation according to controls events and state. Then the SplitManipulator asks the matrix getter for its matrix on each GFX frame, and all is done :) ...
The problem is that the matrix getter doesn't know about current or elapsed time.
- In the case of a unit (or any phsics-based class), the information is given by the way of the step() method (or other), called on each physics frame.
- In the case of AI-based classes, time must be provided the same way.
- For GFX-based classes, it could seems useless to give time since it is usually given by the handle() method in standard manipulators, but this is separated from the matrix getter. You must then rely on one of these solutions :
- The GFX_FRAME event (which is timestamped), stored in the control state of the ControlMapper. In that case, you'll probably have some problems in keeping your getMatrix() method const.
- A user method in your matrix getter that you set the same way the physics-based or AI-based matrix getters do.
Note that events and GFX frame are on the same thread with OSG. Only the delegate handler and the matrix getter have to be thread safe. The matrix getter must provide a lock/mutex in order to protect its internal matrix, whereas the delegate handler must protect almost any access.
- SplitManipulator
- ControlMapper (as a delegate handler - osgGA::GUIEventHandler). See also, for switches / axis bindings :
- UnpilotedUnit (as a matrix getter)
- Author:
- Sukender
- Version:
- 0.2.0