Browse Source

add polylight support to NodePath; prevent compiler warnings; minor style changes to polylightEffect to be consistent with panda conventions

David Rose 21 years ago
parent
commit
c23792f1dc

+ 2 - 2
panda/src/pgraph/lightAttrib.I

@@ -19,7 +19,7 @@
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: LightAttrib::Constructor
 //     Function: LightAttrib::Constructor
-//       Access: Private
+//       Access: Protected
 //  Description: Use LightAttrib::make() to construct a new
 //  Description: Use LightAttrib::make() to construct a new
 //               LightAttrib object.
 //               LightAttrib object.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -30,7 +30,7 @@ LightAttrib() {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: LightAttrib::Copy Constructor
 //     Function: LightAttrib::Copy Constructor
-//       Access: Private
+//       Access: Protected
 //  Description: Use LightAttrib::make() to construct a new
 //  Description: Use LightAttrib::make() to construct a new
 //               LightAttrib object.  The copy constructor is only
 //               LightAttrib object.  The copy constructor is only
 //               defined to facilitate methods like add_on_light().
 //               defined to facilitate methods like add_on_light().

+ 1 - 1
panda/src/pgraph/lightAttrib.h

@@ -34,7 +34,7 @@
 //               from the total set of "on" lights.
 //               from the total set of "on" lights.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDA LightAttrib : public RenderAttrib {
 class EXPCL_PANDA LightAttrib : public RenderAttrib {
-private:
+protected:
   INLINE LightAttrib();
   INLINE LightAttrib();
   INLINE LightAttrib(const LightAttrib &copy);
   INLINE LightAttrib(const LightAttrib &copy);
 
 

+ 47 - 0
panda/src/pgraph/nodePath.cxx

@@ -2095,6 +2095,7 @@ set_light(const NodePath &light, int priority) {
   if (!light.is_empty()) {
   if (!light.is_empty()) {
     Light *light_obj = light.node()->as_light();
     Light *light_obj = light.node()->as_light();
     if (light_obj != (Light *)NULL) {
     if (light_obj != (Light *)NULL) {
+      // It's an actual Light object.
       const RenderAttrib *attrib =
       const RenderAttrib *attrib =
         node()->get_attrib(LightAttrib::get_class_type());
         node()->get_attrib(LightAttrib::get_class_type());
       if (attrib != (const RenderAttrib *)NULL) {
       if (attrib != (const RenderAttrib *)NULL) {
@@ -2112,6 +2113,31 @@ set_light(const NodePath &light, int priority) {
         node()->set_attrib(la->add_on_light(light), priority);
         node()->set_attrib(la->add_on_light(light), priority);
       }
       }
       return;
       return;
+
+    } else if (light.node()->is_of_type(PolylightNode::get_class_type())) {
+      // It's a Polylight object.
+      if (priority != 0) {
+        // PolylightEffects can't have a priority, since they're just
+        // an effect to be applied immediately.
+        pgraph_cat.warning()
+          << "Ignoring priority on set_light(" << light << ")\n";
+      }
+
+      const RenderEffect *effect =
+        node()->get_effect(PolylightEffect::get_class_type());
+      if (effect != (const RenderEffect *)NULL) {
+        const PolylightEffect *ple = DCAST(PolylightEffect, effect);
+        
+        // Modify the existing PolylightEffect to add the indicated
+        // light.
+        node()->set_effect(ple->add_light(light));
+        
+      } else {
+        // Create a new PolylightEffect for this node.
+        CPT(PolylightEffect) ple = DCAST(PolylightEffect, PolylightEffect::make());
+        node()->set_effect(ple->add_light(light));
+      }
+      return;
     }
     }
   }
   }
   nassert_raise("Not a Light object.");
   nassert_raise("Not a Light object.");
@@ -2135,6 +2161,7 @@ void NodePath::
 set_light_off(int priority) {
 set_light_off(int priority) {
   nassertv_always(!is_empty());
   nassertv_always(!is_empty());
   node()->set_attrib(LightAttrib::make_all_off(), priority);
   node()->set_attrib(LightAttrib::make_all_off(), priority);
+  node()->clear_effect(PolylightEffect::get_class_type());
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -2224,6 +2251,16 @@ clear_light(const NodePath &light) {
         }
         }
       }
       }
       return;
       return;
+
+    } else if (light.node()->is_of_type(PolylightNode::get_class_type())) {
+      const RenderEffect *effect =
+        node()->get_effect(PolylightEffect::get_class_type());
+      if (effect != (const RenderEffect *)NULL) {
+        CPT(PolylightEffect) ple = DCAST(PolylightEffect, effect);
+        ple = DCAST(PolylightEffect, ple->remove_light(light));
+        node()->set_effect(ple);
+      }
+      return;
     }
     }
   }
   }
   nassert_raise("Not a Light object.");
   nassert_raise("Not a Light object.");
