00001 // Filename: nodePathCollection.cxx 00002 // Created by: drose (06Mar02) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved 00008 // 00009 // All use of this software is subject to the terms of the Panda 3d 00010 // Software license. You should have received a copy of this license 00011 // along with this source code; you will also find a current copy of 00012 // the license at http://www.panda3d.org/license.txt . 00013 // 00014 // To contact the maintainers of this program write to 00015 // panda3d@yahoogroups.com . 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 #include "nodePathCollection.h" 00020 #include "findApproxPath.h" 00021 #include "findApproxLevel.h" 00022 00023 #include "indent.h" 00024 00025 //////////////////////////////////////////////////////////////////// 00026 // Function: NodePathCollection::Constructor 00027 // Access: Published 00028 // Description: 00029 //////////////////////////////////////////////////////////////////// 00030 NodePathCollection:: 00031 NodePathCollection() { 00032 } 00033 00034 //////////////////////////////////////////////////////////////////// 00035 // Function: NodePathCollection::Copy Constructor 00036 // Access: Published 00037 // Description: 00038 //////////////////////////////////////////////////////////////////// 00039 NodePathCollection:: 00040 NodePathCollection(const NodePathCollection ©) : 00041 _node_paths(copy._node_paths) 00042 { 00043 } 00044 00045 //////////////////////////////////////////////////////////////////// 00046 // Function: NodePathCollection::Copy Assignment Operator 00047 // Access: Published 00048 // Description: 00049 //////////////////////////////////////////////////////////////////// 00050 void NodePathCollection:: 00051 operator = (const NodePathCollection ©) { 00052 _node_paths = copy._node_paths; 00053 } 00054 00055 //////////////////////////////////////////////////////////////////// 00056 // Function: NodePathCollection::add_path 00057 // Access: Published 00058 // Description: Adds a new NodePath to the collection. 00059 //////////////////////////////////////////////////////////////////// 00060 void NodePathCollection:: 00061 add_path(const NodePath &node_path) { 00062 // If the pointer to our internal array is shared by any other 00063 // NodePathCollections, we have to copy the array now so we won't 00064 // inadvertently modify any of our brethren NodePathCollection 00065 // objects. 00066 00067 if (_node_paths.get_ref_count() > 1) { 00068 NodePaths old_node_paths = _node_paths; 00069 _node_paths = NodePaths::empty_array(0); 00070 _node_paths.v() = old_node_paths.v(); 00071 } 00072 00073 _node_paths.push_back(node_path); 00074 } 00075 00076 //////////////////////////////////////////////////////////////////// 00077 // Function: NodePathCollection::remove_path 00078 // Access: Published 00079 // Description: Removes the indicated NodePath from the collection. 00080 // Returns true if the path was removed, false if it was 00081 // not a member of the collection. 00082 //////////////////////////////////////////////////////////////////// 00083 bool NodePathCollection:: 00084 remove_path(const NodePath &node_path) { 00085 int path_index = -1; 00086 for (int i = 0; path_index == -1 && i < (int)_node_paths.size(); i++) { 00087 if (_node_paths[i] == node_path) { 00088 path_index = i; 00089 } 00090 } 00091 00092 if (path_index == -1) { 00093 // The indicated path was not a member of the collection. 00094 return false; 00095 } 00096 00097 // If the pointer to our internal array is shared by any other 00098 // NodePathCollections, we have to copy the array now so we won't 00099 // inadvertently modify any of our brethren NodePathCollection 00100 // objects. 00101 00102 if (_node_paths.get_ref_count() > 1) { 00103 NodePaths old_node_paths = _node_paths; 00104 _node_paths = NodePaths::empty_array(0); 00105 _node_paths.v() = old_node_paths.v(); 00106 } 00107 00108 _node_paths.erase(_node_paths.begin() + path_index); 00109 return true; 00110 } 00111 00112 //////////////////////////////////////////////////////////////////// 00113 // Function: NodePathCollection::add_paths_from 00114 // Access: Published 00115 // Description: Adds all the NodePaths indicated in the other 00116 // collection to this path. The other paths are simply 00117 // appended to the end of the paths in this list; 00118 // duplicates are not automatically removed. 00119 //////////////////////////////////////////////////////////////////// 00120 void NodePathCollection:: 00121 add_paths_from(const NodePathCollection &other) { 00122 int other_num_paths = other.get_num_paths(); 00123 for (int i = 0; i < other_num_paths; i++) { 00124 add_path(other.get_path(i)); 00125 } 00126 } 00127 00128 00129 //////////////////////////////////////////////////////////////////// 00130 // Function: NodePathCollection::remove_paths_from 00131 // Access: Published 00132 // Description: Removes from this collection all of the NodePaths 00133 // listed in the other collection. 00134 //////////////////////////////////////////////////////////////////// 00135 void NodePathCollection:: 00136 remove_paths_from(const NodePathCollection &other) { 00137 NodePaths new_paths; 00138 int num_paths = get_num_paths(); 00139 for (int i = 0; i < num_paths; i++) { 00140 NodePath path = get_path(i); 00141 if (!other.has_path(path)) { 00142 new_paths.push_back(path); 00143 } 00144 } 00145 _node_paths = new_paths; 00146 } 00147 00148 //////////////////////////////////////////////////////////////////// 00149 // Function: NodePathCollection::remove_duplicate_paths 00150 // Access: Published 00151 // Description: Removes any duplicate entries of the same NodePaths 00152 // on this collection. If a NodePath appears multiple 00153 // times, the first appearance is retained; subsequent 00154 // appearances are removed. 00155 //////////////////////////////////////////////////////////////////// 00156 void NodePathCollection:: 00157 remove_duplicate_paths() { 00158 NodePaths new_paths; 00159 00160 int num_paths = get_num_paths(); 00161 for (int i = 0; i < num_paths; i++) { 00162 NodePath path = get_path(i); 00163 bool duplicated = false; 00164 00165 for (int j = 0; j < i && !duplicated; j++) { 00166 duplicated = (path == get_path(j)); 00167 } 00168 00169 if (!duplicated) { 00170 new_paths.push_back(path); 00171 } 00172 } 00173 00174 _node_paths = new_paths; 00175 } 00176 00177 //////////////////////////////////////////////////////////////////// 00178 // Function: NodePathCollection::has_path 00179 // Access: Published 00180 // Description: Returns true if the indicated NodePath appears in 00181 // this collection, false otherwise. 00182 //////////////////////////////////////////////////////////////////// 00183 bool NodePathCollection:: 00184 has_path(const NodePath &path) const { 00185 for (int i = 0; i < get_num_paths(); i++) { 00186 if (path == get_path(i)) { 00187 return true; 00188 } 00189 } 00190 return false; 00191 } 00192 00193 //////////////////////////////////////////////////////////////////// 00194 // Function: NodePathCollection::clear 00195 // Access: Published 00196 // Description: Removes all NodePaths from the collection. 00197 //////////////////////////////////////////////////////////////////// 00198 void NodePathCollection:: 00199 clear() { 00200 _node_paths.clear(); 00201 } 00202 00203 //////////////////////////////////////////////////////////////////// 00204 // Function: NodePathCollection::is_empty 00205 // Access: Published 00206 // Description: Returns true if there are no NodePaths in the 00207 // collection, false otherwise. 00208 //////////////////////////////////////////////////////////////////// 00209 bool NodePathCollection:: 00210 is_empty() const { 00211 return _node_paths.empty(); 00212 } 00213 00214 //////////////////////////////////////////////////////////////////// 00215 // Function: NodePathCollection::get_num_paths 00216 // Access: Published 00217 // Description: Returns the number of NodePaths in the collection. 00218 //////////////////////////////////////////////////////////////////// 00219 int NodePathCollection:: 00220 get_num_paths() const { 00221 return _node_paths.size(); 00222 } 00223 00224 //////////////////////////////////////////////////////////////////// 00225 // Function: NodePathCollection::get_path 00226 // Access: Published 00227 // Description: Returns the nth NodePath in the collection. 00228 //////////////////////////////////////////////////////////////////// 00229 NodePath NodePathCollection:: 00230 get_path(int index) const { 00231 nassertr(index >= 0 && index < (int)_node_paths.size(), NodePath()); 00232 00233 return _node_paths[index]; 00234 } 00235 00236 //////////////////////////////////////////////////////////////////// 00237 // Function: NodePathCollection::operator [] 00238 // Access: Published 00239 // Description: Returns the nth NodePath in the collection. This is 00240 // the same as get_path(), but it may be a more 00241 // convenient way to access it. 00242 //////////////////////////////////////////////////////////////////// 00243 NodePath NodePathCollection:: 00244 operator [] (int index) const { 00245 nassertr(index >= 0 && index < (int)_node_paths.size(), NodePath()); 00246 00247 return _node_paths[index]; 00248 } 00249 00250 //////////////////////////////////////////////////////////////////// 00251 // Function: NodePathCollection::ls 00252 // Access: Published 00253 // Description: Lists all the nodes at and below each node in the 00254 // collection hierarchically. 00255 //////////////////////////////////////////////////////////////////// 00256 void NodePathCollection:: 00257 ls(ostream &out, int indent_level) const { 00258 for (int i = 0; i < get_num_paths(); i++) { 00259 NodePath path = get_path(i); 00260 indent(out, indent_level) << path << "\n"; 00261 path.ls(out, indent_level + 2); 00262 out << "\n"; 00263 } 00264 } 00265 00266 //////////////////////////////////////////////////////////////////// 00267 // Function: NodePathCollection::find_all_matches 00268 // Access: Published 00269 // Description: Returns the complete set of all NodePaths that begin 00270 // with any NodePath in this collection and can be 00271 // extended by path. The shortest paths will be listed 00272 // first. 00273 //////////////////////////////////////////////////////////////////// 00274 NodePathCollection NodePathCollection:: 00275 find_all_matches(const string &path) const { 00276 NodePathCollection result; 00277 00278 FindApproxPath approx_path; 00279 if (approx_path.add_string(path)) { 00280 if (!is_empty()) { 00281 FindApproxLevel level; 00282 for (int i = 0; i < get_num_paths(); i++) { 00283 FindApproxLevelEntry start(get_path(i), approx_path); 00284 level.add_entry(start); 00285 } 00286 get_path(0).r_find_matches(result, level, -1, 00287 NodePath::get_max_search_depth()); 00288 } 00289 } 00290 00291 return result; 00292 } 00293 00294 //////////////////////////////////////////////////////////////////// 00295 // Function: NodePathCollection::reparent_to 00296 // Access: Published 00297 // Description: Reparents all the NodePaths in the collection to the 00298 // indicated node. 00299 //////////////////////////////////////////////////////////////////// 00300 void NodePathCollection:: 00301 reparent_to(const NodePath &other) { 00302 for (int i = 0; i < get_num_paths(); i++) { 00303 get_path(i).reparent_to(other); 00304 } 00305 } 00306 00307 //////////////////////////////////////////////////////////////////// 00308 // Function: NodePathCollection::wrt_reparent_to 00309 // Access: Published 00310 // Description: Reparents all the NodePaths in the collection to the 00311 // indicated node, adjusting each transform so as not to 00312 // move in world coordinates. 00313 //////////////////////////////////////////////////////////////////// 00314 void NodePathCollection:: 00315 wrt_reparent_to(const NodePath &other) { 00316 for (int i = 0; i < get_num_paths(); i++) { 00317 get_path(i).wrt_reparent_to(other); 00318 } 00319 } 00320 00321 //////////////////////////////////////////////////////////////////// 00322 // Function: NodePathCollection::show 00323 // Access: Published 00324 // Description: Shows all NodePaths in the collection. 00325 //////////////////////////////////////////////////////////////////// 00326 void NodePathCollection:: 00327 show() { 00328 for (int i = 0; i < get_num_paths(); i++) { 00329 get_path(i).show(); 00330 } 00331 } 00332 00333 //////////////////////////////////////////////////////////////////// 00334 // Function: NodePathCollection::show 00335 // Access: Published 00336 // Description: Hides all NodePaths in the collection. 00337 //////////////////////////////////////////////////////////////////// 00338 void NodePathCollection:: 00339 hide() { 00340 for (int i = 0; i < get_num_paths(); i++) { 00341 get_path(i).hide(); 00342 } 00343 } 00344 00345 //////////////////////////////////////////////////////////////////// 00346 // Function: NodePathCollection::stash 00347 // Access: Published 00348 // Description: Stashes all NodePaths in the collection. 00349 //////////////////////////////////////////////////////////////////// 00350 void NodePathCollection:: 00351 stash() { 00352 for (int i = 0; i < get_num_paths(); i++) { 00353 get_path(i).stash(); 00354 } 00355 } 00356 00357 //////////////////////////////////////////////////////////////////// 00358 // Function: NodePathCollection::unstash 00359 // Access: Published 00360 // Description: Unstashes all NodePaths in the collection. 00361 //////////////////////////////////////////////////////////////////// 00362 void NodePathCollection:: 00363 unstash() { 00364 for (int i = 0; i < get_num_paths(); i++) { 00365 get_path(i).unstash(); 00366 } 00367 } 00368 00369 //////////////////////////////////////////////////////////////////// 00370 // Function: NodePathCollection::output 00371 // Access: Published 00372 // Description: Writes a brief one-line description of the 00373 // NodePathCollection to the indicated output stream. 00374 //////////////////////////////////////////////////////////////////// 00375 void NodePathCollection:: 00376 output(ostream &out) const { 00377 if (get_num_paths() == 1) { 00378 out << "1 NodePath"; 00379 } else { 00380 out << get_num_paths() << " NodePaths"; 00381 } 00382 } 00383 00384 //////////////////////////////////////////////////////////////////// 00385 // Function: NodePathCollection::write 00386 // Access: Published 00387 // Description: Writes a complete multi-line description of the 00388 // NodePathCollection to the indicated output stream. 00389 //////////////////////////////////////////////////////////////////// 00390 void NodePathCollection:: 00391 write(ostream &out, int indent_level) const { 00392 for (int i = 0; i < get_num_paths(); i++) { 00393 indent(out, indent_level) << get_path(i) << "\n"; 00394 } 00395 }