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