Panda3D

character.cxx

00001 // Filename: character.cxx
00002 // Created by:  drose (06Mar02)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "character.h"
00016 #include "characterJoint.h"
00017 #include "config_char.h"
00018 #include "nodePath.h"
00019 #include "geomNode.h"
00020 #include "datagram.h"
00021 #include "datagramIterator.h"
00022 #include "bamReader.h"
00023 #include "bamWriter.h"
00024 #include "pStatTimer.h"
00025 #include "animControl.h"
00026 #include "clockObject.h"
00027 #include "pStatTimer.h"
00028 #include "camera.h"
00029 #include "cullTraverser.h"
00030 #include "cullTraverserData.h"
00031 
00032 TypeHandle Character::_type_handle;
00033 
00034 PStatCollector Character::_animation_pcollector("*:Animation");
00035 
00036 ////////////////////////////////////////////////////////////////////
00037 //     Function: Character::Copy Constructor
00038 //       Access: Protected
00039 //  Description: Use make_copy() or copy_subgraph() to copy a Character.
00040 ////////////////////////////////////////////////////////////////////
00041 Character::
00042 Character(const Character &copy, bool copy_bundles) :
00043   PartBundleNode(copy),
00044   _lod_center(copy._lod_center),
00045   _lod_far_distance(copy._lod_far_distance),
00046   _lod_near_distance(copy._lod_near_distance),
00047   _lod_delay_factor(copy._lod_delay_factor),
00048   _do_lod_animation(copy._do_lod_animation),
00049   _joints_pcollector(copy._joints_pcollector),
00050   _skinning_pcollector(copy._skinning_pcollector)
00051 {
00052   set_cull_callback();
00053 
00054   if (copy_bundles) {
00055     // Copy the bundle(s).
00056     int num_bundles = copy.get_num_bundles();
00057     for (int i = 0; i < num_bundles; ++i) {
00058       PartBundle *orig_bundle = copy.get_bundle(i);
00059       PT(PartBundle) new_bundle = DCAST(PartBundle, orig_bundle->copy_subgraph());
00060       add_bundle(new_bundle);
00061     }
00062   } else {
00063     // Share the bundles.
00064     int num_bundles = copy.get_num_bundles();
00065     for (int i = 0; i < num_bundles; ++i) {
00066       PartBundle *orig_bundle = copy.get_bundle(i);
00067       add_bundle(orig_bundle);
00068     }
00069   }    
00070   _last_auto_update = -1.0;
00071   _view_frame = -1;
00072   _view_distance2 = 0.0f;
00073 }
00074 
00075 ////////////////////////////////////////////////////////////////////
00076 //     Function: Character::Constructor
00077 //       Access: Public
00078 //  Description:
00079 ////////////////////////////////////////////////////////////////////
00080 Character::
00081 Character(const string &name) :
00082   PartBundleNode(name, new CharacterJointBundle(name)),
00083   _joints_pcollector(PStatCollector(_animation_pcollector, name), "Joints"),
00084   _skinning_pcollector(PStatCollector(_animation_pcollector, name), "Vertices")
00085 {
00086   set_cull_callback();
00087   clear_lod_animation();
00088   _last_auto_update = -1.0;
00089   _view_frame = -1;
00090   _view_distance2 = 0.0f;
00091 }
00092 
00093 ////////////////////////////////////////////////////////////////////
00094 //     Function: Character::Destructor
00095 //       Access: Public
00096 //  Description:
00097 ////////////////////////////////////////////////////////////////////
00098 Character::
00099 ~Character() {
00100   int num_bundles = get_num_bundles();
00101   for (int i = 0; i < num_bundles; ++i) {
00102     r_clear_joint_characters(get_bundle(i));
00103   }
00104 }
00105 
00106 ////////////////////////////////////////////////////////////////////
00107 //     Function: Character::make_copy
00108 //       Access: Public, Virtual
00109 //  Description: The Character make_copy() function will make a new
00110 //               copy of the Character, with all of its joints copied,
00111 //               and with a new set of dynamic vertex arrays all ready
00112 //               to go, but it will not copy any of the original
00113 //               Character's geometry, so the new Character won't look
00114 //               like much.  Use copy_subgraph() to make a full copy
00115 //               of the Character.
00116 ////////////////////////////////////////////////////////////////////
00117 PandaNode *Character::
00118 make_copy() const {
00119   return new Character(*this, true);
00120 }
00121 
00122 ////////////////////////////////////////////////////////////////////
00123 //     Function: Character::dupe_for_flatten
00124 //       Access: Public, Virtual
00125 //  Description: This is similar to make_copy(), but it makes a copy
00126 //               for the specific purpose of flatten.  Typically, this
00127 //               will be a new PandaNode with a new pointer, but all
00128 //               of the internal data will always be shared with the
00129 //               original; whereas the new node returned by
00130 //               make_copy() might not share the internal data.
00131 ////////////////////////////////////////////////////////////////////
00132 PandaNode *Character::
00133 dupe_for_flatten() const {
00134   return new Character(*this, false);
00135 }
00136 
00137 ////////////////////////////////////////////////////////////////////
00138 //     Function: Character::combine_with
00139 //       Access: Published, Virtual
00140 //  Description: Collapses this node with the other node, if possible,
00141 //               and returns a pointer to the combined node, or NULL
00142 //               if the two nodes cannot safely be combined.
00143 //
00144 //               The return value may be this, other, or a new node
00145 //               altogether.
00146 //
00147 //               This function is called from GraphReducer::flatten(),
00148 //               and need not deal with children; its job is just to
00149 //               decide whether to collapse the two nodes and what the
00150 //               collapsed node should look like.
00151 ////////////////////////////////////////////////////////////////////
00152 PandaNode *Character::
00153 combine_with(PandaNode *other) {
00154   if (is_exact_type(get_class_type()) &&
00155       other->is_exact_type(get_class_type())) {
00156     // Two Characters can combine by moving PartBundles from one to the other.
00157     Character *c_other = DCAST(Character, other);
00158     steal_bundles(c_other);
00159     return this;
00160   }
00161 
00162   return PandaNode::combine_with(other);
00163 }
00164 
00165 ////////////////////////////////////////////////////////////////////
00166 //     Function: Character::cull_callback
00167 //       Access: Public, Virtual
00168 //  Description: This function will be called during the cull
00169 //               traversal to perform any additional operations that
00170 //               should be performed at cull time.  This may include
00171 //               additional manipulation of render state or additional
00172 //               visible/invisible decisions, or any other arbitrary
00173 //               operation.
00174 //
00175 //               Note that this function will *not* be called unless
00176 //               set_cull_callback() is called in the constructor of
00177 //               the derived class.  It is necessary to call
00178 //               set_cull_callback() to indicated that we require
00179 //               cull_callback() to be called.
00180 //
00181 //               By the time this function is called, the node has
00182 //               already passed the bounding-volume test for the
00183 //               viewing frustum, and the node's transform and state
00184 //               have already been applied to the indicated
00185 //               CullTraverserData object.
00186 //
00187 //               The return value is true if this node should be
00188 //               visible, or false if it should be culled.
00189 ////////////////////////////////////////////////////////////////////
00190 bool Character::
00191 cull_callback(CullTraverser *trav, CullTraverserData &data) {
00192   // For now, we update the character during the cull traversal; this
00193   // prevents us from needlessly updating characters that aren't in
00194   // the view frustum.  We may need a better way to do this
00195   // optimization later, to handle characters that might animate
00196   // themselves in front of the view frustum.
00197 
00198   if (_do_lod_animation) {
00199     int this_frame = ClockObject::get_global_clock()->get_frame_count();
00200 
00201     CPT(TransformState) rel_transform = get_rel_transform(trav, data);
00202     LPoint3 center = _lod_center * rel_transform->get_mat();
00203     PN_stdfloat dist2 = center.dot(center);
00204 
00205     if (this_frame != _view_frame || dist2 < _view_distance2) {
00206       _view_frame = this_frame;
00207       _view_distance2 = dist2;
00208 
00209       // Now compute the lod delay.
00210       PN_stdfloat dist = sqrt(dist2);
00211       double delay = 0.0;
00212       if (dist > _lod_near_distance) {
00213         delay = _lod_delay_factor * (dist - _lod_near_distance) / (_lod_far_distance - _lod_near_distance);
00214         nassertr(delay > 0.0, false);
00215       }
00216       set_lod_current_delay(delay);
00217 
00218       if (char_cat.is_spam()) {
00219         char_cat.spam() 
00220           << "Distance to " << NodePath::any_path(this) << " in frame "
00221           << this_frame << " is " << dist << ", computed delay is " << delay
00222           << "\n";
00223       }
00224     }
00225   }
00226 
00227   update();
00228   return true;
00229 }
00230 
00231 ////////////////////////////////////////////////////////////////////
00232 //     Function: Character::calc_tight_bounds
00233 //       Access: Public, Virtual
00234 //  Description: This is used to support
00235 //               NodePath::calc_tight_bounds().  It is not intended to
00236 //               be called directly, and it has nothing to do with the
00237 //               normal Panda bounding-volume computation.
00238 //
00239 //               If the node contains any geometry, this updates
00240 //               min_point and max_point to enclose its bounding box.
00241 //               found_any is to be set true if the node has any
00242 //               geometry at all, or left alone if it has none.  This
00243 //               method may be called over several nodes, so it may
00244 //               enter with min_point, max_point, and found_any
00245 //               already set.
00246 //
00247 //               This function is recursive, and the return value is
00248 //               the transform after it has been modified by this
00249 //               node's transform.
00250 ////////////////////////////////////////////////////////////////////
00251 CPT(TransformState) Character::
00252 calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point, bool &found_any,
00253                   const TransformState *transform, Thread *current_thread) const {
00254   // This method is overridden by Character solely to provide a hook
00255   // to force the joints to update before computing the bounding
00256   // volume.
00257   ((Character *)this)->update_to_now();
00258 
00259   // Unfortunately, calling update_to_now() will invalidate the node's
00260   // cached bounding volume, which causes a problem when this is
00261   // called during the traversal, e.g. due to a ShowBoundsEffect.  As
00262   // a hacky fix to work around this, we will force-recompute all of
00263   // the bounding volumes of our parent nodes immediately.
00264   Parents parents = get_parents();
00265   for (int i = 0; i < parents.get_num_parents(); ++i) {
00266     PandaNode *parent = parents.get_parent(i);
00267     parent->get_bounds();
00268   }
00269 
00270   return PandaNode::calc_tight_bounds(min_point, max_point, 
00271                                       found_any, transform, current_thread);
00272 }
00273 
00274 ////////////////////////////////////////////////////////////////////
00275 //     Function: Character::merge_bundles
00276 //       Access: Published
00277 //  Description: Merges old_bundle with new_bundle.  old_bundle
00278 //               must be one of the PartBundles within this node.  At
00279 //               the end of this call, the old_bundle pointer within
00280 //               this node will be replaced with the new_bundle
00281 //               pointer, and all geometry within this node will be
00282 //               updated to reference new_bundle.
00283 //
00284 //               This method is deprecated.  Use the newer version of
00285 //               this method, below.
00286 ////////////////////////////////////////////////////////////////////
00287 void Character::
00288 merge_bundles(PartBundle *old_bundle, PartBundle *new_bundle) {
00289   if (old_bundle == new_bundle) {
00290     // Trivially return.
00291     return;
00292   }
00293 
00294   // Find the PartBundleHandle of old_bundle.
00295   PT(PartBundleHandle) old_bundle_handle;
00296   Bundles::const_iterator bi;
00297   for (bi = _bundles.begin(); bi != _bundles.end(); ++bi) {
00298     if ((*bi)->get_bundle() == old_bundle) {
00299       old_bundle_handle = (*bi);
00300       break;
00301     }
00302   }
00303   nassertv(!old_bundle_handle.is_null());
00304 
00305   PT(PartBundleHandle) new_bundle_handle = new PartBundleHandle(new_bundle);
00306   merge_bundles(old_bundle_handle, new_bundle_handle);
00307 }
00308 
00309 ////////////////////////////////////////////////////////////////////
00310 //     Function: Character::merge_bundles
00311 //       Access: Published
00312 //  Description: Merges old_bundle_handle->get_bundle() with
00313 //               new_bundle.  old_bundle_handle must be one of the
00314 //               PartBundleHandle within this node.  At the end of
00315 //               this call, the bundle pointer within the
00316 //               old_bundle_handle will be replaced with that within
00317 //               the new_bundle_handle pointer, and all geometry
00318 //               within this node will be updated to reference
00319 //               new_bundle.
00320 //
00321 //               Normally, this is called when the two bundles have
00322 //               the same, or nearly the same, hierarchies.  In this
00323 //               case, new_bundle will simply be assigned over the
00324 //               old_bundle position.  However, if any joints are
00325 //               present in one bundle or the other, new_bundle will
00326 //               be modified to contain the union of all joints.
00327 //               
00328 //               The geometry below this node is also updated to
00329 //               reference new_bundle, instead of the original
00330 //               old_bundle.
00331 //
00332 //               This method is intended to unify two different models
00333 //               that share a common skeleton, for instance, different
00334 //               LOD's of the same model.
00335 ////////////////////////////////////////////////////////////////////
00336 void Character::
00337 merge_bundles(PartBundleHandle *old_bundle_handle, 
00338               PartBundleHandle *new_bundle_handle) {
00339   PartBundle *old_bundle = old_bundle_handle->get_bundle();
00340   PartBundle *new_bundle = new_bundle_handle->get_bundle();
00341   new_bundle->merge_anim_preloads(old_bundle);
00342 
00343   update_bundle(old_bundle_handle, new_bundle);
00344 }
00345 
00346 ////////////////////////////////////////////////////////////////////
00347 //     Function: Character::set_lod_animation
00348 //       Access: Published
00349 //  Description: Activates a special mode in which the character
00350 //               animates less frequently as it gets further from the
00351 //               camera.  This is intended as a simple optimization to
00352 //               minimize the effort of computing animation for lots
00353 //               of characters that may not necessarily be very
00354 //               important to animate every frame.
00355 //
00356 //               If the character is closer to the camera than
00357 //               near_distance, then it is animated its normal rate,
00358 //               every frame.  If the character is exactly
00359 //               far_distance away, it is animated only every
00360 //               delay_factor seconds (which should be a number
00361 //               greater than 0).  If the character is between
00362 //               near_distance and far_distance, its animation rate is
00363 //               linearly interpolated according to its distance
00364 //               between the two.  The interpolation function
00365 //               continues beyond far_distance, so that the character
00366 //               is animated increasingly less frequently as it gets
00367 //               farther away.
00368 //
00369 //               The distance calculations are made from center, which
00370 //               is a fixed point relative to the character node, to
00371 //               the camera's lod center or cull center node (or to
00372 //               the camera node itself).
00373 //
00374 //               If multiple cameras are viewing the character in any
00375 //               given frame, the closest one counts.
00376 ////////////////////////////////////////////////////////////////////
00377 void Character::
00378 set_lod_animation(const LPoint3 &center,
00379                   PN_stdfloat far_distance, PN_stdfloat near_distance,
00380                   PN_stdfloat delay_factor) {
00381   nassertv(far_distance >= near_distance);
00382   nassertv(delay_factor >= 0.0f);
00383   _lod_center = center;
00384   _lod_far_distance = far_distance;
00385   _lod_near_distance = near_distance;
00386   _lod_delay_factor = delay_factor;
00387   _do_lod_animation = (_lod_far_distance > _lod_near_distance && _lod_delay_factor > 0.0);
00388   if (!_do_lod_animation) {
00389     set_lod_current_delay(0.0);
00390   }
00391 }
00392 
00393 ////////////////////////////////////////////////////////////////////
00394 //     Function: Character::clear_lod_animation
00395 //       Access: Published
00396 //  Description: Undoes the effect of a recent call to
00397 //               set_lod_animation().  Henceforth, the character will
00398 //               animate every frame, regardless of its distance from
00399 //               the camera.
00400 ////////////////////////////////////////////////////////////////////
00401 void Character::
00402 clear_lod_animation() {
00403   _lod_center = LPoint3::zero();
00404   _lod_far_distance = 0.0f;
00405   _lod_near_distance = 0.0f;
00406   _lod_delay_factor = 0.0f;
00407   _do_lod_animation = false;
00408   set_lod_current_delay(0.0);
00409 }
00410 
00411 ////////////////////////////////////////////////////////////////////
00412 //     Function: Character::find_joint
00413 //       Access: Published
00414 //  Description: Returns a pointer to the joint with the given name,
00415 //               if there is such a joint, or NULL if there is no such
00416 //               joint.  This will not return a pointer to a slider.
00417 ////////////////////////////////////////////////////////////////////
00418 CharacterJoint *Character::
00419 find_joint(const string &name) const {
00420   int num_bundles = get_num_bundles();
00421   for (int i = 0; i < num_bundles; ++i) {
00422     PartGroup *part = get_bundle(i)->find_child(name);
00423     if (part != (PartGroup *)NULL &&
00424         part->is_of_type(CharacterJoint::get_class_type())) {
00425       return DCAST(CharacterJoint, part);
00426     }
00427   }
00428 
00429   return NULL;
00430 }
00431 
00432 ////////////////////////////////////////////////////////////////////
00433 //     Function: Character::find_slider
00434 //       Access: Published
00435 //  Description: Returns a pointer to the slider with the given name,
00436 //               if there is such a slider, or NULL if there is no such
00437 //               slider.  This will not return a pointer to a joint.
00438 ////////////////////////////////////////////////////////////////////
00439 CharacterSlider *Character::
00440 find_slider(const string &name) const {
00441   int num_bundles = get_num_bundles();
00442   for (int i = 0; i < num_bundles; ++i) {
00443     PartGroup *part = get_bundle(i)->find_child(name);
00444     if (part != (PartGroup *)NULL &&
00445         part->is_of_type(CharacterSlider::get_class_type())) {
00446       return DCAST(CharacterSlider, part);
00447     }
00448   }
00449 
00450   return NULL;
00451 }
00452 
00453 ////////////////////////////////////////////////////////////////////
00454 //     Function: Character::write_parts
00455 //       Access: Published
00456 //  Description: Writes a list of the Character's joints and sliders,
00457 //               in their hierchical structure, to the indicated
00458 //               output stream.
00459 ////////////////////////////////////////////////////////////////////
00460 void Character::
00461 write_parts(ostream &out) const {
00462   int num_bundles = get_num_bundles();
00463   for (int i = 0; i < num_bundles; ++i) {
00464     get_bundle(i)->write(out, 0);
00465   }
00466 }
00467 
00468 ////////////////////////////////////////////////////////////////////
00469 //     Function: Character::write_part_values
00470 //       Access: Published
00471 //  Description: Writes a list of the Character's joints and sliders,
00472 //               along with each current position, in their hierchical
00473 //               structure, to the indicated output stream.
00474 ////////////////////////////////////////////////////////////////////
00475 void Character::
00476 write_part_values(ostream &out) const {
00477   int num_bundles = get_num_bundles();
00478   for (int i = 0; i < num_bundles; ++i) {
00479     get_bundle(i)->write_with_value(out, 0);
00480   }
00481 }
00482 
00483 ////////////////////////////////////////////////////////////////////
00484 //     Function: Character::update_to_now
00485 //       Access: Published
00486 //  Description: Advances the character's frame to the current time,
00487 //               and then calls update().  This can be used by show
00488 //               code to force an update of the character's position
00489 //               to the current frame, regardless of whether the
00490 //               character is currently onscreen and animating.
00491 //
00492 //               This method is deprecated.  Call update() instead.
00493 ////////////////////////////////////////////////////////////////////
00494 void Character::
00495 update_to_now() {
00496   update();
00497 }
00498 
00499 ////////////////////////////////////////////////////////////////////
00500 //     Function: Character::update
00501 //       Access: Published
00502 //  Description: Recalculates the Character's joints and vertices for
00503 //               the current frame.  Normally this is performed
00504 //               automatically during the render and need not be
00505 //               called explicitly.
00506 ////////////////////////////////////////////////////////////////////
00507 void Character::
00508 update() {
00509   double now = ClockObject::get_global_clock()->get_frame_time();
00510   if (now != _last_auto_update) {
00511     _last_auto_update = now;
00512 
00513     if (char_cat.is_spam()) {
00514       char_cat.spam() 
00515         << "Animating " << NodePath::any_path(this)
00516         << " at time " << now << "\n";
00517     }
00518     
00519     PStatTimer timer(_joints_pcollector);
00520     do_update();
00521   }
00522 }
00523 
00524 ////////////////////////////////////////////////////////////////////
00525 //     Function: Character::force_update
00526 //       Access: Published
00527 //  Description: Recalculates the character even if we think it
00528 //               doesn't need it.
00529 ////////////////////////////////////////////////////////////////////
00530 void Character::
00531 force_update() {
00532   // Statistics
00533   PStatTimer timer(_joints_pcollector);
00534 
00535   // Update all the joints and sliders.
00536   int num_bundles = get_num_bundles();
00537   for (int i = 0; i < num_bundles; ++i) {
00538     get_bundle(i)->force_update();
00539   }
00540 }
00541 
00542 ////////////////////////////////////////////////////////////////////
00543 //     Function: Character::r_copy_children
00544 //       Access: Protected, Virtual
00545 //  Description: This is called by r_copy_subgraph(); the copy has
00546 //               already been made of this particular node (and this
00547 //               is the copy); this function's job is to copy all of
00548 //               the children from the original.
00549 //
00550 //               Note that it includes the parameter inst_map, which
00551 //               is a map type, and is not (and cannot be) exported
00552 //               from PANDA.DLL.  Thus, any derivative of PandaNode
00553 //               that is not also a member of PANDA.DLL *cannot*
00554 //               access this map, and probably should not even
00555 //               override this function.
00556 ////////////////////////////////////////////////////////////////////
00557 void Character::
00558 r_copy_children(const PandaNode *from, PandaNode::InstanceMap &inst_map,
00559                 Thread *current_thread) {
00560   // We assume there will be no instancing going on below the
00561   // Character node.  If there is, too bad; it will get flattened out.
00562 
00563   // We preempt the node's r_copy_children() operation with our own
00564   // function that keeps track of the old vs. new nodes and also
00565   // updates any Geoms we find with our new dynamic vertices.
00566 
00567   const Character *from_char;
00568   DCAST_INTO_V(from_char, from);
00569   NodeMap node_map;
00570   JointMap joint_map;
00571 
00572   int num_bundles = get_num_bundles();
00573   nassertv(from_char->get_num_bundles() == num_bundles);
00574   int i;
00575   for (i = 0; i < num_bundles; ++i) {
00576     fill_joint_map(joint_map, get_bundle(i), from_char->get_bundle(i));
00577   }
00578 
00579   GeomVertexMap gvmap;
00580   GeomJointMap gjmap;
00581   GeomSliderMap gsmap;
00582   r_copy_char(this, from_char, from_char, node_map, joint_map, 
00583               gvmap, gjmap, gsmap);
00584 
00585   for (i = 0; i < num_bundles; ++i) {
00586     copy_node_pointers(node_map, get_bundle(i), from_char->get_bundle(i));
00587   }
00588 }
00589 
00590 ////////////////////////////////////////////////////////////////////
00591 //     Function: Character::update_bundle
00592 //       Access: Protected, Virtual
00593 //  Description: Replaces the contents of the indicated
00594 //               PartBundleHandle (presumably stored within this node)
00595 //               with new_bundle.
00596 ////////////////////////////////////////////////////////////////////
00597 void Character::
00598 update_bundle(PartBundleHandle *old_bundle_handle, PartBundle *new_bundle) {
00599   if (old_bundle_handle->get_bundle() == new_bundle) {
00600     // Trivially return.
00601     return;
00602   }
00603 
00604   // First, merge the bundles, to ensure we have the same set of
00605   // joints in the new bundle.
00606   JointMap joint_map;
00607   r_merge_bundles(joint_map, old_bundle_handle->get_bundle(), new_bundle);
00608 
00609   PartBundleNode::update_bundle(old_bundle_handle, new_bundle);
00610 
00611   // Now convert the geometry to use the new bundle.
00612   GeomVertexMap gvmap;
00613   GeomJointMap gjmap;
00614   GeomSliderMap gsmap;
00615   r_update_geom(this, joint_map, gvmap, gjmap, gsmap);
00616 }
00617 
00618 ////////////////////////////////////////////////////////////////////
00619 //     Function: Character::get_rel_transform
00620 //       Access: Protected
00621 //  Description: Returns the relative transform to convert from the
00622 //               LODNode space to the camera space.
00623 ////////////////////////////////////////////////////////////////////
00624 CPT(TransformState) Character::
00625 get_rel_transform(CullTraverser *trav, CullTraverserData &data) {
00626   // Get a pointer to the camera node.
00627   Camera *camera = trav->get_scene()->get_camera_node();
00628   
00629   // Get the camera space transform.
00630   CPT(TransformState) rel_transform;
00631 
00632   NodePath lod_center = camera->get_lod_center();
00633   if (!lod_center.is_empty()) {
00634     rel_transform = 
00635       lod_center.get_net_transform()->invert_compose(data.get_net_transform(trav));
00636   } else {
00637     NodePath cull_center = camera->get_cull_center();
00638     if (!cull_center.is_empty()) {
00639       rel_transform = 
00640         cull_center.get_net_transform()->invert_compose(data.get_net_transform(trav));
00641     } else {
00642       rel_transform = data.get_modelview_transform(trav);
00643     }
00644   }
00645 
00646   return rel_transform;
00647 }
00648 
00649 ////////////////////////////////////////////////////////////////////
00650 //     Function: Character::do_update
00651 //       Access: Private
00652 //  Description: The actual implementation of update().  Assumes the
00653 //               appropriate PStatCollector has already been started.
00654 ////////////////////////////////////////////////////////////////////
00655 void Character::
00656 do_update() {
00657   // Update all the joints and sliders.
00658   if (even_animation) {
00659     int num_bundles = get_num_bundles();
00660     for (int i = 0; i < num_bundles; ++i) {
00661       get_bundle(i)->force_update();
00662     }
00663   } else {
00664     int num_bundles = get_num_bundles();
00665     for (int i = 0; i < num_bundles; ++i) {
00666       get_bundle(i)->update();
00667     }
00668   }
00669 }
00670 
00671 ////////////////////////////////////////////////////////////////////
00672 //     Function: Character::set_lod_current_delay
00673 //       Access: Private
00674 //  Description: Changes the amount of delay we should impose due to
00675 //               the LOD animation setting.
00676 ////////////////////////////////////////////////////////////////////
00677 void Character::
00678 set_lod_current_delay(double delay) {
00679   int num_bundles = get_num_bundles();
00680   for (int i = 0; i < num_bundles; ++i) {
00681     get_bundle(i)->set_update_delay(delay);
00682   }
00683 }
00684 
00685 ////////////////////////////////////////////////////////////////////
00686 //     Function: Character::fill_joint_map
00687 //       Access: Private
00688 //  Description: After the joint hierarchy has already been copied
00689 //               from the indicated hierarchy, this recursively walks
00690 //               through the joints and builds up a mapping from old
00691 //               to new.
00692 ////////////////////////////////////////////////////////////////////
00693 void Character::
00694 fill_joint_map(Character::JointMap &joint_map, 
00695                PartGroup *copy, PartGroup *orig) {
00696   joint_map[orig] = copy;
00697 
00698   int i = 0, j = 0;
00699   int copy_num_children = copy->get_num_children();
00700   int orig_num_children = orig->get_num_children();
00701 
00702   while (i < copy_num_children && j < orig_num_children) {
00703     PartGroup *pc = copy->get_child(i);
00704     PartGroup *ac = orig->get_child(j);
00705 
00706     if (pc->get_name() < ac->get_name()) {
00707       i++;
00708     } else if (ac->get_name() < pc->get_name()) {
00709       j++;
00710     } else {
00711       fill_joint_map(joint_map, pc, ac);
00712       i++;
00713       j++;
00714     }
00715   }
00716 }
00717 
00718 ////////////////////////////////////////////////////////////////////
00719 //     Function: Character::r_merge_bundles
00720 //       Access: Private
00721 //  Description: Recursively checks the two bundles for a matching
00722 //               hierarchy, and adds nodes as necessary to "new_group"
00723 //               where they are not already present.  Also fills
00724 //               joint_map in the same manner as fill_joint_map().
00725 ////////////////////////////////////////////////////////////////////
00726 void Character::
00727 r_merge_bundles(Character::JointMap &joint_map, 
00728                 PartGroup *old_group, PartGroup *new_group) {
00729   joint_map[old_group] = new_group;
00730 
00731   if (new_group->is_of_type(CharacterJoint::get_class_type())) {
00732     CharacterJoint *new_joint;
00733     DCAST_INTO_V(new_joint, new_group);
00734 
00735     // Make sure the new_joint references this as its new character.
00736     new_joint->_character = this;
00737 
00738     if (old_group != new_group &&
00739         old_group->is_of_type(CharacterJoint::get_class_type())) {
00740       CharacterJoint *old_joint;
00741       DCAST_INTO_V(old_joint, old_group);
00742 
00743       // Since the old_joint will be getting dropped, reset its
00744       // character reference.
00745       old_joint->_character = NULL;
00746 
00747       // Copy any _net_transform and _local_transform operations to the
00748       // new joint.
00749       CharacterJoint::NodeList::iterator ni;
00750       for (ni = old_joint->_net_transform_nodes.begin();
00751            ni != old_joint->_net_transform_nodes.end();
00752            ++ni) {
00753         new_joint->_net_transform_nodes.insert(*ni);
00754       }
00755       for (ni = old_joint->_local_transform_nodes.begin();
00756            ni != old_joint->_local_transform_nodes.end();
00757            ++ni) {
00758         new_joint->_local_transform_nodes.insert(*ni);
00759       }
00760     }
00761   }
00762 
00763   if (old_group == new_group) {
00764     return;
00765   }
00766     
00767   int i = 0, j = 0;
00768   int old_num_children = old_group->get_num_children();
00769   int new_num_children = new_group->get_num_children();
00770 
00771   PartGroup::Children new_children(PartGroup::get_class_type());
00772   new_children.reserve(max(old_num_children, new_num_children));
00773 
00774   while (i < old_num_children && j < new_num_children) {
00775     PartGroup *pc = old_group->get_child(i);
00776     PartGroup *ac = new_group->get_child(j);
00777 
00778     if (pc->get_name() < ac->get_name()) {
00779       // Here is a group that exists in old_group, but not in
00780       // new_group.  Duplicate it.
00781       PartGroup *new_pc = pc->make_copy();
00782       new_children.push_back(new_pc);
00783 
00784       r_merge_bundles(joint_map, pc, new_pc);
00785       i++;
00786 
00787     } else if (ac->get_name() < pc->get_name()) {
00788       // Here is a group that exists in new_group, but not in
00789       // old_group.  Preserve it.
00790       new_children.push_back(ac);
00791 
00792       r_merge_bundles(joint_map, ac, ac);
00793       j++;
00794 
00795     } else {
00796       // Here is a group that exists in both.  Preserve it.
00797       new_children.push_back(ac);
00798 
00799       r_merge_bundles(joint_map, pc, ac);
00800       i++;
00801       j++;
00802     }
00803   }
00804 
00805   while (i < old_num_children) {
00806     PartGroup *pc = old_group->get_child(i);
00807 
00808     // Here is a group that exists in old_group, but not in
00809     // new_group.  Duplicate it.
00810     PartGroup *new_pc = pc->make_copy();
00811     new_children.push_back(new_pc);
00812     
00813     r_merge_bundles(joint_map, pc, new_pc);
00814     i++;
00815   }
00816 
00817   while (j < new_num_children) {
00818     PartGroup *ac = new_group->get_child(j);
00819 
00820     // Here is a group that exists in new_group, but not in
00821     // old_group.  Preserve it.
00822     new_children.push_back(ac);
00823 
00824     r_merge_bundles(joint_map, ac, ac);
00825     j++;
00826   }
00827 
00828   new_group->_children.swap(new_children);
00829 }
00830 
00831 
00832 ////////////////////////////////////////////////////////////////////
00833 //     Function: Character::r_copy_char
00834 //       Access: Private
00835 //  Description: Recursively walks the scene graph hierarchy below the
00836 //               Character node, duplicating it while noting the
00837 //               orig:copy node mappings, and also updates any
00838 //               GeomNodes found.
00839 ////////////////////////////////////////////////////////////////////
00840 void Character::
00841 r_copy_char(PandaNode *dest, const PandaNode *source,
00842             const Character *from, Character::NodeMap &node_map,
00843             const Character::JointMap &joint_map,
00844             Character::GeomVertexMap &gvmap,
00845             Character::GeomJointMap &gjmap, Character::GeomSliderMap &gsmap) {
00846 
00847   if (source->is_geom_node()) {
00848     const GeomNode *source_gnode;
00849     GeomNode *dest_gnode;
00850     DCAST_INTO_V(source_gnode, source);
00851     DCAST_INTO_V(dest_gnode, dest);
00852 
00853     dest_gnode->remove_all_geoms();
00854     int num_geoms = source_gnode->get_num_geoms();
00855     for (int i = 0; i < num_geoms; i++) {
00856       const Geom *geom = source_gnode->get_geom(i);
00857       const RenderState *state = source_gnode->get_geom_state(i);
00858       dest_gnode->add_geom(copy_geom(geom, joint_map, gvmap, gjmap, gsmap), state);
00859     }
00860   }
00861 
00862   int num_children = source->get_num_children();
00863   for (int i = 0; i < num_children; i++) {
00864     const PandaNode *source_child = source->get_child(i);
00865     int source_sort = source->get_child_sort(i);
00866 
00867     PT(PandaNode) dest_child;
00868     if (source_child->is_of_type(Character::get_class_type())) {
00869       // We make a special case for nodes of type Character.  If we
00870       // encounter one of these, we have a Character under a
00871       // Character, and the nested Character's copy should be called
00872       // instead of ours.
00873       dest_child = source_child->copy_subgraph();
00874 
00875     } else {
00876       // Otherwise, we assume that make_copy() will make a suitable
00877       // copy of the node.  This does limit the sorts of things we can
00878       // have parented to a Character and expect copy_subgraph() to
00879       // work correctly.  Too bad.
00880       dest_child = source_child->make_copy();
00881       r_copy_char(dest_child, source_child, from, node_map, joint_map,
00882                   gvmap, gjmap, gsmap);
00883     }
00884     dest->add_child(dest_child, source_sort);
00885     node_map[source_child] = dest_child;
00886   }
00887 }
00888 
00889 ////////////////////////////////////////////////////////////////////
00890 //     Function: Character::r_update_geom
00891 //       Access: Private
00892 //  Description: Walks the hierarchy, updating any GeomNodes in-place
00893 //               to reference the new animation tables within this
00894 //               Character.
00895 ////////////////////////////////////////////////////////////////////
00896 void Character::
00897 r_update_geom(PandaNode *node, const Character::JointMap &joint_map,
00898               Character::GeomVertexMap &gvmap,
00899               Character::GeomJointMap &gjmap, 
00900               Character::GeomSliderMap &gsmap) {
00901   if (node->is_geom_node()) {
00902     GeomNode *gnode;
00903     DCAST_INTO_V(gnode, node);
00904 
00905     int num_geoms = gnode->get_num_geoms();
00906     for (int i = 0; i < num_geoms; i++) {
00907       CPT(Geom) geom = gnode->get_geom(i);
00908       PT(Geom) new_geom = copy_geom(geom, joint_map, gvmap, gjmap, gsmap);
00909       gnode->set_geom(i, new_geom);
00910     }
00911   }
00912 
00913   int num_children = node->get_num_children();
00914   for (int i = 0; i < num_children; i++) {
00915     PandaNode *child = node->get_child(i);
00916 
00917     r_update_geom(child, joint_map, gvmap, gjmap, gsmap);
00918   }
00919 }
00920 
00921 ////////////////////////////////////////////////////////////////////
00922 //     Function: Character::copy_geom
00923 //       Access: Private
00924 //  Description: Makes a new copy of the Geom with the dynamic vertex
00925 //               arrays replaced to reference this Character instead
00926 //               of the other one.  If no arrays have changed, simply
00927 //               returns the same Geom.
00928 ////////////////////////////////////////////////////////////////////
00929 PT(Geom) Character::
00930 copy_geom(const Geom *source, const Character::JointMap &joint_map,
00931           Character::GeomVertexMap &gvmap, Character::GeomJointMap &gjmap, 
00932           Character::GeomSliderMap &gsmap) {
00933   CPT(GeomVertexFormat) format = source->get_vertex_data()->get_format();
00934   if (format->get_animation().get_animation_type() == Geom::AT_none) {
00935     // Not animated, so never mind.
00936     return (Geom *)source;
00937   }
00938   
00939   PT(Geom) dest = source->make_copy();
00940   
00941   CPT(GeomVertexData) orig_vdata = source->get_vertex_data();
00942   PT(GeomVertexData) new_vdata;
00943   GeomVertexMap::iterator gvmi = gvmap.find(orig_vdata);
00944   if (gvmi != gvmap.end()) {
00945     new_vdata = (*gvmi).second;
00946   } else {
00947     new_vdata = new GeomVertexData(*orig_vdata);
00948 
00949     new_vdata->set_transform_table(redirect_transform_table(orig_vdata->get_transform_table(), joint_map, gjmap));
00950     new_vdata->set_transform_blend_table(redirect_transform_blend_table(orig_vdata->get_transform_blend_table(), joint_map, gjmap));
00951     new_vdata->set_slider_table(redirect_slider_table(orig_vdata->get_slider_table(), gsmap));
00952 
00953     gvmap.insert(GeomVertexMap::value_type(orig_vdata, new_vdata));
00954   }  
00955 
00956   dest->set_vertex_data(new_vdata);
00957   
00958   return dest;
00959 }
00960 
00961 ////////////////////////////////////////////////////////////////////
00962 //     Function: Character::copy_node_pointers
00963 //       Access: Public
00964 //  Description: Creates _net_transform_nodes and _local_transform_nodes
00965 //               as appropriate in each of the Character's joints, as
00966 //               copied from the other Character.
00967 ////////////////////////////////////////////////////////////////////
00968 void Character::
00969 copy_node_pointers(const Character::NodeMap &node_map,
00970                    PartGroup *dest, const PartGroup *source) {
00971   if (dest->is_of_type(CharacterJoint::get_class_type())) {
00972     nassertv(dest != source);
00973     const CharacterJoint *source_joint;
00974     CharacterJoint *dest_joint;
00975     DCAST_INTO_V(source_joint, source);
00976     DCAST_INTO_V(dest_joint, dest);
00977     
00978     CharacterJoint::NodeList::const_iterator ai;
00979     for (ai = source_joint->_net_transform_nodes.begin();
00980          ai != source_joint->_net_transform_nodes.end();
00981          ++ai) {
00982       PandaNode *source_node = (*ai);
00983       
00984       NodeMap::const_iterator mi;
00985       mi = node_map.find(source_node);
00986       if (mi != node_map.end()) {
00987         PandaNode *dest_node = (*mi).second;
00988         
00989         // Here's an internal joint that the source Character was
00990         // animating directly.  We'll animate our corresponding
00991         // joint the same way.
00992         dest_joint->set_character(this);
00993         dest_joint->add_net_transform(dest_node);
00994       }
00995     }
00996     
00997     for (ai = source_joint->_local_transform_nodes.begin();
00998          ai != source_joint->_local_transform_nodes.end();
00999          ++ai) {
01000       PandaNode *source_node = (*ai);
01001       
01002       NodeMap::const_iterator mi;
01003       mi = node_map.find(source_node);
01004       if (mi != node_map.end()) {
01005         PandaNode *dest_node = (*mi).second;
01006         
01007         // Here's an internal joint that the source Character was
01008         // animating directly.  We'll animate our corresponding
01009         // joint the same way.
01010         dest_joint->set_character(this);
01011         dest_joint->add_local_transform(dest_node);
01012       }
01013     }
01014   }
01015 
01016   // Now recurse over children.
01017   int i = 0, j = 0;
01018   int dest_num_children = dest->get_num_children();
01019   int source_num_children = source->get_num_children();
01020 
01021   while (i < dest_num_children && j < source_num_children) {
01022     PartGroup *pc = dest->get_child(i);
01023     PartGroup *ac = source->get_child(j);
01024 
01025     if (pc->get_name() < ac->get_name()) {
01026       i++;
01027     } else if (ac->get_name() < pc->get_name()) {
01028       j++;
01029     } else {
01030       copy_node_pointers(node_map, pc, ac);
01031       i++;
01032       j++;
01033     }
01034   }
01035 }
01036 
01037 ////////////////////////////////////////////////////////////////////
01038 //     Function: Character::redirect_transform_table
01039 //       Access: Private
01040 //  Description: Creates a new TransformTable, similar to the
01041 //               indicated one, with the joint and slider pointers
01042 //               redirected into this object.
01043 ////////////////////////////////////////////////////////////////////
01044 CPT(TransformTable) Character::
01045 redirect_transform_table(const TransformTable *source,
01046                          const Character::JointMap &joint_map,
01047                          Character::GeomJointMap &gjmap) {
01048   if (source == (TransformTable *)NULL) {
01049     return NULL;
01050   }
01051 
01052   PT(TransformTable) dest = new TransformTable(*source);
01053 
01054   int num_transforms = dest->get_num_transforms();
01055   for (int i = 0; i < num_transforms; ++i) {
01056     const VertexTransform *vt = dest->get_transform(i);
01057     PT(JointVertexTransform) new_jvt = redirect_joint(vt, joint_map, gjmap);
01058     if (new_jvt != (JointVertexTransform *)NULL) {
01059       dest->set_transform(i, new_jvt);
01060     }
01061   }
01062 
01063   return TransformTable::register_table(dest);
01064 }
01065 
01066 ////////////////////////////////////////////////////////////////////
01067 //     Function: Character::redirect_transform_blend_table
01068 //       Access: Private
01069 //  Description: Creates a new TransformBlendTable, similar to the
01070 //               indicated one, with the joint and slider pointers
01071 //               redirected into this object.
01072 ////////////////////////////////////////////////////////////////////
01073 CPT(TransformBlendTable) Character::
01074 redirect_transform_blend_table(const TransformBlendTable *source,
01075                                const Character::JointMap &joint_map,
01076                                Character::GeomJointMap &gjmap) {
01077   if (source == (TransformBlendTable *)NULL) {
01078     return NULL;
01079   }
01080 
01081   PT(TransformBlendTable) dest = new TransformBlendTable(*source);
01082 
01083   int num_blends = dest->get_num_blends();
01084   for (int i = 0; i < num_blends; ++i) {
01085     TransformBlend blend = dest->get_blend(i);
01086     int num_transforms = blend.get_num_transforms();
01087     for (int j = 0; j < num_transforms; ++j) {
01088       const VertexTransform *vt = blend.get_transform(j);
01089       PT(JointVertexTransform) new_jvt = redirect_joint(vt, joint_map, gjmap);
01090       if (new_jvt != (JointVertexTransform *)NULL) {
01091         blend.set_transform(j, new_jvt);
01092       }
01093     }
01094     dest->set_blend(i, blend);
01095   }
01096 
01097   return dest;
01098 }
01099 
01100 ////////////////////////////////////////////////////////////////////
01101 //     Function: Character::redirect_slider_table
01102 //       Access: Private
01103 //  Description: Creates a new SliderTable, similar to the
01104 //               indicated one, with the joint and slider pointers
01105 //               redirected into this object.
01106 ////////////////////////////////////////////////////////////////////
01107 CPT(SliderTable) Character::
01108 redirect_slider_table(const SliderTable *source,
01109                       Character::GeomSliderMap &gsmap) {
01110   if (source == (SliderTable *)NULL) {
01111     return NULL;
01112   }
01113 
01114   PT(SliderTable) dest = new SliderTable(*source);
01115 
01116   int num_sliders = dest->get_num_sliders();
01117   for (int i = 0; i < num_sliders; ++i) {
01118     const VertexSlider *vs = dest->get_slider(i);
01119     PT(CharacterVertexSlider) new_cvs = redirect_slider(vs, gsmap);
01120     if (new_cvs != (CharacterVertexSlider *)NULL) {
01121       dest->set_slider(i, new_cvs);
01122     }
01123   }
01124 
01125   return SliderTable::register_table(dest);
01126 }
01127 
01128 ////////////////////////////////////////////////////////////////////
01129 //     Function: Character::redirect_joint
01130 //       Access: Private
01131 //  Description: Creates a new JointVertexTransform that is similar to
01132 //               the indicated one, but points into this character.
01133 //               If one was already created (in the GeomJointMap), returns
01134 //               it instead.
01135 ////////////////////////////////////////////////////////////////////
01136 PT(JointVertexTransform) Character::
01137 redirect_joint(const VertexTransform *vt, 
01138                const Character::JointMap &joint_map,
01139                Character::GeomJointMap &gjmap) {
01140   GeomJointMap::iterator ji;
01141   ji = gjmap.find(vt);
01142   if (ji != gjmap.end()) {
01143     return (*ji).second;
01144   }
01145 
01146   PT(JointVertexTransform) new_jvt;
01147   
01148   if (vt->is_of_type(JointVertexTransform::get_class_type())) {
01149     const JointVertexTransform *jvt = DCAST(JointVertexTransform, vt);
01150     const CharacterJoint *orig_joint = jvt->get_joint();
01151     JointMap::const_iterator jmi = joint_map.find(orig_joint);
01152     if (jmi == joint_map.end()) {
01153       char_cat.error()
01154         << "Could not find joint " << *orig_joint
01155         << " within the character hierarchy.\n";
01156 
01157     } else {
01158       CharacterJoint *joint = DCAST(CharacterJoint, (*jmi).second);
01159       new_jvt = new JointVertexTransform(joint);
01160     }
01161   }
01162 
01163   gjmap[vt] = new_jvt;
01164   return new_jvt;
01165 }
01166 
01167 ////////////////////////////////////////////////////////////////////
01168 //     Function: Character::redirect_slider
01169 //       Access: Private
01170 //  Description: Creates a new CharacterVertexSlider that is similar to
01171 //               the indicated one, but points into this character.
01172 //               If one was already created (in the GeomSliderMap), returns
01173 //               it instead.
01174 ////////////////////////////////////////////////////////////////////
01175 PT(CharacterVertexSlider) Character::
01176 redirect_slider(const VertexSlider *vs, Character::GeomSliderMap &gsmap) {
01177   GeomSliderMap::iterator ji;
01178   ji = gsmap.find(vs);
01179   if (ji != gsmap.end()) {
01180     return (*ji).second;
01181   }
01182 
01183   PT(CharacterVertexSlider) new_cvs;
01184 
01185   if (vs->is_of_type(CharacterVertexSlider::get_class_type())) {
01186     const CharacterVertexSlider *cvs = DCAST(CharacterVertexSlider, vs);
01187     CharacterSlider *slider = find_slider(cvs->get_char_slider()->get_name());
01188     if (slider != (CharacterSlider *)NULL) {
01189       new_cvs = new CharacterVertexSlider(slider);
01190     }
01191   }
01192 
01193   gsmap[vs] = new_cvs;
01194   return new_cvs;
01195 }
01196 
01197 ////////////////////////////////////////////////////////////////////
01198 //     Function: Character::r_clear_joint_characters
01199 //       Access: Private
01200 //  Description: Recursively walks through the joint hierarchy and
01201 //               clears any _character pointers on all the joints.
01202 //               Intended to be called just before Character
01203 //               destruction.
01204 ////////////////////////////////////////////////////////////////////
01205 void Character::
01206 r_clear_joint_characters(PartGroup *part) {
01207   if (part->is_of_type(CharacterJoint::get_class_type())) {
01208     CharacterJoint *joint = DCAST(CharacterJoint, part);
01209 
01210     // It is possible for the joint to reference a different Character
01211     // here--after merge_bundles() has been called, a particular joint
01212     // will be listed within more than one Character node, but it can
01213     // only point back to one of them.
01214     if (joint->get_character() == this) {
01215       joint->set_character(NULL);
01216     }
01217   }
01218 
01219   int num_children = part->get_num_children();
01220   for (int i = 0; i < num_children; ++i) {
01221     PartGroup *child = part->get_child(i);
01222     r_clear_joint_characters(child);
01223   }
01224 }
01225 
01226 ////////////////////////////////////////////////////////////////////
01227 //     Function: Character::register_with_read_factory
01228 //       Access: Public, Static
01229 //  Description: Tells the BamReader how to create objects of type
01230 //               Character.
01231 ////////////////////////////////////////////////////////////////////
01232 void Character::
01233 register_with_read_factory() {
01234   BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
01235 }
01236 
01237 ////////////////////////////////////////////////////////////////////
01238 //     Function: Character::write_datagram
01239 //       Access: Public, Virtual
01240 //  Description: Writes the contents of this object to the datagram
01241 //               for shipping out to a Bam file.
01242 ////////////////////////////////////////////////////////////////////
01243 void Character::
01244 write_datagram(BamWriter *manager, Datagram &dg) {
01245   PartBundleNode::write_datagram(manager, dg);
01246 
01247   // Record 0 parts written--we no longer write an array of parts.
01248   dg.add_uint16(0);
01249 }
01250 
01251 ////////////////////////////////////////////////////////////////////
01252 //     Function: Character::complete_pointers
01253 //       Access: Public, Virtual
01254 //  Description: Receives an array of pointers, one for each time
01255 //               manager->read_pointer() was called in fillin().
01256 //               Returns the number of pointers processed.
01257 ////////////////////////////////////////////////////////////////////
01258 int Character::
01259 complete_pointers(TypedWritable **p_list, BamReader *manager) {
01260   // Pretend to read the _temp_num_parts parts that were found in the
01261   // bam file.
01262   return PartBundleNode::complete_pointers(p_list, manager) + _temp_num_parts;
01263 }
01264 
01265 ////////////////////////////////////////////////////////////////////
01266 //     Function: Character::make_from_bam
01267 //       Access: Protected, Static
01268 //  Description: This function is called by the BamReader's factory
01269 //               when a new object of type Character is encountered
01270 //               in the Bam file.  It should create the Character
01271 //               and extract its information from the file.
01272 ////////////////////////////////////////////////////////////////////
01273 TypedWritable *Character::
01274 make_from_bam(const FactoryParams &params) {
01275   Character *node = new Character("");
01276   DatagramIterator scan;
01277   BamReader *manager;
01278 
01279   parse_params(params, scan, manager);
01280   node->fillin(scan, manager);
01281 
01282   return node;
01283 }
01284 
01285 ////////////////////////////////////////////////////////////////////
01286 //     Function: Character::fillin
01287 //       Access: Protected
01288 //  Description: This internal function is called by make_from_bam to
01289 //               read in all of the relevant data from the BamFile for
01290 //               the new Character.
01291 ////////////////////////////////////////////////////////////////////
01292 void Character::
01293 fillin(DatagramIterator &scan, BamReader *manager) {
01294   PartBundleNode::fillin(scan, manager);
01295 
01296   // We no longer read an array of parts here, but for backward
01297   // compatibility, we must read in the number of parts that used to
01298   // be there, and read past each of the pointers.
01299   _temp_num_parts = scan.get_uint16();
01300   for (unsigned int i = 0; i < _temp_num_parts; i++) {
01301     manager->read_pointer(scan);
01302   }
01303 
01304 #ifdef DO_PSTATS
01305   // Reinitialize our collectors with our name, now that we know it.
01306   if (has_name()) {
01307     _joints_pcollector = 
01308       PStatCollector(PStatCollector(_animation_pcollector, get_name()), "Joints");
01309     _skinning_pcollector = 
01310       PStatCollector(PStatCollector(_animation_pcollector, get_name()), "Vertices");
01311   }
01312 #endif
01313 }
 All Classes Functions Variables Enumerations