2
0
Эх сурвалжийг харах

support setting sprite particles from sample polygon

David Rose 24 жил өмнө
parent
commit
05f3511f52

+ 11 - 7
panda/src/glgsg/glGraphicsStateGuardian.cxx

@@ -1025,8 +1025,13 @@ draw_sprite(GeomSprite *geom, GeomContext *) {
   glLoadIdentity();
 
   // precomputation stuff
-  float half_width = 0.5f * (float) tex->_pbuffer->get_xsize();
-  float half_height = 0.5f * (float) tex->_pbuffer->get_ysize();
+  float tex_left = geom->get_ll_uv()[0];
+  float tex_right = geom->get_ur_uv()[0];
+  float tex_bottom = geom->get_ll_uv()[1];
+  float tex_top = geom->get_ur_uv()[1];
+
+  float half_width = 0.5f * (float) tex->_pbuffer->get_xsize() * fabs(tex_right - tex_left);
+  float half_height = 0.5f * (float) tex->_pbuffer->get_ysize() * fabs(tex_top - tex_bottom);
   float scaled_width, scaled_height;
 
   // set up the texture-rendering state
@@ -1153,7 +1158,6 @@ draw_sprite(GeomSprite *geom, GeomContext *) {
          draw_sprite_vertex_less());
   }
 
-  int tex_bottom = 0, tex_top = 1, tex_right = 1, tex_left = 0;
   Vertexf ul, ur, ll, lr;
 
   if (color_overall == true)
@@ -1210,10 +1214,10 @@ draw_sprite(GeomSprite *geom, GeomContext *) {
     // draw each one as a 2-element tri-strip
     glBegin(GL_TRIANGLE_STRIP);
     glNormal3f(0.0f, 0.0f, 1.0f);
-    glTexCoord2i(tex_left, tex_bottom);  glVertex3fv(ll.get_data());
-    glTexCoord2i(tex_right, tex_bottom); glVertex3fv(lr.get_data());
-    glTexCoord2i(tex_left, tex_top);     glVertex3fv(ul.get_data());
-    glTexCoord2i(tex_right, tex_top);    glVertex3fv(ur.get_data());
+    glTexCoord2f(tex_left, tex_bottom);  glVertex3fv(ll.get_data());
+    glTexCoord2f(tex_right, tex_bottom); glVertex3fv(lr.get_data());
+    glTexCoord2f(tex_left, tex_top);     glVertex3fv(ul.get_data());
+    glTexCoord2f(tex_right, tex_top);    glVertex3fv(ur.get_data());
     glEnd();
   }
 

+ 58 - 10
panda/src/gobj/geomSprite.I

@@ -17,7 +17,7 @@
 ////////////////////////////////////////////////////////////////////
 
 ////////////////////////////////////////////////////////////////////
-//    Function : set_texture
+//    Function : GeomSprite::set_texture
 //      Access : public
 // Description :
 ////////////////////////////////////////////////////////////////////
@@ -27,7 +27,55 @@ set_texture(Texture *tex) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//    Function : get_texture
+//    Function : GeomSprite::set_ll_uv
+//      Access : public
+// Description : Sets the UV coordinate of the lower-left corner of
+//               all the sprites within this GeomSprite object.
+//               Normally this is (0, 0), but it might be set to
+//               something else to use only a portion of the texture.
+////////////////////////////////////////////////////////////////////
+INLINE void GeomSprite::
+set_ll_uv(const TexCoordf &ll_uv) {
+  _ll_uv = ll_uv;
+}
+
+////////////////////////////////////////////////////////////////////
+//    Function : GeomSprite::get_ll_uv
+//      Access : public
+// Description : Returns the UV coordinate of the lower-left corner;
+//               see set_ll_uv().
+////////////////////////////////////////////////////////////////////
+INLINE const TexCoordf &GeomSprite::
+get_ll_uv() const {
+  return _ll_uv;
+}
+
+////////////////////////////////////////////////////////////////////
+//    Function : GeomSprite::set_ur_uv
+//      Access : public
+// Description : Sets the UV coordinate of the upper-right corner of
+//               all the sprites within this GeomSprite object.
+//               Normally this is (1, 1), but it might be set to
+//               something else to use only a portion of the texture.
+////////////////////////////////////////////////////////////////////
+INLINE void GeomSprite::
+set_ur_uv(const TexCoordf &ur_uv) {
+  _ur_uv = ur_uv;
+}
+
+////////////////////////////////////////////////////////////////////
+//    Function : GeomSprite::get_ur_uv
+//      Access : public
+// Description : Returns the UV coordinate of the upper-right corner;
+//               see set_ur_uv().
+////////////////////////////////////////////////////////////////////
+INLINE const TexCoordf &GeomSprite::
+get_ur_uv() const {
+  return _ur_uv;
+}
+
+////////////////////////////////////////////////////////////////////
+//    Function : GeomSprite::get_texture
 //      Access : public
 // Description :
 ////////////////////////////////////////////////////////////////////
