15 #include "characterMaker.h" 16 #include "eggLoader.h" 17 #include "config_egg2pg.h" 18 #include "eggBinner.h" 20 #include "eggPrimitive.h" 22 #include "partGroup.h" 23 #include "characterJoint.h" 24 #include "characterJointBundle.h" 25 #include "characterSlider.h" 26 #include "character.h" 28 #include "transformState.h" 29 #include "eggSurface.h" 31 #include "modelNode.h" 32 #include "characterVertexSlider.h" 33 #include "jointVertexTransform.h" 34 #include "userVertexTransform.h" 35 #include "eggAnimPreload.h" 36 #include "animPreloadTable.h" 49 : _loader(loader), _egg_root(root) {
51 _character_node =
new Character(_egg_root->get_name());
52 _bundle = _character_node->get_bundle(0);
55 _skeleton_root =
new PartGroup(_bundle,
"<skeleton>");
56 _structured = structured;
67 return _character_node;
77 return _egg_root->get_name();
96 nassertr(index < (
int)_parts.size(), NULL);
114 return get_identity_transform();
117 VertexTransforms::iterator vi = _vertex_transforms.find(index);
118 if (vi != _vertex_transforms.end()) {
124 DCAST_INTO_R(joint, part, get_identity_transform());
127 _vertex_transforms[index] = vt;
140 NodeMap::const_iterator nmi = _node_map.find(egg_node);
141 if (nmi == _node_map.end()) {
144 return (*nmi).second;
159 if (part->
is_of_type(CharacterJoint::get_class_type())) {
161 if (joint->_geom_node != (
PandaNode *)NULL) {
162 node = joint->_geom_node;
176 if (child->
is_geom_node() && child->get_name() == name) {
181 node->add_child(geom_node);
195 _morph_root =
new PartGroup(_bundle,
"morph");
198 int index = _parts.size();
199 _parts.push_back(slider);
211 VertexSliders::iterator vi = _vertex_sliders.find(name);
212 if (vi != _vertex_sliders.end()) {
219 _vertex_sliders[name] = slider;
231 build_joint_hierarchy(_egg_root, _skeleton_root, -1);
235 make_geometry(_egg_root);
237 _bundle->sort_descendants();
238 parent_joint_nodes(_skeleton_root);
253 void CharacterMaker::
255 if (egg_node->
is_of_type(EggAnimPreload::get_class_type())) {
259 if (egg_anim_preload->has_fps()) {
260 fps = egg_anim_preload->
get_fps();
264 if (egg_anim_preload->has_num_frames()) {
271 _bundle->set_anim_preload(anim_preload);
273 anim_preload->add_anim(egg_node->get_name(), fps, num_frames);
277 if (egg_node->
is_of_type(EggGroup::get_class_type())) {
282 if (egg_group->get_group_type() == EggGroup::GT_joint) {
295 LMatrix4 matf = LCAST(PN_stdfloat, matd);
298 new CharacterJoint(_character_node, _character_node->get_bundle(0),
299 part, egg_group->get_name(), matf);
300 index = _parts.size();
301 _parts.push_back(joint);
308 matf = LCAST(PN_stdfloat, matd);
309 joint->_default_value = matf;
310 joint->_value = matf;
322 joint->_geom_node = geom_node.p();
328 EggGroup::const_iterator ci;
329 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
330 build_joint_hierarchy((*ci), part, index);
334 _node_map[egg_node] = index;
344 void CharacterMaker::
346 if (part->
is_of_type(CharacterJoint::get_class_type())) {
348 PandaNode *joint_node = joint->_geom_node;
349 if (joint_node != NULL) {
350 _character_node->add_child(joint_node);
352 joint_node->
set_transform(TransformState::make_mat(joint->_net_transform));
369 void CharacterMaker::
370 make_geometry(
EggNode *egg_node) {
371 if (egg_node->
is_of_type(EggBin::get_class_type())) {
374 if (!egg_bin->empty() &&
375 (egg_bin->get_bin_number() == EggBinner::BN_polyset ||
376 egg_bin->get_bin_number() == EggBinner::BN_patches)) {
383 bin_home = _egg_root;
396 _loader.
make_polyset(egg_bin, parent, &transform, is_dynamic,
401 if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
404 EggGroupNode::const_iterator ci;
405 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
431 EggPrimitive::const_iterator vi;
432 for (vi = egg_primitive->begin();
433 vi != egg_primitive->end();
442 if (!vertex->_dxyzs.empty() ||
443 !vertex->_dnormals.empty() ||
444 !vertex->_drgbas.empty()) {
451 if (!(*uvi)->_duvs.empty()) {
463 vertex_home = egg_primitive->get_parent();
465 nassertr(vertex->
gref_size() == 1, NULL);
470 if (home != NULL && home != vertex_home) {
481 nassertr(home != NULL, NULL);
489 if (home->
is_of_type(EggGroup::get_class_type())) {
492 while (egg_group != (
EggGroup *)NULL &&
493 egg_group->get_group_type() != EggGroup::GT_joint &&
494 egg_group->get_dart_type() == EggGroup::DT_none) {
495 nassertr(egg_group->get_parent() != (
EggGroupNode *)NULL, NULL);
496 home = egg_group->get_parent();
498 if (home->
is_of_type(EggGroup::get_class_type())) {
503 if (egg_group != (
EggGroup *)NULL &&
504 egg_group->get_group_type() == EggGroup::GT_joint &&
528 determine_bin_home(
EggBin *egg_bin) {
538 if (!egg_rigid_geometry) {
548 EggGroupNode::const_iterator ci;
549 for (ci = egg_bin->begin(); ci != egg_bin->end(); ++ci) {
552 EggPrimitive::const_iterator vi;
553 for (vi = egg_primitive->begin();
554 vi != egg_primitive->end();
563 if (!vertex->_dxyzs.empty() ||
564 !vertex->_dnormals.empty() ||
565 !vertex->_drgbas.empty()) {
572 if (!(*uvi)->_duvs.empty()) {
584 vertex_home = egg_primitive->get_parent();
586 nassertr(vertex->
gref_size() == 1, NULL);
591 if (home != NULL && home != vertex_home) {
604 nassertr(home != NULL, NULL);
612 if (home->
is_of_type(EggGroup::get_class_type())) {
615 while (egg_group != (
EggGroup *)NULL &&
616 egg_group->get_group_type() != EggGroup::GT_joint &&
617 egg_group->get_dart_type() == EggGroup::DT_none) {
618 nassertr(egg_group->get_parent() != (
EggGroupNode *)NULL, NULL);
619 home = egg_group->get_parent();
621 if (home->
is_of_type(EggGroup::get_class_type())) {
626 if (egg_group != (
EggGroup *)NULL &&
627 egg_group->get_group_type() == EggGroup::GT_joint &&
633 if (egg_group->get_dcs_type() == EggGroup::DC_none) {
649 egg_group->set_dcs_type(EggGroup::DC_default);
653 joint->_geom_node = geom_node.p();
666 get_identity_transform() {
670 return _identity_transform;
A base class for any of a number of kinds of geometry primitives: polygons, point lights...
GroupRef::size_type gref_size() const
Returns the number of elements between gref_begin() and gref_end().
A basic node of the scene graph or data graph.
const EggTransform & get_default_pose() const
Returns a read-only accessor to the initial pose transform.
This is an iterator adaptor that converts any iterator that returns a pair (e.g.
This table records data about a list of animations for a particular model, such as number of frames a...
This is a 4-by-4 transform matrix.
The collection of all the joints and sliders in the character.
const LMatrix4d & get_node_frame_inv() const
Returns the inverse of the matrix returned by get_node_frame().
An animated character, with skeleton-morph animation and either soft-skinned or hard-skinned vertices...
int get_num_children(Thread *current_thread=Thread::get_current_thread()) const
Returns the number of child nodes this node has.
const LMatrix4d & get_vertex_frame() const
Returns the coordinate frame of the vertices referenced by primitives at or under this node...
A base class for nodes in the hierarchy that are not leaf nodes.
PandaNode * get_child(int n, Thread *current_thread=Thread::get_current_thread()) const
Returns the nth child node of this node.
double get_fps() const
This is only valid if has_fps() returns true.
int get_num_children() const
Returns the number of child nodes of the group.
This is a specialization on VertexSlider that returns the slider value associated with a particular C...
GroupRef::const_iterator gref_begin() const
Returns an iterator that can, in conjunction with gref_end(), be used to traverse the entire set of g...
This is an abstract base class that retains some slider value, which is a linear value that typically...
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 a morph slider within the character.
PartGroup * egg_to_part(EggNode *egg_node) const
Returns the PartGroup node associated with the given egg node.
string get_name() const
Returns the name of the character.
VertexSlider * egg_to_slider(const string &name)
Returns the VertexSlider corresponding to the indicated egg slider name.
int create_slider(const string &name)
Creates a new morph slider of the given name, and returns its index.
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
PartGroup * get_child(int n) const
Returns the nth child of the group.
This node is placed at key points within the scene graph to indicate the roots of "models": subtrees ...
int get_num_frames() const
This is only valid if has_num_frames() returns true.
This is a 4-by-4 transform matrix.
This corresponds to an <AnimPreload> entry.
static const LMatrix4d & ident_mat()
Returns an identity matrix.
Any one-, two-, three-, or four-component vertex, possibly with attributes such as a normal...
int egg_to_index(EggNode *egg_node) const
Returns the index number associated with the PartGroup node for the given egg node, or -1.
PandaNode * part_to_node(PartGroup *part, const string &name) const
Returns the scene graph node associated with the given PartGroup node, if there is one...
const_uv_iterator uv_begin() const
Returns an iterator that allows walking through the complete set of named UV's on the vertex...
A base class for things that may be directly added into the egg hierarchy.
This represents one joint of the character's animation, containing an animating transform matrix...
bool has_dcs_type() const
Returns true if the specified DCS type is not DC_none and not DC_unspecified.
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.
VertexTransform * egg_to_transform(EggNode *egg_node)
Returns a JointVertexTransform suitable for applying the animation associated with the given egg node...
void set_preserve_transform(PreserveTransform preserve_transform)
Sets the preserve_transform flag.
virtual bool is_geom_node() const
A simple downcast check.
void set_transform(const TransformState *transform, Thread *current_thread=Thread::get_current_thread())
Sets the transform that will be applied to this node and below.
A node that holds Geom objects, renderable pieces of geometry.
void make_polyset(EggBin *egg_bin, PandaNode *parent, const LMatrix4d *transform, bool is_dynamic, CharacterMaker *character_maker)
Creates a polyset–that is, a Geom–from the primitives that have already been grouped into a bin...
const_uv_iterator uv_end() const
Returns an iterator that allows walking through the complete set of named UV's on the vertex...
Converts an egg data structure, possibly read from an egg file but not necessarily, into a scene graph suitable for rendering.
A type of group node that holds related subnodes.
This is the base class for PartRoot and MovingPart.