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