32 const PN_stdfloat DriveInterface::_hpr_quantize = 0.001;
34 DriveInterface::KeyHeld::
39 _effect_at_change = 0.0f;
42 PN_stdfloat DriveInterface::KeyHeld::
43 get_effect(PN_stdfloat ramp_up_time, PN_stdfloat ramp_down_time) {
48 if (ramp_up_time == 0.0f) {
52 PN_stdfloat change = elapsed / ramp_up_time;
53 _effect = min(_effect_at_change + change, (PN_stdfloat)1.0);
58 if (ramp_down_time == 0.0f) {
62 PN_stdfloat change = elapsed / ramp_down_time;
63 _effect = max(_effect_at_change - change, (PN_stdfloat)0.0);
69 void DriveInterface::KeyHeld::
74 _effect_at_change = _effect;
78 void DriveInterface::KeyHeld::
83 _effect_at_change = 0.0f;
86 bool DriveInterface::KeyHeld::
87 operator < (
const DriveInterface::KeyHeld &other)
const {
88 if (_down != other._down) {
94 return _changed_time > other._changed_time;
101 DriveInterface(
const std::string &name) :
104 _xy_input = define_input(
"xy", EventStoreVec2::get_class_type());
105 _button_events_input = define_input(
"button_events", ButtonEventList::get_class_type());
107 _transform_output = define_output(
"transform", TransformState::get_class_type());
108 _velocity_output = define_output(
"velocity", EventStoreVec3::get_class_type());
110 _transform = TransformState::make_identity();
113 _forward_speed = drive_forward_speed;
114 _reverse_speed = drive_reverse_speed;
115 _rotate_speed = drive_rotate_speed;
116 _vertical_dead_zone = drive_vertical_dead_zone;
117 _horizontal_dead_zone = drive_horizontal_dead_zone;
118 _vertical_center = drive_vertical_center;
119 _horizontal_center = drive_horizontal_center;
121 _vertical_ramp_up_time = drive_vertical_ramp_up_time;
122 _vertical_ramp_down_time = drive_vertical_ramp_down_time;
123 _horizontal_ramp_up_time = drive_horizontal_ramp_up_time;
124 _horizontal_ramp_down_time = drive_horizontal_ramp_down_time;
129 _xyz.set(0.0f, 0.0f, 0.0f);
130 _hpr.set(0.0f, 0.0f, 0.0f);
132 _ignore_mouse =
false;
133 _force_mouse =
false;
134 _stop_this_frame =
false;
154 _xyz.set(0.0f, 0.0f, 0.0f);
155 _hpr.set(0.0f, 0.0f, 0.0f);
159 _right_arrow.clear();
175 LVecBase3 scale, shear;
176 decompose_matrix(mat, scale, shear, _hpr, _xyz);
185 LVecBase3(1.0f, 1.0f, 1.0f),
186 LVecBase3(0.0f, 0.0f, 0.0f),
199 _transform = TransformState::make_pos_hpr(_xyz, _hpr);
200 _velocity->set_value(_vel);
217 void DriveInterface::
218 apply(
double x,
double y,
bool any_button) {
223 if (any_button || _force_mouse) {
234 PN_stdfloat dead_zone_top = _vertical_center + _vertical_dead_zone;
235 PN_stdfloat dead_zone_bottom = _vertical_center - _vertical_dead_zone;
237 if (y >= dead_zone_top) {
240 PN_stdfloat throttle =
242 (min(y, 1.0) - dead_zone_top) /
243 (1.0f - dead_zone_top);
244 _speed = throttle * _forward_speed;
246 }
else if (y <= dead_zone_bottom) {
248 PN_stdfloat throttle =
249 (max(y, -1.0) - dead_zone_bottom) /
250 (-1.0f - dead_zone_bottom);
251 _speed = -throttle * _reverse_speed;
256 PN_stdfloat dead_zone_right = _horizontal_center + _horizontal_dead_zone;
257 PN_stdfloat dead_zone_left = _horizontal_center - _horizontal_dead_zone;
259 if (x >= dead_zone_right) {
262 PN_stdfloat throttle =
263 (min(x, 1.0) - dead_zone_right) /
264 (1.0f - dead_zone_right);
265 _rot_speed = throttle * _rotate_speed;
267 }
else if (x <= dead_zone_left) {
269 PN_stdfloat throttle =
270 (max(x, -1.0) - dead_zone_left) /
271 (-1.0f - dead_zone_left);
272 _rot_speed = -throttle * _rotate_speed;
280 PN_stdfloat throttle;
282 if (_up_arrow < _down_arrow) {
283 throttle = _up_arrow.get_effect(_vertical_ramp_up_time,
284 _vertical_ramp_down_time);
285 _speed = throttle * _forward_speed;
286 _down_arrow._effect = 0.0f;
289 throttle = _down_arrow.get_effect(_vertical_ramp_up_time,
290 _vertical_ramp_down_time);
291 _speed = -throttle * _reverse_speed;
292 _up_arrow._effect = 0.0f;
296 if (_right_arrow < _left_arrow) {
297 throttle = _right_arrow.get_effect(_horizontal_ramp_up_time,
298 _horizontal_ramp_down_time);
299 _rot_speed = throttle * _rotate_speed;
300 _left_arrow._effect = 0.0f;
303 throttle = _left_arrow.get_effect(_horizontal_ramp_up_time,
304 _horizontal_ramp_down_time);
305 _rot_speed = -throttle * _rotate_speed;
306 _right_arrow._effect = 0.0f;
308 _right_arrow._effect = throttle;
309 _left_arrow._effect = throttle;
312 if (_speed == 0.0f && _rot_speed == 0.0f) {
313 _vel.set(0.0f, 0.0f, 0.0f);
320 if (_stop_this_frame) {
323 _stop_this_frame =
false;
330 rot_mat.set_rotate_mat_normaxis(_hpr[0], LVector3::up());
333 _vel = LVector3::forward() * distance;
334 LVector3 step = (_vel * rot_mat);
338 switch (get_default_coordinate_system()) {
365 void DriveInterface::
369 bool required_buttons_match;
370 const ButtonEventList *button_events = check_button_events(input, required_buttons_match);
378 if (required_buttons_match && input.
has_data(_xy_input)) {
389 if (required_buttons_match && button_events !=
nullptr) {
392 for (
int i = 0; i < num_events; i++) {
394 if (be._type != ButtonEvent::T_keystroke) {
395 bool down = (be._type != ButtonEvent::T_up);
397 if (be._button == KeyboardButton::up()) {
398 _up_arrow.set_key(down);
399 }
else if (be._button == KeyboardButton::down()) {
400 _down_arrow.set_key(down);
401 }
else if (be._button == KeyboardButton::left()) {
402 _left_arrow.set_key(down);
403 }
else if (be._button == KeyboardButton::right()) {
404 _right_arrow.set_key(down);
411 _transform = TransformState::make_pos_hpr(_xyz, _hpr);
412 _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.
int get_num_outputs() const
Returns the number of different outputs that have been defined for this node using define_output().
const LMatrix4 & get_mat()
Returns the current transform.
void collect_leftovers()
Pick up any nodes that didn't get completely traversed.
void reset()
Reinitializes the driver to the origin and resets any knowledge about buttons being held down.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An optional parameter associated with an event.
get_value
Retrieves the value stored in the parameter.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool has_data(int index) const
Returns true if the indicated parameter has been stored, false otherwise.
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.
void set_force_roll(PN_stdfloat force_roll)
This function is no longer used and does nothing.
void force_dgraph()
This is a special kludge for DriveInterface to allow us to avoid the one- frame latency after a colli...
void set_data(int index, const EventParameter &data)
Sets the data for the indicated parameter.
get_frame_time
Returns the time in seconds as of the last time tick() was called (typically, this will be as of the ...
This is the base class for some classes that monitor the mouse and keyboard input and perform some ac...
TypedWritableReferenceCount * get_ptr() const
Retrieves a pointer to the actual value stored in the parameter.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TypeHandle is the identifier used to differentiate C++ class types.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_dt
Returns the elapsed time for the previous frame: the number of seconds elapsed between the last two c...
Encapsulates the data generated from (or sent into) any particular DataNode.
This object supervises the traversal of the data graph and the moving of data from one DataNode to it...