@@ -37,7 +85,7 @@ get_texture(void) const {
 }
 
 ////////////////////////////////////////////////////////////////////
-//    Function : set_alpha_disable
+//    Function : GeomSprite::set_alpha_disable
 //      Access : public
 // Description :
 ////////////////////////////////////////////////////////////////////
@@ -47,7 +95,7 @@ set_alpha_disable(bool a) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//    Function : get_alpha_disable
+//    Function : GeomSprite::get_alpha_disable
 //      Access : public
 // Description :
 ////////////////////////////////////////////////////////////////////
@@ -57,7 +105,7 @@ get_alpha_disable(void) const {
 }
 
 ////////////////////////////////////////////////////////////////////
-//    Function : set_x_texel_ratio
+//    Function : GeomSprite::set_x_texel_ratio
 //      Access : public
 // Description :
 ////////////////////////////////////////////////////////////////////
@@ -68,7 +116,7 @@ set_x_texel_ratio(PTA_float x_texel_ratio, GeomBindType x_bind_type) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//    Function : set_y_texel_ratio
+//    Function : GeomSprite::set_y_texel_ratio
 //      Access : public
 // Description :
 ////////////////////////////////////////////////////////////////////
@@ -79,7 +127,7 @@ set_y_texel_ratio(PTA_float y_texel_ratio, GeomBindType y_bind_type) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//    Function : set_thetas
+//    Function : GeomSprite::set_thetas
 //      Access : public
 // Description :
 ////////////////////////////////////////////////////////////////////
@@ -90,7 +138,7 @@ set_thetas(PTA_float theta, GeomBindType theta_bind_type) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//    Function : get_x_bind_type
+//    Function : GeomSprite::get_x_bind_type
 //      Access : public
 // Description :
 ////////////////////////////////////////////////////////////////////
@@ -100,7 +148,7 @@ get_x_bind_type(void) const {
 }
 
 ////////////////////////////////////////////////////////////////////
-//    Function : get_y_bind_type
+//    Function : GeomSprite::get_y_bind_type
 //      Access : public
 // Description :
 ////////////////////////////////////////////////////////////////////
@@ -110,7 +158,7 @@ get_y_bind_type(void) const {
 }
 
 ////////////////////////////////////////////////////////////////////
-//    Function : get_theta_bind_type
+//    Function : GeomSprite::get_theta_bind_type
 //      Access : public
 // Description :
 ////////////////////////////////////////////////////////////////////

+ 4 - 1
panda/src/gobj/geomSprite.cxx

@@ -37,7 +37,10 @@ TypeHandle GeomSprite::_type_handle;
 ////////////////////////////////////////////////////////////////////
 GeomSprite::
 GeomSprite(Texture *tex, bool alpha_disable) :
