39 Character(
const Character ©,
bool copy_bundles) :
41 _lod_center(copy._lod_center),
42 _lod_far_distance(copy._lod_far_distance),
43 _lod_near_distance(copy._lod_near_distance),
44 _lod_delay_factor(copy._lod_delay_factor),
45 _do_lod_animation(copy._do_lod_animation),
46 _joints_pcollector(copy._joints_pcollector),
47 _skinning_pcollector(copy._skinning_pcollector)
53 int num_bundles = copy.get_num_bundles();
54 for (
int i = 0; i < num_bundles; ++i) {
57 add_bundle(new_bundle);
61 int num_bundles = copy.get_num_bundles();
62 for (
int i = 0; i < num_bundles; ++i) {
64 add_bundle(orig_bundle);
67 _last_auto_update = -1.0;
69 _view_distance2 = 0.0f;
76 Character(
const std::string &name) :
78 _joints_pcollector(
PStatCollector(_animation_pcollector, name),
"Joints"),
79 _skinning_pcollector(
PStatCollector(_animation_pcollector, name),
"Vertices")
82 clear_lod_animation();
83 _last_auto_update = -1.0;
85 _view_distance2 = 0.0f;
93 int num_bundles = get_num_bundles();
94 for (
int i = 0; i < num_bundles; ++i) {
95 r_clear_joint_characters(get_bundle(i));
139 steal_bundles(c_other);
171 if (_do_lod_animation) {
174 CPT(
TransformState) rel_transform = get_rel_transform(trav, data);
175 LPoint3 center = _lod_center * rel_transform->get_mat();
176 PN_stdfloat dist2 = center.dot(center);
178 if (this_frame != _view_frame || dist2 < _view_distance2) {
179 _view_frame = this_frame;
180 _view_distance2 = dist2;
183 PN_stdfloat dist = sqrt(dist2);
185 if (dist > _lod_near_distance) {
186 delay = _lod_delay_factor * (dist - _lod_near_distance) / (_lod_far_distance - _lod_near_distance);
187 nassertr(delay > 0.0,
false);
189 set_lod_current_delay(delay);
191 if (char_cat.is_spam()) {
194 << this_frame <<
" is " << dist <<
", computed delay is " << delay
219 calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
bool &found_any,
231 for (
size_t i = 0; i < parents.get_num_parents(); ++i) {
233 parent->get_bounds();
236 return PandaNode::calc_tight_bounds(min_point, max_point,
237 found_any, transform, current_thread);
250 if (old_bundle == new_bundle) {
257 Bundles::const_iterator bi;
258 for (bi = _bundles.begin(); bi != _bundles.end(); ++bi) {
259 if ((*bi)->get_bundle() == old_bundle) {
260 old_bundle_handle = (*bi);
264 nassertv(!old_bundle_handle.is_null());
267 merge_bundles(old_bundle_handle, new_bundle_handle);
296 update_bundle(old_bundle_handle, new_bundle);
323 PN_stdfloat far_distance, PN_stdfloat near_distance,
324 PN_stdfloat delay_factor) {
325 nassertv(far_distance >= near_distance);
326 nassertv(delay_factor >= 0.0f);
327 _lod_center = center;
328 _lod_far_distance = far_distance;
329 _lod_near_distance = near_distance;
330 _lod_delay_factor = delay_factor;
331 _do_lod_animation = (_lod_far_distance > _lod_near_distance && _lod_delay_factor > 0.0);
332 if (!_do_lod_animation) {
333 set_lod_current_delay(0.0);
344 _lod_center = LPoint3::zero();
345 _lod_far_distance = 0.0f;
346 _lod_near_distance = 0.0f;
347 _lod_delay_factor = 0.0f;
348 _do_lod_animation =
false;
349 set_lod_current_delay(0.0);
359 int num_bundles = get_num_bundles();
360 for (
int i = 0; i < num_bundles; ++i) {
377 int num_bundles = get_num_bundles();
378 for (
int i = 0; i < num_bundles; ++i) {
380 if (part !=
nullptr &&
381 part->
is_of_type(CharacterSlider::get_class_type())) {
395 int num_bundles = get_num_bundles();
396 for (
int i = 0; i < num_bundles; ++i) {
397 get_bundle(i)->
write(out, 0);
408 int num_bundles = get_num_bundles();
409 for (
int i = 0; i < num_bundles; ++i) {
435 if (now != _last_auto_update) {
436 _last_auto_update = now;
438 if (char_cat.is_spam()) {
441 <<
" at time " << now <<
"\n";
458 int num_bundles = get_num_bundles();
459 for (
int i = 0; i < num_bundles; ++i) {
485 DCAST_INTO_V(from_char, from);
489 int num_bundles = get_num_bundles();
490 nassertv(from_char->get_num_bundles() == num_bundles);
492 for (i = 0; i < num_bundles; ++i) {
493 fill_joint_map(joint_map, get_bundle(i), from_char->get_bundle(i));
499 r_copy_char(
this, from_char, from_char, node_map, joint_map,
500 gvmap, gjmap, gsmap);
502 for (i = 0; i < num_bundles; ++i) {
503 copy_node_pointers(node_map, get_bundle(i), from_char->get_bundle(i));
513 if (old_bundle_handle->
get_bundle() == new_bundle) {
521 r_merge_bundles(joint_map, old_bundle_handle->
get_bundle(), new_bundle);
523 PartBundleNode::update_bundle(old_bundle_handle, new_bundle);
529 r_update_geom(
this, joint_map, gvmap, gjmap, gsmap);
547 lod_center.get_net_transform()->invert_compose(data.get_net_transform(trav));
552 cull_center.get_net_transform()->invert_compose(data.get_net_transform(trav));
554 rel_transform = data.get_modelview_transform(trav);
558 return rel_transform;
568 if (even_animation) {
569 int num_bundles = get_num_bundles();
570 for (
int i = 0; i < num_bundles; ++i) {
574 int num_bundles = get_num_bundles();
575 for (
int i = 0; i < num_bundles; ++i) {
586 set_lod_current_delay(
double delay) {
587 int num_bundles = get_num_bundles();
588 for (
int i = 0; i < num_bundles; ++i) {
601 joint_map[orig] = copy;
607 while (i < copy_num_children && j < orig_num_children) {
611 if (pc->get_name() < ac->get_name()) {
613 }
else if (ac->get_name() < pc->get_name()) {
616 fill_joint_map(joint_map, pc, ac);
631 joint_map[old_group] = new_group;
635 DCAST_INTO_V(new_joint, new_group);
638 new_joint->_character =
this;
640 if (old_group != new_group &&
643 DCAST_INTO_V(old_joint, old_group);
647 old_joint->_character =
nullptr;
651 CharacterJoint::NodeList::iterator ni;
652 for (ni = old_joint->_net_transform_nodes.
begin();
653 ni != old_joint->_net_transform_nodes.
end();
655 new_joint->_net_transform_nodes.insert(*ni);
657 for (ni = old_joint->_local_transform_nodes.
begin();
658 ni != old_joint->_local_transform_nodes.
end();
660 new_joint->_local_transform_nodes.insert(*ni);
665 if (old_group == new_group) {
674 new_children.reserve(std::max(old_num_children, new_num_children));
676 while (i < old_num_children && j < new_num_children) {
680 if (pc->get_name() < ac->get_name()) {
684 new_children.push_back(new_pc);
686 r_merge_bundles(joint_map, pc, new_pc);
689 }
else if (ac->get_name() < pc->get_name()) {
692 new_children.push_back(ac);
694 r_merge_bundles(joint_map, ac, ac);
699 new_children.push_back(ac);
701 r_merge_bundles(joint_map, pc, ac);
707 while (i < old_num_children) {
713 new_children.push_back(new_pc);
715 r_merge_bundles(joint_map, pc, new_pc);
719 while (j < new_num_children) {
724 new_children.push_back(ac);
726 r_merge_bundles(joint_map, ac, ac);
730 new_group->_children.swap(new_children);
749 DCAST_INTO_V(source_gnode, source);
750 DCAST_INTO_V(dest_gnode, dest);
754 for (
int i = 0; i < num_geoms; i++) {
755 const Geom *geom = source_gnode->get_geom(i);
757 dest_gnode->
add_geom(copy_geom(geom, joint_map, gvmap, gjmap, gsmap), state);
762 for (
int i = 0; i < num_children; i++) {
767 if (source_child->
is_of_type(Character::get_class_type())) {
771 dest_child = source_child->copy_subgraph();
779 r_copy_char(dest_child, source_child, from, node_map, joint_map,
780 gvmap, gjmap, gsmap);
782 dest->add_child(dest_child, source_sort);
783 node_map[source_child] = dest_child;
798 DCAST_INTO_V(gnode, node);
801 for (
int i = 0; i < num_geoms; i++) {
802 CPT(
Geom) geom = gnode->get_geom(i);
803 PT(
Geom) new_geom = copy_geom(geom, joint_map, gvmap, gjmap, gsmap);
809 for (
int i = 0; i < num_children; i++) {
812 r_update_geom(child, joint_map, gvmap, gjmap, gsmap);
826 if (format->get_animation().get_animation_type() == Geom::AT_none) {
828 return (
Geom *)source;
835 GeomVertexMap::iterator gvmi = gvmap.find(orig_vdata);
836 if (gvmi != gvmap.end()) {
837 new_vdata = (*gvmi).second;
841 new_vdata->set_transform_table(redirect_transform_table(orig_vdata->get_transform_table(), joint_map, gjmap));
842 new_vdata->set_transform_blend_table(redirect_transform_blend_table(orig_vdata->get_transform_blend_table(), joint_map, gjmap));
843 new_vdata->set_slider_table(redirect_slider_table(orig_vdata->get_slider_table(), gsmap));
845 gvmap.insert(GeomVertexMap::value_type(orig_vdata, new_vdata));
848 dest->set_vertex_data(new_vdata);
861 nassertv(dest != source);
864 DCAST_INTO_V(source_joint, source);
865 DCAST_INTO_V(dest_joint, dest);
867 CharacterJoint::NodeList::const_iterator ai;
868 for (ai = source_joint->_net_transform_nodes.
begin();
869 ai != source_joint->_net_transform_nodes.
end();
873 NodeMap::const_iterator mi;
874 mi = node_map.find(source_node);
875 if (mi != node_map.end()) {
880 dest_joint->set_character(
this);
885 for (ai = source_joint->_local_transform_nodes.
begin();
886 ai != source_joint->_local_transform_nodes.
end();
890 NodeMap::const_iterator mi;
891 mi = node_map.find(source_node);
892 if (mi != node_map.end()) {
897 dest_joint->set_character(
this);
908 while (i < dest_num_children && j < source_num_children) {
912 if (pc->get_name() < ac->get_name()) {
914 }
else if (ac->get_name() < pc->get_name()) {
917 copy_node_pointers(node_map, pc, ac);
932 if (source ==
nullptr) {
938 int num_transforms = dest->get_num_transforms();
939 for (
int i = 0; i < num_transforms; ++i) {
942 if (new_jvt !=
nullptr) {
943 dest->set_transform(i, new_jvt);
947 return TransformTable::register_table(dest);
958 if (source ==
nullptr) {
964 int num_blends = dest->get_num_blends();
965 for (
int i = 0; i < num_blends; ++i) {
968 for (
int j = 0; j < num_transforms; ++j) {
971 if (new_jvt !=
nullptr) {
975 dest->set_blend(i, blend);
988 if (source ==
nullptr) {
994 int num_sliders = dest->get_num_sliders();
995 for (
int i = 0; i < num_sliders; ++i) {
998 if (new_cvs !=
nullptr) {
999 dest->set_slider(i, new_cvs);
1003 return SliderTable::register_table(dest);
1015 GeomJointMap::iterator ji;
1016 ji = gjmap.find(vt);
1017 if (ji != gjmap.end()) {
1018 return (*ji).second;
1023 if (vt->
is_of_type(JointVertexTransform::get_class_type())) {
1026 JointMap::const_iterator jmi = joint_map.find(orig_joint);
1027 if (jmi == joint_map.end()) {
1029 <<
"Could not find joint " << *orig_joint
1030 <<
" within the character hierarchy.\n";
1038 gjmap[vt] = new_jvt;
1049 GeomSliderMap::iterator ji;
1050 ji = gsmap.find(vs);
1051 if (ji != gsmap.end()) {
1052 return (*ji).second;
1057 if (vs->
is_of_type(CharacterVertexSlider::get_class_type())) {
1060 if (slider !=
nullptr) {
1065 gsmap[vs] = new_cvs;
1075 r_clear_joint_characters(
PartGroup *part) {
1083 if (joint->get_character() ==
this) {
1084 joint->set_character(
nullptr);
1089 for (
int i = 0; i < num_children; ++i) {
1091 r_clear_joint_characters(child);
1138 node->fillin(scan, manager);
1149 PartBundleNode::fillin(scan, manager);
1155 for (
unsigned int i = 0; i < _temp_num_parts; i++) {
1162 _joints_pcollector =
1164 _skinning_pcollector =
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_geom_state
Returns the RenderState associated with the nth geom of the node.
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
void set_geom(int n, Geom *geom)
Replaces the nth Geom of the node with a new pointer.
A basic node of the scene graph or data graph.
const CharacterSlider * get_char_slider() const
Returns the CharacterSlider object for which this object returns the slider value.
bool is_exact_type(TypeHandle handle) const
Returns true if the current object is the indicated type exactly.
This is our own Panda specialization on the default STL map.
CharacterJoint * find_joint(const std::string &name) const
Returns a pointer to the joint with the given name, if there is such a joint, or NULL if there is no ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
The collection of all the joints and sliders in the character.
virtual PandaNode * dupe_for_flatten() const
This is similar to make_copy(), but it makes a copy for the specific purpose of flatten.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
void update()
Recalculates the Character's joints and vertices for the current frame.
virtual PandaNode * combine_with(PandaNode *other)
Collapses this PandaNode with the other PandaNode, if possible, and returns a pointer to the combined...
An animated character, with skeleton-morph animation and either soft- skinned or hard-skinned vertice...
bool is_empty() const
Returns true if the NodePath contains no nodes.
CharacterSlider * find_slider(const std::string &name) const
Returns a pointer to the slider with the given name, if there is such a slider, or NULL if there is n...
virtual PandaNode * combine_with(PandaNode *other)
Collapses this node with the other node, if possible, and returns a pointer to the combined node,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Base class for objects that can be written to and read from Bam files.
iterator_0 begin()
Returns the iterator that marks the first element in the ordered vector.
virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data)
This function will be called during the cull traversal to perform any additional operations that shou...
This collects together the pieces of data that are accumulated for each node while walking the scene ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is a specialization on VertexSlider that returns the slider value associated with a particular C...
This is an abstract base class that retains some slider value, which is a linear value that typically...
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool add_net_transform(PandaNode *node)
Adds the indicated node to the list of nodes that will be updated each frame with the joint's net tra...
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
This is a morph slider within the character.
iterator_0 end()
Returns the iterator that marks the end of the ordered vector.
get_num_children
Returns the number of child nodes of the group.
get_lod_center
Returns the point from which the LOD distances will be measured, if it was set by set_lod_center(),...
This is a trivial class returned by PartBundleNode::get_bundle().
void update_to_now()
Advances the character's frame to the current time, and then calls update().
bool force_update()
Updates all the parts in the bundle to reflect the data for the current frame, whether we believe it ...
get_parents
Returns an object that can be used to walk through the list of parents of the node,...
static NodePath any_path(PandaNode *node, Thread *current_thread=Thread::get_current_thread())
Returns a new NodePath that represents any arbitrary path from the root to the indicated node.
virtual int complete_pointers(TypedWritable **plist, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin().
get_bundle
Returns the actual PartBundle embedded within the handle.
bool add_local_transform(PandaNode *node)
Adds the indicated node to the list of nodes that will be updated each frame with the joint's local t...
PartGroup * find_child(const std::string &name) const
Returns the first descendant found with the indicated name, or NULL if no such descendant exists.
A lightweight class that represents a single element that may be timed and/or counted via stats.
virtual void write(std::ostream &out, int indent_level) const
Writes a brief description of the bundle and all of its descendants.
Stores the total set of VertexSliders that the vertices in a particular GeomVertexData object might d...
void parse_params(const FactoryParams ¶ms, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
void add_uint16(uint16_t value)
Adds an unsigned 16-bit integer to the datagram.
get_num_children
Returns the number of child nodes this node has.
CPT(TransformState) Character
This is used to support NodePath::calc_tight_bounds().
get_frame_time
Returns the time in seconds as of the last time tick() was called (typically, this will be as of the ...
get_frame_count
Returns the number of times tick() has been called since the ClockObject was created,...
virtual Geom * make_copy() const
Returns a newly-allocated Geom that is a shallow copy of this one.
This is a node that contains a pointer to an PartBundle.
virtual void write_with_value(std::ostream &out, int indent_level) const
Writes a brief description of the group, showing its current value, and that of all of its descendant...
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A container for geometry primitives.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void register_factory(TypeHandle handle, CreateFunc *func, void *user_data=nullptr)
Registers a new kind of thing the Factory will be able to create.
void set_update_delay(double delay)
Specifies the minimum amount of time, in seconds, that should elapse between any two consecutive upda...
Camera * get_camera_node() const
Returns the camera used to render the scene.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int get_child_sort(int n, Thread *current_thread=Thread::get_current_thread()) const
Returns the sort index of the nth child node of this node (that is, the number that was passed to add...
virtual void write_datagram(BamWriter *manager, Datagram &me)
Writes the contents of this object to the datagram for shipping out to a Bam file.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual PandaNode * make_copy() const
Returns a newly-allocated PandaNode that is a shallow copy of this one.
virtual bool is_character_joint() const
Returns true if this part is a CharacterJoint, false otherwise.
get_cull_center
Returns the point from which the culling operations will be performed, if it was set by set_cull_cent...
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
void set_lod_animation(const LPoint3 ¢er, PN_stdfloat far_distance, PN_stdfloat near_distance, PN_stdfloat delay_factor)
Activates a special mode in which the character animates less frequently as it gets further from the ...
get_parent
Returns the nth parent node of this node.
PT(Geom) Character
Makes a new copy of the Geom with the dynamic vertex arrays replaced to reference this Character inst...
uint16_t get_uint16()
Extracts an unsigned 16-bit integer.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
get_num_geoms
Returns the number of geoms in the node.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A thread; that is, a lightweight process.
This is the root of a MovingPart hierarchy.
This represents one joint of the character's animation, containing an animating transform matrix.
bool read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.
SceneSetup * get_scene() const
Returns the SceneSetup object.
bool update()
Updates all the parts in the bundle to reflect the data for the current frame (as set in each of the ...
void clear_lod_animation()
Undoes the effect of a recent call to set_lod_animation().
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin().
void force_update()
Recalculates the character even if we think it doesn't need it.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PartGroup * copy_subgraph() const
Allocates and returns a new copy of this node and of all of its children.
A class to retrieve the individual data elements previously stored in a Datagram.
get_child
Returns the nth child of the group.
bool has_name() const
Returns true if the Namable has a nonempty name set, false if the name is empty.
get_child
Returns the nth child node of this node.
TypeHandle is the identifier used to differentiate C++ class types.
virtual PartGroup * make_copy() const
Allocates and returns a new copy of the node.
A node that can be positioned around in the scene graph to represent a point of view for rendering a ...
void merge_anim_preloads(const PartBundle *other)
Copies the contents of the other PartBundle's preload table into this one.
void write_parts(std::ostream &out) const
Writes a list of the Character's joints and sliders, in their hierchical structure,...
virtual bool is_geom_node() const
A simple downcast check.
void write_part_values(std::ostream &out) const
Writes a list of the Character's joints and sliders, along with each current position,...
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
static void register_with_read_factory()
Tells the BamReader how to create objects of type Character.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
A node that holds Geom objects, renderable pieces of geometry.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void add_geom(Geom *geom, const RenderState *state=RenderState::make_empty())
Adds a new Geom to the node.
virtual PandaNode * make_copy() const
The Character make_copy() function will make a new copy of the Character, with all of its joints copi...
void remove_all_geoms()
Removes all the geoms from the node at once.
This is the base class for PartRoot and MovingPart.