diff --git a/panda/src/gobj/lens.cxx b/panda/src/gobj/lens.cxx index 6fd3778431..9d5c131e1b 100644 --- a/panda/src/gobj/lens.cxx +++ b/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; } diff --git a/panda/src/pgraph/nodePath.cxx b/panda/src/pgraph/nodePath.cxx index ba11a1b34f..579d1157f2 100644 --- a/panda/src/pgraph/nodePath.cxx +++ b/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)); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/pgraph/nodePath.h b/panda/src/pgraph/nodePath.h index 3a48baea0f..2a5bda7ad9 100644 --- a/panda/src/pgraph/nodePath.h +++ b/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; diff --git a/panda/src/pgraph/texProjectorEffect.I b/panda/src/pgraph/texProjectorEffect.I index 5739fe6131..c6e8bfe0c6 100644 --- a/panda/src/pgraph/texProjectorEffect.I +++ b/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); } diff --git a/panda/src/pgraph/texProjectorEffect.cxx b/panda/src/pgraph/texProjectorEffect.cxx index a5bfe52cf0..26504a1364 100644 --- a/panda/src/pgraph/texProjectorEffect.cxx +++ b/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()); + 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)); + // 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()) { diff --git a/panda/src/pgraph/texProjectorEffect.h b/panda/src/pgraph/texProjectorEffect.h index b9843918d6..5775f70b74 100644 --- a/panda/src/pgraph/texProjectorEffect.h +++ b/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 Stages;