-  _texture(tex), _alpha_disable(alpha_disable) {
+  _texture(tex), _alpha_disable(alpha_disable) 
+{
+  _ll_uv.set(0.0, 0.0);
+  _ur_uv.set(1.0, 1.0);
   _x_texel_ratio.clear();
   _y_texel_ratio.clear();
 

+ 18 - 10
panda/src/gobj/geomSprite.h

@@ -43,24 +43,30 @@ public:
   virtual Geom *explode() const {
     return new GeomSprite(*this); }
 
-  static float get_frustum_top(void) { return 1.0f; }
-  static float get_frustum_bottom(void) { return -1.0f; }
-  static float get_frustum_left(void) { return -1.0f; }
-  static float get_frustum_right(void) { return 1.0f; }
+  static float get_frustum_top() { return 1.0f; }
+  static float get_frustum_bottom() { return -1.0f; }
+  static float get_frustum_left() { return -1.0f; }
+  static float get_frustum_right() { return 1.0f; }
 
   INLINE void set_texture(Texture *tex);
-  INLINE Texture *get_texture(void) const;
+  INLINE Texture *get_texture() const;
+
+  INLINE void set_ll_uv(const TexCoordf &ll_uv);
+  INLINE const TexCoordf &get_ll_uv() const;
+
+  INLINE void set_ur_uv(const TexCoordf &ur_uv);
+  INLINE const TexCoordf &get_ur_uv() const;
 
   INLINE void set_alpha_disable(bool a);
-  INLINE bool get_alpha_disable(void) const;
+  INLINE bool get_alpha_disable() const;
 
   INLINE void set_x_texel_ratio(PTA_float x_texel_ratio, GeomBindType x_bind_type);
   INLINE void set_y_texel_ratio(PTA_float y_texel_ratio, GeomBindType y_bind_type);
   INLINE void set_thetas(PTA_float theta, GeomBindType theta_bind_type);
 
-  INLINE GeomBindType get_x_bind_type(void) const;
-  INLINE GeomBindType get_y_bind_type(void) const;
-  INLINE GeomBindType get_theta_bind_type(void) const;
+  INLINE GeomBindType get_x_bind_type() const;
+  INLINE GeomBindType get_y_bind_type() const;
+  INLINE GeomBindType get_theta_bind_type() const;
 
   // public so we don't have to issue them...
   PTA_float _x_texel_ratio;
@@ -69,6 +75,8 @@ public:
 
 protected:
   PT(Texture) _texture;
+  TexCoordf _ll_uv;
+  TexCoordf _ur_uv;
 
   bool _alpha_disable;
 
@@ -77,7 +85,7 @@ protected:
   GeomBindType _theta_bind_type;
 
 public:
-  static void register_with_read_factory(void);
+  static void register_with_read_factory();
   virtual void write_datagram(BamWriter *manager, Datagram &me);
 
   int complete_pointers(vector_typedWritable &plist, BamReader *manager);

+ 1 - 1
panda/src/particlesystem/Sources.pp

@@ -4,7 +4,7 @@
 #begin lib_target
   #define TARGET particlesystem
   #define LOCAL_LIBS \
-    physics sgraph sgattrib graph sgraphutil
+    sgmanip physics sgraph sgattrib graph sgraphutil
     
   #define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx    
 

+ 72 - 24
panda/src/particlesystem/spriteParticleRenderer.I

@@ -17,7 +17,7 @@
 ////////////////////////////////////////////////////////////////////
 
 ////////////////////////////////////////////////////////////////////
-// Function : set_texture
+// Function : SpriteParticleRenderer::set_texture
 //   Access : public
 ////////////////////////////////////////////////////////////////////
 INLINE void SpriteParticleRenderer::
@@ -26,7 +26,33 @@ set_texture(Texture *tex) {
 }
 
 ////////////////////////////////////////////////////////////////////
-// Function : set_color
+//    Function : SpriteParticleRenderer::set_ll_uv
+//      Access : public
+// Description : Sets the UV coordinate of the lower-left corner of
+//               all the sprites generated by this renderer.  Normally
+//               this is (0, 0), but it might be set to something else
+//               to use only a portion of the texture.
+////////////////////////////////////////////////////////////////////
+INLINE void SpriteParticleRenderer::
+set_ll_uv(const TexCoordf &ll_uv) {
+  _sprite_primitive->set_ll_uv(ll_uv);
+}
+
+////////////////////////////////////////////////////////////////////
+//    Function : SpriteParticleRenderer::set_ur_uv
+//      Access : public
+// Description : Sets the UV coordinate of the upper-right corner of
+//               all the sprites generated by this renderer.  Normally
+//               this is (1, 1), but it might be set to something else
+//               to use only a portion of the texture.
+////////////////////////////////////////////////////////////////////
+INLINE void SpriteParticleRenderer::
+set_ur_uv(const TexCoordf &ur_uv) {
+  _sprite_primitive->set_ur_uv(ur_uv);
+}
+
+////////////////////////////////////////////////////////////////////
+// Function : SpriteParticleRenderer::set_color
 //   Access : public
 ////////////////////////////////////////////////////////////////////
 INLINE void SpriteParticleRenderer::
@@ -35,7 +61,7 @@ set_color(const Colorf &color) {
 }
 
 ////////////////////////////////////////////////////////////////////
-// Function : set_x_scale_flag
+// Function : SpriteParticleRenderer::set_x_scale_flag
 //   Access : public
 ////////////////////////////////////////////////////////////////////
 INLINE void SpriteParticleRenderer::
@@ -53,7 +79,7 @@ set_x_scale_flag(bool animate_x_ratio) {
 }
 
 ////////////////////////////////////////////////////////////////////
-// Function : set_y_scale_flag
+// Function : SpriteParticleRenderer::set_y_scale_flag
 //   Access : public
 ////////////////////////////////////////////////////////////////////
 INLINE void SpriteParticleRenderer::
@@ -71,7 +97,7 @@ set_y_scale_flag(bool animate_y_ratio) {
 }
 
 ////////////////////////////////////////////////////////////////////
-// Function : set_anim_angle_flag
+// Function : SpriteParticleRenderer::set_anim_angle_flag
 //   Access : public
 ////////////////////////////////////////////////////////////////////
 INLINE void SpriteParticleRenderer::
@@ -89,7 +115,7 @@ set_anim_angle_flag(bool animate_theta) {
 }
 
 ////////////////////////////////////////////////////////////////////
-// Function : set_initial_x_scale
+// Function : SpriteParticleRenderer::set_initial_x_scale
 //   Access : public
 ////////////////////////////////////////////////////////////////////
 INLINE void SpriteParticleRenderer::
@@ -98,7 +124,7 @@ set_initial_x_scale(float initial_x_scale) {
 }
 
 ////////////////////////////////////////////////////////////////////
-// Function : set_final_x_scale
+// Function : SpriteParticleRenderer::set_final_x_scale
 //   Access : public
 ////////////////////////////////////////////////////////////////////
 INLINE void SpriteParticleRenderer::
@@ -107,7 +133,7 @@ set_final_x_scale(float final_x_scale) {
 }
 
 ////////////////////////////////////////////////////////////////////
-// Function : set_initial_y_scale
+// Function : SpriteParticleRenderer::set_initial_y_scale
 //   Access : public
 ////////////////////////////////////////////////////////////////////
 INLINE void SpriteParticleRenderer::
@@ -116,7 +142,7 @@ set_initial_y_scale(float initial_y_scale) {
 }
 
 ////////////////////////////////////////////////////////////////////
-// Function : set_final_y_scale
+// Function : SpriteParticleRenderer::set_final_y_scale
 //   Access : public
 ////////////////////////////////////////////////////////////////////
 INLINE void SpriteParticleRenderer::
@@ -125,7 +151,7 @@ set_final_y_scale(float final_y_scale) {
 }
 
 ////////////////////////////////////////////////////////////////////
-// Function : set_nonanimated_theta
+// Function : SpriteParticleRenderer::set_nonanimated_theta
 //   Access : public
 ////////////////////////////////////////////////////////////////////
 INLINE void SpriteParticleRenderer::
@@ -134,7 +160,7 @@ set_nonanimated_theta(float theta) {
 }
 
 ////////////////////////////////////////////////////////////////////
-// Function : set_alpha_blend_method
+// Function : SpriteParticleRenderer::set_alpha_blend_method
 //   Access : public
 ////////////////////////////////////////////////////////////////////
 INLINE void SpriteParticleRenderer::
@@ -143,7 +169,7 @@ set_alpha_blend_method(ParticleRendererBlendMethod bm) {
 }
 
 ////////////////////////////////////////////////////////////////////
-// Function : set_alpha_disable
+// Function : SpriteParticleRenderer::set_alpha_disable
 //   Access : public
 ////////////////////////////////////////////////////////////////////
 INLINE void SpriteParticleRenderer::
@@ -152,7 +178,7 @@ set_alpha_disable(bool ad) {
 }
 
 ////////////////////////////////////////////////////////////////////
-// Function : get_texture
+// Function : SpriteParticleRenderer::get_texture
 //   Access : public
 ////////////////////////////////////////////////////////////////////
 INLINE Texture *SpriteParticleRenderer::
@@ -161,7 +187,29 @@ get_texture(void) const {
 }
 
 ////////////////////////////////////////////////////////////////////
-// Function : get_color
+//    Function : SpriteParticleRenderer::get_ll_uv
+//      Access : public
+// Description : Returns the UV coordinate of the lower-left corner;
+//               see set_ll_uv().
+////////////////////////////////////////////////////////////////////
+INLINE const TexCoordf &SpriteParticleRenderer::
+get_ll_uv() const {
+  return _sprite_primitive->get_ll_uv();
+}
+
+////////////////////////////////////////////////////////////////////
+//    Function : SpriteParticleRenderer::get_ur_uv
+//      Access : public
+// Description : Returns the UV coordinate of the upper-right corner;
+//               see set_ur_uv().
+////////////////////////////////////////////////////////////////////
+INLINE const TexCoordf &SpriteParticleRenderer::
+get_ur_uv() const {
+  return _sprite_primitive->get_ur_uv();
+}
+
+////////////////////////////////////////////////////////////////////
+// Function : SpriteParticleRenderer::get_color
 //   Access : public
 ////////////////////////////////////////////////////////////////////
 INLINE Colorf SpriteParticleRenderer::
@@ -170,7 +218,7 @@ get_color(void) const {
 }
 
 ////////////////////////////////////////////////////////////////////
-// Function : get_x_scale_flag
+// Function : SpriteParticleRenderer::get_x_scale_flag
 //   Access : public
 ////////////////////////////////////////////////////////////////////
 INLINE bool SpriteParticleRenderer::
@@ -179,7 +227,7 @@ get_x_scale_flag(void) const {
 }
 
 ////////////////////////////////////////////////////////////////////
-// Function : get_y_scale_flag
+// Function : SpriteParticleRenderer::get_y_scale_flag
 //   Access : public
 ////////////////////////////////////////////////////////////////////
 INLINE bool SpriteParticleRenderer::
@@ -188,7 +236,7 @@ get_y_scale_flag(void) const {
 }
 
 ////////////////////////////////////////////////////////////////////
-// Function : get_anim_angle_flag
+// Function : SpriteParticleRenderer::get_anim_angle_flag
 //   Access : public
 ////////////////////////////////////////////////////////////////////
 INLINE bool SpriteParticleRenderer::
@@ -197,7 +245,7 @@ get_anim_angle_flag(void) const {
 }
 
 ////////////////////////////////////////////////////////////////////
-// Function : get_initial_x_scale
+// Function : SpriteParticleRenderer::get_initial_x_scale
 //   Access : public
 ////////////////////////////////////////////////////////////////////
 INLINE float SpriteParticleRenderer::
@@ -206,7 +254,7 @@ get_initial_x_scale(void) const {
 }
 
 ////////////////////////////////////////////////////////////////////
-// Function : get_final_x_scale
+// Function : SpriteParticleRenderer::get_final_x_scale
 //   Access : public
 ////////////////////////////////////////////////////////////////////
 INLINE float SpriteParticleRenderer::
@@ -215,7 +263,7 @@ get_final_x_scale(void) const {
 }
 
 ////////////////////////////////////////////////////////////////////
-// Function : get_initial_y_scale
+// Function : SpriteParticleRenderer::get_initial_y_scale
 //   Access : public
 ////////////////////////////////////////////////////////////////////
 INLINE float SpriteParticleRenderer::
@@ -224,7 +272,7 @@ get_initial_y_scale(void) const {
 }
 
 ////////////////////////////////////////////////////////////////////
-// Function : get_final_y_scale
+// Function : SpriteParticleRenderer::get_final_y_scale
 //   Access : public
 ////////////////////////////////////////////////////////////////////
 INLINE float SpriteParticleRenderer::
@@ -233,7 +281,7 @@ get_final_y_scale(void) const {
 }
 
 ////////////////////////////////////////////////////////////////////
-// Function : get_nonanimated_theta
+// Function : SpriteParticleRenderer::get_nonanimated_theta
 //   Access : public
 ////////////////////////////////////////////////////////////////////
 INLINE float SpriteParticleRenderer::
@@ -242,7 +290,7 @@ get_nonanimated_theta(void) const {
 }
 
 ////////////////////////////////////////////////////////////////////
-// Function : get_alpha_blend_method
+// Function : SpriteParticleRenderer::get_alpha_blend_method
 //   Access : public
 ////////////////////////////////////////////////////////////////////
 INLINE BaseParticleRenderer::ParticleRendererBlendMethod SpriteParticleRenderer::
@@ -251,7 +299,7 @@ get_alpha_blend_method(void) const {
 }
 
 ////////////////////////////////////////////////////////////////////
-// Function : get_alpha_disable
+// Function : SpriteParticleRenderer::get_alpha_disable
 //   Access : public
 ////////////////////////////////////////////////////////////////////
 INLINE bool SpriteParticleRenderer::

+ 102 - 9
panda/src/particlesystem/spriteParticleRenderer.cxx

@@ -18,11 +18,15 @@
 
 #include <boundingSphere.h>
 #include <geom.h>
+#include <nodePath.h>
+#include <nodeTransitionWrapper.h>
+#include <textureTransition.h>
+#include <wrt.h>
 
 #include "spriteParticleRenderer.h"
 
 ////////////////////////////////////////////////////////////////////
-//    Function : SpriteParticleRenderer
+//    Function : SpriteParticleRenderer::SpriteParticleRenderer
 //      Access : public
 // Description : constructor
 ////////////////////////////////////////////////////////////////////
@@ -46,7 +50,7 @@ SpriteParticleRenderer(Texture *tex) :
 }
 
 ////////////////////////////////////////////////////////////////////
-//    Function : SpriteParticleRenderer
+//    Function : SpriteParticleRenderer::SpriteParticleRenderer
 //      Access : public
 // Description : copy constructor
 ////////////////////////////////////////////////////////////////////
@@ -68,7 +72,7 @@ SpriteParticleRenderer(const SpriteParticleRenderer& copy) :
 }
 
 ////////////////////////////////////////////////////////////////////
