nodePathCollection.cxx 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. // Filename: nodePathCollection.cxx
  2. // Created by: drose (06Mar02)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. //
  6. // PANDA 3D SOFTWARE
  7. // Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
  8. //
  9. // All use of this software is subject to the terms of the Panda 3d
  10. // Software license. You should have received a copy of this license
  11. // along with this source code; you will also find a current copy of
  12. // the license at http://etc.cmu.edu/panda3d/docs/license/ .
  13. //
  14. // To contact the maintainers of this program write to
  15. // [email protected] .
  16. //
  17. ////////////////////////////////////////////////////////////////////
  18. #include "nodePathCollection.h"
  19. #include "findApproxPath.h"
  20. #include "findApproxLevelEntry.h"
  21. #include "colorAttrib.h"
  22. #include "indent.h"
  23. ////////////////////////////////////////////////////////////////////
  24. // Function: NodePathCollection::Constructor
  25. // Access: Published
  26. // Description:
  27. ////////////////////////////////////////////////////////////////////
  28. NodePathCollection::
  29. NodePathCollection() {
  30. }
  31. ////////////////////////////////////////////////////////////////////
  32. // Function: NodePathCollection::Copy Constructor
  33. // Access: Published
  34. // Description:
  35. ////////////////////////////////////////////////////////////////////
  36. NodePathCollection::
  37. NodePathCollection(const NodePathCollection &copy) :
  38. _node_paths(copy._node_paths)
  39. {
  40. }
  41. ////////////////////////////////////////////////////////////////////
  42. // Function: NodePathCollection::Copy Assignment Operator
  43. // Access: Published
  44. // Description:
  45. ////////////////////////////////////////////////////////////////////
  46. void NodePathCollection::
  47. operator = (const NodePathCollection &copy) {
  48. _node_paths = copy._node_paths;
  49. }
  50. ////////////////////////////////////////////////////////////////////
  51. // Function: NodePathCollection::add_path
  52. // Access: Published
  53. // Description: Adds a new NodePath to the collection.
  54. ////////////////////////////////////////////////////////////////////
  55. void NodePathCollection::
  56. add_path(const NodePath &node_path) {
  57. // If the pointer to our internal array is shared by any other
  58. // NodePathCollections, we have to copy the array now so we won't
  59. // inadvertently modify any of our brethren NodePathCollection
  60. // objects.
  61. if (_node_paths.get_ref_count() > 1) {
  62. NodePaths old_node_paths = _node_paths;
  63. _node_paths = NodePaths::empty_array(0);
  64. _node_paths.v() = old_node_paths.v();
  65. }
  66. _node_paths.push_back(node_path);
  67. }
  68. ////////////////////////////////////////////////////////////////////
  69. // Function: NodePathCollection::remove_path
  70. // Access: Published
  71. // Description: Removes the indicated NodePath from the collection.
  72. // Returns true if the path was removed, false if it was
  73. // not a member of the collection.
  74. ////////////////////////////////////////////////////////////////////
  75. bool NodePathCollection::
  76. remove_path(const NodePath &node_path) {
  77. int path_index = -1;
  78. for (int i = 0; path_index == -1 && i < (int)_node_paths.size(); i++) {
  79. if (_node_paths[i] == node_path) {
  80. path_index = i;
  81. }
  82. }
  83. if (path_index == -1) {
  84. // The indicated path was not a member of the collection.
  85. return false;
  86. }
  87. // If the pointer to our internal array is shared by any other
  88. // NodePathCollections, we have to copy the array now so we won't
  89. // inadvertently modify any of our brethren NodePathCollection
  90. // objects.
  91. if (_node_paths.get_ref_count() > 1) {
  92. NodePaths old_node_paths = _node_paths;
  93. _node_paths = NodePaths::empty_array(0);
  94. _node_paths.v() = old_node_paths.v();
  95. }
  96. _node_paths.erase(_node_paths.begin() + path_index);
  97. return true;
  98. }
  99. ////////////////////////////////////////////////////////////////////
  100. // Function: NodePathCollection::add_paths_from
  101. // Access: Published
  102. // Description: Adds all the NodePaths indicated in the other
  103. // collection to this path. The other paths are simply
  104. // appended to the end of the paths in this list;
  105. // duplicates are not automatically removed.
  106. ////////////////////////////////////////////////////////////////////
  107. void NodePathCollection::
  108. add_paths_from(const NodePathCollection &other) {
  109. int other_num_paths = other.get_num_paths();
  110. for (int i = 0; i < other_num_paths; i++) {
  111. add_path(other.get_path(i));
  112. }
  113. }
  114. ////////////////////////////////////////////////////////////////////
  115. // Function: NodePathCollection::remove_paths_from
  116. // Access: Published
  117. // Description: Removes from this collection all of the NodePaths
  118. // listed in the other collection.
  119. ////////////////////////////////////////////////////////////////////
  120. void NodePathCollection::
  121. remove_paths_from(const NodePathCollection &other) {
  122. NodePaths new_paths;
  123. int num_paths = get_num_paths();
  124. for (int i = 0; i < num_paths; i++) {
  125. NodePath path = get_path(i);
  126. if (!other.has_path(path)) {
  127. new_paths.push_back(path);
  128. }
  129. }
  130. _node_paths = new_paths;
  131. }
  132. ////////////////////////////////////////////////////////////////////
  133. // Function: NodePathCollection::remove_duplicate_paths
  134. // Access: Published
  135. // Description: Removes any duplicate entries of the same NodePaths
  136. // on this collection. If a NodePath appears multiple
  137. // times, the first appearance is retained; subsequent
  138. // appearances are removed.
  139. ////////////////////////////////////////////////////////////////////
  140. void NodePathCollection::
  141. remove_duplicate_paths() {
  142. NodePaths new_paths;
  143. int num_paths = get_num_paths();
  144. for (int i = 0; i < num_paths; i++) {
  145. NodePath path = get_path(i);
  146. bool duplicated = false;
  147. for (int j = 0; j < i && !duplicated; j++) {
  148. duplicated = (path == get_path(j));
  149. }
  150. if (!duplicated) {
  151. new_paths.push_back(path);
  152. }
  153. }
  154. _node_paths = new_paths;
  155. }
  156. ////////////////////////////////////////////////////////////////////
  157. // Function: NodePathCollection::has_path
  158. // Access: Published
  159. // Description: Returns true if the indicated NodePath appears in
  160. // this collection, false otherwise.
  161. ////////////////////////////////////////////////////////////////////
  162. bool NodePathCollection::
  163. has_path(const NodePath &path) const {
  164. for (int i = 0; i < get_num_paths(); i++) {
  165. if (path == get_path(i)) {
  166. return true;
  167. }
  168. }
  169. return false;
  170. }
  171. ////////////////////////////////////////////////////////////////////
  172. // Function: NodePathCollection::clear
  173. // Access: Published
  174. // Description: Removes all NodePaths from the collection.
  175. ////////////////////////////////////////////////////////////////////
  176. void NodePathCollection::
  177. clear() {
  178. _node_paths.clear();
  179. }
  180. ////////////////////////////////////////////////////////////////////
  181. // Function: NodePathCollection::is_empty
  182. // Access: Published
  183. // Description: Returns true if there are no NodePaths in the
  184. // collection, false otherwise.
  185. ////////////////////////////////////////////////////////////////////
  186. bool NodePathCollection::
  187. is_empty() const {
  188. return _node_paths.empty();
  189. }
  190. ////////////////////////////////////////////////////////////////////
  191. // Function: NodePathCollection::get_num_paths
  192. // Access: Published
  193. // Description: Returns the number of NodePaths in the collection.
  194. ////////////////////////////////////////////////////////////////////
  195. int NodePathCollection::
  196. get_num_paths() const {
  197. return _node_paths.size();
  198. }
  199. ////////////////////////////////////////////////////////////////////
  200. // Function: NodePathCollection::get_path
  201. // Access: Published
  202. // Description: Returns the nth NodePath in the collection.
  203. ////////////////////////////////////////////////////////////////////
  204. NodePath NodePathCollection::
  205. get_path(int index) const {
  206. nassertr(index >= 0 && index < (int)_node_paths.size(), NodePath());
  207. return _node_paths[index];
  208. }
  209. ////////////////////////////////////////////////////////////////////
  210. // Function: NodePathCollection::operator []
  211. // Access: Published
  212. // Description: Returns the nth NodePath in the collection. This is
  213. // the same as get_path(), but it may be a more
  214. // convenient way to access it.
  215. ////////////////////////////////////////////////////////////////////
  216. NodePath NodePathCollection::
  217. operator [] (int index) const {
  218. nassertr(index >= 0 && index < (int)_node_paths.size(), NodePath());
  219. return _node_paths[index];
  220. }
  221. ////////////////////////////////////////////////////////////////////
  222. // Function: NodePathCollection::ls
  223. // Access: Published
  224. // Description: Lists all the nodes at and below each node in the
  225. // collection hierarchically.
  226. ////////////////////////////////////////////////////////////////////
  227. void NodePathCollection::
  228. ls(ostream &out, int indent_level) const {
  229. for (int i = 0; i < get_num_paths(); i++) {
  230. NodePath path = get_path(i);
  231. indent(out, indent_level) << path << "\n";
  232. path.ls(out, indent_level + 2);
  233. out << "\n";
  234. }
  235. }
  236. ////////////////////////////////////////////////////////////////////
  237. // Function: NodePathCollection::find_all_matches
  238. // Access: Published
  239. // Description: Returns the complete set of all NodePaths that begin
  240. // with any NodePath in this collection and can be
  241. // extended by path. The shortest paths will be listed
  242. // first.
  243. ////////////////////////////////////////////////////////////////////
  244. NodePathCollection NodePathCollection::
  245. find_all_matches(const string &path) const {
  246. NodePathCollection result;
  247. FindApproxPath approx_path;
  248. if (approx_path.add_string(path)) {
  249. if (!is_empty()) {
  250. FindApproxLevelEntry *level = NULL;
  251. for (int i = 0; i < get_num_paths(); i++) {
  252. FindApproxLevelEntry *start =
  253. new FindApproxLevelEntry(get_path(i), approx_path);
  254. start->_next = level;
  255. level = start;
  256. }
  257. get_path(0).find_matches(result, level, -1);
  258. }
  259. }
  260. return result;
  261. }
  262. ////////////////////////////////////////////////////////////////////
  263. // Function: NodePathCollection::reparent_to
  264. // Access: Published
  265. // Description: Reparents all the NodePaths in the collection to the
  266. // indicated node.
  267. ////////////////////////////////////////////////////////////////////
  268. void NodePathCollection::
  269. reparent_to(const NodePath &other) {
  270. for (int i = 0; i < get_num_paths(); i++) {
  271. get_path(i).reparent_to(other);
  272. }
  273. }
  274. ////////////////////////////////////////////////////////////////////
  275. // Function: NodePathCollection::wrt_reparent_to
  276. // Access: Published
  277. // Description: Reparents all the NodePaths in the collection to the
  278. // indicated node, adjusting each transform so as not to
  279. // move in world coordinates.
  280. ////////////////////////////////////////////////////////////////////
  281. void NodePathCollection::
  282. wrt_reparent_to(const NodePath &other) {
  283. for (int i = 0; i < get_num_paths(); i++) {
  284. get_path(i).wrt_reparent_to(other);
  285. }
  286. }
  287. ////////////////////////////////////////////////////////////////////
  288. // Function: NodePathCollection::show
  289. // Access: Published
  290. // Description: Shows all NodePaths in the collection.
  291. ////////////////////////////////////////////////////////////////////
  292. void NodePathCollection::
  293. show() {
  294. for (int i = 0; i < get_num_paths(); i++) {
  295. get_path(i).show();
  296. }
  297. }
  298. ////////////////////////////////////////////////////////////////////
  299. // Function: NodePathCollection::show
  300. // Access: Published
  301. // Description: Hides all NodePaths in the collection.
  302. ////////////////////////////////////////////////////////////////////
  303. void NodePathCollection::
  304. hide() {
  305. for (int i = 0; i < get_num_paths(); i++) {
  306. get_path(i).hide();
  307. }
  308. }
  309. ////////////////////////////////////////////////////////////////////
  310. // Function: NodePathCollection::stash
  311. // Access: Published
  312. // Description: Stashes all NodePaths in the collection.
  313. ////////////////////////////////////////////////////////////////////
  314. void NodePathCollection::
  315. stash() {
  316. for (int i = 0; i < get_num_paths(); i++) {
  317. get_path(i).stash();
  318. }
  319. }
  320. ////////////////////////////////////////////////////////////////////
  321. // Function: NodePathCollection::unstash
  322. // Access: Published
  323. // Description: Unstashes all NodePaths in the collection.
  324. ////////////////////////////////////////////////////////////////////
  325. void NodePathCollection::
  326. unstash() {
  327. for (int i = 0; i < get_num_paths(); i++) {
  328. get_path(i).unstash();
  329. }
  330. }
  331. ////////////////////////////////////////////////////////////////////
  332. // Function: NodePathCollection::detach
  333. // Access: Published
  334. // Description: Detaches all NodePaths in the collection.
  335. ////////////////////////////////////////////////////////////////////
  336. void NodePathCollection::
  337. detach() {
  338. for (int i = 0; i < get_num_paths(); i++) {
  339. get_path(i).detach_node();
  340. }
  341. }
  342. ////////////////////////////////////////////////////////////////////
  343. // Function: NodePathCollection::get_collide_mask
  344. // Access: Published
  345. // Description: Returns the union of all of the into_collide_masks
  346. // for nodes at this level and below. This is the same
  347. // thing as node()->get_net_collide_mask().
  348. //
  349. // If you want to return what the into_collide_mask of
  350. // this node itself is, without regard to its children,
  351. // use node()->get_into_collide_mask().
  352. ////////////////////////////////////////////////////////////////////
  353. CollideMask NodePathCollection::
  354. get_collide_mask() const {
  355. CollideMask collide_mask;
  356. for (int i = 0; i < get_num_paths(); i++) {
  357. collide_mask |= get_path(i).get_collide_mask();
  358. }
  359. return collide_mask;
  360. }
  361. ////////////////////////////////////////////////////////////////////
  362. // Function: NodePathCollection::set_collide_mask
  363. // Access: Published
  364. // Description: Recursively applies the indicated CollideMask to the
  365. // into_collide_masks for all nodes at this level and
  366. // below. Only nodes
  367. //
  368. // The default is to change all bits, but if
  369. // bits_to_change is not all bits on, then only the bits
  370. // that are set in bits_to_change are modified, allowing
  371. // this call to change only a subset of the bits in the
  372. // subgraph.
  373. ////////////////////////////////////////////////////////////////////
  374. void NodePathCollection::
  375. set_collide_mask(CollideMask new_mask, CollideMask bits_to_change,
  376. TypeHandle node_type) {
  377. for (int i = 0; i < get_num_paths(); i++) {
  378. get_path(i).set_collide_mask(new_mask, bits_to_change, node_type);
  379. }
  380. }
  381. ////////////////////////////////////////////////////////////////////
  382. // Function: NodePathCollection::set_color
  383. // Access: Published
  384. // Description: Colors all NodePaths in the collection
  385. ////////////////////////////////////////////////////////////////////
  386. void NodePathCollection::
  387. set_color(float r, float g, float b, float a, int priority) {
  388. for (int i = 0; i < get_num_paths(); i++) {
  389. get_path(i).set_color(Colorf(r, g, b, a), priority);
  390. }
  391. }
  392. ////////////////////////////////////////////////////////////////////
  393. // Function: NodePathCollection::set_color
  394. // Access: Published
  395. // Description: Colors all NodePaths in the collection
  396. ////////////////////////////////////////////////////////////////////
  397. void NodePathCollection::
  398. set_color(const Colorf &color, int priority) {
  399. for (int i = 0; i < get_num_paths(); i++) {
  400. get_path(i).node()->set_attrib(ColorAttrib::make_flat(color), priority);
  401. }
  402. }
  403. ////////////////////////////////////////////////////////////////////
  404. // Function: NodePathCollection::output
  405. // Access: Published
  406. // Description: Writes a brief one-line description of the
  407. // NodePathCollection to the indicated output stream.
  408. ////////////////////////////////////////////////////////////////////
  409. void NodePathCollection::
  410. output(ostream &out) const {
  411. if (get_num_paths() == 1) {
  412. out << "1 NodePath";
  413. } else {
  414. out << get_num_paths() << " NodePaths";
  415. }
  416. }
  417. ////////////////////////////////////////////////////////////////////
  418. // Function: NodePathCollection::write
  419. // Access: Published
  420. // Description: Writes a complete multi-line description of the
  421. // NodePathCollection to the indicated output stream.
  422. ////////////////////////////////////////////////////////////////////
  423. void NodePathCollection::
  424. write(ostream &out, int indent_level) const {
  425. for (int i = 0; i < get_num_paths(); i++) {
  426. indent(out, indent_level) << get_path(i) << "\n";
  427. }
  428. }