37 Trackball(
const std::string &name) :
40 _pixel_xy_input = define_input(
"pixel_xy", EventStoreVec2::get_class_type());
42 _transform_output = define_output(
"transform", TransformState::get_class_type());
44 _transform = TransformState::make_identity();
50 _lastx = _lasty = 0.5f;
52 _rotation = LMatrix4::ident_mat();
53 _translation.set(0.0f, 0.0f, 0.0f);
54 _mat = LMatrix4::ident_mat();
55 _orig = LMatrix4::ident_mat();
57 _cs = get_default_coordinate_system();
58 _control_mode = CM_default;
65 if (trackball_use_alt_keys) {
68 watch_button(KeyboardButton::control());
69 watch_button(KeyboardButton::meta());
70 watch_button(KeyboardButton::alt());
86 _rotation = LMatrix4::ident_mat();
87 _translation.set(0.0f, 0.0f, 0.0f);
88 _orig = LMatrix4::ident_mat();
89 _mat = LMatrix4::ident_mat();
108 _fwdscale = fwdscale;
120 PN_stdfloat Trackball::
122 return _translation[0];
125 PN_stdfloat Trackball::
127 return _translation[1];
130 PN_stdfloat Trackball::
132 return _translation[2];
146 set_pos(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
147 _translation.set(x, y, z);
152 set_x(PN_stdfloat x) {
158 set_y(PN_stdfloat y) {
164 set_z(PN_stdfloat z) {
175 LVecBase3 scale, shear, hpr, translate;
176 decompose_matrix(_rotation, scale, shear, hpr, translate);
180 PN_stdfloat Trackball::
182 LVecBase3 scale, shear, hpr, translate;
183 decompose_matrix(_rotation, scale, shear, hpr, translate);
187 PN_stdfloat Trackball::
189 LVecBase3 scale, shear, hpr, translate;
190 decompose_matrix(_rotation, scale, shear, hpr, translate);
194 PN_stdfloat Trackball::
196 LVecBase3 scale, shear, hpr, translate;
197 decompose_matrix(_rotation, scale, shear, hpr, translate);
207 LVecBase3 scale, shear, old_hpr, translate;
208 decompose_matrix(_rotation, scale, shear, old_hpr, translate);
209 compose_matrix(_rotation, scale, shear, hpr, translate);
214 set_hpr(PN_stdfloat h, PN_stdfloat p, PN_stdfloat r) {
215 LVecBase3 scale, shear, hpr, translate;
216 decompose_matrix(_rotation, scale, shear, hpr, translate);
218 compose_matrix(_rotation, scale, shear, hpr, translate);
223 set_h(PN_stdfloat h) {
224 LVecBase3 scale, shear, hpr, translate;
225 decompose_matrix(_rotation, scale, shear, hpr, translate);
227 compose_matrix(_rotation, scale, shear, hpr, translate);
232 set_p(PN_stdfloat p) {
233 LVecBase3 scale, shear, hpr, translate;
234 decompose_matrix(_rotation, scale, shear, hpr, translate);
236 compose_matrix(_rotation, scale, shear, hpr, translate);
241 set_r(PN_stdfloat r) {
242 LVecBase3 scale, shear, hpr, translate;
243 decompose_matrix(_rotation, scale, shear, hpr, translate);
245 compose_matrix(_rotation, scale, shear, hpr, translate);
258 _translation.set(0.0f, 0.0f, 0.0f);
267 _rotation = LMatrix4::translate_mat(LVecBase3(x, y, z)) * _rotation;
275 return _rotation.get_row3(3);
283 _rotation.set_row(3, LVecBase3(0.0f, 0.0f, 0.0f));
284 _rotation = LMatrix4::translate_mat(-origin) * _rotation;
316 _control_mode = control_mode;
324 return _control_mode;
375 _mat = invert(_orig);
407 apply(
double x,
double y,
int button) {
408 if (button && !_rel_to.
is_empty()) {
414 if (button == B1_MASK && _control_mode != CM_default) {
417 switch (_control_mode) {
431 button = B2_MASK | B3_MASK;
440 if (button == B1_MASK) {
444 x * _fwdscale * LVector3::right(_cs) +
445 y * _fwdscale * LVector3::down(_cs);
447 }
else if (button == (B2_MASK | B3_MASK)) {
451 LMatrix4::rotate_mat_normaxis((x - y) * _rotscale,
452 LVector3::forward(_cs), _cs);
454 }
else if ((button == B2_MASK) || (button == (B1_MASK | B3_MASK))) {
459 LMatrix4::rotate_mat_normaxis(x * _rotscale, LVector3::up(_cs), _cs) *
460 LMatrix4::rotate_mat_normaxis(y * _rotscale, LVector3::right(_cs), _cs);
462 }
else if ((button == B3_MASK) || (button == (B1_MASK | B2_MASK))) {
466 _translation -= y * _fwdscale * LVector3::forward(_cs);
487 m.get_row3(_translation,3);
489 _rotation.set_row(3, LVecBase3(0.0f, 0.0f, 0.0f));
498 _orig = _rotation * LMatrix4::translate_mat(_translation);
506 _mat = invert(_orig);
525 bool required_buttons_match;
526 check_button_events(input, required_buttons_match);
529 if (required_buttons_match && input.
has_data(_pixel_xy_input)) {
532 const LVecBase2 &p = pixel_xy->
get_value();
533 PN_stdfloat this_x = p[0];
534 PN_stdfloat this_y = p[1];
538 if (is_down(KeyboardButton::alt())) {
540 this_button |= B2_MASK;
541 if (is_down(KeyboardButton::meta()) || is_down(KeyboardButton::control())) {
542 this_button |= B3_MASK;
545 }
else if (is_down(KeyboardButton::meta()) || is_down(KeyboardButton::control())) {
547 this_button |= B3_MASK;
551 this_button |= B1_MASK;
555 this_button |= B2_MASK;
558 this_button |= B3_MASK;
561 PN_stdfloat x = this_x - _lastx;
562 PN_stdfloat y = this_y - _lasty;
564 if (this_button == _last_button) {
565 apply(x, y, this_button);
568 _last_button = this_button;
576 _transform = TransformState::make_mat(_mat);