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);
const LMatrix4 & get_trans_mat() const
Returns the actual transform that will be applied to the scene graph.
void set_mat(const LMatrix4 &mat)
Stores the indicated transform in the trackball.
void set_control_mode(ControlMode control_mode)
Sets the control mode.
An optional parameter associated with an event.
bool is_empty() const
Returns true if the NodePath contains no nodes.
get_value
Retrieves the value stored in the parameter.
void set_invert(bool flag)
Sets the invert flag.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool has_data(int index) const
Returns true if the indicated parameter has been stored, false otherwise.
A handy class object for storing simple values (like integers or strings) passed along with an Event ...
CoordinateSystem get_coordinate_system() const
Returns the coordinate system of the Trackball.
void set_coordinate_system(CoordinateSystem cs)
Sets the coordinate system of the Trackball.
const LPoint3 & get_pos() const
Return the offset from the center of rotation.
PN_stdfloat get_forward_scale() const
Returns the scale factor applied to forward and backward motion.
void set_data(int index, const EventParameter &data)
Sets the data for the indicated parameter.
ControlMode get_control_mode() const
Returns the control mode.
LPoint3 get_origin() const
Returns the current center of rotation.
const NodePath & get_rel_to() const
Returns the NodePath that all trackball manipulations are relative to, or the empty path.
void reset()
Reinitializes all transforms to identity.
void move_origin(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z)
Moves the center of rotation by the given amount.
LVecBase3 get_hpr() const
Return the trackball's orientation.
const LMatrix4 & get_mat() const
Returns the matrix represented by the trackball rotation.
This is the base class for some classes that monitor the mouse and keyboard input and perform some ac...
TypedWritableReferenceCount * get_ptr() const
Retrieves a pointer to the actual value stored in the parameter.
const EventParameter & get_data(int index) const
Extracts the data for the indicated index, if it has been stored, or the empty parameter if it has no...
bool get_invert() const
Returns the invert flag.
void set_origin(const LVecBase3 &origin)
Directly sets the center of rotation.
void set_rel_to(const NodePath &rel_to)
Sets the NodePath that all trackball manipulations are to be assumed to be relative to.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TypeHandle is the identifier used to differentiate C++ class types.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
const TransformState * get_transform(Thread *current_thread=Thread::get_current_thread()) const
Returns the complete transform object set on this node.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_hpr(const LVecBase3 &hpr)
Directly set the mover's orientation.
void set_forward_scale(PN_stdfloat fwdscale)
Changes the scale factor applied to forward and backward motion.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
void set_pos(const LVecBase3 &vec)
Directly set the offset from the rotational origin.
Encapsulates the data generated from (or sent into) any particular DataNode.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void reset_origin_here()
Reposition the center of rotation to coincide with the current translation offset.
This object supervises the traversal of the data graph and the moving of data from one DataNode to it...