-//    Function : ~SpriteParticleRenderer
+//    Function : SpriteParticleRenderer::~SpriteParticleRenderer
 //      Access : public
 // Description : destructor
 ////////////////////////////////////////////////////////////////////
@@ -77,7 +81,7 @@ SpriteParticleRenderer::
 }
 
 ////////////////////////////////////////////////////////////////////
-//    Function : make_copy
+//    Function : SpriteParticleRenderer::make_copy
 //      Access : public
 // Description : child dynamic copy
 ////////////////////////////////////////////////////////////////////
@@ -87,7 +91,96 @@ make_copy(void) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//    Function : resize_pool
+//    Function : SpriteParticleRenderer::set_from_node
+//      Access : public
+// Description : Sets the properties on this render from the geometry
+//               referenced by the indicated NodePath.  This should be
+//               a reference to a GeomNode; it extracts out the
+//               Texture and UV range from the GeomNode.
+////////////////////////////////////////////////////////////////////
+void SpriteParticleRenderer::
+set_from_node(const NodePath &node_path) {
+  nassertv(!node_path.is_empty());
+
+  // The bottom node must be a GeomNode.  If it is not, find the first
+  // GeomNode beneath it.
+  NodePath geom_node_path = node_path;
+  if (!geom_node_path.node()->is_of_type(GeomNode::get_class_type())) {
+    geom_node_path = node_path.find("**/+GeomNode");
+    if (geom_node_path.empty()) {
+      particlesystem_cat.error()
+        << node_path << " does not contain a GeomNode.\n";
+      return;
+    }
+  }
+  GeomNode *gnode = DCAST(GeomNode, geom_node_path.node());
+
+  // Get the texture off the node.  We use wrt() to determine the net
+  // texture that's applied, based on all the arcs from the root; not
+  // just the bottom arc.
+  Texture *tex;
+  NodeTransitionWrapper ntw(TextureTransition::get_class_type());
+  wrt(gnode, geom_node_path.begin(), geom_node_path.end(), 
+      (Node *)NULL, ntw, RenderRelation::get_class_type());
+  const TextureTransition *tt;
+  if (get_transition_into(tt, ntw)) {
+    if (tt->is_on()) {
+      tex = tt->get_texture();
+    }
+  }
+
+  if (tex == (Texture *)NULL) {
+    particlesystem_cat.error()
+      << geom_node_path << " has no texture.\n";
+    return;
+  }
+
+  // Now examine the UV's of the first Geom within the GeomNode.
+  nassertv(gnode->get_num_geoms() > 0);
+  Geom *geom = DCAST(Geom, gnode->get_geom(0));
+
+  PTA_TexCoordf texcoords;
+  GeomBindType bind;
+  PTA_ushort tindex;
+  geom->get_texcoords(texcoords, bind, tindex);
+  if (bind != G_PER_VERTEX) {
+    particlesystem_cat.error()
+      << geom_node_path << " has no UV's in its first Geom.\n";
+    return;
+  }
+
+  int num_verts = geom->get_num_vertices();
+  if (num_verts == 0) {
+    particlesystem_cat.error()
+      << geom_node_path << " has no vertices in its first Geom.\n";
+    return;
+  }
+
+  Geom::TexCoordIterator ti = geom->make_texcoord_iterator();
+
+  const TexCoordf &first_texcoord = geom->get_next_texcoord(ti);
+  TexCoordf min_uv = first_texcoord;
+  TexCoordf max_uv = first_texcoord;
+
+  for (int v = 1; v < num_verts; v++) {
+    const TexCoordf &texcoord = geom->get_next_texcoord(ti);    
+
+    min_uv[0] = min(min_uv[0], texcoord[0]);
+    max_uv[0] = max(max_uv[0], texcoord[0]);
+    min_uv[1] = min(min_uv[1], texcoord[1]);
+    max_uv[1] = max(max_uv[1], texcoord[1]);
+  }
+
+  // We don't really pay attention to orientation of UV's here; a
+  // minor flaw.  We assume the minimum is in the lower-left, and the
+  // maximum is in the upper-right.
+  set_texture(tex);
+  set_ll_uv(min_uv);
+  set_ur_uv(max_uv);
+}
+
+////////////////////////////////////////////////////////////////////
+//    Function : SpriteParticleRenderer::resize_pool
 //      Access : private
 // Description : reallocate the vertex pool.
 ////////////////////////////////////////////////////////////////////
