41 _new_parent =
nullptr;
42 _has_rest_frame =
false;
43 _rest_frames_differ =
false;
53 if (back ==
nullptr) {
54 return LMatrix4d::ident_mat();
58 DCAST_INTO_R(joint, back, LMatrix4d::ident_mat());
60 return joint->get_frame(n);
70 if (back ==
nullptr) {
71 return LMatrix4d::ident_mat();
75 DCAST_INTO_R(joint, back, LMatrix4d::ident_mat());
78 if (!db.
get_matrix(joint, EggCharacterDb::TT_net_frame, n, mat)) {
81 if (_parent !=
nullptr) {
84 db.
set_matrix(joint, EggCharacterDb::TT_net_frame, n, mat);
96 if (back ==
nullptr) {
97 return LMatrix4d::ident_mat();
101 DCAST_INTO_R(joint, back, LMatrix4d::ident_mat());
104 if (!db.
get_matrix(joint, EggCharacterDb::TT_net_frame_inv, n, mat)) {
107 mat.invert_in_place();
108 db.
set_matrix(joint, EggCharacterDb::TT_net_frame_inv, n, mat);
126 for (
int model_index = 0; model_index < num_models; model_index++) {
129 DCAST_INTO_V(joint,
get_model(model_index));
130 if (joint->
is_of_type(EggJointNodePointer::get_class_type())) {
135 _rest_frames_differ =
false;
146 if (new_owner ==
nullptr) {
147 for (
int model_index = 0; model_index < num_models; model_index++) {
150 DCAST_INTO_V(joint,
get_model(model_index));
155 for (
int model_index = 0; model_index < num_models; model_index++) {
158 DCAST_INTO_V(joint,
get_model(model_index));
159 DCAST_INTO_V(new_joint, new_owner->
get_model(model_index));
184 vector_stdfloat i, j, k, a, b, c, x, y, z;
189 for (
int model_index = 0; model_index < num_models; model_index++) {
191 if (back !=
nullptr) {
193 DCAST_INTO_R(joint, back,
false);
196 for (
int n = 0; n < num_frames; n++) {
198 if (_parent == new_parent) {
200 transform = LMatrix4d::ident_mat();
202 }
else if (_parent ==
nullptr) {
206 }
else if (new_parent ==
nullptr) {
217 transform = joint->get_frame(n) * transform;
218 LVecBase3d scale, shear, hpr, translate;
219 if (!decompose_matrix(transform, scale, shear, hpr, translate)) {
223 i.push_back(scale[0]);
224 j.push_back(scale[1]);
225 k.push_back(scale[2]);
226 a.push_back(shear[0]);
227 b.push_back(shear[1]);
228 c.push_back(shear[2]);
229 hprs.push_back(LCAST(PN_stdfloat, hpr));
230 x.push_back(translate[0]);
231 y.push_back(translate[1]);
232 z.push_back(translate[2]);
254 compressor.
write_hprs(dg, &hprs[0], num_rows);
266 std::ostringstream sstr;
267 OCompressStream zstr(&sstr,
false);
270 return sstr.str().length();
282 BackPointers::iterator bpi;
283 for (bpi = _back_pointers.begin(); bpi != _back_pointers.end(); ++bpi) {
285 if (back !=
nullptr) {
287 DCAST_INTO_R(joint, back,
false);
294 Children::iterator ci;
295 for (ci = _children.begin(); ci != _children.end(); ++ci) {
311 BackPointers::iterator bpi;
312 for (bpi = _back_pointers.begin(); bpi != _back_pointers.end(); ++bpi) {
314 if (back !=
nullptr) {
316 DCAST_INTO_V(joint, back);
321 Children::iterator ci;
322 for (ci = _children.begin(); ci != _children.end(); ++ci) {
334 BackPointers::iterator bpi;
335 for (bpi = _back_pointers.begin(); bpi != _back_pointers.end(); ++bpi) {
337 if (back !=
nullptr) {
339 DCAST_INTO_V(joint, back);
351 BackPointers::iterator bpi;
352 for (bpi = _back_pointers.begin(); bpi != _back_pointers.end(); ++bpi) {
354 if (back !=
nullptr) {
356 DCAST_INTO_V(joint, back);
368 BackPointers::iterator bpi;
369 for (bpi = _back_pointers.begin(); bpi != _back_pointers.end(); ++bpi) {
371 if (back !=
nullptr) {
373 DCAST_INTO_V(joint, back);
378 Children::iterator ci;
379 for (ci = _children.begin(); ci != _children.end(); ++ci) {
394 DCAST_INTO_V(source_joint, _back_pointers[source_model]);
395 BackPointers::iterator bpi;
396 for (bpi = _back_pointers.begin(); bpi != _back_pointers.end(); ++bpi) {
398 if (back !=
nullptr) {
400 DCAST_INTO_V(joint, back);
406 Children::iterator ci;
407 for (ci = _children.begin(); ci != _children.end(); ++ci) {
418 nassertv(egg_object !=
nullptr);
419 if (egg_object->
is_of_type(EggGroup::get_class_type())) {
423 if (!_has_rest_frame) {
425 _has_rest_frame =
true;
430 if (!_rest_frame.almost_equal(joint->
get_frame(0), 0.0001)) {
431 _rest_frames_differ =
true;
435 }
else if (egg_object->
is_of_type(EggTable::get_class_type())) {
441 nout <<
"Invalid object added to joint for back pointer.\n";
449 write(std::ostream &out,
int indent_level)
const {
451 <<
"Joint " << get_name()
454 for (
int model_index = 0; model_index < num_models; model_index++) {
456 out <<
" " << model_index;
461 Children::const_iterator ci;
462 for (ci = _children.begin(); ci != _children.end(); ++ci) {
463 (*ci)->write(out, indent_level + 2);
466 indent(out, indent_level) <<
"}\n";
474 do_begin_reparent() {
475 _got_new_parent_depth =
false;
492 if (_got_new_parent_depth) {
495 if (_new_parent ==
nullptr) {
497 _got_new_parent_depth =
true;
498 _new_parent_depth = 0;
501 if (!chain.insert(
this).second) {
505 bool cycle = _new_parent->calc_new_parent_depth(chain);
506 _new_parent_depth = _new_parent->_new_parent_depth + 1;
515 do_begin_compute_reparent() {
516 _got_new_net_frame =
false;
517 _got_new_net_frame_inv =
false;
518 _computed_reparent =
false;
528 if (_computed_reparent) {
534 _computed_reparent =
true;
536 if (_parent == _new_parent) {
544 if (back ==
nullptr) {
551 DCAST_INTO_R(joint, back,
false);
554 if (_parent ==
nullptr) {
556 transform = _new_parent->get_new_net_frame_inv(model_index, n, db);
558 }
else if (_new_parent ==
nullptr) {
566 _new_parent->get_new_net_frame_inv(model_index, n, db);
569 db.
set_matrix(joint, EggCharacterDb::TT_rebuild_frame, n,
570 joint->get_frame(n) * transform);
585 if (_new_parent !=
nullptr && _new_parent->
has_model(model_index)) {
586 DCAST_INTO_R(parent_joint, _new_parent->
get_model(model_index),
false);
591 DCAST_INTO_R(joint,
get_model(model_index),
false);
605 do_finish_reparent() {
607 for (
int model_index = 0; model_index < num_models; model_index++) {
609 if (_new_parent !=
nullptr && _new_parent->
has_model(model_index)) {
610 DCAST_INTO_V(parent_joint, _new_parent->
get_model(model_index));
615 DCAST_INTO_V(joint,
get_model(model_index));
616 joint->do_finish_reparent(parent_joint);
620 _parent = _new_parent;
621 if (_parent !=
nullptr) {
622 _parent->_children.push_back(
this);
631 make_new_joint(
const string &name) {
633 child->set_name(name);
634 child->_parent =
this;
635 child->_new_parent =
this;
636 _children.push_back(child);
640 for (
int i = 0; i < num_models; i++) {
643 DCAST_INTO_R(joint,
get_model(i),
nullptr);
657 find_joint_exact(
const string &name) {
658 Children::const_iterator ci;
659 for (ci = _children.begin(); ci != _children.end(); ++ci) {
661 if (child->get_name() == name) {
665 if (result !=
nullptr) {
678 find_joint_matches(
const string &name) {
679 Children::const_iterator ci;
680 for (ci = _children.begin(); ci != _children.end(); ++ci) {
686 if (result !=
nullptr) {
705 if (child->_new_parent ==
nullptr) {
709 return is_new_ancestor(child->_new_parent);
717 const LMatrix4d &EggJointData::
719 if (!_got_new_net_frame) {
720 _new_net_frame = get_new_frame(model_index, n, db);
721 if (_new_parent !=
nullptr) {
722 _new_net_frame = _new_net_frame * _new_parent->get_new_net_frame(model_index, n, db);
724 _got_new_net_frame =
true;
726 return _new_net_frame;
732 const LMatrix4d &EggJointData::
733 get_new_net_frame_inv(
int model_index,
int n,
EggCharacterDb &db) {
734 if (!_got_new_net_frame_inv) {
735 _new_net_frame_inv.invert_from(get_new_frame(model_index, n, db));
736 if (_new_parent !=
nullptr) {
737 _new_net_frame_inv = _new_parent->get_new_net_frame_inv(model_index, n, db) * _new_net_frame_inv;
739 _got_new_net_frame_inv =
true;
741 return _new_net_frame_inv;
749 LMatrix4d EggJointData::
751 do_compute_reparent(model_index, n, db);
754 if (back ==
nullptr) {
755 return LMatrix4d::ident_mat();
759 DCAST_INTO_R(joint, back, LMatrix4d::ident_mat());
762 if (!db.
get_matrix(joint, EggCharacterDb::TT_rebuild_frame, n, mat)) {
764 return joint->get_frame(n);
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void optimize()
Resets the table before writing to disk so that redundant rows (e.g.
int get_num_frames(int model_index) const
Returns the number of frames of animation for this particular component in the indicated model.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_model(int model_index, EggBackPointer *back)
Sets the back_pointer associated with the given model_index.
void optimize()
Calls optimize() on all models, and recursively on all joints at this node and below.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual LMatrix4d get_frame(int n) const
Returns the transform matrix corresponding to this joint position in the nth frame.
int get_num_models() const
Returns the maximum number of back pointers this component may have.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
EggBackPointer * get_model(int model_index) const
Returns the back pointer to an egg file for the indicated model if it exists, or NULL if it does not.
This class manages a lossy compression and decompression of a stream of floating-point numbers to a d...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the base class of both EggJointData and EggSliderData.
LMatrix4d get_net_frame_inv(int model_index, int n, EggCharacterDb &db) const
Returns the inverse of get_net_frame().
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is our own Panda specialization on the default STL vector.
void apply_default_pose(int source_model, int frame)
Applies the pose from the indicated frame of the indicated source model_index as the initial pose for...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void move_vertices_to(EggJointPointer *new_joint)
Moves the vertices assigned to this joint into the other joint (which should be of the same type).
This stores a pointer back to a <Joint> node.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This class is used during joint optimization or restructuring to store the table of interim joint com...
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
bool has_rest_frame() const
Returns true if the joint knows its rest frame, false otherwise.
void set_matrix(const EggJointPointer *joint, TableType type, int frame, const LMatrix4d &mat)
Stores the matrix for the indicated joint, type, and frame in the database.
virtual void quantize_channels(const std::string &components, double quantum)
Rounds the named components of the transform to the nearest multiple of quantum.
LMatrix4d get_net_frame(int model_index, int n, EggCharacterDb &db) const
Returns the complete transform from the root corresponding to this joint position in the nth frame in...
virtual void apply_default_pose(EggJointPointer *source_joint, int frame)
Applies the pose from the indicated frame of the indicated source joint as the initial pose for this ...
This is a base class for EggJointNodePointer and EggMatrixTablePointer.
void move_vertices_to(EggJointData *new_owner)
Moves the vertices assigned to this joint into the indicated joint, without changing their weight ass...
bool matches_name(const std::string &name) const
Returns true if the indicated name matches any name that was ever matched with this particular joint,...
Represents a set of characters, as read and collected from possibly several model and/or animation eg...
bool has_model(int model_index) const
Returns true if the component has a back pointer to an egg file somewhere for the indicated model,...
Represents a single character, as read and collected from several models and animation files.
void write_reals(Datagram &datagram, const PN_stdfloat *array, int length)
Writes an array of floating-point numbers to the indicated datagram.
int score_reparent_to(EggJointData *new_parent, EggCharacterDb &db)
Computes a score >= 0 reflecting the similarity of the current joint's animation (in world space) to ...
const LMatrix4d & get_rest_frame() const
Returns the rest frame of the joint.
This is one node of a hierarchy of EggJointData nodes, each of which represents a single joint of the...
virtual bool do_rebuild(EggCharacterDb &db)
Rebuilds the entire table all at once, based on the frames added by repeated calls to add_rebuild_fra...
virtual void add_back_pointer(int model_index, EggObject *egg_object)
Adds the indicated model joint or anim table to the data.
This stores a pointer back to an EggXfmSAnim table (i.e.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void force_initial_rest_frame()
Forces all of the joints to have the same rest frame value as the first joint read in.
virtual void zero_channels(const std::string &components)
Zeroes out the named components of the transform in the animation frames.
LMatrix4d get_frame(int model_index, int n) const
Returns the local transform matrix corresponding to this joint position in the nth frame in the indic...
void zero_channels(const std::string &components)
Calls zero_channels() on all models for this joint, but does not recurse downwards.
void quantize_channels(const std::string &components, double quantum)
Calls quantize_channels() on all models for this joint, and then recurses downwards to all joints bel...
void write_hprs(Datagram &datagram, const LVecBase3 *array, int length)
Writes an array of HPR angles to the indicated datagram.
virtual void expose(EggGroup::DCSType dcs_type)
Flags the joint with the indicated DCS flag so that it will be loaded as a separate node in the playe...
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
bool do_rebuild_all(EggCharacterDb &db)
Calls do_rebuild() on all models, and recursively on all joints at this node and below.
This is our own Panda specialization on the default STL set.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TypeHandle is the identifier used to differentiate C++ class types.
This stores a pointer from an EggJointData or EggSliderData object back to the referencing data in an...
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
void expose(EggGroup::DCSType dcs_type=EggGroup::DC_default)
Calls expose() on all models for this joint, but does not recurse downwards.
The highest-level base class in the egg directory.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool get_matrix(const EggJointPointer *joint, TableType type, int frame, LMatrix4d &mat) const
Looks up the data for the indicated joint, type, and frame, and fills it in result (and returns true)...
static bool is_compression_available()
Returns true if the FFTW library is compiled in, so that this class is actually capable of doing usef...
size_t get_length() const
Returns the number of bytes in the datagram.
const void * get_data() const
Returns a pointer to the beginning of the datagram's data.