00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "auto_bind.h"
00021 #include "animBundleNode.h"
00022 #include "partBundleNode.h"
00023 #include "config_chan.h"
00024 #include "string_utils.h"
00025
00026 typedef pset<AnimBundleNode *> AnimNodes;
00027 typedef pmap<string, AnimNodes> Anims;
00028
00029 typedef pset<PartBundleNode *> PartNodes;
00030 typedef pmap<string, PartNodes> Parts;
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 static void
00041 bind_anims(const PartNodes &parts, const AnimNodes &anims,
00042 AnimControlCollection &controls,
00043 int hierarchy_match_flags) {
00044
00045 PartNodes::const_iterator pni;
00046
00047 for (pni = parts.begin(); pni != parts.end(); ++pni) {
00048 PartBundle *part = (*pni)->get_bundle();
00049
00050 AnimNodes::const_iterator ani;
00051 for (ani = anims.begin(); ani != anims.end(); ++ani) {
00052 AnimBundle *anim = (*ani)->get_bundle();
00053
00054 if (chan_cat.is_info()) {
00055 chan_cat.info()
00056 << "Attempting to bind " << *part << " to " << *anim << "\n";
00057 }
00058
00059 PT(AnimControl) control =
00060 part->bind_anim(anim, hierarchy_match_flags);
00061 string name = anim->get_name();
00062 if (control != (AnimControl *)NULL) {
00063 if (controls.find_anim(name) != (AnimControl *)NULL) {
00064
00065 int index = 0;
00066 string new_name;
00067 do {
00068 index++;
00069 new_name = name + '.' + format_string(index);
00070 } while (controls.find_anim(new_name) != (AnimControl *)NULL);
00071 name = new_name;
00072 }
00073
00074 controls.store_anim(control, name);
00075 }
00076
00077 if (chan_cat.is_info()) {
00078 if (control == (AnimControl *)NULL) {
00079 chan_cat.info()
00080 << "Bind failed.\n";
00081 } else {
00082 chan_cat.info()
00083 << "Bind succeeded, index "
00084 << control->get_channel_index() << "; accessible as "
00085 << name << "\n";
00086 }
00087 }
00088 }
00089 }
00090 }
00091
00092
00093
00094
00095
00096
00097
00098 static void
00099 r_find_bundles(PandaNode *node, Anims &anims, Parts &parts) {
00100 if (node->is_of_type(AnimBundleNode::get_class_type())) {
00101 AnimBundleNode *bn = DCAST(AnimBundleNode, node);
00102 anims[bn->get_bundle()->get_name()].insert(bn);
00103
00104 } else if (node->is_of_type(PartBundleNode::get_class_type())) {
00105 PartBundleNode *bn = DCAST(PartBundleNode, node);
00106 parts[bn->get_bundle()->get_name()].insert(bn);
00107 }
00108
00109 PandaNode::Children cr = node->get_children();
00110 int num_children = cr.get_num_children();
00111 for (int i = 0; i < num_children; i++) {
00112 r_find_bundles(cr.get_child(i), anims, parts);
00113 }
00114 }
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 void
00127 auto_bind(PandaNode *root_node, AnimControlCollection &controls,
00128 int hierarchy_match_flags) {
00129
00130 Anims anims;
00131 Parts parts;
00132 r_find_bundles(root_node, anims, parts);
00133
00134 if (chan_cat.is_debug()) {
00135 int anim_count = 0;
00136 Anims::const_iterator ai;
00137 for (ai = anims.begin(); ai != anims.end(); ++ai) {
00138 anim_count += (int)(*ai).second.size();
00139 }
00140 chan_cat.debug()
00141 << "Found " << anim_count << " anims:\n";
00142 for (ai = anims.begin(); ai != anims.end(); ++ai) {
00143 chan_cat.debug(false)
00144 << " " << (*ai).first;
00145 if ((*ai).second.size() != 1) {
00146 chan_cat.debug(false)
00147 << "*" << ((*ai).second.size());
00148 }
00149 }
00150 chan_cat.debug(false)
00151 << "\n";
00152
00153 int part_count = 0;
00154 Parts::const_iterator pi;
00155 for (pi = parts.begin(); pi != parts.end(); ++pi) {
00156 part_count += (int)(*pi).second.size();
00157 }
00158 chan_cat.debug()
00159 << "Found " << part_count << " parts:\n";
00160 for (pi = parts.begin(); pi != parts.end(); ++pi) {
00161 chan_cat.debug(false)
00162 << " " << (*pi).first;
00163 if ((*pi).second.size() != 1) {
00164 chan_cat.debug(false)
00165 << "*" << ((*pi).second.size());
00166 }
00167 }
00168 chan_cat.debug(false)
00169 << "\n";
00170 }
00171
00172
00173
00174 Anims::const_iterator ai = anims.begin();
00175 Parts::const_iterator pi = parts.begin();
00176
00177 while (ai != anims.end() && pi != parts.end()) {
00178 if ((*ai).first < (*pi).first) {
00179
00180 ++ai;
00181
00182 } else if ((*pi).first < (*ai).first) {
00183
00184 ++pi;
00185
00186 } else {
00187
00188 bind_anims((*pi).second, (*ai).second, controls,
00189 hierarchy_match_flags);
00190 ++pi;
00191
00192
00193
00194
00195 }
00196 }
00197 }
00198
00199