diff --git a/panda/src/char/character.I b/panda/src/char/character.I index 6b53e4395f..c6f4090624 100644 --- a/panda/src/char/character.I +++ b/panda/src/char/character.I @@ -28,4 +28,25 @@ get_bundle(int i) const { return DCAST(CharacterJointBundle, PartBundleNode::get_bundle(i)); } +//////////////////////////////////////////////////////////////////// +// Function: Character::get_num_parts +// Access: Published +// Description: Returns the total number of moving parts (e.g. joints +// and sliders) associated with the Character. +//////////////////////////////////////////////////////////////////// +INLINE int Character:: +get_num_parts() const { + return _parts.size(); +} +//////////////////////////////////////////////////////////////////// +// Function: Character::get_part +// Access: Published +// Description: Returns the nth moving part associated with the +// Character. +//////////////////////////////////////////////////////////////////// +INLINE PartGroup *Character:: +get_part(int n) const { + nassertr(n >= 0 && n < (int)_parts.size(), NULL); + return _parts[n]; +} diff --git a/panda/src/char/character.cxx b/panda/src/char/character.cxx index 867bd396bc..34560a2de2 100644 --- a/panda/src/char/character.cxx +++ b/panda/src/char/character.cxx @@ -42,6 +42,7 @@ PStatCollector Character::_animation_pcollector("*:Animation"); Character:: Character(const Character ©) : PartBundleNode(copy), + _parts(copy._parts), _joints_pcollector(copy._joints_pcollector), _skinning_pcollector(copy._skinning_pcollector) { @@ -375,6 +376,11 @@ copy_joints(PartGroup *copy, PartGroup *orig) { copy->_children.push_back(copy_child); copy_joints(copy_child, orig_child); } + + Parts::iterator pi = find(_parts.begin(), _parts.end(), orig); + if (pi != _parts.end()) { + (*pi) = copy; + } } //////////////////////////////////////////////////////////////////// @@ -418,6 +424,7 @@ r_copy_children(const PandaNode *from, PandaNode::InstanceMap &inst_map, GeomSliderMap gsmap; r_copy_char(this, from_char, from_char, node_map, joint_map, gvmap, gjmap, gsmap); + copy_node_pointers(from_char, node_map); } //////////////////////////////////////////////////////////////////// @@ -552,6 +559,64 @@ copy_geom(const Geom *source, const Character *from, return dest; } +//////////////////////////////////////////////////////////////////// +// Function: Character::copy_node_pointers +// Access: Public +// Description: Creates _net_transform_nodes and _local_transform_nodes +// as appropriate in each of the Character's joints, as +// copied from the other Character. +//////////////////////////////////////////////////////////////////// +void Character:: +copy_node_pointers(const Character *from, const Character::NodeMap &node_map) { + nassertv(_parts.size() == from->_parts.size()); + for (int i = 0; i < (int)_parts.size(); i++) { + if (_parts[i]->is_of_type(CharacterJoint::get_class_type())) { + nassertv(_parts[i] != from->_parts[i]); + CharacterJoint *source_joint; + CharacterJoint *dest_joint; + DCAST_INTO_V(source_joint, from->_parts[i]); + DCAST_INTO_V(dest_joint, _parts[i]); + + CharacterJoint::NodeList::const_iterator ai; + for (ai = source_joint->_net_transform_nodes.begin(); + ai != source_joint->_net_transform_nodes.end(); + ++ai) { + PandaNode *source_node = (*ai); + + NodeMap::const_iterator mi; + mi = node_map.find(source_node); + if (mi != node_map.end()) { + PandaNode *dest_node = (*mi).second; + + // Here's an internal joint that the source Character was + // animating directly. We'll animate our corresponding + // joint the same way. + dest_joint->set_character(this); + dest_joint->add_net_transform(dest_node); + } + } + + for (ai = source_joint->_local_transform_nodes.begin(); + ai != source_joint->_local_transform_nodes.end(); + ++ai) { + PandaNode *source_node = (*ai); + + NodeMap::const_iterator mi; + mi = node_map.find(source_node); + if (mi != node_map.end()) { + PandaNode *dest_node = (*mi).second; + + // Here's an internal joint that the source Character was + // animating directly. We'll animate our corresponding + // joint the same way. + dest_joint->set_character(this); + dest_joint->add_local_transform(dest_node); + } + } + } + } +} + //////////////////////////////////////////////////////////////////// // Function: Character::redirect_transform_table // Access: Private @@ -755,7 +820,12 @@ register_with_read_factory() { void Character:: write_datagram(BamWriter *manager, Datagram &dg) { PartBundleNode::write_datagram(manager, dg); - dg.add_uint16(0); + + dg.add_uint16(_parts.size()); + Parts::const_iterator pi; + for (pi = _parts.begin(); pi != _parts.end(); pi++) { + manager->write_pointer(dg, (*pi)); + } } //////////////////////////////////////////////////////////////////// @@ -767,7 +837,14 @@ write_datagram(BamWriter *manager, Datagram &dg) { //////////////////////////////////////////////////////////////////// int Character:: complete_pointers(TypedWritable **p_list, BamReader *manager) { - return PartBundleNode::complete_pointers(p_list, manager) + _temp_num_parts; + int pi = PartBundleNode::complete_pointers(p_list, manager); + + int num_parts = _parts.size(); + for (int i = 0; i < num_parts; i++) { + _parts[i] = DCAST(PartGroup, p_list[pi++]); + } + + return pi; } //////////////////////////////////////////////////////////////////// @@ -804,9 +881,12 @@ fillin(DatagramIterator &scan, BamReader *manager) { // Read the number of parts to expect in the _parts list, and then // fill the array up with NULLs. We'll fill in the actual values in // complete_pointers, later. - _temp_num_parts = scan.get_uint16(); - for (int i = 0; i < _temp_num_parts; i++) { + int num_parts = scan.get_uint16(); + _parts.clear(); + _parts.reserve(num_parts); + for (int i = 0; i < num_parts; i++) { manager->read_pointer(scan); + _parts.push_back((PartGroup *)NULL); } #ifdef DO_PSTATS diff --git a/panda/src/char/character.h b/panda/src/char/character.h index f1c9666b91..55b94b8541 100644 --- a/panda/src/char/character.h +++ b/panda/src/char/character.h @@ -64,6 +64,9 @@ public: PUBLISHED: INLINE CharacterJointBundle *get_bundle(int i) const; + INLINE int get_num_parts() const; + INLINE PartGroup *get_part(int n) const; + CharacterJoint *find_joint(const string &name) const; CharacterSlider *find_slider(const string &name) const; @@ -94,6 +97,7 @@ private: PT(Geom) copy_geom(const Geom *source, const Character *from, const JointMap &joint_map, GeomVertexMap &gvmap, GeomJointMap &gjmap, GeomSliderMap &gsmap); + void copy_node_pointers(const Character *from, const NodeMap &node_map); CPT(TransformTable) redirect_transform_table(const TransformTable *source, const JointMap &joint_map, GeomJointMap &gjmap); @@ -110,9 +114,10 @@ private: void r_clear_joint_characters(PartGroup *part); + // This vector is used by the ComputedVertices object to index back // into our joints and sliders. - //typedef vector_PartGroupStar Parts; - //Parts _parts; + typedef vector_PartGroupStar Parts; + Parts _parts; double _last_auto_update; @@ -121,8 +126,6 @@ private: PStatCollector _skinning_pcollector; static PStatCollector _animation_pcollector; - unsigned int _temp_num_parts; - public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); @@ -151,6 +154,8 @@ private: static TypeHandle _type_handle; friend class CharacterMaker; + friend class ComputedVerticesMaker; + friend class ComputedVertices; }; #include "character.I" diff --git a/panda/src/egg2pg/characterMaker.cxx b/panda/src/egg2pg/characterMaker.cxx index 35ccea60d8..8b5db0d52a 100644 --- a/panda/src/egg2pg/characterMaker.cxx +++ b/panda/src/egg2pg/characterMaker.cxx @@ -61,6 +61,7 @@ CharacterMaker(EggGroup *root, EggLoader &loader) Character *CharacterMaker:: make_node() { make_bundle(); + _character_node->_parts = _parts; return _character_node; }