diff --git a/panda/src/device/buttonNode.cxx b/panda/src/device/buttonNode.cxx index 4b49f4ce40..6c9a79372d 100644 --- a/panda/src/device/buttonNode.cxx +++ b/panda/src/device/buttonNode.cxx @@ -119,7 +119,10 @@ transmit_data(AllTransitionsWrapper &data) { if (is_valid()) { _button->poll(); _button->lock(); - (*_button_events) = (*_button->get_button_events()); + + // We can no longer copy these in the old scene graph. + // (*_button_events) = (*_button->get_button_events()); + _button->get_button_events()->clear(); _button->unlock(); diff --git a/panda/src/device/buttonNode.h b/panda/src/device/buttonNode.h index f4bba7181d..3d576a5a55 100644 --- a/panda/src/device/buttonNode.h +++ b/panda/src/device/buttonNode.h @@ -26,6 +26,7 @@ #include #include +#include //////////////////////////////////////////////////////////////////// diff --git a/panda/src/device/clientButtonDevice.I b/panda/src/device/clientButtonDevice.I index 6f88f84d45..fe0b046229 100644 --- a/panda/src/device/clientButtonDevice.I +++ b/panda/src/device/clientButtonDevice.I @@ -122,7 +122,7 @@ is_button_known(int index) const { // This must be periodically cleared, or the buttons // will accumulate. //////////////////////////////////////////////////////////////////// -INLINE ButtonEventDataTransition *ClientButtonDevice:: +INLINE ButtonEventList *ClientButtonDevice:: get_button_events() const { return _button_events; } diff --git a/panda/src/device/clientButtonDevice.cxx b/panda/src/device/clientButtonDevice.cxx index a3df1aa90a..921ab09079 100644 --- a/panda/src/device/clientButtonDevice.cxx +++ b/panda/src/device/clientButtonDevice.cxx @@ -19,7 +19,7 @@ #include "clientButtonDevice.h" -#include +#include "indent.h" TypeHandle ClientButtonDevice::_type_handle; @@ -32,7 +32,7 @@ ClientButtonDevice:: ClientButtonDevice(ClientBase *client, const string &device_name): ClientDevice(client, get_class_type(), device_name) { - _button_events = new ButtonEventDataTransition(); + _button_events = new ButtonEventList(); } @@ -53,7 +53,7 @@ set_button_state(int index, bool down) { ButtonHandle handle = _buttons[index]._handle; if (handle != ButtonHandle::none()) { - _button_events->push_back(ButtonEvent(handle, down ? ButtonEvent::T_down : ButtonEvent::T_up)); + _button_events->add_event(ButtonEvent(handle, down ? ButtonEvent::T_down : ButtonEvent::T_up)); } } diff --git a/panda/src/device/clientButtonDevice.h b/panda/src/device/clientButtonDevice.h index 519620696c..7edb5be842 100644 --- a/panda/src/device/clientButtonDevice.h +++ b/panda/src/device/clientButtonDevice.h @@ -19,14 +19,14 @@ #ifndef CLIENTBUTTONDEVICE_H #define CLIENTBUTTONDEVICE_H -#include +#include "pandabase.h" #include "clientDevice.h" -#include -#include -#include -#include +#include "buttonHandle.h" +#include "buttonEvent.h" +#include "buttonEventList.h" +#include "pointerTo.h" //////////////////////////////////////////////////////////////////// // Class : ClientButtonDevice @@ -52,7 +52,7 @@ public: INLINE bool get_button_state(int index) const; INLINE bool is_button_known(int index) const; - INLINE ButtonEventDataTransition *get_button_events() const; + INLINE ButtonEventList *get_button_events() const; virtual void output(ostream &out) const; virtual void write(ostream &out, int indent_level = 0) const; @@ -81,7 +81,7 @@ protected: typedef pvector Buttons; Buttons _buttons; - PT(ButtonEventDataTransition) _button_events; + PT(ButtonEventList) _button_events; public: static TypeHandle get_class_type() { diff --git a/panda/src/device/qpbuttonNode.cxx b/panda/src/device/qpbuttonNode.cxx index 4c5b72bd1e..c61c4b13e3 100644 --- a/panda/src/device/qpbuttonNode.cxx +++ b/panda/src/device/qpbuttonNode.cxx @@ -120,8 +120,7 @@ do_transmit_data(const DataNodeTransmit &, DataNodeTransmit &output) { _button->poll(); _button->lock(); - // *** here we should copy the button events from the ClientButtonDevice. - // (*_button_events) = (*_button->get_button_events()); + (*_button_events) = (*_button->get_button_events()); _button->get_button_events()->clear(); _button->unlock(); diff --git a/panda/src/pgraph/qpnodePath.I b/panda/src/pgraph/qpnodePath.I index 64f76a5ece..d3ad29df93 100644 --- a/panda/src/pgraph/qpnodePath.I +++ b/panda/src/pgraph/qpnodePath.I @@ -376,7 +376,7 @@ ls(ostream &out, int indent_level) const { // Access: Published // Description: Returns the complete state object set on this node. //////////////////////////////////////////////////////////////////// -INLINE CPT(RenderState) qpNodePath:: +INLINE const RenderState *qpNodePath:: get_state() const { nassertr_always(!is_empty(), RenderState::make_empty()); return node()->get_state(); @@ -409,7 +409,7 @@ get_net_state() const { // Access: Published // Description: Returns the complete transform object set on this node. //////////////////////////////////////////////////////////////////// -INLINE CPT(TransformState) qpNodePath:: +INLINE const TransformState *qpNodePath:: get_transform() const { nassertr_always(!is_empty(), TransformState::make_identity()); return node()->get_transform(); diff --git a/panda/src/pgraph/qpnodePath.cxx b/panda/src/pgraph/qpnodePath.cxx index b25d735edb..357c5c19e7 100644 --- a/panda/src/pgraph/qpnodePath.cxx +++ b/panda/src/pgraph/qpnodePath.cxx @@ -141,7 +141,7 @@ get_children() const { } //////////////////////////////////////////////////////////////////// -// Function: qoNodePath::find +// Function: qpNodePath::find // Access: Published // Description: Searches for a node below the referenced node that // matches the indicated string. Returns the shortest @@ -162,6 +162,30 @@ find(const string &path) const { return col.get_path(0); } +//////////////////////////////////////////////////////////////////// +// Function: qpNodePath::find_path_to +// Access: Published +// Description: Searches for the indicated node below this node and +// returns the shortest NodePath that connects them. +//////////////////////////////////////////////////////////////////// +qpNodePath qpNodePath:: +find_path_to(PandaNode *node) const { + nassertr_always(!is_empty(), fail()); + nassertr(node != (PandaNode *)NULL, fail()); + + qpNodePathCollection col; + qpFindApproxPath approx_path; + approx_path.add_match_many(0); + approx_path.add_match_pointer(node, 0); + find_matches(col, approx_path, 1); + + if (col.is_empty()) { + return qpNodePath::not_found(); + } + + return col.get_path(0); +} + //////////////////////////////////////////////////////////////////// // Function: qpNodePath::find_all_matches // Access: Published @@ -863,7 +887,25 @@ heads_up(const LPoint3f &point, const LVector3f &up) { void qpNodePath:: set_pos(const qpNodePath &other, const LVecBase3f &pos) { nassertv_always(!is_empty()); - set_transform(other, get_transform(other)->set_pos(pos)); + CPT(TransformState) rel_transform = get_transform(other); + + CPT(TransformState) orig_transform = get_transform(); + if (orig_transform->has_components()) { + // If we had a componentwise transform before we started, we + // should be careful to preserve the other two components. We + // wouldn't need to do this, except for the possibility of + // numerical error or decompose ambiguity. + const LVecBase3f &orig_hpr = orig_transform->get_hpr(); + const LVecBase3f &orig_scale = orig_transform->get_scale(); + + set_transform(other, rel_transform->set_pos(pos)); + set_pos_hpr_scale(get_transform()->get_pos(), orig_hpr, orig_scale); + + } else { + // If we didn't have a componentwise transform already, never + // mind. + set_transform(other, rel_transform->set_pos(pos)); + } } void qpNodePath:: @@ -911,39 +953,53 @@ get_pos(const qpNodePath &other) const { void qpNodePath:: set_hpr(const qpNodePath &other, const LVecBase3f &hpr) { nassertv_always(!is_empty()); - CPT(TransformState) transform = get_transform(other); - nassertv(transform->has_components()); - set_transform(other, transform->set_hpr(hpr)); + CPT(TransformState) rel_transform = get_transform(other); + nassertv(rel_transform->has_components()); + + CPT(TransformState) orig_transform = get_transform(); + if (orig_transform->has_components()) { + // If we had a componentwise transform before we started, we + // should be careful to preserve the other two components. We + // wouldn't need to do this, except for the possibility of + // numerical error or decompose ambiguity. + const LVecBase3f &orig_pos = orig_transform->get_pos(); + const LVecBase3f &orig_scale = orig_transform->get_scale(); + + set_transform(other, rel_transform->set_hpr(hpr)); + const TransformState *new_transform = get_transform(); + if (new_transform->has_components()) { + set_pos_hpr_scale(orig_pos, new_transform->get_hpr(), orig_scale); + } + + } else { + // If we didn't have a componentwise transform already, never + // mind. + set_transform(other, rel_transform->set_hpr(hpr)); + } } void qpNodePath:: set_h(const qpNodePath &other, float h) { nassertv_always(!is_empty()); - CPT(TransformState) transform = get_transform(other); - nassertv(transform->has_components()); - LVecBase3f hpr = transform->get_hpr(); + LVecBase3f hpr = get_hpr(other); hpr[0] = h; - set_transform(other, transform->set_hpr(hpr)); + set_hpr(other, hpr); } void qpNodePath:: set_p(const qpNodePath &other, float p) { nassertv_always(!is_empty()); - CPT(TransformState) transform = get_transform(other); - nassertv(transform->has_components()); - LVecBase3f hpr = transform->get_hpr(); + LVecBase3f hpr = get_hpr(other); hpr[1] = p; - set_transform(other, transform->set_hpr(hpr)); + set_hpr(other, hpr); } void qpNodePath:: set_r(const qpNodePath &other, float r) { nassertv_always(!is_empty()); - CPT(TransformState) transform = get_transform(other); - nassertv(transform->has_components()); - LVecBase3f hpr = transform->get_hpr(); + LVecBase3f hpr = get_hpr(other); hpr[2] = r; - set_transform(other, transform->set_hpr(hpr)); + set_hpr(other, hpr); } //////////////////////////////////////////////////////////////////// @@ -985,39 +1041,53 @@ get_hpr(const qpNodePath &other, float roll) const { void qpNodePath:: set_scale(const qpNodePath &other, const LVecBase3f &scale) { nassertv_always(!is_empty()); - CPT(TransformState) transform = get_transform(other); - nassertv(transform->has_components()); - set_transform(other, transform->set_scale(scale)); + CPT(TransformState) rel_transform = get_transform(other); + nassertv(rel_transform->has_components()); + + CPT(TransformState) orig_transform = get_transform(); + if (orig_transform->has_components()) { + // If we had a componentwise transform before we started, we + // should be careful to preserve the other two components. We + // wouldn't need to do this, except for the possibility of + // numerical error or decompose ambiguity. + const LVecBase3f &orig_pos = orig_transform->get_pos(); + const LVecBase3f &orig_hpr = orig_transform->get_hpr(); + + set_transform(other, rel_transform->set_scale(scale)); + const TransformState *new_transform = get_transform(); + if (new_transform->has_components()) { + set_pos_hpr_scale(orig_pos, orig_hpr, new_transform->get_scale()); + } + + } else { + // If we didn't have a componentwise transform already, never + // mind. + set_transform(other, rel_transform->set_scale(scale)); + } } void qpNodePath:: set_sx(const qpNodePath &other, float sx) { nassertv_always(!is_empty()); - CPT(TransformState) transform = get_transform(other); - nassertv(transform->has_components()); - LVecBase3f scale = transform->get_scale(); + LVecBase3f scale = get_scale(other); scale[0] = sx; - set_transform(other, transform->set_scale(scale)); + set_scale(other, scale); } void qpNodePath:: set_sy(const qpNodePath &other, float sy) { nassertv_always(!is_empty()); - CPT(TransformState) transform = get_transform(other); - nassertv(transform->has_components()); - LVecBase3f scale = transform->get_scale(); + LVecBase3f scale = get_scale(other); scale[1] = sy; - set_transform(other, transform->set_scale(scale)); + set_scale(other, scale); } void qpNodePath:: set_sz(const qpNodePath &other, float sz) { nassertv_always(!is_empty()); - CPT(TransformState) transform = get_transform(other); - nassertv(transform->has_components()); - LVecBase3f scale = transform->get_scale(); + LVecBase3f scale = get_scale(other); scale[2] = sz; - set_transform(other, transform->set_scale(scale)); + set_scale(other, scale); } //////////////////////////////////////////////////////////////////// @@ -1044,11 +1114,31 @@ void qpNodePath:: set_pos_hpr(const qpNodePath &other, const LVecBase3f &pos, const LVecBase3f &hpr) { nassertv_always(!is_empty()); - CPT(TransformState) transform = get_transform(other); - nassertv(transform->has_components()); - transform = TransformState::make_pos_hpr_scale - (pos, hpr, transform->get_scale()); - set_transform(other, transform); + CPT(TransformState) rel_transform = get_transform(other); + nassertv(rel_transform->has_components()); + + CPT(TransformState) orig_transform = get_transform(); + if (orig_transform->has_components()) { + // If we had a componentwise transform before we started, we + // should be careful to preserve the other two components. We + // wouldn't need to do this, except for the possibility of + // numerical error or decompose ambiguity. + const LVecBase3f &orig_scale = orig_transform->get_scale(); + + set_transform(other, TransformState::make_pos_hpr_scale + (pos, hpr, rel_transform->get_scale())); + const TransformState *new_transform = get_transform(); + if (new_transform->has_components()) { + set_pos_hpr_scale(new_transform->get_pos(), new_transform->get_hpr(), + orig_scale); + } + + } else { + // If we didn't have a componentwise transform already, never + // mind. + set_transform(other, TransformState::make_pos_hpr_scale + (pos, hpr, rel_transform->get_scale())); + } } //////////////////////////////////////////////////////////////////// @@ -1061,6 +1151,10 @@ set_pos_hpr(const qpNodePath &other, const LVecBase3f &pos, //////////////////////////////////////////////////////////////////// void qpNodePath:: set_hpr_scale(const qpNodePath &other, const LVecBase3f &hpr, const LVecBase3f &scale) { + // We don't bother trying very hard to preserve pos across this + // operation, unlike the work we do above to preserve hpr or scale, + // since it generally doesn't matter that much if pos is off by a + // few thousandths. nassertv_always(!is_empty()); CPT(TransformState) transform = get_transform(other); transform = TransformState::make_pos_hpr_scale diff --git a/panda/src/pgraph/qpnodePath.h b/panda/src/pgraph/qpnodePath.h index 0c2be06a0c..ebb0fbcf5d 100644 --- a/panda/src/pgraph/qpnodePath.h +++ b/panda/src/pgraph/qpnodePath.h @@ -187,6 +187,7 @@ PUBLISHED: INLINE qpNodePath get_parent() const; qpNodePath find(const string &path) const; + qpNodePath find_path_to(PandaNode *node) const; qpNodePathCollection find_all_matches(const string &path) const; qpNodePathCollection find_all_paths_to(PandaNode *node) const; @@ -216,13 +217,13 @@ PUBLISHED: // Aggregate transform and state information. - INLINE CPT(RenderState) get_state() const; + INLINE const RenderState *get_state() const; INLINE void set_state(const RenderState *state) const; CPT(RenderState) get_state(const qpNodePath &other) const; void set_state(const qpNodePath &other, const RenderState *state) const; INLINE CPT(RenderState) get_net_state() const; - INLINE CPT(TransformState) get_transform() const; + INLINE const TransformState *get_transform() const; INLINE void set_transform(const TransformState *transform) const; CPT(TransformState) get_transform(const qpNodePath &other) const; void set_transform(const qpNodePath &other, const TransformState *transform) const;