00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "driveInterface.h"
00020 #include "config_tform.h"
00021
00022 #include "compose_matrix.h"
00023 #include "mouseAndKeyboard.h"
00024 #include "mouseData.h"
00025 #include "clockObject.h"
00026 #include "modifierButtons.h"
00027 #include "keyboardButton.h"
00028 #include "mouseButton.h"
00029 #include "buttonEventList.h"
00030 #include "dataNodeTransmit.h"
00031 #include "dataGraphTraverser.h"
00032
00033 TypeHandle DriveInterface::_type_handle;
00034 const float DriveInterface::_hpr_quantize = 0.001;
00035
00036 DriveInterface::KeyHeld::
00037 KeyHeld() {
00038 _down = false;
00039 _changed_time = 0.0f;
00040 _effect = 0.0f;
00041 _effect_at_change = 0.0f;
00042 }
00043
00044 float DriveInterface::KeyHeld::
00045 get_effect(float ramp_up_time, float ramp_down_time) {
00046 double elapsed = ClockObject::get_global_clock()->get_frame_time() - _changed_time;
00047
00048 if (_down) {
00049
00050
00051 if (ramp_up_time == 0.0f) {
00052 _effect = 1.0f;
00053
00054 } else {
00055 float change = elapsed / ramp_up_time;
00056 _effect = min(_effect_at_change + change, 1.0f);
00057 }
00058
00059 } else {
00060
00061
00062 if (ramp_down_time == 0.0f) {
00063 _effect = 0.0f;
00064
00065 } else {
00066 float change = elapsed / ramp_down_time;
00067 _effect = max(_effect_at_change - change, 0.0f);
00068 }
00069 }
00070
00071 return _effect;
00072 }
00073
00074 void DriveInterface::KeyHeld::
00075 set_key(bool down) {
00076 if (_down != down) {
00077 _down = down;
00078 _changed_time = ClockObject::get_global_clock()->get_frame_time();
00079 _effect_at_change = _effect;
00080 }
00081 }
00082
00083 void DriveInterface::KeyHeld::
00084 clear() {
00085 _down = false;
00086 _changed_time = 0.0f;
00087 _effect = 0.0f;
00088 _effect_at_change = 0.0f;
00089 }
00090
00091 bool DriveInterface::KeyHeld::
00092 operator < (const DriveInterface::KeyHeld &other) const {
00093 if (_down != other._down) {
00094
00095
00096 return _down;
00097 }
00098
00099
00100 return _changed_time > other._changed_time;
00101 }
00102
00103
00104
00105
00106
00107
00108 DriveInterface::
00109 DriveInterface(const string &name) :
00110 DataNode(name)
00111 {
00112 _xy_input = define_input("xy", EventStoreVec2::get_class_type());
00113 _button_events_input = define_input("button_events", ButtonEventList::get_class_type());
00114
00115 _transform_output = define_output("transform", EventStoreTransform::get_class_type());
00116 _velocity_output = define_output("velocity", EventStoreVec3::get_class_type());
00117
00118 _transform = new EventStoreTransform(TransformState::make_identity());
00119 _velocity = new EventStoreVec3(LVector3f::zero());
00120
00121 _forward_speed = drive_forward_speed;
00122 _reverse_speed = drive_reverse_speed;
00123 _rotate_speed = drive_rotate_speed;
00124 _vertical_dead_zone = drive_vertical_dead_zone;
00125 _horizontal_dead_zone = drive_horizontal_dead_zone;
00126 _vertical_center = drive_vertical_center;
00127 _horizontal_center = drive_horizontal_center;
00128
00129 _vertical_ramp_up_time = drive_vertical_ramp_up_time;
00130 _vertical_ramp_down_time = drive_vertical_ramp_down_time;
00131 _horizontal_ramp_up_time = drive_horizontal_ramp_up_time;
00132 _horizontal_ramp_down_time = drive_horizontal_ramp_down_time;
00133
00134 _speed = 0.0f;
00135 _rot_speed = 0.0f;
00136
00137 _xyz.set(0.0f, 0.0f, 0.0f);
00138 _hpr.set(0.0f, 0.0f, 0.0f);
00139
00140 _ignore_mouse = false;
00141 _force_mouse = false;
00142 _stop_this_frame = false;
00143
00144 _mods.add_button(MouseButton::one());
00145 _mods.add_button(MouseButton::two());
00146 _mods.add_button(MouseButton::three());
00147 }
00148
00149
00150
00151
00152
00153
00154
00155
00156 DriveInterface::
00157 ~DriveInterface() {
00158 }
00159
00160
00161
00162
00163
00164
00165
00166 void DriveInterface::
00167 reset() {
00168 _xyz.set(0.0f, 0.0f, 0.0f);
00169 _hpr.set(0.0f, 0.0f, 0.0f);
00170 _up_arrow.clear();
00171 _down_arrow.clear();
00172 _left_arrow.clear();
00173 _right_arrow.clear();
00174
00175 _mods.all_buttons_up();
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185 void DriveInterface::
00186 set_force_roll(float) {
00187 }
00188
00189
00190
00191
00192
00193
00194 void DriveInterface::
00195 set_mat(const LMatrix4f &mat) {
00196 LVecBase3f scale;
00197 decompose_matrix(mat, scale, _hpr, _xyz);
00198 }
00199
00200
00201
00202
00203
00204
00205 const LMatrix4f &DriveInterface::
00206 get_mat() {
00207 compose_matrix(_mat, LVecBase3f(1.0f, 1.0f, 1.0f), _hpr, _xyz);
00208 return _mat;
00209 }
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 void DriveInterface::
00221 force_dgraph() {
00222 _transform->set_value(TransformState::make_pos_hpr(_xyz, _hpr));
00223 _velocity->set_value(_vel);
00224
00225 DataNodeTransmit output;
00226 output.reserve(get_num_outputs());
00227 output.set_data(_transform_output, EventParameter(_transform));
00228 output.set_data(_velocity_output, EventParameter(_velocity));
00229
00230 DataGraphTraverser dg_trav;
00231 dg_trav.traverse_below(this, output);
00232 dg_trav.collect_leftovers();
00233 }
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 void DriveInterface::
00244 apply(double x, double y, bool any_button) {
00245
00246
00247 _speed = 0.0f;
00248 _rot_speed = 0.0f;
00249
00250 if (any_button || _force_mouse) {
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261 float dead_zone_top = _vertical_center + _vertical_dead_zone;
00262 float dead_zone_bottom = _vertical_center - _vertical_dead_zone;
00263
00264 if (y >= dead_zone_top) {
00265
00266
00267 float throttle =
00268
00269 (min(y, 1.0) - dead_zone_top) /
00270 (1.0f - dead_zone_top);
00271 _speed = throttle * _forward_speed;
00272
00273 } else if (y <= dead_zone_bottom) {
00274
00275 float throttle =
00276 (max(y, -1.0) - dead_zone_bottom) /
00277 (-1.0f - dead_zone_bottom);
00278 _speed = -throttle * _reverse_speed;
00279 }
00280
00281
00282
00283
00284 float dead_zone_right = _horizontal_center + _horizontal_dead_zone;
00285 float dead_zone_left = _horizontal_center - _horizontal_dead_zone;
00286
00287 if (x >= dead_zone_right) {
00288
00289
00290
00291 float throttle =
00292 (min(x, 1.0) - dead_zone_right) /
00293 (1.0f - dead_zone_right);
00294 _rot_speed = throttle * _rotate_speed;
00295
00296 } else if (x <= dead_zone_left) {
00297
00298 float throttle =
00299 (max(x, -1.0) - dead_zone_left) /
00300 (-1.0f - dead_zone_left);
00301 _rot_speed = -throttle * _rotate_speed;
00302 }
00303
00304 } else {
00305
00306
00307
00308
00309 float throttle;
00310
00311 if (_up_arrow < _down_arrow) {
00312 throttle = _up_arrow.get_effect(_vertical_ramp_up_time,
00313 _vertical_ramp_down_time);
00314 _speed = throttle * _forward_speed;
00315 _down_arrow._effect = 0.0f;
00316
00317 } else {
00318 throttle = _down_arrow.get_effect(_vertical_ramp_up_time,
00319 _vertical_ramp_down_time);
00320 _speed = -throttle * _reverse_speed;
00321 _up_arrow._effect = 0.0f;
00322 }
00323
00324
00325 if (_right_arrow < _left_arrow) {
00326 throttle = _right_arrow.get_effect(_horizontal_ramp_up_time,
00327 _horizontal_ramp_down_time);
00328 _rot_speed = throttle * _rotate_speed;
00329 _left_arrow._effect = 0.0f;
00330
00331 } else {
00332 throttle = _left_arrow.get_effect(_horizontal_ramp_up_time,
00333 _horizontal_ramp_down_time);
00334 _rot_speed = -throttle * _rotate_speed;
00335 _right_arrow._effect = 0.0f;
00336 }
00337 _right_arrow._effect = throttle;
00338 _left_arrow._effect = throttle;
00339 }
00340
00341 if (_speed == 0.0f && _rot_speed == 0.0f) {
00342 _vel.set(0.0f, 0.0f, 0.0f);
00343 return;
00344 }
00345
00346
00347 float distance = ClockObject::get_global_clock()->get_dt() * _speed;
00348 float rotation = ClockObject::get_global_clock()->get_dt() * _rot_speed;
00349 if (_stop_this_frame) {
00350 distance = 0.0f;
00351 rotation = 0.0f;
00352 _stop_this_frame = false;
00353 }
00354
00355
00356
00357
00358
00359 LMatrix3f rot_mat =
00360 LMatrix3f::rotate_mat_normaxis(_hpr[0], LVector3f::up());
00361
00362
00363 _vel = LVector3f::forward() * distance;
00364 LVector3f step = (_vel * rot_mat);
00365
00366
00367
00368
00369 switch (default_coordinate_system) {
00370 case CS_zup_right:
00371 case CS_zup_left:
00372 step[2] = 0.0f;
00373 break;
00374
00375 case CS_yup_right:
00376 case CS_yup_left:
00377 step[1] = 0.0f;
00378 break;
00379
00380 default:
00381 break;
00382 }
00383
00384 _xyz += step;
00385 _hpr[0] -= rotation;
00386 }
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 void DriveInterface::
00402 do_transmit_data(const DataNodeTransmit &input, DataNodeTransmit &output) {
00403
00404 double x = 0.0f;
00405 double y = 0.0f;
00406
00407 bool got_mouse = false;
00408
00409 if (input.has_data(_xy_input)) {
00410 const EventStoreVec2 *xy;
00411 DCAST_INTO_V(xy, input.get_data(_xy_input).get_ptr());
00412 const LVecBase2f &p = xy->get_value();
00413 x = p[0];
00414 y = p[1];
00415
00416 got_mouse = true;
00417 }
00418
00419
00420 if (input.has_data(_button_events_input)) {
00421 const ButtonEventList *button_events;
00422 DCAST_INTO_V(button_events, input.get_data(_button_events_input).get_ptr());
00423
00424 int num_events = button_events->get_num_events();
00425 for (int i = 0; i < num_events; i++) {
00426 const ButtonEvent &be = button_events->get_event(i);
00427 if (be._type != ButtonEvent::T_keystroke) {
00428 bool down = (be._type == ButtonEvent::T_down);
00429
00430 if (down) {
00431
00432
00433 if (got_mouse && !_ignore_mouse) {
00434 _mods.add_event(be);
00435 }
00436 } else {
00437
00438
00439
00440 _mods.add_event(be);
00441 }
00442
00443 if (be._button == KeyboardButton::up()) {
00444 _up_arrow.set_key(down);
00445 } else if (be._button == KeyboardButton::down()) {
00446 _down_arrow.set_key(down);
00447 } else if (be._button == KeyboardButton::left()) {
00448 _left_arrow.set_key(down);
00449 } else if (be._button == KeyboardButton::right()) {
00450 _right_arrow.set_key(down);
00451 }
00452 }
00453 }
00454 }
00455
00456 apply(x, y, _mods.is_any_down());
00457 _transform->set_value(TransformState::make_pos_hpr(_xyz, _hpr));
00458 _velocity->set_value(_vel);
00459 output.set_data(_transform_output, EventParameter(_transform));
00460 output.set_data(_velocity_output, EventParameter(_velocity));
00461 }