@@ -143,7 +236,7 @@ resize_pool(int new_size) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//    Function : init_geoms
+//    Function : SpriteParticleRenderer::init_geoms
 //      Access : private
 // Description : initializes everything, called on traumatic events
 //               such as construction and serious particlesystem
@@ -158,7 +251,7 @@ init_geoms(void) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//    Function : birth_particle
+//    Function : SpriteParticleRenderer::birth_particle
 //      Access : private
 // Description : child birth, one of those 'there-if-we-want-it'
 //               things.  not really too useful here, so it turns
@@ -169,7 +262,7 @@ birth_particle(int) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//    Function : kill_particle
+//    Function : SpriteParticleRenderer::kill_particle
 //      Access : private
 // Description : child death
 ////////////////////////////////////////////////////////////////////
@@ -178,7 +271,7 @@ kill_particle(int) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//    Function : render
+//    Function : SpriteParticleRenderer::render
 //      Access : private
 // Description : big child render.  populates the geom node.
 ////////////////////////////////////////////////////////////////////

+ 8 - 0
panda/src/particlesystem/spriteParticleRenderer.h

@@ -30,6 +30,8 @@
 #include "baseParticleRenderer.h"
 #include "baseParticle.h"
 
+class NodePath;
+
 ////////////////////////////////////////////////////////////////////
 //       Class : SpriteParticleRenderer
 // Description : Renders a particle system with high-speed nasty
@@ -73,7 +75,11 @@ PUBLISHED:
 
   virtual BaseParticleRenderer *make_copy(void);
 
+  void set_from_node(const NodePath &node_path);
+
   INLINE void set_texture(Texture *tex);
+  INLINE void set_ll_uv(const TexCoordf &ll_uv);
+  INLINE void set_ur_uv(const TexCoordf &ur_uv);
   INLINE void set_color(const Colorf &color);
   INLINE void set_x_scale_flag(bool animate_x_ratio);
   INLINE void set_y_scale_flag(bool animate_y_ratio);
@@ -87,6 +93,8 @@ PUBLISHED:
   INLINE void set_alpha_disable(bool ad);
 
   INLINE Texture *get_texture(void) const;
+  INLINE const TexCoordf &get_ll_uv() const;
+  INLINE const TexCoordf &get_ur_uv() const;
   INLINE Colorf get_color(void) const;
   INLINE bool get_x_scale_flag(void) const;
   INLINE bool get_y_scale_flag(void) const;