Panda3D
|
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 ©, 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 ¢er, 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 ¶ms) { 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 }