David Rose пре 21 година
родитељ
комит
f678c0c932

+ 36 - 26
panda/src/pgraph/billboardEffect.cxx

@@ -145,22 +145,19 @@ cull_callback(CullTraverser *trav, CullTraverserData &data,
     camera_transform = _look_at.get_net_transform();
   }
 
-  CPT(TransformState) billboard_transform =
-    compute_billboard(net_transform, camera_transform);
-
-  node_transform = billboard_transform->compose(node_transform);
+  compute_billboard(node_transform, net_transform, camera_transform);
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: BillboardEffect::has_net_transform
+//     Function: BillboardEffect::has_adjust_transform
 //       Access: Public, Virtual
 //  Description: Should be overridden by derived classes to return
-//               true if net_transform() has been defined, and
+//               true if adjust_transform() has been defined, and
 //               therefore the RenderEffect has some effect on the
-//               node's apparent net transform.
+//               node's apparent local and net transforms.
 ////////////////////////////////////////////////////////////////////
 bool BillboardEffect::
-has_net_transform() const {
+has_adjust_transform() const {
   // A BillboardEffect can only affect the net transform when it is to
   // a particular node.  A billboard to a camera is camera-dependent,
   // of course, so it has no effect in the absence of any particular
@@ -169,31 +166,30 @@ has_net_transform() const {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: BillboardEffect::net_transform
+//     Function: BillboardEffect::adjust_transform
 //       Access: Public, Virtual
-//  Description: Given the node's parent's net transform, compute its
-//               parent's new net transform after application of the
-//               RenderEffect.  Presumably this interposes some
-//               special transform derived from the RenderEffect.
-//               This may only be called if has_net_transform(),
-//               above, has been defined to return true.
+//  Description: Performs some operation on the node's apparent net
+//               and/or local transforms.  This will only be called if
+//               has_adjust_transform() is redefined to return true.
+//
+//               Both parameters are in/out.  The original transforms
+//               will be passed in, and they may (or may not) be
+//               modified in-place by the RenderEffect.
 ////////////////////////////////////////////////////////////////////
-CPT(TransformState) BillboardEffect::
-net_transform(const TransformState *orig_net_transform) const {
+void BillboardEffect::
+adjust_transform(CPT(TransformState) &net_transform,
+                 CPT(TransformState) &node_transform) const {
   // A BillboardEffect can only affect the net transform when it is to
   // a particular node.  A billboard to a camera is camera-dependent,
   // of course, so it has no effect in the absence of any particular
   // camera viewing it.
   if (_look_at.is_empty()) {
-    return orig_net_transform;
+    return;
   }
 
   CPT(TransformState) camera_transform = _look_at.get_net_transform();
 
-  CPT(TransformState) billboard_transform =
-    compute_billboard(orig_net_transform, camera_transform);
-
-  return orig_net_transform->compose(billboard_transform);
+  compute_billboard(node_transform, net_transform, camera_transform);
 }
 
 
@@ -246,12 +242,26 @@ compare_to_impl(const RenderEffect *other) const {
 //       Access: Private
 //  Description: Computes the billboard operation given the parent's
 //               net transform and the camera transform.
+//
+//               The result is applied to node_transform, which is
+//               modified in-place.
 ////////////////////////////////////////////////////////////////////
-CPT(TransformState) BillboardEffect::
-compute_billboard(const TransformState *net_transform, 
+void BillboardEffect::
+compute_billboard(CPT(TransformState) &node_transform, 
+                  const TransformState *net_transform, 
                   const TransformState *camera_transform) const {
+  // First, extract out just the translation component of the node's
+  // local transform.  This gets applied to the net transform, to
+  // compute the look-at direction properly.
+  CPT(TransformState) translate = TransformState::make_pos(node_transform->get_pos());
+
+  // And then the translation gets removed from the node, but we keep
+  // its rotation etc., which gets applied after the billboard
+  // operation.
+  node_transform = node_transform->set_pos(LPoint3f(0.0f, 0.0f, 0.0f));
+
   CPT(TransformState) rel_transform =
-    net_transform->invert_compose(camera_transform);
+    net_transform->compose(translate)->invert_compose(camera_transform);
   const LMatrix4f &rel_mat = rel_transform->get_mat();
 
   // Determine the look_at point in the camera space.
@@ -289,7 +299,7 @@ compute_billboard(const TransformState *net_transform,
     rotate.set_row(3, translate);
   }
 
-  return TransformState::make_mat(rotate);
+  node_transform = translate->compose(TransformState::make_mat(rotate))->compose(node_transform);
 }
 
 ////////////////////////////////////////////////////////////////////

+ 6 - 4
panda/src/pgraph/billboardEffect.h

@@ -63,15 +63,17 @@ public:
                              CPT(TransformState) &node_transform,
                              CPT(RenderState) &node_state) const;
 
-  virtual bool has_net_transform() const;
-  virtual CPT(TransformState) net_transform(const TransformState *orig_net_transform) const;
+  virtual bool has_adjust_transform() const;
+  virtual void adjust_transform(CPT(TransformState) &net_transform,
+                                CPT(TransformState) &node_transform) const;
 
 protected:
   virtual int compare_to_impl(const RenderEffect *other) const;
 
 private:
-  CPT(TransformState) compute_billboard(const TransformState *net_transform, 
-                                        const TransformState *camera_transform) const;
+  void compute_billboard(CPT(TransformState) &node_transform, 
+                         const TransformState *net_transform, 
+                         const TransformState *camera_transform) const;
 
 private:
   bool _off;

+ 34 - 31
panda/src/pgraph/compassEffect.cxx

@@ -144,12 +144,13 @@ cull_callback(CullTraverser *, CullTraverserData &data,
   }
 
   CPT(TransformState) true_net_transform = data._net_transform;
-  CPT(TransformState) want_transform = net_transform(data._net_transform);
+  CPT(TransformState) want_net_transform = data._net_transform;
+  adjust_transform(want_net_transform, node_transform);
 
   // Now compute the transform that will convert true_net_transform to
   // want_transform.  This is inv(true_net_transform) * want_transform.
   CPT(TransformState) compass_transform =
-    true_net_transform->invert_compose(want_transform);
+    true_net_transform->invert_compose(want_net_transform);
 
   // And modify our local node's apparent transform so that
   // true_net_transform->compose(new_node_transform) produces the same
@@ -159,33 +160,35 @@ cull_callback(CullTraverser *, CullTraverserData &data,
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: CompassEffect::has_net_transform
+//     Function: CompassEffect::has_adjust_transform
 //       Access: Public, Virtual
 //  Description: Should be overridden by derived classes to return
-//               true if net_transform() has been defined, and
+//               true if adjust_transform() has been defined, and
 //               therefore the RenderEffect has some effect on the
-//               node's apparent net transform.
+//               node's apparent local and net transforms.
 ////////////////////////////////////////////////////////////////////
 bool CompassEffect::
-has_net_transform() const {
+has_adjust_transform() const {
   return (_properties != 0);
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: CompassEffect::net_transform
+//     Function: CompassEffect::adjust_transform
 //       Access: Public, Virtual
-//  Description: Given the node's parent's net transform, compute its
-//               parent's new net transform after application of the
-//               RenderEffect.  Presumably this interposes some
-//               special transform derived from the RenderEffect.
-//               This may only be called if has_net_transform(),
-//               above, has been defined to return true.
+//  Description: Performs some operation on the node's apparent net
+//               and/or local transforms.  This will only be called if
+//               has_adjust_transform() is redefined to return true.
+//
+//               Both parameters are in/out.  The original transforms
+//               will be passed in, and they may (or may not) be
+//               modified in-place by the RenderEffect.
 ////////////////////////////////////////////////////////////////////
-CPT(TransformState) CompassEffect::
-net_transform(const TransformState *orig_net_transform) const {
+void CompassEffect::
+adjust_transform(CPT(TransformState) &net_transform,
+                 CPT(TransformState) &node_transform) const {
   if (_properties == 0) {
     // Nothing to do.
-    return orig_net_transform;
+    return;
   }
 
   // The reference transform: where we are acting as if we inherit
@@ -198,19 +201,19 @@ net_transform(const TransformState *orig_net_transform) const {
     ref_transform = _reference.get_net_transform();
   }
 
-  // Now compute the transform we actually want to achieve.  This is
-  // all of the components from the net transform we want to inherit
-  // normally from our parent, with all of the components from the ref
-  // transform we want to inherit from our reference.
-  CPT(TransformState) want_transform;
+  // Now compute the net transform we actually want to achieve.  This
+  // is all of the components from the net transform we want to
+  // inherit normally from our parent, with all of the components from
+  // the ref transform we want to inherit from our reference.
+  CPT(TransformState) want_net_transform;
   if (_properties == P_all) {
     // If we want to steal the whole transform, that's easy.
-    want_transform = ref_transform;
+    want_net_transform = ref_transform;
 
   } else {
     // How much of the pos do we want to steal?  We can always
     // determine a transform's pos, even if it's nondecomposable.
-    LVecBase3f want_pos = orig_net_transform->get_pos();
+    LVecBase3f want_pos = net_transform->get_pos();
     const LVecBase3f &ref_pos = ref_transform->get_pos();
     if ((_properties & P_x) != 0) {
       want_pos[0] = ref_pos[0];
@@ -224,29 +227,29 @@ net_transform(const TransformState *orig_net_transform) const {
 
     if ((_properties & ~P_pos) == 0) {
       // If we only want to steal the pos, that's pretty easy.
-      want_transform = orig_net_transform->set_pos(want_pos);
+      want_net_transform = net_transform->set_pos(want_pos);
   
     } else if ((_properties & (P_rot | P_scale)) == (P_rot | P_scale)) {
       // If we want to steal everything *but* the pos, also easy.
-      want_transform = ref_transform->set_pos(want_pos);
+      want_net_transform = ref_transform->set_pos(want_pos);
       
     } else {
       // For any other combination, we have to be able to decompose both
       // transforms.
-      if (!orig_net_transform->has_components() || 
+      if (!net_transform->has_components() || 
           !ref_transform->has_components()) {
         // If we can't decompose, just do the best we can: steal
         // everything but the pos.
-        want_transform = ref_transform->set_pos(want_pos);
+        want_net_transform = ref_transform->set_pos(want_pos);
 
       } else {
         // If we can decompose, then take only the components we want.
-        LQuaternionf want_quat = orig_net_transform->get_quat();
+        LQuaternionf want_quat = net_transform->get_quat();
         if ((_properties & P_rot) != 0) {
           want_quat = ref_transform->get_quat();
         }
 
-        LVecBase3f want_scale = orig_net_transform->get_scale();
+        LVecBase3f want_scale = net_transform->get_scale();
         const LVecBase3f &ref_scale = ref_transform->get_scale();
         if ((_properties & P_sx) != 0) {
           want_scale[0] = ref_scale[0];
@@ -258,13 +261,13 @@ net_transform(const TransformState *orig_net_transform) const {
           want_scale[2] = ref_scale[2];
         }
 
-        want_transform =
+        want_net_transform =
           TransformState::make_pos_quat_scale(want_pos, want_quat, want_scale);
       }
     }
   }
 
-  return want_transform;
+  net_transform = want_net_transform;
 }
 
 ////////////////////////////////////////////////////////////////////

+ 3 - 2
panda/src/pgraph/compassEffect.h

@@ -88,8 +88,9 @@ public:
                              CPT(TransformState) &node_transform,
                              CPT(RenderState) &node_state) const;
 
-  virtual bool has_net_transform() const;
-  virtual CPT(TransformState) net_transform(const TransformState *orig_net_transform) const;
+  virtual bool has_adjust_transform() const;
+  virtual void adjust_transform(CPT(TransformState) &net_transform,
+                                CPT(TransformState) &node_transform) const;
 
 protected:
   virtual int compare_to_impl(const RenderEffect *other) const;

+ 3 - 3
panda/src/pgraph/nodePath.cxx

@@ -4821,8 +4821,8 @@ r_get_net_transform(NodePathComponent *comp) const {
     CPT(TransformState) transform = comp->get_node()->get_transform();
 
     CPT(RenderEffects) effects = comp->get_node()->get_effects();
-    if (effects->has_net_transform()) {
-      net_transform = effects->net_transform(net_transform);
+    if (effects->has_adjust_transform()) {
+      effects->adjust_transform(net_transform, transform);
     }
       
     return net_transform->compose(transform);
@@ -4846,7 +4846,7 @@ r_get_partial_transform(NodePathComponent *comp, int n) const {
   if (n == 0 || comp == (NodePathComponent *)NULL) {
     return TransformState::make_identity();
   } else {
-    if (comp->get_node()->get_effects()->has_net_transform()) {
+    if (comp->get_node()->get_effects()->has_adjust_transform()) {
       return NULL;
     }
     CPT(TransformState) transform = comp->get_node()->get_transform();

+ 15 - 15
panda/src/pgraph/renderEffect.cxx

@@ -162,31 +162,31 @@ cull_callback(CullTraverser *, CullTraverserData &,
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: RenderEffect::has_net_transform
+//     Function: RenderEffect::has_adjust_transform
 //       Access: Public, Virtual
 //  Description: Should be overridden by derived classes to return
-//               true if net_transform() has been defined, and
+//               true if adjust_transform() has been defined, and
 //               therefore the RenderEffect has some effect on the
-//               node's apparent net transform.
+//               node's apparent local and net transforms.
 ////////////////////////////////////////////////////////////////////
 bool RenderEffect::
-has_net_transform() const {
+has_adjust_transform() const {
   return false;
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: RenderEffect::net_transform
+//     Function: RenderEffect::adjust_transform
 //       Access: Public, Virtual
-//  Description: Given the node's parent's net transform, compute its
-//               parent's new net transform after application of the
-//               RenderEffect.  Presumably this interposes some
-//               special transform derived from the RenderEffect.
-//               This may only be called if has_net_transform(),
-//               above, has been defined to return true.
-////////////////////////////////////////////////////////////////////
-CPT(TransformState) RenderEffect::
-net_transform(CPT(TransformState) &orig_net_transform) const {
-  return orig_net_transform;
+//  Description: Performs some operation on the node's apparent net
+//               and/or local transforms.  This will only be called if
+//               has_adjust_transform() is redefined to return true.
+//
+//               Both parameters are in/out.  The original transforms
+//               will be passed in, and they may (or may not) be
+//               modified in-place by the RenderEffect.
+////////////////////////////////////////////////////////////////////
+void RenderEffect::
+adjust_transform(CPT(TransformState) &, CPT(TransformState) &) const {
 }
 
 ////////////////////////////////////////////////////////////////////

+ 3 - 2
panda/src/pgraph/renderEffect.h

@@ -75,8 +75,9 @@ public:
                              CPT(TransformState) &node_transform,
                              CPT(RenderState) &node_state) const;
 
-  virtual bool has_net_transform() const;
-  virtual CPT(TransformState) net_transform(CPT(TransformState) &orig_net_transform) const;
+  virtual bool has_adjust_transform() const;
+  virtual void adjust_transform(CPT(TransformState) &net_transform,
+                                CPT(TransformState) &node_transform) const;
 
 PUBLISHED:
   INLINE int compare_to(const RenderEffect &other) const;

+ 7 - 7
panda/src/pgraph/renderEffects.I

@@ -201,19 +201,19 @@ has_cull_callback() const {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: RenderEffects::has_net_transform
+//     Function: RenderEffects::has_adjust_transform
 //       Access: Public
 //  Description: This function is provided as an optimization, to
 //               speed up the render-time checking for the existance
-//               of an effect with a compute_net_transform on this
+//               of an effect with a compute_adjust_transform on this
 //               state.
 ////////////////////////////////////////////////////////////////////
 INLINE bool RenderEffects::
-has_net_transform() const {
-  if ((_flags & F_checked_net_transform) == 0) {
+has_adjust_transform() const {
+  if ((_flags & F_checked_adjust_transform) == 0) {
     // We pretend this function is const, even though it transparently
-    // modifies the internal net_transform cache.
-    ((RenderEffects *)this)->determine_net_transform();
+    // modifies the internal adjust_transform cache.
+    ((RenderEffects *)this)->determine_adjust_transform();
   }
-  return ((_flags & F_has_net_transform) != 0);
+  return ((_flags & F_has_adjust_transform) != 0);
 }

+ 13 - 15
panda/src/pgraph/renderEffects.cxx

@@ -421,10 +421,10 @@ cull_callback(CullTraverser *trav, CullTraverserData &data,
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: RenderEffects::net_transform
+//     Function: RenderEffects::adjust_transform
 //       Access: Public
-//  Description: Calls net_transform() on all effects.  You may check
-//               has_net_transform() first to see if any effects
+//  Description: Calls adjust_transform() on all effects.  You may check
+//               has_adjust_transform() first to see if any effects
 //               define this method to do anything useful.
 //
 //               The order in which the individual effects are applied
@@ -432,15 +432,13 @@ cull_callback(CullTraverser *trav, CullTraverserData &data,
 //               change to the transform on any particular node, you
 //               might get indeterminate results.
 ////////////////////////////////////////////////////////////////////
-CPT(TransformState) RenderEffects::
-net_transform(const TransformState *orig_net_transform) const {
-  CPT(TransformState) net_transform = orig_net_transform;
+void RenderEffects::
+adjust_transform(CPT(TransformState) &net_transform,
+                 CPT(TransformState) &node_transform) const {
   Effects::const_iterator ei;
   for (ei = _effects.begin(); ei != _effects.end(); ++ei) {
-    net_transform = (*ei)._effect->net_transform(net_transform);
+    (*ei)._effect->adjust_transform(net_transform, node_transform);
   }
-
-  return net_transform;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -597,18 +595,18 @@ determine_cull_callback() {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: RenderEffects::determine_net_transform
+//     Function: RenderEffects::determine_adjust_transform
 //       Access: Private
-//  Description: This is the private implementation of has_net_transform().
+//  Description: This is the private implementation of has_adjust_transform().
 ////////////////////////////////////////////////////////////////////
 void RenderEffects::
-determine_net_transform() {
-  _flags |= F_checked_net_transform;
+determine_adjust_transform() {
+  _flags |= F_checked_adjust_transform;
 
   Effects::const_iterator ei;
   for (ei = _effects.begin(); ei != _effects.end(); ++ei) {
-    if ((*ei)._effect->has_net_transform()) {
-      _flags |= F_has_net_transform;
+    if ((*ei)._effect->has_adjust_transform()) {
+      _flags |= F_has_adjust_transform;
       return;
     }
   }

+ 12 - 11
panda/src/pgraph/renderEffects.h

@@ -102,15 +102,16 @@ public:
                      CPT(TransformState) &node_transform,
                      CPT(RenderState) &node_state) const;
 
-  INLINE bool has_net_transform() const;
-  CPT(TransformState) net_transform(const TransformState *orig_net_transform) const;
+  INLINE bool has_adjust_transform() const;
+  virtual void adjust_transform(CPT(TransformState) &net_transform,
+                                CPT(TransformState) &node_transform) const;
 
 private:
   static CPT(RenderEffects) return_new(RenderEffects *state);
   void determine_decal();
   void determine_show_bounds();
   void determine_cull_callback();
-  void determine_net_transform();
+  void determine_adjust_transform();
 
 private:
   typedef pset<const RenderEffects *, indirect_less<const RenderEffects *> > States;
@@ -142,14 +143,14 @@ private:
   Effects _effects;
 
   enum Flags {
-    F_checked_decal         = 0x0001,
-    F_has_decal             = 0x0002,
-    F_checked_show_bounds   = 0x0004,
-    F_has_show_bounds       = 0x0008,
-    F_checked_cull_callback = 0x0010,
-    F_has_cull_callback     = 0x0020,
-    F_checked_net_transform = 0x0040,
-    F_has_net_transform     = 0x0080,
+    F_checked_decal            = 0x0001,
+    F_has_decal                = 0x0002,
+    F_checked_show_bounds      = 0x0004,
+    F_has_show_bounds          = 0x0008,
+    F_checked_cull_callback    = 0x0010,
+    F_has_cull_callback        = 0x0020,
+    F_checked_adjust_transform = 0x0040,
+    F_has_adjust_transform     = 0x0080,
   };
   int _flags;