new joint freezing on a low level

This commit is contained in:
Zachary Pavlov 2007-05-31 23:44:39 +00:00
parent c7a0652426
commit 81b52e39c5
5 changed files with 105 additions and 1 deletions

View File

@ -233,6 +233,79 @@ make_child_dynamic(const string &name) {
return (AnimGroup *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: AnimGroup::make_child_fixed
// Access: Public
// Description: Finds the indicated child and replaces it with an
// AnimChannelMatrixFixed with the specified transform
// This may be called before binding the animation to a
// character to replace certain joints with
// frozen ones.
//
// Returns NULL if the named child cannot be found.
////////////////////////////////////////////////////////////////////
void AnimGroup::
void make_child_fixed(const string &name, const LMatrix4f &mat) {
Children::iterator ci;
for (ci = _children.begin(); ci != _children.end(); ++ci) {
AnimGroup *child = (*ci);
if (child->get_name() == name) {
AnimGroup *new_child = NULL;
if (child->is_of_type(AnimChannelMatrix::get_class_type())) {
AnimChannelMatrix *mchild = DCAST(AnimChannelMatrix, child);
AnimChannelMatrixFixed *new_mchild =
new AnimChannelMatrixFixed(this, name, mat);
new_child = new_mchild;
}
if (new_child != (AnimGroup *)NULL) {
new_child->_children.swap(child->_children);
nassertr(_children.back() == new_child, NULL);
// The new child was appended to the end of our children list
// by its constructor. Reposition it to replace the original
// child.
// I would like to use these lines, but for some reason it
// crashes:
/*
{
(*ci) = new_child;
_children.pop_back();
}
*/
// But this longer way of achieving the same result works
// instead:
{
Children::iterator nci;
Children new_children;
for (nci = _children.begin(); nci != _children.end(); ++nci) {
if ((*nci) == child) {
new_children.push_back(new_child);
} else if ((*nci) != new_child) {
new_children.push_back(*nci);
}
}
new_children.swap(_children);
}
return new_child;
}
}
AnimGroup *result = child->make_child_fixed(name, mat);
if (result != (AnimGroup *)NULL) {
return result;
}
}
return (AnimGroup *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: AnimGroup::get_value_type
// Access: Public, Virtual

View File

@ -52,7 +52,7 @@ PUBLISHED:
AnimGroup *find_child(const string &name) const;
AnimGroup *make_child_dynamic(const string &name);
void make_child_fixed(const string &name, const LMatrix4f &mat);
public:
virtual TypeHandle get_value_type() const;
@ -85,6 +85,7 @@ protected:
void fillin(DatagramIterator& scan, BamReader* manager);
private:
typedef pvector< string > frozenJoints;
int _num_children;
public:

View File

@ -207,3 +207,17 @@ get_control_effect(AnimControl *control) const {
return do_get_control_effect(control, cdata);
}
////////////////////////////////////////////////////////////////////
// Function: PartBundle::freeze_joint
// Access: Protected
// Description: stores away a joint freeze for bind time
////////////////////////////////////////////////////////////////////
INLINE void PartBundle::
freeze_joint(string jointName, LMatrix4f transform) const
{
JointTransform jt;
jt.name=jointName;
jt.transform=transform;
_frozen_joints.push_back(jt);
}

View File

@ -213,6 +213,11 @@ bind_anim(AnimBundle *anim, int hierarchy_match_flags,
return NULL;
}
}
JointTransformList::iterator jti;
for (jti = _frozen_joints.begin(); jti != _frozen_joints.end(); ++jti) {
anim->make_child_fixed((*jti).name, (*jti).transform);
}
if (!check_hierarchy(anim, NULL, hierarchy_match_flags)) {
return NULL;

View File

@ -109,6 +109,8 @@ PUBLISHED:
INLINE int get_num_nodes() const;
INLINE PartBundleNode *get_node(int n) const;
INLINE void freeze_joint(string jointName, LMatrix4f transform) const;
void clear_control_effects();
INLINE void set_control_effect(AnimControl *control, float effect);
INLINE float get_control_effect(AnimControl *control) const;
@ -194,6 +196,15 @@ public:
private:
static TypeHandle _type_handle;
typedef struct {
string name;
LMatrix4f transform;
} JointTransform ;
typedef pvector< JointTransform > JointTransformList;
JointTransformList _frozen_joints;
friend class PartBundleNode;
friend class MovingPartBase;
friend class MovingPartMatrix;