From 120e6ae0a702bfd3aa886606b7d9335a02b3a230 Mon Sep 17 00:00:00 2001 From: Josh Yelon Date: Tue, 7 Feb 2006 20:18:28 +0000 Subject: [PATCH] More flexible cardmaker, supports 3 texcoords --- panda/src/grutil/cardMaker.I | 125 ++++++++++++++++++++++++++++----- panda/src/grutil/cardMaker.cxx | 101 ++++++++++++++++---------- panda/src/grutil/cardMaker.h | 9 ++- 3 files changed, 178 insertions(+), 57 deletions(-) diff --git a/panda/src/grutil/cardMaker.I b/panda/src/grutil/cardMaker.I index 65b3278c84..154730e40a 100644 --- a/panda/src/grutil/cardMaker.I +++ b/panda/src/grutil/cardMaker.I @@ -36,21 +36,6 @@ INLINE CardMaker:: ~CardMaker() { } -//////////////////////////////////////////////////////////////////// -// Function: CardMaker::set_uv_range -// Access: Public -// Description: Sets the range of UV's that will be applied to the -// vertices. If set_has_uvs() is true (as it is by -// default), the vertices will be generated with the -// indicated range of UV's, which will be useful if a -// texture is applied. -//////////////////////////////////////////////////////////////////// -INLINE void CardMaker:: -set_uv_range(const TexCoordf &ll, const TexCoordf &ur) { - _ll = ll; - _ur = ur; -} - //////////////////////////////////////////////////////////////////// // Function: CardMaker::set_has_uvs // Access: Public @@ -62,6 +47,95 @@ set_has_uvs(bool flag) { _has_uvs = flag; } +//////////////////////////////////////////////////////////////////// +// Function: CardMaker::set_uv_range +// Access: Public +// Description: Sets the range of UV's that will be applied to the +// vertices. If set_has_uvs() is true (as it is by +// default), the vertices will be generated with the +// indicated range of UV's, which will be useful if a +// texture is applied. +//////////////////////////////////////////////////////////////////// +INLINE void CardMaker:: +set_uv_range(const TexCoord3f &ll, const TexCoord3f &lr, const TexCoord3f &ur, const TexCoord3f &ul) { + _ll_tex = ll; + _lr_tex = lr; + _ur_tex = ur; + _ul_tex = ul; +} + +//////////////////////////////////////////////////////////////////// +// Function: CardMaker::set_uv_range +// Access: Public +// Description: Sets the range of UV's that will be applied to the +// vertices. If set_has_uvs() is true (as it is by +// default), the vertices will be generated with the +// indicated range of UV's, which will be useful if a +// texture is applied. +//////////////////////////////////////////////////////////////////// +INLINE void CardMaker:: +set_uv_range(const TexCoordf &ll, const TexCoordf &lr, const TexCoordf &ur, const TexCoordf &ul) { + _ll_tex.set(ll[0], ll[1], 0.0f); + _lr_tex.set(lr[0], lr[1], 0.0f); + _ur_tex.set(ur[0], ur[1], 0.0f); + _ul_tex.set(ul[0], ul[1], 0.0f); +} + +//////////////////////////////////////////////////////////////////// +// Function: CardMaker::set_uv_range +// Access: Public +// Description: Sets the range of UV's that will be applied to the +// vertices. If set_has_uvs() is true (as it is by +// default), the vertices will be generated with the +// indicated range of UV's, which will be useful if a +// texture is applied. +//////////////////////////////////////////////////////////////////// +INLINE void CardMaker:: +set_uv_range(const TexCoordf &ll, const TexCoordf &ur) { + _ll_tex.set(ll[0], ll[1], 0.0f); + _lr_tex.set(ur[0], ll[1], 0.0f); + _ur_tex.set(ur[0], ur[1], 0.0f); + _ul_tex.set(ll[0], ur[1], 0.0f); +} + +//////////////////////////////////////////////////////////////////// +// Function: CardMaker::set_uv_range +// Access: Public +// Description: Sets the range of UV's that will be applied to the +// vertices. If set_has_uvs() is true (as it is by +// default), the vertices will be generated with the +// indicated range of UV's, which will be useful if a +// texture is applied. +//////////////////////////////////////////////////////////////////// +INLINE void CardMaker:: +set_uv_range(const LVector4f &x, const LVector4f &y, const LVector4f &z) { + _ll_tex.set(x[0], y[0], z[0]); + _lr_tex.set(x[1], y[1], z[1]); + _ur_tex.set(x[2], y[2], z[2]); + _ul_tex.set(x[3], y[3], z[3]); +} + +//////////////////////////////////////////////////////////////////// +// Function: CardMaker::set_uv_range_cube +// Access: Public +// Description: Sets the range of UV's that will be applied to the +// vertices appropriately for a cube-map face. +//////////////////////////////////////////////////////////////////// +INLINE void CardMaker:: +set_uv_range_cube(int face) { + LVector4f varya(-1, 1, 1, -1); + LVector4f varyb(-1, -1, 1, 1); + LVector4f fixed( 1, 1, 1, 1); + switch(face) { + case 0: set_uv_range( fixed, varya, varyb); break; // positive_x + case 1: set_uv_range(-fixed, -varya, -varyb); break; // negative_x + case 2: set_uv_range( varya, fixed, varyb); break; // positive_y + case 3: set_uv_range(-varya, -fixed, -varyb); break; // negative_y + case 4: set_uv_range( varya, varyb, fixed); break; // positive_z + case 5: set_uv_range(-varya, -varyb, -fixed); break; // negative_z + } +} + //////////////////////////////////////////////////////////////////// // Function: CardMaker::set_frame // Access: Public @@ -69,7 +143,10 @@ set_has_uvs(bool flag) { //////////////////////////////////////////////////////////////////// INLINE void CardMaker:: set_frame(float left, float right, float bottom, float top) { - set_frame(LVecBase4f(left, right, bottom, top)); + _ll_pos.set(left, 0.0f, bottom); + _lr_pos.set(right, 0.0f, bottom); + _ur_pos.set(right, 0.0f, top); + _ul_pos.set(left, 0.0f, top); } //////////////////////////////////////////////////////////////////// @@ -79,7 +156,21 @@ set_frame(float left, float right, float bottom, float top) { //////////////////////////////////////////////////////////////////// INLINE void CardMaker:: set_frame(const LVecBase4f &frame) { - _frame = frame; + set_frame(frame[0], frame[1], frame[2], frame[3]); +} + +//////////////////////////////////////////////////////////////////// +// Function: CardMaker::set_frame +// Access: Public +// Description: Sets the size of the card. +//////////////////////////////////////////////////////////////////// +INLINE void CardMaker:: +set_frame(const Vertexf &ll, const Vertexf &lr, const Vertexf &ur, const Vertexf &ul) +{ + _ll_pos = ll; + _lr_pos = lr; + _ur_pos = ur; + _ul_pos = ul; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/grutil/cardMaker.cxx b/panda/src/grutil/cardMaker.cxx index 73fa19ca38..a29eadc10e 100644 --- a/panda/src/grutil/cardMaker.cxx +++ b/panda/src/grutil/cardMaker.cxx @@ -24,7 +24,7 @@ #include "geom.h" #include "geomTristrips.h" #include "geomVertexWriter.h" - +#include "geomVertexFormat.h" //////////////////////////////////////////////////////////////////// // Function: CardMaker::reset @@ -34,11 +34,20 @@ void CardMaker:: reset() { _has_uvs = true; - _ll.set(0.0f, 0.0f); - _ur.set(1.0f, 1.0f); - _frame.set(0.0f, 1.0f, 0.0f, 1.0f); + + _ll_pos.set(0.0f, 0.0f, 0.0f); + _lr_pos.set(1.0f, 0.0f, 0.0f); + _ur_pos.set(1.0f, 0.0f, 1.0f); + _ul_pos.set(0.0f, 0.0f, 1.0f); + + _ll_tex.set(0.0f, 0.0f, 0.0f); + _lr_tex.set(1.0f, 0.0f, 0.0f); + _ur_tex.set(1.0f, 1.0f, 0.0f); + _ul_tex.set(0.0f, 1.0f, 0.0f); + _has_color = false; _color.set(1.0f, 1.0f, 1.0f, 1.0f); + _has_normals = true; _source_geometry = (PandaNode *)NULL; _source_frame.set(0.0f, 0.0f, 0.0f, 0.0f); @@ -59,21 +68,30 @@ generate() { PT(GeomNode) gnode = new GeomNode(get_name()); - float left = _frame[0]; - float right = _frame[1]; - float bottom = _frame[2]; - float top = _frame[3]; - CPT(GeomVertexFormat) format; if (_has_normals) { if (_has_uvs) { - format = GeomVertexFormat::get_v3n3cpt2(); + format = GeomVertexFormat::register_format(new GeomVertexArrayFormat + (InternalName::get_vertex(), 3, + GeomEnums::NT_float32, GeomEnums::C_point, + InternalName::get_normal(), 3, + GeomEnums::NT_float32, GeomEnums::C_vector, + InternalName::get_color(), 1, + GeomEnums::NT_packed_dabc, GeomEnums::C_color, + InternalName::get_texcoord(), 3, + GeomEnums::NT_float32, GeomEnums::C_texcoord)); } else { format = GeomVertexFormat::get_v3n3cp(); } } else { if (_has_uvs) { - format = GeomVertexFormat::get_v3cpt2(); + format = GeomVertexFormat::register_format(new GeomVertexArrayFormat + (InternalName::get_vertex(), 3, + GeomEnums::NT_float32, GeomEnums::C_point, + InternalName::get_color(), 1, + GeomEnums::NT_packed_dabc, GeomEnums::C_color, + InternalName::get_texcoord(), 3, + GeomEnums::NT_float32, GeomEnums::C_texcoord)); } else { format = GeomVertexFormat::get_v3cp(); } @@ -84,10 +102,10 @@ generate() { GeomVertexWriter vertex(vdata, InternalName::get_vertex()); GeomVertexWriter color(vdata, InternalName::get_color()); - vertex.add_data3f(Vertexf::rfu(left, 0.0f, top)); - vertex.add_data3f(Vertexf::rfu(left, 0.0f, bottom)); - vertex.add_data3f(Vertexf::rfu(right, 0.0f, top)); - vertex.add_data3f(Vertexf::rfu(right, 0.0f, bottom)); + vertex.add_data3f(_ul_pos); + vertex.add_data3f(_ll_pos); + vertex.add_data3f(_ur_pos); + vertex.add_data3f(_lr_pos); color.add_data4f(_color); color.add_data4f(_color); @@ -96,18 +114,27 @@ generate() { if (_has_uvs) { GeomVertexWriter texcoord(vdata, InternalName::get_texcoord()); - texcoord.add_data2f(_ll[0], _ur[1]); - texcoord.add_data2f(_ll[0], _ll[1]); - texcoord.add_data2f(_ur[0], _ur[1]); - texcoord.add_data2f(_ur[0], _ll[1]); + texcoord.add_data3f(_ul_tex); + texcoord.add_data3f(_ll_tex); + texcoord.add_data3f(_ur_tex); + texcoord.add_data3f(_lr_tex); } if (_has_normals) { GeomVertexWriter normal(vdata, InternalName::get_normal()); - normal.add_data3f(LVector3f::back()); - normal.add_data3f(LVector3f::back()); - normal.add_data3f(LVector3f::back()); - normal.add_data3f(LVector3f::back()); + LVector3f n; + n = (_ll_pos - _ul_pos).cross(_ur_pos - _ul_pos); + n.normalize(); + normal.add_data3f(n); + n = (_lr_pos - _ll_pos).cross(_ul_pos - _ll_pos); + n.normalize(); + normal.add_data3f(n); + n = (_ul_pos - _ur_pos).cross(_lr_pos - _ur_pos); + n.normalize(); + normal.add_data3f(n); + n = (_ur_pos - _lr_pos).cross(_ll_pos - _lr_pos); + n.normalize(); + normal.add_data3f(n); } PT(GeomTristrips) strip = new GeomTristrips(Geom::UH_static); @@ -134,24 +161,22 @@ rescale_source_geometry() { PT(PandaNode) root = _source_geometry->copy_subgraph(); // Determine the translate and scale appropriate for our geometry. - float geom_center_x = (_source_frame[0] + _source_frame[1]) * 0.5f; - float geom_center_y = (_source_frame[2] + _source_frame[3]) * 0.5f; + LVector3f frame_max = _ll_pos.fmax(_lr_pos.fmax(_ur_pos.fmax(_ul_pos))); + LVector3f frame_min = _ll_pos.fmin(_lr_pos.fmin(_ur_pos.fmax(_ul_pos))); + LVector3f frame_ctr = (frame_max + frame_min) * 0.5f; + + LVector3f geom_center((_source_frame[0] + _source_frame[1]) * 0.5f, + frame_ctr[1], + (_source_frame[2] + _source_frame[3]) * 0.5f); - float frame_center_x = (_frame[0] + _frame[1]) * 0.5f; - float frame_center_y = (_frame[2] + _frame[3]) * 0.5f; - - float scale_x = - (_frame[1] - _frame[0]) / (_source_frame[1] - _source_frame[0]); - float scale_y = - (_frame[3] - _frame[2]) / (_source_frame[3] - _source_frame[2]); - - LVector3f trans = LVector3f::rfu(frame_center_x - geom_center_x, 0.0f, - frame_center_y - geom_center_y); - LVector3f scale = LVector3f::rfu(scale_x, 1.0f, scale_y); + LVector3f scale((frame_max[0] - frame_min[0]) / (_source_frame[1] - _source_frame[0]), + 0.0, + (frame_max[2] - frame_min[2]) / (_source_frame[3] - _source_frame[2])); + + LVector3f trans = frame_ctr - geom_center; CPT(TransformState) transform = - TransformState::make_pos_hpr_scale(trans, LPoint3f(0.0f, 0.0f, 0.0f), - scale); + TransformState::make_pos_hpr_scale(trans, LPoint3f(0.0f, 0.0f, 0.0f), scale); root->set_transform(transform); if (_has_color) { diff --git a/panda/src/grutil/cardMaker.h b/panda/src/grutil/cardMaker.h index f254dc9ea0..033fa7e326 100644 --- a/panda/src/grutil/cardMaker.h +++ b/panda/src/grutil/cardMaker.h @@ -39,10 +39,15 @@ PUBLISHED: void reset(); INLINE void set_uv_range(const TexCoordf &ll, const TexCoordf &ur); + INLINE void set_uv_range(const TexCoordf &ll, const TexCoordf &lr, const TexCoordf &ur, const TexCoordf &ul); + INLINE void set_uv_range(const TexCoord3f &ll, const TexCoord3f &lr, const TexCoord3f &ur, const TexCoord3f &ul); + INLINE void set_uv_range(const LVector4f &x, const LVector4f &y, const LVector4f &z); INLINE void set_has_uvs(bool flag); + INLINE void set_uv_range_cube(int face); INLINE void set_frame(float left, float right, float bottom, float top); INLINE void set_frame(const LVecBase4f &frame); + INLINE void set_frame(const Vertexf &ll, const Vertexf &lr, const Vertexf &ur, const Vertexf &ul); INLINE void set_color(float r, float g, float b, float a); INLINE void set_color(const Colorf &color); @@ -58,8 +63,8 @@ private: PT(PandaNode) rescale_source_geometry(); bool _has_uvs; - TexCoordf _ll, _ur; - LVecBase4f _frame; + Vertexf _ul_tex, _ll_tex, _lr_tex, _ur_tex; + TexCoord3f _ul_pos, _ll_pos, _lr_pos, _ur_pos; bool _has_color; Colorf _color;