From c7d4e746fafe5aa459816e670022e290b1b722ed Mon Sep 17 00:00:00 2001 From: David Rose Date: Mon, 11 Apr 2005 23:10:21 +0000 Subject: [PATCH] fix some bam issues --- panda/src/char/character.I | 36 ++++ panda/src/char/character.cxx | 191 ++++++++++++++---- panda/src/char/character.h | 12 +- panda/src/egg2pg/characterMaker.cxx | 11 +- panda/src/gobj/qpgeomVertexData.I | 2 + panda/src/gobj/qpgeomVertexData.cxx | 2 +- panda/src/gobj/sliderTable.I | 33 ++- panda/src/gobj/sliderTable.cxx | 94 ++++++--- panda/src/gobj/sliderTable.h | 16 +- panda/src/gobj/transformBlend.I | 24 +++ panda/src/gobj/transformBlend.h | 2 + .../particlesystem/spriteParticleRenderer.cxx | 56 ++--- 12 files changed, 374 insertions(+), 105 deletions(-) diff --git a/panda/src/char/character.I b/panda/src/char/character.I index 7c482e686d..8887caf6eb 100644 --- a/panda/src/char/character.I +++ b/panda/src/char/character.I @@ -62,6 +62,42 @@ get_part(int n) const { return _parts[n]; } +//////////////////////////////////////////////////////////////////// +// Function: Character::find_joint +// Access: Published +// Description: Returns a pointer to the joint with the given name, +// if there is such a joint, or NULL if there is no such +// joint. This will not return a pointer to a slider. +//////////////////////////////////////////////////////////////////// +INLINE CharacterJoint *Character:: +find_joint(const string &name) const { + PartGroup *part = get_bundle()->find_child(name); + if (part != (PartGroup *)NULL && + part->is_of_type(CharacterJoint::get_class_type())) { + return DCAST(CharacterJoint, part); + } + + return NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: Character::find_slider +// Access: Published +// Description: Returns a pointer to the slider with the given name, +// if there is such a slider, or NULL if there is no such +// slider. This will not return a pointer to a joint. +//////////////////////////////////////////////////////////////////// +INLINE CharacterSlider *Character:: +find_slider(const string &name) const { + PartGroup *part = get_bundle()->find_child(name); + if (part != (PartGroup *)NULL && + part->is_of_type(CharacterSlider::get_class_type())) { + return DCAST(CharacterSlider, part); + } + + return NULL; +} + //////////////////////////////////////////////////////////////////// // Function: Character::write_parts // Access: Published diff --git a/panda/src/char/character.cxx b/panda/src/char/character.cxx index d9e28c4b48..46becdbfb7 100644 --- a/panda/src/char/character.cxx +++ b/panda/src/char/character.cxx @@ -377,49 +377,69 @@ r_copy_char(PandaNode *dest, const PandaNode *source, //////////////////////////////////////////////////////////////////// PT(Geom) Character:: copy_geom(const Geom *source, const Character *from) { - GeomBindType bind; - PTA_ushort index; - - PTA_Vertexf coords; - PTA_Normalf norms; - PTA_Colorf colors; - PTA_TexCoordf texcoords; - - PT(Geom) dest = (Geom *)source; - - source->get_coords(coords, index); - if ((coords != (void *)NULL) && (coords == (from->_cv._coords))) { - if (dest == source) { - dest = source->make_copy(); + if (source->is_of_type(qpGeom::get_class_type())) { + CPT(qpGeom) qpsource = DCAST(qpGeom, source); + CPT(qpGeomVertexFormat) format = qpsource->get_vertex_data()->get_format(); + if (format->get_animation().get_animation_type() == + qpGeomVertexAnimationSpec::AT_none) { + // Not animated, so never mind. + return (Geom *)source; } - dest->set_coords(_cv._coords, index); - } - source->get_normals(norms, bind, index); - if (bind != G_OFF && norms == from->_cv._norms) { - if (dest == source) { - dest = source->make_copy(); + PT(qpGeom) dest = new qpGeom(*qpsource); + PT(qpGeomVertexData) vdata = dest->modify_vertex_data(); + + vdata->set_transform_palette(redirect_transform_palette(vdata->get_transform_palette())); + vdata->set_transform_blend_palette(redirect_transform_blend_palette(vdata->get_transform_blend_palette())); + vdata->set_slider_table(redirect_slider_table(vdata->get_slider_table())); + + return dest.p(); + + } else { + GeomBindType bind; + PTA_ushort index; + + PTA_Vertexf coords; + PTA_Normalf norms; + PTA_Colorf colors; + PTA_TexCoordf texcoords; + + PT(Geom) dest = (Geom *)source; + + source->get_coords(coords, index); + if ((coords != (void *)NULL) && (coords == (from->_cv._coords))) { + if (dest == source) { + dest = source->make_copy(); + } + dest->set_coords(_cv._coords, index); } - dest->set_normals(_cv._norms, bind, index); - } - - source->get_colors(colors, bind, index); - if (bind != G_OFF && colors == from->_cv._colors) { - if (dest == source) { - dest = source->make_copy(); + + source->get_normals(norms, bind, index); + if (bind != G_OFF && norms == from->_cv._norms) { + if (dest == source) { + dest = source->make_copy(); + } + dest->set_normals(_cv._norms, bind, index); } - dest->set_colors(_cv._colors, bind, index); - } - - source->get_texcoords(texcoords, bind, index); - if (bind != G_OFF && texcoords == from->_cv._texcoords) { - if (dest == source) { - dest = source->make_copy(); + + source->get_colors(colors, bind, index); + if (bind != G_OFF && colors == from->_cv._colors) { + if (dest == source) { + dest = source->make_copy(); + } + dest->set_colors(_cv._colors, bind, index); } - dest->set_texcoords(_cv._texcoords, bind, index); + + source->get_texcoords(texcoords, bind, index); + if (bind != G_OFF && texcoords == from->_cv._texcoords) { + if (dest == source) { + dest = source->make_copy(); + } + dest->set_texcoords(_cv._texcoords, bind, index); + } + + return dest; } - - return dest; } //////////////////////////////////////////////////////////////////// @@ -478,6 +498,103 @@ copy_node_pointers(const Character *from, const Character::NodeMap &node_map) { } } +//////////////////////////////////////////////////////////////////// +// Function: Character::redirect_transform_palette +// Access: Public +// Description: Creates a new TransformPalette, similar to the +// indicated one, with the joint and slider pointers +// redirected into this object. +//////////////////////////////////////////////////////////////////// +CPT(TransformPalette) Character:: +redirect_transform_palette(const TransformPalette *source) { + if (source == (TransformPalette *)NULL) { + return NULL; + } + + PT(TransformPalette) dest = new TransformPalette(*source); + + int num_transforms = dest->get_num_transforms(); + for (int i = 0; i < num_transforms; ++i) { + const VertexTransform *vt = dest->get_transform(i); + if (vt->is_of_type(JointVertexTransform::get_class_type())) { + const JointVertexTransform *jvt = DCAST(JointVertexTransform, vt); + CharacterJoint *joint = find_joint(jvt->get_joint()->get_name()); + if (joint != (CharacterJoint *)NULL) { + CPT(JointVertexTransform) new_jvt = new JointVertexTransform(joint); + dest->set_transform(i, new_jvt); + } + } + } + + return TransformPalette::register_palette(dest); +} + +//////////////////////////////////////////////////////////////////// +// Function: Character::redirect_transform_blend_palette +// Access: Public +// Description: Creates a new TransformBlendPalette, similar to the +// indicated one, with the joint and slider pointers +// redirected into this object. +//////////////////////////////////////////////////////////////////// +CPT(TransformBlendPalette) Character:: +redirect_transform_blend_palette(const TransformBlendPalette *source) { + if (source == (TransformBlendPalette *)NULL) { + return NULL; + } + + PT(TransformBlendPalette) dest = new TransformBlendPalette(*source); + + int num_blends = dest->get_num_blends(); + for (int i = 0; i < num_blends; ++i) { + TransformBlend blend = dest->get_blend(i); + int num_transforms = blend.get_num_transforms(); + for (int j = 0; j < num_transforms; ++j) { + const VertexTransform *vt = blend.get_transform(j); + if (vt->is_of_type(JointVertexTransform::get_class_type())) { + const JointVertexTransform *jvt = DCAST(JointVertexTransform, vt); + CharacterJoint *joint = find_joint(jvt->get_joint()->get_name()); + if (joint != (CharacterJoint *)NULL) { + CPT(JointVertexTransform) new_jvt = new JointVertexTransform(joint); + blend.set_transform(j, new_jvt); + } + } + } + dest->set_blend(i, blend); + } + + return dest; +} + +//////////////////////////////////////////////////////////////////// +// Function: Character::redirect_slider_table +// Access: Public +// Description: Creates a new SliderTable, similar to the +// indicated one, with the joint and slider pointers +// redirected into this object. +//////////////////////////////////////////////////////////////////// +CPT(SliderTable) Character:: +redirect_slider_table(const SliderTable *source) { + if (source == (SliderTable *)NULL) { + return NULL; + } + + PT(SliderTable) dest = new SliderTable(*source); + + int num_sliders = dest->get_num_sliders(); + for (int i = 0; i < num_sliders; ++i) { + const VertexSlider *vs = dest->get_slider(i); + if (vs->is_of_type(CharacterVertexSlider::get_class_type())) { + const CharacterVertexSlider *cvs = DCAST(CharacterVertexSlider, vs); + CharacterSlider *slider = find_slider(cvs->get_char_slider()->get_name()); + if (slider != (CharacterSlider *)NULL) { + CPT(CharacterVertexSlider) new_cvs = new CharacterVertexSlider(slider); + dest->set_slider(i, new_cvs); + } + } + } + + return SliderTable::register_table(dest); +} //////////////////////////////////////////////////////////////////// // Function: Character::register_with_read_factory diff --git a/panda/src/char/character.h b/panda/src/char/character.h index 617fa29495..b1d1739594 100644 --- a/panda/src/char/character.h +++ b/panda/src/char/character.h @@ -22,12 +22,16 @@ #include "pandabase.h" #include "computedVertices.h" - +#include "characterJoint.h" +#include "characterSlider.h" #include "partBundleNode.h" #include "vector_PartGroupStar.h" #include "pointerTo.h" #include "geom.h" #include "pStatCollector.h" +#include "transformPalette.h" +#include "transformBlendPalette.h" +#include "sliderTable.h" class CharacterJointBundle; class ComputedVertices; @@ -59,6 +63,9 @@ PUBLISHED: INLINE int get_num_parts() const; INLINE PartGroup *get_part(int n) const; + INLINE CharacterJoint *find_joint(const string &name) const; + INLINE CharacterSlider *find_slider(const string &name) const; + INLINE void write_parts(ostream &out) const; INLINE void write_part_values(ostream &out) const; @@ -77,6 +84,9 @@ private: const Character *from, NodeMap &node_map); PT(Geom) copy_geom(const Geom *source, const Character *from); void copy_node_pointers(const Character *from, const NodeMap &node_map); + CPT(TransformPalette) redirect_transform_palette(const TransformPalette *source); + CPT(TransformBlendPalette) redirect_transform_blend_palette(const TransformBlendPalette *source); + CPT(SliderTable) redirect_slider_table(const SliderTable *source); // These are the actual dynamic vertex pools for this Character's // ComputedVertices--the vertices that it will recompute each frame diff --git a/panda/src/egg2pg/characterMaker.cxx b/panda/src/egg2pg/characterMaker.cxx index eeed386a88..1539299572 100644 --- a/panda/src/egg2pg/characterMaker.cxx +++ b/panda/src/egg2pg/characterMaker.cxx @@ -168,12 +168,14 @@ part_to_node(PartGroup *part, const string &name) const { // GeomNode. Look for a child of this node. If it doesn't have a // child yet, add a GeomNode and return it. Otherwise, if it // already has a child, return that. - if (node->is_geom_node() && node->get_name() == name) { + if (node->is_geom_node() && + (name.empty() || node->get_name() == name)) { return node; } for (int i = 0; i < node->get_num_children(); i++) { PandaNode *child = node->get_child(i); - if (child->is_geom_node() && child->get_name() == name) { + if (child->is_geom_node() && + (name.empty() || child->get_name() == name)) { return child; } } @@ -683,8 +685,9 @@ determine_bin_home(EggBin *egg_bin) { CharacterJoint *joint; DCAST_INTO_R(joint, egg_to_part(egg_group), home); egg_group->set_dcs_type(EggGroup::DC_default); - PT(GeomNode) geom_node = new GeomNode(egg_group->get_name()); - joint->_geom_node = geom_node.p(); + + PT(PandaNode) geom_node = new PandaNode(egg_group->get_name()); + joint->_geom_node = geom_node; } return home; diff --git a/panda/src/gobj/qpgeomVertexData.I b/panda/src/gobj/qpgeomVertexData.I index 56bcc003f8..a43a8267ad 100644 --- a/panda/src/gobj/qpgeomVertexData.I +++ b/panda/src/gobj/qpgeomVertexData.I @@ -430,7 +430,9 @@ CData() { INLINE qpGeomVertexData::CData:: CData(const qpGeomVertexData::CData ©) : _arrays(copy._arrays), + _transform_palette(copy._transform_palette), _transform_blend_palette(copy._transform_blend_palette), + _slider_table(copy._slider_table), _animated_vertices(copy._animated_vertices), _animated_vertices_modified(copy._animated_vertices_modified), _modified(copy._modified) diff --git a/panda/src/gobj/qpgeomVertexData.cxx b/panda/src/gobj/qpgeomVertexData.cxx index 4444ddd39d..3dea6753dd 100644 --- a/panda/src/gobj/qpgeomVertexData.cxx +++ b/panda/src/gobj/qpgeomVertexData.cxx @@ -1174,7 +1174,7 @@ update_animated_vertices(qpGeomVertexData::CDWriter &cdata, bool from_app) { int num_morphs = _format->get_num_morphs(); for (int mi = 0; mi < num_morphs; mi++) { CPT(InternalName) slider_name = _format->get_morph_slider(mi); - const VertexSlider *slider = table->get_slider(slider_name); + const VertexSlider *slider = table->find_slider(slider_name); if (slider != (VertexSlider *)NULL) { float slider_value = slider->get_slider(); if (slider_value != 0.0f) { diff --git a/panda/src/gobj/sliderTable.I b/panda/src/gobj/sliderTable.I index 6dd152a91c..7c3ab7f4e9 100644 --- a/panda/src/gobj/sliderTable.I +++ b/panda/src/gobj/sliderTable.I @@ -61,18 +61,39 @@ register_table(const SliderTable *table) { return table; } +//////////////////////////////////////////////////////////////////// +// Function: SliderTable::get_num_sliders +// Access: Published +// Description: Returns the number of sliders in the palette. +//////////////////////////////////////////////////////////////////// +INLINE int SliderTable:: +get_num_sliders() const { + return _sliders.size(); +} + //////////////////////////////////////////////////////////////////// // Function: SliderTable::get_slider // Access: Published +// Description: Returns the nth slider in the palette. +//////////////////////////////////////////////////////////////////// +INLINE const VertexSlider *SliderTable:: +get_slider(int n) const { + nassertr(n >= 0 && n < (int)_sliders.size(), NULL); + return _sliders[n]; +} + +//////////////////////////////////////////////////////////////////// +// Function: SliderTable::find_slider +// Access: Published // Description: Returns the slider with the indicated name, or NULL // if no slider in the table has that name. //////////////////////////////////////////////////////////////////// INLINE const VertexSlider *SliderTable:: -get_slider(const InternalName *name) const { - Sliders::const_iterator si; - si = _sliders.find(name); - if (si != _sliders.end()) { - return (*si).second; +find_slider(const InternalName *name) const { + SlidersByName::const_iterator sni; + sni = _sliders_by_name.find(name); + if (sni != _sliders_by_name.end()) { + return (*sni).second; } return NULL; } @@ -85,7 +106,7 @@ get_slider(const InternalName *name) const { //////////////////////////////////////////////////////////////////// INLINE bool SliderTable:: has_slider(const InternalName *name) const { - return (get_slider(name) != (VertexSlider *)NULL); + return (find_slider(name) != (VertexSlider *)NULL); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/sliderTable.cxx b/panda/src/gobj/sliderTable.cxx index 3997e475bf..2525a262b2 100644 --- a/panda/src/gobj/sliderTable.cxx +++ b/panda/src/gobj/sliderTable.cxx @@ -41,7 +41,8 @@ SliderTable() : SliderTable:: SliderTable(const SliderTable ©) : _is_registered(false), - _sliders(copy._sliders) + _sliders(copy._sliders), + _sliders_by_name(copy._sliders_by_name) { } @@ -54,6 +55,7 @@ void SliderTable:: operator = (const SliderTable ©) { nassertv(!_is_registered); _sliders = copy._sliders; + _sliders_by_name = copy._sliders_by_name; } //////////////////////////////////////////////////////////////////// @@ -69,33 +71,73 @@ SliderTable:: } //////////////////////////////////////////////////////////////////// -// Function: SliderTable::remove_slider +// Function: SliderTable::set_slider // Access: Published -// Description: Removes the named slider. Only valid for +// Description: Replaces the nth slider. Only valid for // unregistered tables. //////////////////////////////////////////////////////////////////// void SliderTable:: -remove_slider(const InternalName *name) { +set_slider(int n, const VertexSlider *slider) { nassertv(!_is_registered); + nassertv(n >= 0 && n < (int)_sliders.size()); - Sliders::iterator si = _sliders.find(name); - if (si != _sliders.end()) { - _sliders.erase(si); + if (_sliders[n]->get_name() != slider->get_name()) { + // Not allowed to move a slider this way. + nassertv(!has_slider(slider->get_name())); } + + _sliders[n] = slider; + _sliders_by_name[slider->get_name()] = slider; +} + +//////////////////////////////////////////////////////////////////// +// Function: SliderTable::remove_slider +// Access: Published +// Description: Removes the nth slider. Only valid for +// unregistered tables. +//////////////////////////////////////////////////////////////////// +void SliderTable:: +remove_slider(int n) { + nassertv(!_is_registered); + nassertv(n >= 0 && n < (int)_sliders.size()); + + SlidersByName::iterator si = _sliders_by_name.find(_sliders[n]->get_name()); + nassertv(si != _sliders_by_name.end()); + _sliders_by_name.erase(si); + + _sliders.erase(_sliders.begin() + n); } //////////////////////////////////////////////////////////////////// // Function: SliderTable::add_slider // Access: Published // Description: Adds a new slider to the table, or replaces an -// existing slider with the same name. Only valid for +// existing slider with the same name, and returns the +// index number of the new slider. Only valid for // unregistered tables. //////////////////////////////////////////////////////////////////// -void SliderTable:: -add_slider(VertexSlider *slider) { - nassertv(!_is_registered); +int SliderTable:: +add_slider(const VertexSlider *slider) { + nassertr(!_is_registered, -1); - _sliders[slider->get_name()] = slider; + SlidersByName::iterator sni = _sliders_by_name.find(slider->get_name()); + if (sni != _sliders_by_name.end()) { + // We've already got a slider with this name; replace it. + CPT(VertexSlider) orig_slider = (*sni).second; + Sliders::iterator si = find(_sliders.begin(), _sliders.end(), orig_slider); + nassertr(si != _sliders.end(), -1); + (*si) = slider; + (*sni).second = slider; + + return si - _sliders.begin(); + } + + // This is the first slider with this name. + int new_index = (int)_sliders.size(); + _sliders.push_back(slider); + _sliders_by_name[slider->get_name()] = slider; + + return new_index; } //////////////////////////////////////////////////////////////////// @@ -105,9 +147,8 @@ add_slider(VertexSlider *slider) { //////////////////////////////////////////////////////////////////// void SliderTable:: write(ostream &out) const { - Sliders::const_iterator si; - for (si = _sliders.begin(); si != _sliders.end(); ++si) { - out << *(*si).second << "\n"; + for (size_t i = 0; i < _sliders.size(); ++i) { + out << i << ". " << *_sliders[i] << "\n"; } } @@ -122,7 +163,8 @@ do_register() { Sliders::iterator si; for (si = _sliders.begin(); si != _sliders.end(); ++si) { - bool inserted = (*si).second->_tables.insert(this).second; + const VertexSlider *slider = (*si); + bool inserted = ((VertexSlider *)slider)->_tables.insert(this).second; nassertv(inserted); } _is_registered = true; @@ -140,7 +182,8 @@ do_unregister() { Sliders::iterator si; for (si = _sliders.begin(); si != _sliders.end(); ++si) { - (*si).second->_tables.erase(this); + const VertexSlider *slider = (*si); + ((VertexSlider *)slider)->_tables.erase(this); } _is_registered = false; } @@ -169,8 +212,8 @@ write_datagram(BamWriter *manager, Datagram &dg) { dg.add_uint16(_sliders.size()); Sliders::const_iterator si; for (si = _sliders.begin(); si != _sliders.end(); ++si) { - manager->write_pointer(dg, (*si).first); - manager->write_pointer(dg, (*si).second); + manager->write_pointer(dg, (*si)->get_name()); + manager->write_pointer(dg, (*si)); } manager->write_cdata(dg, _cycler); @@ -187,11 +230,14 @@ int SliderTable:: complete_pointers(TypedWritable **p_list, BamReader *manager) { int pi = TypedWritableReferenceCount::complete_pointers(p_list, manager); - for (size_t i = 0; i < _num_sliders; ++i) { + Sliders::iterator si; + for (si = _sliders.begin(); si != _sliders.end(); ++si) { CPT(InternalName) name = DCAST(InternalName, p_list[pi++]); PT(VertexSlider) slider = DCAST(VertexSlider, p_list[pi++]); - bool inserted = _sliders.insert(Sliders::value_type(name, slider)).second; + (*si) = slider; + + bool inserted = _sliders_by_name.insert(SlidersByName::value_type(name, slider)).second; nassertr(inserted, pi); } @@ -229,10 +275,12 @@ void SliderTable:: fillin(DatagramIterator &scan, BamReader *manager) { TypedWritable::fillin(scan, manager); - _num_sliders = scan.get_uint16(); - for (size_t i = 0; i < _num_sliders; ++i) { + size_t num_sliders = scan.get_uint16(); + _sliders.reserve(num_sliders); + for (size_t i = 0; i < num_sliders; ++i) { manager->read_pointer(scan); manager->read_pointer(scan); + _sliders.push_back(NULL); } manager->read_cdata(scan, _cycler); diff --git a/panda/src/gobj/sliderTable.h b/panda/src/gobj/sliderTable.h index c8f8fcf3ef..ba9f9023fd 100644 --- a/panda/src/gobj/sliderTable.h +++ b/panda/src/gobj/sliderTable.h @@ -55,13 +55,17 @@ PUBLISHED: INLINE bool is_registered() const; INLINE static CPT(SliderTable) register_table(const SliderTable *table); - INLINE const VertexSlider *get_slider(const InternalName *name) const; + INLINE int get_num_sliders() const; + INLINE const VertexSlider *get_slider(int n) const; + + INLINE const VertexSlider *find_slider(const InternalName *name) const; INLINE bool has_slider(const InternalName *name) const; INLINE bool is_empty() const; INLINE UpdateSeq get_modified() const; - void remove_slider(const InternalName *name); - void add_slider(VertexSlider *slider); + void set_slider(int n, const VertexSlider *slider); + void remove_slider(int n); + int add_slider(const VertexSlider *slider); void write(ostream &out) const; @@ -73,11 +77,11 @@ private: private: bool _is_registered; - typedef pmap< CPT(InternalName), PT(VertexSlider) > Sliders; + typedef pvector< CPT(VertexSlider) > Sliders; Sliders _sliders; - // This is only filled in while reading from the bam stream. - size_t _num_sliders; + typedef pmap< CPT(InternalName), const VertexSlider *> SlidersByName; + SlidersByName _sliders_by_name; // This is the data that must be cycled between pipeline stages. class EXPCL_PANDA CData : public CycleData { diff --git a/panda/src/gobj/transformBlend.I b/panda/src/gobj/transformBlend.I index 7b42c5c6e0..8c907ccef6 100644 --- a/panda/src/gobj/transformBlend.I +++ b/panda/src/gobj/transformBlend.I @@ -177,6 +177,30 @@ get_weight(int n) const { return _entries[n]._weight; } +//////////////////////////////////////////////////////////////////// +// Function: TransformBlend::set_transform +// Access: Published +// Description: Replaces the nth transform stored in the blend +// object. +//////////////////////////////////////////////////////////////////// +INLINE void TransformBlend:: +set_transform(int n, const VertexTransform *transform) { + nassertv(n >= 0 && n < (int)_entries.size()); + _entries[n]._transform = transform; +} + +//////////////////////////////////////////////////////////////////// +// Function: TransformBlend::set_weight +// Access: Published +// Description: Replaces the weight associated with the nth transform +// stored in the blend object. +//////////////////////////////////////////////////////////////////// +INLINE void TransformBlend:: +set_weight(int n, float weight) { + nassertv(n >= 0 && n < (int)_entries.size()); + _entries[n]._weight = weight; +} + //////////////////////////////////////////////////////////////////// // Function: TransformBlend::update_blend // Access: Published diff --git a/panda/src/gobj/transformBlend.h b/panda/src/gobj/transformBlend.h index 41fdb9a849..7c529f8be0 100644 --- a/panda/src/gobj/transformBlend.h +++ b/panda/src/gobj/transformBlend.h @@ -69,6 +69,8 @@ PUBLISHED: INLINE int get_num_transforms() const; INLINE const VertexTransform *get_transform(int n) const; INLINE float get_weight(int n) const; + INLINE void set_transform(int n, const VertexTransform *transform); + INLINE void set_weight(int n, float weight); INLINE void update_blend() const; diff --git a/panda/src/particlesystem/spriteParticleRenderer.cxx b/panda/src/particlesystem/spriteParticleRenderer.cxx index a93486c5fc..3b4da32778 100644 --- a/panda/src/particlesystem/spriteParticleRenderer.cxx +++ b/panda/src/particlesystem/spriteParticleRenderer.cxx @@ -152,33 +152,35 @@ set_from_node(const NodePath &node_path, bool size_from_texels) { qpGeomVertexReader texcoord(qpgeom->get_vertex_data()); qpGeomVertexReader vertex(qpgeom->get_vertex_data()); - bool found_any = false; - for (int pi = 0; pi < qpgeom->get_num_primitives(); ++pi) { - const qpGeomPrimitive *primitive = qpgeom->get_primitive(pi); - for (int vi = 0; vi < primitive->get_num_vertices(); ++vi) { - int vert = primitive->get_vertex(vi); - texcoord.set_vertex(vert); - vertex.set_vertex(vert); - - if (!found_any) { - min_uv = max_uv = texcoord.get_data2f(); - min_xyz = max_xyz = vertex.get_data3f(); - - } else { - const LVecBase2f &uv = texcoord.get_data2f(); - const LVecBase3f &xyz = vertex.get_data3f(); - - 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]); - - 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 (texcoord.has_column() && vertex.has_column()) { + bool found_any = false; + for (int pi = 0; pi < qpgeom->get_num_primitives(); ++pi) { + const qpGeomPrimitive *primitive = qpgeom->get_primitive(pi); + for (int vi = 0; vi < primitive->get_num_vertices(); ++vi) { + int vert = primitive->get_vertex(vi); + texcoord.set_vertex(vert); + vertex.set_vertex(vert); + + if (!found_any) { + min_uv = max_uv = texcoord.get_data2f(); + min_xyz = max_xyz = vertex.get_data3f(); + + } else { + const LVecBase2f &uv = texcoord.get_data2f(); + const LVecBase3f &xyz = vertex.get_data3f(); + + 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]); + + 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]); + } } } }