Browse Source

NodePath::set_tex_projector(..., lens_index)

David Rose 14 years ago
parent
commit
2c7d493513

+ 18 - 16
panda/src/gobj/lens.cxx

@@ -1738,8 +1738,8 @@ do_define_geom_data(CData *cdata) {
     PN_stdfloat t = 2.0f * (PN_stdfloat)si / (PN_stdfloat)num_segments;
 
     // Upper left, top edge.
-    LPoint2 p1(-1.0f + t, 1.0f);
-    if (!extrude(p1, near_point, far_point)) {
+    LPoint3 p1(-1.0f + t, 1.0f, 0.0f);
+    if (!do_extrude(cdata, p1, near_point, far_point)) {
       // Hey, this point is off the lens!  Can't do a frustum.
       return 0;
     }
@@ -1747,8 +1747,8 @@ do_define_geom_data(CData *cdata) {
     vertex.add_data3(far_point);
 
     // Upper right, right edge.
-    LPoint2 p2(1.0f, 1.0f - t);
-    if (!extrude(p2, near_point, far_point)) {
+    LPoint3 p2(1.0f, 1.0f - t, 0.0f);
+    if (!do_extrude(cdata, p2, near_point, far_point)) {
       // Hey, this point is off the lens!  Can't do a frustum.
       return 0;
     }
@@ -1756,8 +1756,8 @@ do_define_geom_data(CData *cdata) {
     vertex.add_data3(far_point);
 
     // Lower right, bottom edge.
-    LPoint2 p3(1.0f - t, -1.0f);
-    if (!extrude(p3, near_point, far_point)) {
+    LPoint3 p3(1.0f - t, -1.0f, 0.0f);
+    if (!do_extrude(cdata, p3, near_point, far_point)) {
       // Hey, this point is off the lens!  Can't do a frustum.
       return 0;
     }
@@ -1765,8 +1765,8 @@ do_define_geom_data(CData *cdata) {
     vertex.add_data3(far_point);
 
     // Lower left, left edge.
-    LPoint2 p4(-1.0f, -1.0f + t);
-    if (!extrude(p4, near_point, far_point)) {
+    LPoint3 p4(-1.0f, -1.0f + t, 0.0f);
+    if (!do_extrude(cdata, p4, near_point, far_point)) {
       // Hey, this point is off the lens!  Can't do a frustum.
       return 0;
     }
@@ -1774,14 +1774,16 @@ do_define_geom_data(CData *cdata) {
     vertex.add_data3(far_point);
   }
 
-  // Finally, add one more pair for the viewing axis.
-  LPoint3 near_axis = LPoint3::origin(cdata->_cs) + LVector3::forward(cdata->_cs) * cdata->_near_distance;
-  LPoint3 far_axis = LPoint3::origin(cdata->_cs) + LVector3::forward(cdata->_cs) * cdata->_far_distance;
-  const LMatrix4 &lens_mat = do_get_lens_mat(cdata);
-  near_axis = near_axis * lens_mat;
-  far_axis = far_axis * lens_mat;
-  vertex.add_data3(near_axis);
-  vertex.add_data3(far_axis);
+  // Finally, add one more pair for the viewing axis (or more
+  // specifically, the center of the lens).
+  LPoint3 pc(-cdata->_film_offset[0], -cdata->_film_offset[1], 0.0f);
+  if (!do_extrude(cdata, pc, near_point, far_point)) {
+    vertex.add_data3(0.0f, 0.0f, 0.0f);
+    vertex.add_data3(0.0f, 0.0f, 0.0f);
+  } else {
+    vertex.add_data3(near_point);
+    vertex.add_data3(far_point);
+  }
 
   return num_segments;
 }

+ 7 - 2
panda/src/pgraph/nodePath.cxx

@@ -4661,9 +4661,14 @@ get_tex_gen_light(TextureStage *stage) const {
 //               texture transform to particular node's position in
 //               space, allowing a LerpInterval (for instance) to
 //               adjust this node's texture coordinates.
+//
+//               If to is a LensNode, then the fourth parameter,
+//               lens_index, can be provided to select a particular
+//               lens to apply.  Otherwise lens_index is not used.
 ////////////////////////////////////////////////////////////////////
 void NodePath::
-set_tex_projector(TextureStage *stage, const NodePath &from, const NodePath &to) {
+set_tex_projector(TextureStage *stage, const NodePath &from, const NodePath &to,
+                  int lens_index) {
   nassertv_always(!is_empty());
 
   const RenderEffect *effect =
@@ -4678,7 +4683,7 @@ set_tex_projector(TextureStage *stage, const NodePath &from, const NodePath &to)
     tpe = DCAST(TexProjectorEffect, TexProjectorEffect::make());
   }
 
-  node()->set_effect(tpe->add_stage(stage, from, to));
+  node()->set_effect(tpe->add_stage(stage, from, to, lens_index));
 }
 
 ////////////////////////////////////////////////////////////////////

+ 2 - 1
panda/src/pgraph/nodePath.h

@@ -721,7 +721,8 @@ PUBLISHED:
   RenderAttrib::TexGenMode get_tex_gen(TextureStage *stage) const;
   NodePath get_tex_gen_light(TextureStage *stage) const;
 
-  void set_tex_projector(TextureStage *stage, const NodePath &from, const NodePath &to);
+  void set_tex_projector(TextureStage *stage, const NodePath &from, const NodePath &to,
+                         int lens_index = 0);
   void clear_tex_projector(TextureStage *stage);
   void clear_tex_projector();
   bool has_tex_projector(TextureStage *stage) const;

+ 14 - 0
panda/src/pgraph/texProjectorEffect.I

@@ -56,6 +56,16 @@ set_from(const NodePath &from) {
   _from = from;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: TexProjectorEffect::StageDef::set_lens_index
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE void TexProjectorEffect::StageDef::
+set_lens_index(int lens_index) {
+  _lens_index = lens_index;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: TexProjectorEffect::StageDef::compare_to
 //       Access: Public
@@ -68,5 +78,9 @@ compare_to(const TexProjectorEffect::StageDef &other) const {
     return compare;
   }
 
+  if (_lens_index != other._lens_index) {
+    return _lens_index - other._lens_index;
+  }
+
   return _from.compare_to(other._from);
 }

+ 38 - 17
panda/src/pgraph/texProjectorEffect.cxx

@@ -66,14 +66,16 @@ make() {
 //
 //               Furthermore, if the "to" node is a LensNode, its
 //               projection matrix is also applied to the texture
-//               transform.
+//               transform.  In this case, the lens_index may be used
+//               to select the particular lens that should be used.
 ////////////////////////////////////////////////////////////////////
 CPT(RenderEffect) TexProjectorEffect::
-add_stage(TextureStage *stage, const NodePath &from, const NodePath &to) const {
+add_stage(TextureStage *stage, const NodePath &from, const NodePath &to, int lens_index) const {
   TexProjectorEffect *effect = new TexProjectorEffect(*this);
   StageDef &def = effect->_stages[stage];
   def.set_from(from);
   def.set_to(to);
+  def.set_lens_index(lens_index);
   return return_new(effect);
 }
 
@@ -151,6 +153,22 @@ get_to(TextureStage *stage) const {
   return (*mi).second._to;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: TexProjectorEffect::get_lens_index
+//       Access: Published
+//  Description: Returns the lens_index associated with the
+//               TexProjectorEffect on the indicated stage.  This is
+//               only used if the "to" node is a LensNode, in which
+//               case it specifies the particular lens that should be
+//               used.
+////////////////////////////////////////////////////////////////////
+int TexProjectorEffect::
+get_lens_index(TextureStage *stage) const {
+  Stages::const_iterator mi = _stages.find(stage);
+  nassertr(mi != _stages.end(), 0);
+  return (*mi).second._lens_index;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: TexProjectorEffect::output
 //       Access: Public, Virtual
@@ -165,7 +183,7 @@ output(ostream &out) const {
     TextureStage *stage = (*mi).first;
     const StageDef &def = (*mi).second;
     out << " " << stage->get_name() << "(" << def._to
-        << ", " << def._from << ")";
+        << ", " << def._from << ", " << def._lens_index << ")";
   }
 }
 
@@ -217,21 +235,24 @@ cull_callback(CullTraverser *trav, CullTraverserData &data,
         def._to_lens_node->get_lens() != (Lens *)NULL) {
       
       // Get the lens's projection matrix, as a TransformState.
-      CPT(TransformState) projmat = TransformState::make_mat(def._to_lens_node->get_lens()->get_projection_mat());
-
-      // We need a special transform to convert the -0.5, 0.5
-      // centering of the lens's projection matrix to UV's in the
-      // range of (0, 1).
-      static CPT(TransformState) fixmat;
-      if (fixmat == (TransformState *)NULL) {
-        fixmat = TransformState::make_pos_hpr_scale
-          (LVecBase3(0.5f, 0.5f, 0.0f),
-           LVecBase3(0.0f, 0.0f, 0.0f),
-           LVecBase3(0.5f, 0.5f, 1.0f));
+      Lens *lens = def._to_lens_node->get_lens(def._lens_index);
+      if (lens != NULL) {
+        CPT(TransformState) projmat = TransformState::make_mat(lens->get_projection_mat());
+
+        // We need a special transform to convert the -0.5, 0.5
+        // centering of the lens's projection matrix to UV's in the
+        // range of (0, 1).
+        static CPT(TransformState) fixmat;
+        if (fixmat == (TransformState *)NULL) {
+          fixmat = TransformState::make_pos_hpr_scale
+            (LVecBase3(0.5f, 0.5f, 0.0f),
+             LVecBase3(0.0f, 0.0f, 0.0f),
+             LVecBase3(0.5f, 0.5f, 1.0f));
+        }
+        
+        // Now apply both to the current transform.
+        transform = fixmat->compose(projmat)->compose(transform);
       }
-
-      // Now apply both to the current transform.
-      transform = fixmat->compose(projmat)->compose(transform);
     }
 
     if (!transform->is_identity()) {

+ 4 - 1
panda/src/pgraph/texProjectorEffect.h

@@ -67,7 +67,7 @@ public:
 PUBLISHED:
   static CPT(RenderEffect) make();
 
-  CPT(RenderEffect) add_stage(TextureStage *stage, const NodePath &from, const NodePath &to) const;
+  CPT(RenderEffect) add_stage(TextureStage *stage, const NodePath &from, const NodePath &to, int lens_index = 0) const;
   CPT(RenderEffect) remove_stage(TextureStage *stage) const;
 
   bool is_empty() const;
@@ -75,6 +75,7 @@ PUBLISHED:
 
   NodePath get_from(TextureStage *stage) const;
   NodePath get_to(TextureStage *stage) const;
+  int get_lens_index(TextureStage *stage) const;
 
 public:
   virtual void output(ostream &out) const;
@@ -93,12 +94,14 @@ private:
     INLINE StageDef();
     INLINE void set_from(const NodePath &from);
     void set_to(const NodePath &to);
+    INLINE void set_lens_index(int lens_index);
 
     INLINE int compare_to(const StageDef &other) const;
 
     NodePath _from;
     NodePath _to;
     LensNode *_to_lens_node;
+    int _lens_index;
   };
 
   typedef pmap<PT(TextureStage), StageDef> Stages;