@@ -2250,6 +2287,16 @@ has_light(const NodePath &light) const {
         const LightAttrib *la = DCAST(LightAttrib, attrib);
         const LightAttrib *la = DCAST(LightAttrib, attrib);
         return la->has_on_light(light);
         return la->has_on_light(light);
       }
       }
+      return false;
+
+    } else if (light.node()->is_of_type(PolylightNode::get_class_type())) {
+      const RenderEffect *effect =
+        node()->get_effect(PolylightEffect::get_class_type());
+      if (effect != (const RenderEffect *)NULL) {
+        const PolylightEffect *ple = DCAST(PolylightEffect, effect);
+        return ple->has_light(light);
+      }
+      return false;
     }
     }
   }
   }
   nassert_raise("Not a Light object.");
   nassert_raise("Not a Light object.");

+ 4 - 4
panda/src/pgraph/polylightEffect.I

@@ -19,7 +19,7 @@
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PolylightEffect::Constructor
 //     Function: PolylightEffect::Constructor
-//       Access: Private
+//       Access: Protected
 //  Description: Use PolylightEffect::make() to construct a new
 //  Description: Use PolylightEffect::make() to construct a new
 //               PolylightEffect object.
 //               PolylightEffect object.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -29,7 +29,7 @@ PolylightEffect() {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PolylightEffect::Constructor
 //     Function: PolylightEffect::Constructor
-//       Access: Private
+//       Access: Protected
 //  Description: Copy Constructor used by the const methods
 //  Description: Copy Constructor used by the const methods
 //               to modify data on a copy and return a new one
 //               to modify data on a copy and return a new one
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -55,9 +55,9 @@ get_weight() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PolylightEffect::get_contrib
 //     Function: PolylightEffect::get_contrib
 //       Access: Published
 //       Access: Published
-//  Description: Returns CALL or CPROXIMAL
+//  Description: Returns CT_all or CT_proximal
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-INLINE PolylightEffect::Contrib_Type PolylightEffect::
+INLINE PolylightEffect::ContribType PolylightEffect::
 get_contrib() const {
 get_contrib() const {
   return _contribution_type;
   return _contribution_type;
 }
 }

+ 55 - 10
panda/src/pgraph/polylightEffect.cxx

