15 #include "driveInterface.h"
16 #include "config_tform.h"
18 #include "compose_matrix.h"
19 #include "mouseAndKeyboard.h"
20 #include "mouseData.h"
21 #include "clockObject.h"
22 #include "modifierButtons.h"
23 #include "keyboardButton.h"
24 #include "mouseButton.h"
25 #include "buttonEventList.h"
26 #include "dataNodeTransmit.h"
27 #include "dataGraphTraverser.h"
30 const PN_stdfloat DriveInterface::_hpr_quantize = 0.001;
32 DriveInterface::KeyHeld::
37 _effect_at_change = 0.0f;
40 PN_stdfloat DriveInterface::KeyHeld::
41 get_effect(PN_stdfloat ramp_up_time, PN_stdfloat ramp_down_time) {
46 if (ramp_up_time == 0.0f) {
50 PN_stdfloat change = elapsed / ramp_up_time;
51 _effect = min(_effect_at_change + change, (PN_stdfloat)1.0);
56 if (ramp_down_time == 0.0f) {
60 PN_stdfloat change = elapsed / ramp_down_time;
61 _effect = max(_effect_at_change - change, (PN_stdfloat)0.0);
67 void DriveInterface::KeyHeld::
72 _effect_at_change = _effect;
76 void DriveInterface::KeyHeld::
81 _effect_at_change = 0.0f;
84 bool DriveInterface::KeyHeld::
85 operator < (
const DriveInterface::KeyHeld &other)
const {
86 if (_down != other._down) {
93 return _changed_time > other._changed_time;
102 DriveInterface(
const string &name) :
105 _xy_input = define_input(
"xy", EventStoreVec2::get_class_type());
106 _button_events_input = define_input(
"button_events", ButtonEventList::get_class_type());
108 _transform_output = define_output(
"transform", TransformState::get_class_type());
109 _velocity_output = define_output(
"velocity", EventStoreVec3::get_class_type());
111 _transform = TransformState::make_identity();
114 _forward_speed = drive_forward_speed;
115 _reverse_speed = drive_reverse_speed;
116 _rotate_speed = drive_rotate_speed;
117 _vertical_dead_zone = drive_vertical_dead_zone;
118 _horizontal_dead_zone = drive_horizontal_dead_zone;
119 _vertical_center = drive_vertical_center;
120 _horizontal_center = drive_horizontal_center;
122 _vertical_ramp_up_time = drive_vertical_ramp_up_time;
123 _vertical_ramp_down_time = drive_vertical_ramp_down_time;
124 _horizontal_ramp_up_time = drive_horizontal_ramp_up_time;
125 _horizontal_ramp_down_time = drive_horizontal_ramp_down_time;
130 _xyz.set(0.0f, 0.0f, 0.0f);
131 _hpr.set(0.0f, 0.0f, 0.0f);
133 _ignore_mouse =
false;
134 _force_mouse =
false;
135 _stop_this_frame =
false;
159 _xyz.set(0.0f, 0.0f, 0.0f);
160 _hpr.set(0.0f, 0.0f, 0.0f);
164 _right_arrow.clear();
186 decompose_matrix(mat, scale, shear, _hpr, _xyz);
214 _transform = TransformState::make_pos_hpr(_xyz, _hpr);
215 _velocity->set_value(_vel);
235 void DriveInterface::
236 apply(
double x,
double y,
bool any_button) {
241 if (any_button || _force_mouse) {
252 PN_stdfloat dead_zone_top = _vertical_center + _vertical_dead_zone;
253 PN_stdfloat dead_zone_bottom = _vertical_center - _vertical_dead_zone;
255 if (y >= dead_zone_top) {
258 PN_stdfloat throttle =
260 (min(y, 1.0) - dead_zone_top) /
261 (1.0f - dead_zone_top);
262 _speed = throttle * _forward_speed;
264 }
else if (y <= dead_zone_bottom) {
266 PN_stdfloat throttle =
267 (max(y, -1.0) - dead_zone_bottom) /
268 (-1.0f - dead_zone_bottom);
269 _speed = -throttle * _reverse_speed;
274 PN_stdfloat dead_zone_right = _horizontal_center + _horizontal_dead_zone;
275 PN_stdfloat dead_zone_left = _horizontal_center - _horizontal_dead_zone;
277 if (x >= dead_zone_right) {
281 PN_stdfloat throttle =
282 (min(x, 1.0) - dead_zone_right) /
283 (1.0f - dead_zone_right);
284 _rot_speed = throttle * _rotate_speed;
286 }
else if (x <= dead_zone_left) {
288 PN_stdfloat throttle =
289 (max(x, -1.0) - dead_zone_left) /
290 (-1.0f - dead_zone_left);
291 _rot_speed = -throttle * _rotate_speed;
299 PN_stdfloat throttle;
301 if (_up_arrow < _down_arrow) {
302 throttle = _up_arrow.get_effect(_vertical_ramp_up_time,
303 _vertical_ramp_down_time);
304 _speed = throttle * _forward_speed;
305 _down_arrow._effect = 0.0f;
308 throttle = _down_arrow.get_effect(_vertical_ramp_up_time,
309 _vertical_ramp_down_time);
310 _speed = -throttle * _reverse_speed;
311 _up_arrow._effect = 0.0f;
315 if (_right_arrow < _left_arrow) {
316 throttle = _right_arrow.get_effect(_horizontal_ramp_up_time,
317 _horizontal_ramp_down_time);
318 _rot_speed = throttle * _rotate_speed;
319 _left_arrow._effect = 0.0f;
322 throttle = _left_arrow.get_effect(_horizontal_ramp_up_time,
323 _horizontal_ramp_down_time);
324 _rot_speed = -throttle * _rotate_speed;
325 _right_arrow._effect = 0.0f;
327 _right_arrow._effect = throttle;
328 _left_arrow._effect = throttle;
331 if (_speed == 0.0f && _rot_speed == 0.0f) {
332 _vel.set(0.0f, 0.0f, 0.0f);
339 if (_stop_this_frame) {
342 _stop_this_frame =
false;
359 switch (get_default_coordinate_system()) {
391 void DriveInterface::
395 bool required_buttons_match;
396 const ButtonEventList *button_events = check_button_events(input, required_buttons_match);
404 if (required_buttons_match && input.
has_data(_xy_input)) {
415 if (required_buttons_match && button_events != (
const ButtonEventList *)NULL) {
418 for (
int i = 0; i < num_events; i++) {
420 if (be._type != ButtonEvent::T_keystroke) {
421 bool down = (be._type != ButtonEvent::T_up);
423 if (be._button == KeyboardButton::up()) {
424 _up_arrow.set_key(down);
425 }
else if (be._button == KeyboardButton::down()) {
426 _down_arrow.set_key(down);
427 }
else if (be._button == KeyboardButton::left()) {
428 _left_arrow.set_key(down);
429 }
else if (be._button == KeyboardButton::right()) {
430 _right_arrow.set_key(down);
437 _transform = TransformState::make_pos_hpr(_xyz, _hpr);
438 _velocity->set_value(_vel);
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
void set_mat(const LMatrix4 &mat)
Stores the indicated transform in the DriveInterface.
const LMatrix4 & get_mat()
Returns the current transform.
void collect_leftovers()
Pick up any nodes that didn't get completely traversed.
This is the base class for all three-component vectors and points.
void reset()
Reinitializes the driver to the origin and resets any knowledge about buttons being held down...
An optional parameter associated with an event.
static const LVector3f & zero()
Returns a zero-length vector.
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
A handy class object for storing simple values (like integers or strings) passed along with an Event ...
void traverse_below(PandaNode *node, const DataNodeTransmit &output)
Continues the traversal to all the children of the indicated node, passing in the given data...
void reserve(int num_wires)
Tells the DataNodeTransmit object how many wires it is expected to store data for.
static Thread * get_current_thread()
Returns a pointer to the currently-executing Thread object.
static LVector3f forward(CoordinateSystem cs=CS_default)
Returns the forward vector for the given coordinate system.
void set_force_roll(PN_stdfloat force_roll)
This function is no longer used and does nothing.
double get_dt(Thread *current_thread=Thread::get_current_thread()) const
Returns the elapsed time for the previous frame: the number of seconds elapsed between the last two c...
void force_dgraph()
This is a special kludge for DriveInterface to allow us to avoid the one-frame latency after a collis...
void set_data(int index, const EventParameter &data)
Sets the data for the indicated parameter.
This is a 4-by-4 transform matrix.
double get_frame_time(Thread *current_thread=Thread::get_current_thread()) const
Returns the time in seconds as of the last time tick() was called (typically, this will be as of the ...
const EventParameter & get_data(int index) const
Extracts the data for the indicated index, if it has been stored, or the empty parameter if it has no...
This is the base class for all two-component vectors and points.
This is the base class for some classes that monitor the mouse and keyboard input and perform some ac...
int get_num_outputs() const
Returns the number of different outputs that have been defined for this node using define_output()...
const Type & get_value() const
Retrieves the value stored in the parameter.
TypedWritableReferenceCount * get_ptr() const
Retrieves a pointer to the actual value stored in the parameter.
TypeHandle is the identifier used to differentiate C++ class types.
This is a 3-by-3 transform matrix.
bool has_data(int index) const
Returns true if the indicated parameter has been stored, false otherwise.
static LVector3f up(CoordinateSystem cs=CS_default)
Returns the up vector for the given coordinate system.
Encapsulates the data generated from (or sent into) any particular DataNode.
void set_rotate_mat_normaxis(float angle, const LVecBase3f &axis, CoordinateSystem cs=CS_default)
Fills mat with a matrix that rotates by the given angle in degrees counterclockwise about the indicat...
This object supervises the traversal of the data graph and the moving of data from one DataNode to it...