00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "trackball.h"
00016 #include "buttonEvent.h"
00017 #include "buttonEventList.h"
00018 #include "dataNodeTransmit.h"
00019 #include "compose_matrix.h"
00020 #include "mouseData.h"
00021 #include "modifierButtons.h"
00022 #include "linmath_events.h"
00023 #include "mouseButton.h"
00024 #include "keyboardButton.h"
00025
00026 TypeHandle Trackball::_type_handle;
00027
00028
00029 #define B1_MASK 0x01
00030 #define B2_MASK 0x02
00031 #define B3_MASK 0x04
00032
00033
00034
00035
00036
00037
00038 Trackball::
00039 Trackball(const string &name) :
00040 MouseInterfaceNode(name)
00041 {
00042 _pixel_xy_input = define_input("pixel_xy", EventStoreVec2::get_class_type());
00043
00044 _transform_output = define_output("transform", TransformState::get_class_type());
00045
00046 _transform = TransformState::make_identity();
00047
00048 _rotscale = 0.3;
00049 _fwdscale = 0.3;
00050
00051 _last_button = 0;
00052 _lastx = _lasty = 0.5f;
00053
00054 _rotation = LMatrix4::ident_mat();
00055 _translation.set(0.0f, 0.0f, 0.0f);
00056 _mat = LMatrix4::ident_mat();
00057 _orig = LMatrix4::ident_mat();
00058 _invert = true;
00059 _cs = get_default_coordinate_system();
00060 _control_mode = CM_default;
00061
00062
00063 watch_button(MouseButton::one());
00064 watch_button(MouseButton::two());
00065 watch_button(MouseButton::three());
00066
00067 if (trackball_use_alt_keys) {
00068
00069
00070 watch_button(KeyboardButton::control());
00071 watch_button(KeyboardButton::meta());
00072 watch_button(KeyboardButton::alt());
00073 }
00074 }
00075
00076
00077
00078
00079
00080
00081 Trackball::
00082 ~Trackball() {
00083 }
00084
00085
00086
00087
00088
00089
00090 void Trackball::
00091 reset() {
00092 _rotation = LMatrix4::ident_mat();
00093 _translation.set(0.0f, 0.0f, 0.0f);
00094 _orig = LMatrix4::ident_mat();
00095 _mat = LMatrix4::ident_mat();
00096 }
00097
00098
00099
00100
00101
00102
00103
00104 PN_stdfloat Trackball::
00105 get_forward_scale() const {
00106 return _fwdscale;
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 void Trackball::
00118 set_forward_scale(PN_stdfloat fwdscale) {
00119 _fwdscale = fwdscale;
00120 }
00121
00122
00123
00124
00125
00126
00127
00128 const LPoint3 &Trackball::
00129 get_pos() const {
00130 return _translation;
00131 }
00132
00133 PN_stdfloat Trackball::
00134 get_x() const {
00135 return _translation[0];
00136 }
00137
00138 PN_stdfloat Trackball::
00139 get_y() const {
00140 return _translation[1];
00141 }
00142
00143 PN_stdfloat Trackball::
00144 get_z() const {
00145 return _translation[2];
00146 }
00147
00148
00149
00150
00151
00152
00153
00154 void Trackball::
00155 set_pos(const LVecBase3 &vec) {
00156 _translation = vec;
00157 recompute();
00158 }
00159
00160 void Trackball::
00161 set_pos(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
00162 _translation.set(x, y, z);
00163 recompute();
00164 }
00165
00166 void Trackball::
00167 set_x(PN_stdfloat x) {
00168 _translation[0] = x;
00169 recompute();
00170 }
00171
00172 void Trackball::
00173 set_y(PN_stdfloat y) {
00174 _translation[1] = y;
00175 recompute();
00176 }
00177
00178 void Trackball::
00179 set_z(PN_stdfloat z) {
00180 _translation[2] = z;
00181 recompute();
00182 }
00183
00184
00185
00186
00187
00188
00189
00190 LVecBase3 Trackball::
00191 get_hpr() const {
00192 LVecBase3 scale, shear, hpr, translate;
00193 decompose_matrix(_rotation, scale, shear, hpr, translate);
00194 return hpr;
00195 }
00196
00197 PN_stdfloat Trackball::
00198 get_h() const {
00199 LVecBase3 scale, shear, hpr, translate;
00200 decompose_matrix(_rotation, scale, shear, hpr, translate);
00201 return hpr[0];
00202 }
00203
00204 PN_stdfloat Trackball::
00205 get_p() const {
00206 LVecBase3 scale, shear, hpr, translate;
00207 decompose_matrix(_rotation, scale, shear, hpr, translate);
00208 return hpr[1];
00209 }
00210
00211 PN_stdfloat Trackball::
00212 get_r() const {
00213 LVecBase3 scale, shear, hpr, translate;
00214 decompose_matrix(_rotation, scale, shear, hpr, translate);
00215 return hpr[2];
00216 }
00217
00218
00219
00220
00221
00222
00223
00224 void Trackball::
00225 set_hpr(const LVecBase3 &hpr) {
00226 LVecBase3 scale, shear, old_hpr, translate;
00227 decompose_matrix(_rotation, scale, shear, old_hpr, translate);
00228 compose_matrix(_rotation, scale, shear, hpr, translate);
00229 recompute();
00230 }
00231
00232 void Trackball::
00233 set_hpr(PN_stdfloat h, PN_stdfloat p, PN_stdfloat r) {
00234 LVecBase3 scale, shear, hpr, translate;
00235 decompose_matrix(_rotation, scale, shear, hpr, translate);
00236 hpr.set(h, p, r);
00237 compose_matrix(_rotation, scale, shear, hpr, translate);
00238 recompute();
00239 }
00240
00241 void Trackball::
00242 set_h(PN_stdfloat h) {
00243 LVecBase3 scale, shear, hpr, translate;
00244 decompose_matrix(_rotation, scale, shear, hpr, translate);
00245 hpr[0] = h;
00246 compose_matrix(_rotation, scale, shear, hpr, translate);
00247 recompute();
00248 }
00249
00250 void Trackball::
00251 set_p(PN_stdfloat p) {
00252 LVecBase3 scale, shear, hpr, translate;
00253 decompose_matrix(_rotation, scale, shear, hpr, translate);
00254 hpr[1] = p;
00255 compose_matrix(_rotation, scale, shear, hpr, translate);
00256 recompute();
00257 }
00258
00259 void Trackball::
00260 set_r(PN_stdfloat r) {
00261 LVecBase3 scale, shear, hpr, translate;
00262 decompose_matrix(_rotation, scale, shear, hpr, translate);
00263 hpr[2] = r;
00264 compose_matrix(_rotation, scale, shear, hpr, translate);
00265 recompute();
00266 }
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 void Trackball::
00277 reset_origin_here() {
00278 recompute();
00279 _rotation = _orig;
00280 _translation.set(0.0f, 0.0f, 0.0f);
00281 }
00282
00283
00284
00285
00286
00287
00288
00289 void Trackball::
00290 move_origin(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
00291 _rotation = LMatrix4::translate_mat(LVecBase3(x, y, z)) * _rotation;
00292 }
00293
00294
00295
00296
00297
00298
00299 LPoint3 Trackball::
00300 get_origin() const {
00301 return _rotation.get_row3(3);
00302 }
00303
00304
00305
00306
00307
00308
00309 void Trackball::
00310 set_origin(const LVecBase3 &origin) {
00311 _rotation.set_row(3, LVecBase3(0.0f, 0.0f, 0.0f));
00312 _rotation = LMatrix4::translate_mat(-origin) * _rotation;
00313 }
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 void Trackball::
00324 set_invert(bool flag) {
00325 _invert = flag;
00326 }
00327
00328
00329
00330
00331
00332
00333
00334
00335 bool Trackball::
00336 get_invert() const {
00337 return _invert;
00338 }
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351 void Trackball::
00352 set_control_mode(ControlMode control_mode) {
00353 _control_mode = control_mode;
00354 }
00355
00356
00357
00358
00359
00360
00361 Trackball::ControlMode Trackball::
00362 get_control_mode() const {
00363 return _control_mode;
00364 }
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376 void Trackball::
00377 set_rel_to(const NodePath &rel_to) {
00378 _rel_to = rel_to;
00379 }
00380
00381
00382
00383
00384
00385
00386
00387 const NodePath &Trackball::
00388 get_rel_to() const {
00389 return _rel_to;
00390 }
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402 void Trackball::
00403 set_coordinate_system(CoordinateSystem cs) {
00404 _cs = cs;
00405 }
00406
00407
00408
00409
00410
00411
00412
00413 CoordinateSystem Trackball::
00414 get_coordinate_system() const {
00415 return _cs;
00416 }
00417
00418
00419
00420
00421
00422
00423
00424
00425 void Trackball::
00426 set_mat(const LMatrix4 &mat) {
00427 _orig = mat;
00428 if (_invert) {
00429 _mat = invert(_orig);
00430 } else {
00431 _mat = _orig;
00432 }
00433
00434 reextract();
00435 }
00436
00437
00438
00439
00440
00441
00442
00443
00444 const LMatrix4 &Trackball::
00445 get_mat() const {
00446 return _orig;
00447 }
00448
00449
00450
00451
00452
00453
00454
00455
00456 const LMatrix4 &Trackball::
00457 get_trans_mat() const {
00458 return _mat;
00459 }
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469 void Trackball::
00470 apply(double x, double y, int button) {
00471 if (button && !_rel_to.is_empty()) {
00472
00473
00474 reextract();
00475 }
00476
00477 if (button == B1_MASK && _control_mode != CM_default) {
00478
00479
00480
00481 switch (_control_mode) {
00482 case CM_truck:
00483 button = B1_MASK;
00484 break;
00485
00486 case CM_pan:
00487 button = B2_MASK;
00488 break;
00489
00490 case CM_dolly:
00491 button = B3_MASK;
00492 break;
00493
00494 case CM_roll:
00495 button = B2_MASK | B3_MASK;
00496 break;
00497
00498 case CM_default:
00499
00500 nassertv(false);
00501 }
00502 }
00503
00504 if (button == B1_MASK) {
00505
00506
00507 _translation +=
00508 x * _fwdscale * LVector3::right(_cs) +
00509 y * _fwdscale * LVector3::down(_cs);
00510
00511 } else if (button == (B2_MASK | B3_MASK)) {
00512
00513
00514
00515 _rotation *=
00516 LMatrix4::rotate_mat_normaxis((x - y) * _rotscale,
00517 LVector3::forward(_cs), _cs);
00518
00519 } else if ((button == B2_MASK) || (button == (B1_MASK | B3_MASK))) {
00520
00521
00522
00523
00524 _rotation *=
00525 LMatrix4::rotate_mat_normaxis(x * _rotscale, LVector3::up(_cs), _cs) *
00526 LMatrix4::rotate_mat_normaxis(y * _rotscale, LVector3::right(_cs), _cs);
00527
00528 } else if ((button == B3_MASK) || (button == (B1_MASK | B2_MASK))) {
00529
00530
00531
00532 _translation -= y * _fwdscale * LVector3::forward(_cs);
00533 }
00534
00535 if (button) {
00536 recompute();
00537 }
00538 }
00539
00540
00541
00542
00543
00544
00545
00546
00547 void Trackball::
00548 reextract() {
00549 LMatrix4 m = _orig;
00550 if (!_rel_to.is_empty()) {
00551 NodePath root;
00552 m = _orig * root.get_transform(_rel_to)->get_mat();
00553 }
00554
00555 m.get_row3(_translation,3);
00556 _rotation = m;
00557 _rotation.set_row(3, LVecBase3(0.0f, 0.0f, 0.0f));
00558 }
00559
00560
00561
00562
00563
00564
00565
00566 void Trackball::
00567 recompute() {
00568 _orig = _rotation * LMatrix4::translate_mat(_translation);
00569
00570 if (!_rel_to.is_empty()) {
00571 NodePath root;
00572 _orig = _orig * _rel_to.get_transform(root)->get_mat();
00573 }
00574
00575 if (_invert) {
00576 _mat = invert(_orig);
00577 } else {
00578 _mat = _orig;
00579 }
00580 }
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596 void Trackball::
00597 do_transmit_data(DataGraphTraverser *, const DataNodeTransmit &input,
00598 DataNodeTransmit &output) {
00599
00600 bool required_buttons_match;
00601 check_button_events(input, required_buttons_match);
00602
00603
00604 if (required_buttons_match && input.has_data(_pixel_xy_input)) {
00605 const EventStoreVec2 *pixel_xy;
00606 DCAST_INTO_V(pixel_xy, input.get_data(_pixel_xy_input).get_ptr());
00607 const LVecBase2 &p = pixel_xy->get_value();
00608 PN_stdfloat this_x = p[0];
00609 PN_stdfloat this_y = p[1];
00610 int this_button = 0;
00611
00612 if (is_down(MouseButton::one())) {
00613 if (is_down(KeyboardButton::alt())) {
00614
00615 this_button |= B2_MASK;
00616 if (is_down(KeyboardButton::meta()) || is_down(KeyboardButton::control())) {
00617 this_button |= B3_MASK;
00618 }
00619
00620 } else if (is_down(KeyboardButton::meta()) || is_down(KeyboardButton::control())) {
00621
00622 this_button |= B3_MASK;
00623
00624 } else {
00625
00626 this_button |= B1_MASK;
00627 }
00628 }
00629 if (is_down(MouseButton::two())) {
00630 this_button |= B2_MASK;
00631 }
00632 if (is_down(MouseButton::three())) {
00633 this_button |= B3_MASK;
00634 }
00635
00636 PN_stdfloat x = this_x - _lastx;
00637 PN_stdfloat y = this_y - _lasty;
00638
00639 if (this_button == _last_button) {
00640 apply(x, y, this_button);
00641 }
00642
00643 _last_button = this_button;
00644 _lastx = this_x;
00645 _lasty = this_y;
00646 } else {
00647 _last_button = 0;
00648 }
00649
00650
00651 _transform = TransformState::make_mat(_mat);
00652 output.set_data(_transform_output, EventParameter(_transform));
00653 }