NodePath::set_tex_projector(..., lens_index)

This commit is contained in:
David Rose 2012-02-14 02:40:51 +00:00
parent 2a782774aa
commit 2c7d493513
6 changed files with 82 additions and 36 deletions

View File

@ -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;
}

View File

@ -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));
}
////////////////////////////////////////////////////////////////////

View File

@ -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;

View File

@ -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);
}

View File

@ -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()) {

View File

@ -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;