@@ -36,7 +36,7 @@ TypeHandle PolylightEffect::_type_handle;
 CPT(RenderEffect) PolylightEffect::
 CPT(RenderEffect) PolylightEffect::
 make() {
 make() {
   PolylightEffect *effect = new PolylightEffect;
   PolylightEffect *effect = new PolylightEffect;
-  effect->_contribution_type = CPROXIMAL;
+  effect->_contribution_type = CT_proximal;
   effect->_weight = 0.9;
   effect->_weight = 0.9;
   effect->_effect_center = LPoint3f(0.0,0.0,0.0);
   effect->_effect_center = LPoint3f(0.0,0.0,0.0);
   return return_new(effect);
   return return_new(effect);
@@ -48,7 +48,7 @@ make() {
 //  Description: Constructs a new PolylightEffect object.
 //  Description: Constructs a new PolylightEffect object.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 CPT(RenderEffect) PolylightEffect::
 CPT(RenderEffect) PolylightEffect::
-make(float weight, Contrib_Type contrib, LPoint3f effect_center) {
+make(float weight, ContribType contrib, LPoint3f effect_center) {
   PolylightEffect *effect = new PolylightEffect;
   PolylightEffect *effect = new PolylightEffect;
   effect->_contribution_type = contrib;
   effect->_contribution_type = contrib;
   effect->_weight = weight;
   effect->_weight = weight;
@@ -62,7 +62,8 @@ make(float weight, Contrib_Type contrib, LPoint3f effect_center) {
 //  Description: Constructs a new PolylightEffect object.
 //  Description: Constructs a new PolylightEffect object.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 CPT(RenderEffect) PolylightEffect::
 CPT(RenderEffect) PolylightEffect::
-make(float weight, Contrib_Type contrib, LPoint3f effect_center, LIGHTGROUP lights) {
+make(float weight, ContribType contrib, LPoint3f effect_center,
+     const LightGroup &lights) {
   PolylightEffect *effect = new PolylightEffect;
   PolylightEffect *effect = new PolylightEffect;
   effect->_contribution_type = contrib;
   effect->_contribution_type = contrib;
   effect->_weight = weight;
   effect->_weight = weight;
@@ -82,7 +83,7 @@ make(float weight, Contrib_Type contrib, LPoint3f effect_center, LIGHTGROUP ligh
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool PolylightEffect::
 bool PolylightEffect::
 has_cull_callback() const {
 has_cull_callback() const {
-  return true;
+  return !_lightgroup.empty();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -129,7 +130,7 @@ do_poly_light(const CullTraverserData *data, const TransformState *node_transfor
   r = 1.0;
   r = 1.0;
   g = 1.0;
   g = 1.0;
   b = 1.0;
   b = 1.0;
-  LIGHTGROUP::const_iterator light_iter; 
+  LightGroup::const_iterator light_iter; 
   // Cycle through all the lights in this effect's lightgroup
   // Cycle through all the lights in this effect's lightgroup
   for (light_iter = _lightgroup.begin(); light_iter != _lightgroup.end(); light_iter++){
   for (light_iter = _lightgroup.begin(); light_iter != _lightgroup.end(); light_iter++){
     const PolylightNode *light = DCAST(PolylightNode, (*light_iter).node()); 
     const PolylightNode *light = DCAST(PolylightNode, (*light_iter).node()); 
@@ -179,7 +180,7 @@ do_poly_light(const CullTraverserData *data, const TransformState *node_transfor
   } // for all lights
   } // for all lights
 
 
 
 
-  if ( _contribution_type == CALL) {
+  if ( _contribution_type == CT_all) {
     // Sometimes to prevent snapping of color at light volume boundaries
     // Sometimes to prevent snapping of color at light volume boundaries
     // just divide total contribution by all the lights in the effect
     // just divide total contribution by all the lights in the effect
     // whether or not they contribute color
     // whether or not they contribute color
@@ -204,6 +205,24 @@ do_poly_light(const CullTraverserData *data, const TransformState *node_transfor
   return ColorScaleAttrib::make(LVecBase4f(r, g, b, 1.0));
   return ColorScaleAttrib::make(LVecBase4f(r, g, b, 1.0));
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: PolylightEffect::output
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+void PolylightEffect::
+output(ostream &out) const {
+  out << get_type() << ":";
+    
+  LightGroup::const_iterator li;
+  for (li = _lightgroup.begin(); li != _lightgroup.end(); ++li) {
+    NodePath light = (*li);
+    out << " " << light;
+  }
+  out << " weight " << _weight << " contrib " << _contribution_type
+      << " center " << _effect_center;
+}
+
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PolylightEffect::compare_to_impl
 //     Function: PolylightEffect::compare_to_impl
@@ -265,10 +284,11 @@ add_light(const NodePath &newlight) const {
 CPT(RenderEffect) PolylightEffect::
 CPT(RenderEffect) PolylightEffect::
 remove_light(const NodePath &newlight) const {
 remove_light(const NodePath &newlight) const {
   PolylightEffect *effect = new PolylightEffect(*this);
   PolylightEffect *effect = new PolylightEffect(*this);
-  LIGHTGROUP::iterator light_iter;
+  LightGroup::iterator light_iter;
   light_iter = find(effect->_lightgroup.begin(),effect->_lightgroup.end(), newlight); 
   light_iter = find(effect->_lightgroup.begin(),effect->_lightgroup.end(), newlight); 
-  if(light_iter == effect->_lightgroup.end()) {
-    cerr << "Light Not Found!\n";
+  if (light_iter == effect->_lightgroup.end()) {
+    pgraph_cat.debug()
+      << "Attempt to remove Polylight " << newlight << "; not found.\n";
   } else {
   } else {
     // Remove light
     // Remove light
     effect->_lightgroup.erase(light_iter);
     effect->_lightgroup.erase(light_iter);
@@ -303,7 +323,7 @@ set_weight(float w) const {
 //               Here, we just pass that to the make
 //               Here, we just pass that to the make
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 CPT(RenderEffect) PolylightEffect::
 CPT(RenderEffect) PolylightEffect::
-set_contrib(Contrib_Type ct) const {
+set_contrib(ContribType ct) const {
   PolylightEffect *effect = new PolylightEffect(*this);
   PolylightEffect *effect = new PolylightEffect(*this);
   effect->_contribution_type = ct;
   effect->_contribution_type = ct;
   return return_new(effect);
   return return_new(effect);
@@ -325,3 +345,28 @@ set_effect_center(LPoint3f ec) const{
   return return_new(effect);
   return return_new(effect);
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: PolylightEffect::has_light
+//       Access: Published
+//  Description: Returns true if the indicated light is listed in the
+//               PolylightEffect, false otherwise.
+////////////////////////////////////////////////////////////////////
+bool PolylightEffect::
+has_light(const NodePath &light) const {
+  LightGroup::const_iterator li;
+  li = find(_lightgroup.begin(), _lightgroup.end(), light); 
+  return (li != _lightgroup.end());
+}
+
+ostream &
+operator << (ostream &out, PolylightEffect::ContribType ct) {
+  switch (ct) {
+  case PolylightEffect::CT_proximal:
+    return out << "proximal";
+
+  case PolylightEffect::CT_all:
+    return out << "all";
+  }
+
+  return out << "**Invalid ContribType(" << (int)ct << ")**";
+}

+ 22 - 15
panda/src/pgraph/polylightEffect.h

@@ -40,36 +40,33 @@
 //               specially for night scenes
 //               specially for night scenes
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDA PolylightEffect : public RenderEffect {
 class EXPCL_PANDA PolylightEffect : public RenderEffect {
-
-
 PUBLISHED:
 PUBLISHED:
-  enum Contrib_Type {
-    CPROXIMAL,
-    CALL,
+  enum ContribType {
+    CT_proximal,
+    CT_all,
   };
   };
 
 
-private:
+  typedef pvector< NodePath > LightGroup;
+
+protected:
   INLINE PolylightEffect();
   INLINE PolylightEffect();
   INLINE PolylightEffect(const PolylightEffect &copy);
   INLINE PolylightEffect(const PolylightEffect &copy);
-  Contrib_Type _contribution_type;
-  float _weight;
-  typedef pvector< NodePath > LIGHTGROUP;
-  LIGHTGROUP _lightgroup;
-  LPoint3f _effect_center;
 
 
 PUBLISHED:
 PUBLISHED:
   static CPT(RenderEffect) make();
   static CPT(RenderEffect) make();
-  static CPT(RenderEffect) make(float weight, Contrib_Type contrib, LPoint3f effect_center);
-  static CPT(RenderEffect) make(float weight, Contrib_Type contrib, LPoint3f effect_center, LIGHTGROUP lights);
+  static CPT(RenderEffect) make(float weight, ContribType contrib, LPoint3f effect_center);
+  static CPT(RenderEffect) make(float weight, ContribType contrib, LPoint3f effect_center, const LightGroup &lights);
   CPT(RenderEffect) add_light(const NodePath &newlight) const;
   CPT(RenderEffect) add_light(const NodePath &newlight) const;
   CPT(RenderEffect) remove_light(const NodePath &newlight) const;
   CPT(RenderEffect) remove_light(const NodePath &newlight) const;
   CPT(RenderEffect) set_weight(float w) const;
   CPT(RenderEffect) set_weight(float w) const;
-  CPT(RenderEffect) set_contrib(Contrib_Type c) const;
+  CPT(RenderEffect) set_contrib(ContribType c) const;
   CPT(RenderEffect) set_effect_center(LPoint3f ec) const;
   CPT(RenderEffect) set_effect_center(LPoint3f ec) const;
   INLINE float get_weight() const;
   INLINE float get_weight() const;
-  INLINE Contrib_Type get_contrib() const;
+  INLINE ContribType get_contrib() const;
   INLINE LPoint3f get_effect_center()const;
   INLINE LPoint3f get_effect_center()const;
 
 
+  bool has_light(const NodePath &light) const;
+
 public:
 public:
   virtual bool has_cull_callback() const;
   virtual bool has_cull_callback() const;
   virtual void cull_callback(CullTraverser *trav, CullTraverserData &data,
   virtual void cull_callback(CullTraverser *trav, CullTraverserData &data,
@@ -78,6 +75,14 @@ public:
 
 
   CPT(RenderAttrib) do_poly_light(const CullTraverserData *data, const TransformState *node_transform) const;
   CPT(RenderAttrib) do_poly_light(const CullTraverserData *data, const TransformState *node_transform) const;
 
 
+  virtual void output(ostream &out) const;
+
+private:
+  ContribType _contribution_type;
+  float _weight;
+  LightGroup _lightgroup;
+  LPoint3f _effect_center;
+
 protected:
 protected:
   virtual int compare_to_impl(const RenderEffect *other) const;
   virtual int compare_to_impl(const RenderEffect *other) const;
 
 
@@ -101,6 +106,8 @@ private:
 
 
 #include "polylightEffect.I"
 #include "polylightEffect.I"
 
 
+ostream &operator << (ostream &out, PolylightEffect::ContribType ct);
+
 #endif
 #endif
 
 
 
 

+ 2 - 2
panda/src/pgraph/textureAttrib.I

@@ -19,7 +19,7 @@
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: TextureAttrib::Constructor
 //     Function: TextureAttrib::Constructor
-//       Access: Private
+//       Access: Protected
 //  Description: Use TextureAttrib::make() to construct a new
 //  Description: Use TextureAttrib::make() to construct a new
 //               TextureAttrib object.
 //               TextureAttrib object.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -31,7 +31,7 @@ TextureAttrib() {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: TextureAttrib::Copy Constructor
 //     Function: TextureAttrib::Copy Constructor
-//       Access: Private
+//       Access: Protected
 //  Description: Use TextureAttrib::make() to construct a new
 //  Description: Use TextureAttrib::make() to construct a new
 //               TextureAttrib object.  The copy constructor is only
 //               TextureAttrib object.  The copy constructor is only
 //               defined to facilitate methods like add_on_stage().
 //               defined to facilitate methods like add_on_stage().

+ 4 - 3
panda/src/pgraph/textureAttrib.cxx

@@ -780,8 +780,9 @@ fillin(DatagramIterator &scan, BamReader *manager) {
     
     
     // Push back a NULL pointer for each off TextureStage for now, until
     // Push back a NULL pointer for each off TextureStage for now, until
     // we get the actual list of pointers later in complete_pointers().
     // we get the actual list of pointers later in complete_pointers().
-    //_off_stages.reserve(num_off_stages);
-    for (int i = 0; i < num_off_stages; i++) {
+    int i;
+    _off_stages.reserve(num_off_stages);
+    for (i = 0; i < num_off_stages; i++) {
       manager->read_pointer(scan);
       manager->read_pointer(scan);
       _off_stages.push_back(NULL);
       _off_stages.push_back(NULL);
     }
     }
@@ -790,7 +791,7 @@ fillin(DatagramIterator &scan, BamReader *manager) {
     // just read the pointers, all allocation will happen from
     // just read the pointers, all allocation will happen from
     // complete_pointers because, it is a map template we get the
     // complete_pointers because, it is a map template we get the
     // actual list of pointers later in complete_pointers().
     // actual list of pointers later in complete_pointers().
-    for (int i = 0; i < _num_on_textures; i++) {
+    for (i = 0; i < _num_on_textures; i++) {
       manager->read_pointer(scan);
       manager->read_pointer(scan);
       manager->read_pointer(scan);
       manager->read_pointer(scan);
     }
     }

+ 1 - 1
panda/src/pgraph/textureAttrib.h

@@ -36,7 +36,7 @@
 //               secondary texture.
 //               secondary texture.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDA TextureAttrib : public RenderAttrib {
 class EXPCL_PANDA TextureAttrib : public RenderAttrib {
-private:
+protected:
   INLINE TextureAttrib();
   INLINE TextureAttrib();
   INLINE TextureAttrib(const TextureAttrib &copy);
   INLINE TextureAttrib(const TextureAttrib &copy);