mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
Comments and clean up
This commit is contained in:
parent
682fa4af45
commit
7e9a871491
@ -189,189 +189,118 @@ extract_textures_from_node(const NodePath &node_path, NodePathCollection &np_col
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function : SpriteParticleRenderer::set_from_node
|
// Function : SpriteParticleRenderer::set_from_node
|
||||||
// Access : public
|
// Access : public
|
||||||
// Description : Sets the properties on this render from the geometry
|
// Description : If the source type is important, use this one.
|
||||||
|
//
|
||||||
|
// model and node should lead to node_path like this:
|
||||||
|
// node_path = loader.loadModel(model).find(node)
|
||||||
|
//
|
||||||
|
// This will remove all previously add textures and
|
||||||
|
// resize the renderer to match the new geometry.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void SpriteParticleRenderer::
|
||||||
|
set_from_node(const NodePath &node_path, const string &model, const string &node, bool size_from_texels) {
|
||||||
|
// Clear all texture information
|
||||||
|
_anims.clear();
|
||||||
|
add_from_node(node_path,model,node,size_from_texels,true);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function : SpriteParticleRenderer::set_from_node
|
||||||
|
// Access : public
|
||||||
|
// Description : Sets the properties on this renderer from the geometry
|
||||||
// referenced by the indicated NodePath. This should be
|
// referenced by the indicated NodePath. This should be
|
||||||
// a reference to a GeomNode or a SequenceNode; it
|
// a reference to a GeomNode or a SequenceNode; it
|
||||||
// extracts out the texture and UV range from the node.
|
// extracts out the texture and UV range from the node.
|
||||||
//
|
//
|
||||||
// If node_path references a SequenceNode with multiple
|
// This will remove all previously added textures and
|
||||||
// GeomNodes beneath it, the size data will correspond
|
// animations. It will also resize the renderer to match
|
||||||
// to the first GeomNode found with a valid texture, and
|
// this new geometry.
|
||||||
// the texture and UV information will be stored for each
|
//
|
||||||
// individual node.
|
// If node_path refers to a GeomNode(or has one beneath it)
|
||||||
|
// the texture, its size, and UV data will be extracted
|
||||||
|
// from that.
|
||||||
|
//
|
||||||
|
// If node_path references a SequenceNode(or has one
|
||||||
|
// beneath it) with multiple GeomNodes beneath it,
|
||||||
|
// the size data will correspond only to the first
|
||||||
|
// GeomNode found with a valid texture, while the texture
|
||||||
|
// and UV information will be stored for each individual
|
||||||
|
// node.
|
||||||
//
|
//
|
||||||
// If size_from_texels is true, the particle size is
|
// If size_from_texels is true, the particle size is
|
||||||
// based on the number of texels in the source image;
|
// based on the number of texels in the source image;
|
||||||
// otherwise, it is based on the size of the first
|
// otherwise, it is based on the size of the first
|
||||||
// polygon found in the node.
|
// polygon found in the node.
|
||||||
|
//
|
||||||
|
// model and node are the two items used to construct
|
||||||
|
// node_path. If the source type is important, use
|
||||||
|
// set_from_node(NodePath,string,string,bool) instead.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void SpriteParticleRenderer::
|
|
||||||
set_from_node(const NodePath &node_path, const string &model, const string &node, bool size_from_texels) {
|
|
||||||
set_from_node(node_path,size_from_texels);
|
|
||||||
get_last_anim()->set_source_info(model,node);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SpriteParticleRenderer::
|
void SpriteParticleRenderer::
|
||||||
set_from_node(const NodePath &node_path, bool size_from_texels) {
|
set_from_node(const NodePath &node_path, bool size_from_texels) {
|
||||||
nassertv(!node_path.is_empty());
|
|
||||||
|
|
||||||
NodePathCollection np_col;
|
|
||||||
TextureCollection tex_col;
|
|
||||||
pvector< TexCoordf > ll,ur;
|
|
||||||
GeomNode *gnode = NULL;
|
|
||||||
const Geom *geom;
|
|
||||||
const GeomPrimitive *primitive;
|
|
||||||
bool got_texcoord,got_vertex;
|
|
||||||
|
|
||||||
// Clear all texture information
|
// Clear all texture information
|
||||||
_anims.clear();
|
_anims.clear();
|
||||||
|
add_from_node(node_path,size_from_texels,true);
|
||||||
// Load the found textures into the renderer.
|
|
||||||
if (extract_textures_from_node(node_path,np_col,tex_col)) {
|
|
||||||
for (int i = 0; i < np_col.get_num_paths(); ++i) {
|
|
||||||
// Get the node from which we'll extract the geometry information.
|
|
||||||
gnode = DCAST(GeomNode, np_col[i].node());
|
|
||||||
|
|
||||||
// Now examine the UV's of the first Geom within the GeomNode.
|
|
||||||
nassertv(gnode->get_num_geoms() > 0);
|
|
||||||
geom = gnode->get_geom(0);
|
|
||||||
|
|
||||||
got_texcoord = false;
|
|
||||||
TexCoordf min_uv(0.0f, 0.0f);
|
|
||||||
TexCoordf max_uv(0.0f, 0.0f);
|
|
||||||
|
|
||||||
GeomVertexReader texcoord(geom->get_vertex_data(),
|
|
||||||
InternalName::get_texcoord());
|
|
||||||
if (texcoord.has_column()) {
|
|
||||||
for (int pi = 0; pi < geom->get_num_primitives(); ++pi) {
|
|
||||||
primitive = geom->get_primitive(pi);
|
|
||||||
for (int vi = 0; vi < primitive->get_num_vertices(); ++vi) {
|
|
||||||
int vert = primitive->get_vertex(vi);
|
|
||||||
texcoord.set_row(vert);
|
|
||||||
|
|
||||||
if (!got_texcoord) {
|
|
||||||
min_uv = max_uv = texcoord.get_data2f();
|
|
||||||
got_texcoord = true;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
const LVecBase2f &uv = texcoord.get_data2f();
|
|
||||||
|
|
||||||
min_uv[0] = min(min_uv[0], uv[0]);
|
|
||||||
max_uv[0] = max(max_uv[0], uv[0]);
|
|
||||||
min_uv[1] = min(min_uv[1], uv[1]);
|
|
||||||
max_uv[1] = max(max_uv[1], uv[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (got_texcoord) {
|
|
||||||
// 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.
|
|
||||||
ll.push_back(min_uv);
|
|
||||||
ur.push_back(max_uv);
|
|
||||||
// set_ll_uv(min_uv);
|
|
||||||
// set_ur_uv(max_uv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_anims.push_back(new SpriteAnim(tex_col,ll,ur));
|
|
||||||
|
|
||||||
gnode = DCAST(GeomNode, np_col[0].node());
|
|
||||||
geom = gnode->get_geom(0);
|
|
||||||
|
|
||||||
got_vertex = false;
|
|
||||||
Vertexf min_xyz(0.0f, 0.0f, 0.0f);
|
|
||||||
Vertexf max_xyz(0.0f, 0.0f, 0.0f);
|
|
||||||
|
|
||||||
GeomVertexReader vertex(geom->get_vertex_data(),
|
|
||||||
InternalName::get_vertex());
|
|
||||||
if (vertex.has_column()) {
|
|
||||||
for (int pi = 0; pi < geom->get_num_primitives(); ++pi) {
|
|
||||||
const GeomPrimitive *primitive = geom->get_primitive(pi);
|
|
||||||
for (int vi = 0; vi < primitive->get_num_vertices(); ++vi) {
|
|
||||||
int vert = primitive->get_vertex(vi);
|
|
||||||
vertex.set_row(vert);
|
|
||||||
|
|
||||||
if (!got_vertex) {
|
|
||||||
min_xyz = max_xyz = vertex.get_data3f();
|
|
||||||
got_vertex = true;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
const LVecBase3f &xyz = vertex.get_data3f();
|
|
||||||
|
|
||||||
min_xyz[0] = min(min_xyz[0], xyz[0]);
|
|
||||||
max_xyz[0] = max(max_xyz[0], xyz[0]);
|
|
||||||
min_xyz[1] = min(min_xyz[1], xyz[1]);
|
|
||||||
max_xyz[1] = max(max_xyz[1], xyz[1]);
|
|
||||||
min_xyz[2] = min(min_xyz[2], xyz[2]);
|
|
||||||
max_xyz[2] = max(max_xyz[2], xyz[2]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (got_vertex) {
|
|
||||||
float width = max_xyz[0] - min_xyz[0];
|
|
||||||
float height = max(max_xyz[1] - min_xyz[1],
|
|
||||||
max_xyz[2] - min_xyz[2]);
|
|
||||||
|
|
||||||
if (size_from_texels && got_texcoord) {
|
|
||||||
// If size_from_texels is true, we get the particle size from the
|
|
||||||
// number of texels in the source image.
|
|
||||||
float y_texels = _anims[0]->get_frame(0)->get_y_size() * fabs(_anims[0]->get_ur(0)[1] - _anims[0]->get_ll(0)[1]);
|
|
||||||
set_size(y_texels * width / height, y_texels);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// If size_from_texels is false, we get the particle size from
|
|
||||||
// the size of the polygon.
|
|
||||||
set_size(width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// With no vertices, just punt.
|
|
||||||
set_size(1.0f, 1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
init_geoms();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function : SpriteParticleRenderer::add_from_node
|
// Function : SpriteParticleRenderer::add_from_node
|
||||||
// Access : public
|
// Access : public
|
||||||
// Description : Sets the properties on this render from the geometry
|
// Description : This will allow the renderer to randomly choose
|
||||||
// referenced by the indicated NodePath. This should be
|
// from more than one texture or sequence at particle
|
||||||
// a reference to a GeomNode; it extracts out the
|
// birth.
|
||||||
// Texture and UV range from the GeomNode.
|
|
||||||
//
|
//
|
||||||
// If size_from_texels is true, the particle size is
|
// If the source type is important, use this one.
|
||||||
// based on the number of texels in the source image;
|
//
|
||||||
// otherwise, it is based on the size of the polygon
|
// model and node should lead to node_path like this:
|
||||||
// found in the GeomNode.
|
// node_path = loader.loadModel(model).find(node)
|
||||||
|
//
|
||||||
|
// If resize is true, or if there are no textures
|
||||||
|
// currently on the renderer, it will force the
|
||||||
|
// renderer to use the size information from this
|
||||||
|
// node from now on. (Default is false)
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void SpriteParticleRenderer::
|
void SpriteParticleRenderer::
|
||||||
add_from_node(const NodePath &node_path, const string &model, const string &node, bool size_from_texels, bool resize) {
|
add_from_node(const NodePath &node_path, const string &model, const string &node, bool size_from_texels, bool resize) {
|
||||||
|
int anim_count = _anims.size();
|
||||||
|
if (anim_count == 0)
|
||||||
|
resize = true;
|
||||||
add_from_node(node_path,size_from_texels,resize);
|
add_from_node(node_path,size_from_texels,resize);
|
||||||
get_last_anim()->set_source_info(model,node);
|
if (anim_count < _anims.size()) {
|
||||||
|
get_last_anim()->set_source_info(model,node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function : SpriteParticleRenderer::add_from_node
|
||||||
|
// Access : public
|
||||||
|
// Description : This will allow the renderer to randomly choose
|
||||||
|
// from more than one texture or sequence at particle
|
||||||
|
// birth.
|
||||||
|
//
|
||||||
|
// If resize is true, or if there are no textures
|
||||||
|
// currently on the renderer, it will force the
|
||||||
|
// renderer to use the size information from this
|
||||||
|
// node from now on. (Default is false)
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
void SpriteParticleRenderer::
|
void SpriteParticleRenderer::
|
||||||
add_from_node(const NodePath &node_path, bool size_from_texels, bool resize) {
|
add_from_node(const NodePath &node_path, bool size_from_texels, bool resize) {
|
||||||
nassertv(!node_path.is_empty());
|
nassertv(!node_path.is_empty());
|
||||||
|
|
||||||
pvector< TexCoordf > ll,ur;
|
|
||||||
GeomNode *gnode = NULL;
|
|
||||||
NodePathCollection np_col;
|
NodePathCollection np_col;
|
||||||
TextureCollection tex_col;
|
TextureCollection tex_col;
|
||||||
const Geom *geom;
|
|
||||||
const GeomPrimitive *primitive;
|
if (_anims.empty())
|
||||||
bool got_texcoord,got_vertex;
|
resize = true;
|
||||||
|
|
||||||
// Load the found textures into the renderer.
|
// Load the found textures into the renderer.
|
||||||
if (extract_textures_from_node(node_path,np_col,tex_col)) {
|
if (extract_textures_from_node(node_path,np_col,tex_col)) {
|
||||||
|
pvector< TexCoordf > ll,ur;
|
||||||
|
GeomNode *gnode = NULL;
|
||||||
|
const Geom *geom;
|
||||||
|
const GeomPrimitive *primitive;
|
||||||
|
bool got_texcoord;
|
||||||
|
|
||||||
for (int i = 0; i < np_col.get_num_paths(); ++i) {
|
for (int i = 0; i < np_col.get_num_paths(); ++i) {
|
||||||
// Get the node from which we'll extract the geometry information.
|
// Get the node from which we'll extract the geometry information.
|
||||||
gnode = DCAST(GeomNode, np_col[i].node());
|
gnode = DCAST(GeomNode, np_col[i].node());
|
||||||
@ -424,7 +353,7 @@ add_from_node(const NodePath &node_path, bool size_from_texels, bool resize) {
|
|||||||
gnode = DCAST(GeomNode, np_col[0].node());
|
gnode = DCAST(GeomNode, np_col[0].node());
|
||||||
geom = gnode->get_geom(0);
|
geom = gnode->get_geom(0);
|
||||||
|
|
||||||
got_vertex = false;
|
bool got_vertex = false;
|
||||||
Vertexf min_xyz(0.0f, 0.0f, 0.0f);
|
Vertexf min_xyz(0.0f, 0.0f, 0.0f);
|
||||||
Vertexf max_xyz(0.0f, 0.0f, 0.0f);
|
Vertexf max_xyz(0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
@ -432,7 +361,7 @@ add_from_node(const NodePath &node_path, bool size_from_texels, bool resize) {
|
|||||||
InternalName::get_vertex());
|
InternalName::get_vertex());
|
||||||
if (vertex.has_column()) {
|
if (vertex.has_column()) {
|
||||||
for (int pi = 0; pi < geom->get_num_primitives(); ++pi) {
|
for (int pi = 0; pi < geom->get_num_primitives(); ++pi) {
|
||||||
const GeomPrimitive *primitive = geom->get_primitive(pi);
|
primitive = geom->get_primitive(pi);
|
||||||
for (int vi = 0; vi < primitive->get_num_vertices(); ++vi) {
|
for (int vi = 0; vi < primitive->get_num_vertices(); ++vi) {
|
||||||
int vert = primitive->get_vertex(vi);
|
int vert = primitive->get_vertex(vi);
|
||||||
vertex.set_row(vert);
|
vertex.set_row(vert);
|
||||||
@ -477,9 +406,8 @@ add_from_node(const NodePath &node_path, bool size_from_texels, bool resize) {
|
|||||||
set_size(1.0f, 1.0f);
|
set_size(1.0f, 1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init_geoms();
|
init_geoms();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -661,6 +589,8 @@ render(pvector< PT(PhysicsObject) >& po_vector, int ttl_particles) {
|
|||||||
// This is an experimental age offset so that the animations don't appear synchronized.
|
// This is an experimental age offset so that the animations don't appear synchronized.
|
||||||
// If we are using animations, try to vary the frame flipping a bit for particles in the same litter.
|
// If we are using animations, try to vary the frame flipping a bit for particles in the same litter.
|
||||||
// A similar effect might be a achieved by using a small lifespan spread value on the factory.
|
// A similar effect might be a achieved by using a small lifespan spread value on the factory.
|
||||||
|
|
||||||
|
// Perhaps we should look into other methods. The age offset doesn't seem to be cutting it.
|
||||||
if (_animate_frames) {
|
if (_animate_frames) {
|
||||||
cur_particle->set_age(cur_particle->get_age()+i/10.0*cur_particle->get_lifespan());
|
cur_particle->set_age(cur_particle->get_age()+i/10.0*cur_particle->get_lifespan());
|
||||||
}
|
}
|
||||||
@ -762,7 +692,6 @@ render(pvector< PT(PhysicsObject) >& po_vector, int ttl_particles) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Send the data on its way...
|
// Send the data on its way...
|
||||||
// if(anim_index>_anims.size() || frame > _sprite_writer[anim_index].size())
|
|
||||||
_sprite_writer[anim_index][frame].vertex.add_data3f(position);
|
_sprite_writer[anim_index][frame].vertex.add_data3f(position);
|
||||||
_sprite_writer[anim_index][frame].color.add_data4f(c);
|
_sprite_writer[anim_index][frame].color.add_data4f(c);
|
||||||
|
|
||||||
|
@ -35,6 +35,13 @@
|
|||||||
|
|
||||||
class NodePath;
|
class NodePath;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : SpriteWriter
|
||||||
|
// Description : Helper class used by SpriteParticleRenderer to
|
||||||
|
// keep track of the various GeomVertexWriters
|
||||||
|
// associated with each geom created in
|
||||||
|
// SpriteParticleRenderer::init_geoms().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
class SpriteWriter {
|
class SpriteWriter {
|
||||||
public:
|
public:
|
||||||
SpriteWriter(GeomVertexWriter v,
|
SpriteWriter(GeomVertexWriter v,
|
||||||
@ -64,6 +71,12 @@ public:
|
|||||||
GeomVertexWriter aspect_ratio;
|
GeomVertexWriter aspect_ratio;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : SpriteAnim
|
||||||
|
// Description : Helper class used by SpriteParticleRenderer to
|
||||||
|
// keep track of its textures and their respective UVs
|
||||||
|
// and source types.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
class SpriteAnim : public ReferenceCount{
|
class SpriteAnim : public ReferenceCount{
|
||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
enum SourceType {
|
enum SourceType {
|
||||||
@ -265,7 +278,6 @@ private:
|
|||||||
pvector<int> _anim_size; // Holds the number of frames in each animation.
|
pvector<int> _anim_size; // Holds the number of frames in each animation.
|
||||||
pvector<int*> _ttl_count; // _ttl_count[i][j] holds the number of particles attached to animation 'i' at frame 'j'.
|
pvector<int*> _ttl_count; // _ttl_count[i][j] holds the number of particles attached to animation 'i' at frame 'j'.
|
||||||
pvector<int> _birth_list; // Holds the list of particles that need a new random animation to start on.
|
pvector<int> _birth_list; // Holds the list of particles that need a new random animation to start on.
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "spriteParticleRenderer.I"
|
#include "spriteParticleRenderer.I"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user