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