NodePath_extensions.py 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903
  1. ####################################################################
  2. #Dtool_funcToMethod(func, class)
  3. #del func
  4. #####################################################################
  5. """
  6. NodePath-extensions module: contains methods to extend functionality
  7. of the NodePath class
  8. """
  9. from panda3d.core import NodePath
  10. from .extension_native_helpers import Dtool_funcToMethod
  11. import warnings
  12. ####################################################################
  13. def id(self):
  14. """Deprecated. Returns a unique id identifying the NodePath instance"""
  15. if __debug__:
  16. warnings.warn("NodePath.id() is deprecated. Use hash(NodePath) or NodePath.get_key() instead.", DeprecationWarning, stacklevel=2)
  17. return self.getKey()
  18. Dtool_funcToMethod(id, NodePath)
  19. del id
  20. #####################################################################
  21. def getChildrenAsList(self):
  22. """Deprecated. Converts a node path's child NodePathCollection into a list"""
  23. if __debug__:
  24. warnings.warn("NodePath.getChildrenAsList() is deprecated. Use get_children() instead.", DeprecationWarning, stacklevel=2)
  25. return list(self.getChildren())
  26. Dtool_funcToMethod(getChildrenAsList, NodePath)
  27. del getChildrenAsList
  28. #####################################################################
  29. def printChildren(self):
  30. """Deprecated. Prints out the children of the bottom node of a node path"""
  31. if __debug__:
  32. warnings.warn("NodePath.printChildren() is deprecated.", DeprecationWarning, stacklevel=2)
  33. for child in self.getChildren():
  34. print(child.getName())
  35. Dtool_funcToMethod(printChildren, NodePath)
  36. del printChildren
  37. #####################################################################
  38. def removeChildren(self):
  39. """Deprecated. Deletes the children of the bottom node of a node path"""
  40. if __debug__:
  41. warnings.warn("NodePath.removeChildren() is deprecated. Use get_children().detach() instead.", DeprecationWarning, stacklevel=2)
  42. self.getChildren().detach()
  43. Dtool_funcToMethod(removeChildren, NodePath)
  44. del removeChildren
  45. #####################################################################
  46. def toggleVis(self):
  47. """Deprecated. Toggles visibility of a nodePath"""
  48. if __debug__:
  49. warnings.warn("NodePath.toggleVis() is deprecated. Use is_hidden(), show() and hide() instead.", DeprecationWarning, stacklevel=2)
  50. if self.isHidden():
  51. self.show()
  52. return 1
  53. else:
  54. self.hide()
  55. return 0
  56. Dtool_funcToMethod(toggleVis, NodePath)
  57. del toggleVis
  58. #####################################################################
  59. def showSiblings(self):
  60. """Deprecated. Show all the siblings of a node path"""
  61. if __debug__:
  62. warnings.warn("NodePath.showSiblings() is deprecated.", DeprecationWarning, stacklevel=2)
  63. for sib in self.getParent().getChildren():
  64. if sib.node() != self.node():
  65. sib.show()
  66. Dtool_funcToMethod(showSiblings, NodePath)
  67. del showSiblings
  68. #####################################################################
  69. def hideSiblings(self):
  70. """Deprecated. Hide all the siblings of a node path"""
  71. if __debug__:
  72. warnings.warn("NodePath.hideSiblings() is deprecated.", DeprecationWarning, stacklevel=2)
  73. for sib in self.getParent().getChildren():
  74. if sib.node() != self.node():
  75. sib.hide()
  76. Dtool_funcToMethod(hideSiblings, NodePath)
  77. del hideSiblings
  78. #####################################################################
  79. def showAllDescendants(self):
  80. """Deprecated. Show the node path and all its children"""
  81. if __debug__:
  82. warnings.warn("NodePath.showAllDescendants() is deprecated.", DeprecationWarning, stacklevel=2)
  83. self.show()
  84. for child in self.getChildren():
  85. child.showAllDescendants()
  86. Dtool_funcToMethod(showAllDescendants, NodePath)
  87. del showAllDescendants
  88. #####################################################################
  89. def isolate(self):
  90. """Deprecated. Show the node path and hide its siblings"""
  91. if __debug__:
  92. warnings.warn("NodePath.isolate() is deprecated.", DeprecationWarning, stacklevel=2)
  93. self.showAllDescendants()
  94. for sib in self.getParent().getChildren():
  95. if sib.node() != self.node():
  96. sib.hide()
  97. Dtool_funcToMethod(isolate, NodePath)
  98. del isolate
  99. #####################################################################
  100. def remove(self):
  101. """Deprecated. Remove a node path from the scene graph"""
  102. if __debug__:
  103. warnings.warn("NodePath.remove() is deprecated. Use remove_node() instead.", DeprecationWarning, stacklevel=2)
  104. # Send message in case anyone needs to do something
  105. # before node is deleted
  106. from direct.showbase.MessengerGlobal import messenger
  107. messenger.send('preRemoveNodePath', [self])
  108. # Remove nodePath
  109. self.removeNode()
  110. Dtool_funcToMethod(remove, NodePath)
  111. del remove
  112. #####################################################################
  113. def lsNames(self):
  114. """Deprecated. Walk down a tree and print out the path"""
  115. if __debug__:
  116. warnings.warn("NodePath.lsNames() is deprecated.", DeprecationWarning, stacklevel=2)
  117. if self.isEmpty():
  118. print("(empty)")
  119. else:
  120. type = self.node().getType().getName()
  121. name = self.getName()
  122. print(type + " " + name)
  123. self.lsNamesRecurse()
  124. Dtool_funcToMethod(lsNames, NodePath)
  125. del lsNames
  126. #####################################################################
  127. def lsNamesRecurse(self, indentString=' '):
  128. """Deprecated. Walk down a tree and print out the path"""
  129. if __debug__:
  130. warnings.warn("NodePath.lsNamesRecurse() is deprecated.", DeprecationWarning, stacklevel=2)
  131. for nodePath in self.getChildren():
  132. type = nodePath.node().getType().getName()
  133. name = nodePath.getName()
  134. print(indentString + type + " " + name)
  135. nodePath.lsNamesRecurse(indentString + " ")
  136. Dtool_funcToMethod(lsNamesRecurse, NodePath)
  137. del lsNamesRecurse
  138. #####################################################################
  139. def reverseLsNames(self):
  140. """Deprecated. Walk up a tree and print out the path to the root"""
  141. if __debug__:
  142. warnings.warn("NodePath.reverseLsNames() is deprecated.", DeprecationWarning, stacklevel=2)
  143. ancestors = list(self.getAncestors())
  144. ancestry = ancestors.reverse()
  145. indentString = ""
  146. for nodePath in ancestry:
  147. type = nodePath.node().getType().getName()
  148. name = nodePath.getName()
  149. print(indentString + type + " " + name)
  150. indentString = indentString + " "
  151. Dtool_funcToMethod(reverseLsNames, NodePath)
  152. del reverseLsNames
  153. #####################################################################
  154. def getAncestry(self):
  155. """Deprecated. Get a list of a node path's ancestors"""
  156. if __debug__:
  157. warnings.warn("NodePath.getAncestry() is deprecated. Use get_ancestors() instead.", DeprecationWarning, stacklevel=2)
  158. ancestors = list(self.getAncestors())
  159. ancestors.reverse()
  160. return ancestors
  161. Dtool_funcToMethod(getAncestry, NodePath)
  162. del getAncestry
  163. #####################################################################
  164. def pPrintString(self, other = None):
  165. """
  166. Deprecated. pretty print
  167. """
  168. if __debug__:
  169. warnings.warn("NodePath.pPrintString() is deprecated.", DeprecationWarning, stacklevel=2)
  170. # Normally I would have put the if __debug__ around
  171. # the entire funciton, the that doesn't seem to work
  172. # with -extensions. Maybe someone will look into
  173. # this further.
  174. if other:
  175. pos = self.getPos(other)
  176. hpr = self.getHpr(other)
  177. scale = self.getScale(other)
  178. shear = self.getShear(other)
  179. otherString = " 'other': %s,\n" % (other.getName(),)
  180. else:
  181. pos = self.getPos()
  182. hpr = self.getHpr()
  183. scale = self.getScale()
  184. shear = self.getShear()
  185. otherString = '\n'
  186. return (
  187. "%s = {"%(self.getName()) +
  188. otherString +
  189. " 'Pos': (%s),\n" % pos.pPrintValues() +
  190. " 'Hpr': (%s),\n" % hpr.pPrintValues() +
  191. " 'Scale': (%s),\n" % scale.pPrintValues() +
  192. " 'Shear': (%s),\n" % shear.pPrintValues() +
  193. "}")
  194. Dtool_funcToMethod(pPrintString, NodePath)
  195. del pPrintString
  196. #####################################################################
  197. def printPos(self, other = None, sd = 2):
  198. """ Deprecated. Pretty print a node path's pos """
  199. if __debug__:
  200. warnings.warn("NodePath.printPos() is deprecated.", DeprecationWarning, stacklevel=2)
  201. formatString = '%0.' + '%d' % sd + 'f'
  202. if other:
  203. pos = self.getPos(other)
  204. otherString = other.getName() + ', '
  205. else:
  206. pos = self.getPos()
  207. otherString = ''
  208. print((self.getName() + '.setPos(' + otherString +
  209. formatString % pos[0] + ', ' +
  210. formatString % pos[1] + ', ' +
  211. formatString % pos[2] +
  212. ')\n'))
  213. Dtool_funcToMethod(printPos, NodePath)
  214. del printPos
  215. #####################################################################
  216. def printHpr(self, other = None, sd = 2):
  217. """ Deprecated. Pretty print a node path's hpr """
  218. if __debug__:
  219. warnings.warn("NodePath.printHpr() is deprecated.", DeprecationWarning, stacklevel=2)
  220. formatString = '%0.' + '%d' % sd + 'f'
  221. if other:
  222. hpr = self.getHpr(other)
  223. otherString = other.getName() + ', '
  224. else:
  225. hpr = self.getHpr()
  226. otherString = ''
  227. print((self.getName() + '.setHpr(' + otherString +
  228. formatString % hpr[0] + ', ' +
  229. formatString % hpr[1] + ', ' +
  230. formatString % hpr[2] +
  231. ')\n'))
  232. Dtool_funcToMethod(printHpr, NodePath)
  233. del printHpr
  234. #####################################################################
  235. def printScale(self, other = None, sd = 2):
  236. """ Deprecated. Pretty print a node path's scale """
  237. if __debug__:
  238. warnings.warn("NodePath.printScale() is deprecated.", DeprecationWarning, stacklevel=2)
  239. formatString = '%0.' + '%d' % sd + 'f'
  240. if other:
  241. scale = self.getScale(other)
  242. otherString = other.getName() + ', '
  243. else:
  244. scale = self.getScale()
  245. otherString = ''
  246. print((self.getName() + '.setScale(' + otherString +
  247. formatString % scale[0] + ', ' +
  248. formatString % scale[1] + ', ' +
  249. formatString % scale[2] +
  250. ')\n'))
  251. Dtool_funcToMethod(printScale, NodePath)
  252. del printScale
  253. #####################################################################
  254. def printPosHpr(self, other = None, sd = 2):
  255. """ Deprecated. Pretty print a node path's pos and, hpr """
  256. if __debug__:
  257. warnings.warn("NodePath.printPosHpr() is deprecated.", DeprecationWarning, stacklevel=2)
  258. formatString = '%0.' + '%d' % sd + 'f'
  259. if other:
  260. pos = self.getPos(other)
  261. hpr = self.getHpr(other)
  262. otherString = other.getName() + ', '
  263. else:
  264. pos = self.getPos()
  265. hpr = self.getHpr()
  266. otherString = ''
  267. print((self.getName() + '.setPosHpr(' + otherString +
  268. formatString % pos[0] + ', ' +
  269. formatString % pos[1] + ', ' +
  270. formatString % pos[2] + ', ' +
  271. formatString % hpr[0] + ', ' +
  272. formatString % hpr[1] + ', ' +
  273. formatString % hpr[2] +
  274. ')\n'))
  275. Dtool_funcToMethod(printPosHpr, NodePath)
  276. del printPosHpr
  277. #####################################################################
  278. def printPosHprScale(self, other = None, sd = 2):
  279. """ Deprecated. Pretty print a node path's pos, hpr, and scale """
  280. if __debug__:
  281. warnings.warn("NodePath.printPosHprScale() is deprecated.", DeprecationWarning, stacklevel=2)
  282. formatString = '%0.' + '%d' % sd + 'f'
  283. if other:
  284. pos = self.getPos(other)
  285. hpr = self.getHpr(other)
  286. scale = self.getScale(other)
  287. otherString = other.getName() + ', '
  288. else:
  289. pos = self.getPos()
  290. hpr = self.getHpr()
  291. scale = self.getScale()
  292. otherString = ''
  293. print((self.getName() + '.setPosHprScale(' + otherString +
  294. formatString % pos[0] + ', ' +
  295. formatString % pos[1] + ', ' +
  296. formatString % pos[2] + ', ' +
  297. formatString % hpr[0] + ', ' +
  298. formatString % hpr[1] + ', ' +
  299. formatString % hpr[2] + ', ' +
  300. formatString % scale[0] + ', ' +
  301. formatString % scale[1] + ', ' +
  302. formatString % scale[2] +
  303. ')\n'))
  304. Dtool_funcToMethod(printPosHprScale, NodePath)
  305. del printPosHprScale
  306. #####################################################################
  307. def printTransform(self, other = None, sd = 2, fRecursive = 0):
  308. "Deprecated."
  309. if __debug__:
  310. warnings.warn("NodePath.printTransform() is deprecated.", DeprecationWarning, stacklevel=2)
  311. from panda3d.core import Vec3
  312. fmtStr = '%%0.%df' % sd
  313. name = self.getName()
  314. if other is None:
  315. transform = self.getTransform()
  316. else:
  317. transform = self.getTransform(other)
  318. if transform.hasPos():
  319. pos = transform.getPos()
  320. if not pos.almostEqual(Vec3(0)):
  321. outputString = '%s.setPos(%s, %s, %s)' % (name, fmtStr, fmtStr, fmtStr)
  322. print(outputString % (pos[0], pos[1], pos[2]))
  323. if transform.hasHpr():
  324. hpr = transform.getHpr()
  325. if not hpr.almostEqual(Vec3(0)):
  326. outputString = '%s.setHpr(%s, %s, %s)' % (name, fmtStr, fmtStr, fmtStr)
  327. print(outputString % (hpr[0], hpr[1], hpr[2]))
  328. if transform.hasScale():
  329. if transform.hasUniformScale():
  330. scale = transform.getUniformScale()
  331. if scale != 1.0:
  332. outputString = '%s.setScale(%s)' % (name, fmtStr)
  333. print(outputString % scale)
  334. else:
  335. scale = transform.getScale()
  336. if not scale.almostEqual(Vec3(1)):
  337. outputString = '%s.setScale(%s, %s, %s)' % (name, fmtStr, fmtStr, fmtStr)
  338. print(outputString % (scale[0], scale[1], scale[2]))
  339. if fRecursive:
  340. for child in self.getChildren():
  341. child.printTransform(other, sd, fRecursive)
  342. Dtool_funcToMethod(printTransform, NodePath)
  343. del printTransform
  344. #####################################################################
  345. def iPos(self, other = None):
  346. """ Deprecated. Set node path's pos to 0, 0, 0 """
  347. if __debug__:
  348. warnings.warn("NodePath.iPos() is deprecated.", DeprecationWarning, stacklevel=2)
  349. if other:
  350. self.setPos(other, 0, 0, 0)
  351. else:
  352. self.setPos(0, 0, 0)
  353. Dtool_funcToMethod(iPos, NodePath)
  354. del iPos
  355. #####################################################################
  356. def iHpr(self, other = None):
  357. """ Deprecated. Set node path's hpr to 0, 0, 0 """
  358. if __debug__:
  359. warnings.warn("NodePath.iHpr() is deprecated.", DeprecationWarning, stacklevel=2)
  360. if other:
  361. self.setHpr(other, 0, 0, 0)
  362. else:
  363. self.setHpr(0, 0, 0)
  364. Dtool_funcToMethod(iHpr, NodePath)
  365. del iHpr
  366. #####################################################################
  367. def iScale(self, other = None):
  368. """ Deprecated. Set node path's scale to 1, 1, 1 """
  369. if __debug__:
  370. warnings.warn("NodePath.iScale() is deprecated.", DeprecationWarning, stacklevel=2)
  371. if other:
  372. self.setScale(other, 1, 1, 1)
  373. else:
  374. self.setScale(1, 1, 1)
  375. Dtool_funcToMethod(iScale, NodePath)
  376. del iScale
  377. #####################################################################
  378. def iPosHpr(self, other = None):
  379. """ Deprecated. Set node path's pos and hpr to 0, 0, 0 """
  380. if __debug__:
  381. warnings.warn("NodePath.iPosHpr() is deprecated.", DeprecationWarning, stacklevel=2)
  382. if other:
  383. self.setPosHpr(other, 0, 0, 0, 0, 0, 0)
  384. else:
  385. self.setPosHpr(0, 0, 0, 0, 0, 0)
  386. Dtool_funcToMethod(iPosHpr, NodePath)
  387. del iPosHpr
  388. #####################################################################
  389. def iPosHprScale(self, other = None):
  390. """ Deprecated. Set node path's pos and hpr to 0, 0, 0 and scale to 1, 1, 1 """
  391. if __debug__:
  392. warnings.warn("NodePath.iPosHprScale() is deprecated.", DeprecationWarning, stacklevel=2)
  393. if other:
  394. self.setPosHprScale(other, 0, 0, 0, 0, 0, 0, 1, 1, 1)
  395. else:
  396. self.setPosHprScale(0, 0, 0, 0, 0, 0, 1, 1, 1)
  397. # private methods
  398. Dtool_funcToMethod(iPosHprScale, NodePath)
  399. del iPosHprScale
  400. #####################################################################
  401. def place(self):
  402. from direct.showbase import ShowBaseGlobal
  403. ShowBaseGlobal.base.startDirect(fWantTk = 1)
  404. # Don't use a regular import, to prevent ModuleFinder from picking
  405. # it up as a dependency when building a .p3d package.
  406. import importlib
  407. Placer = importlib.import_module('direct.tkpanels.Placer')
  408. return Placer.place(self)
  409. Dtool_funcToMethod(place, NodePath)
  410. del place
  411. #####################################################################
  412. def explore(self):
  413. from direct.showbase import ShowBaseGlobal
  414. ShowBaseGlobal.base.startDirect(fWantTk = 1)
  415. # Don't use a regular import, to prevent ModuleFinder from picking
  416. # it up as a dependency when building a .p3d package.
  417. import importlib
  418. SceneGraphExplorer = importlib.import_module('direct.tkwidgets.SceneGraphExplorer')
  419. return SceneGraphExplorer.explore(self)
  420. Dtool_funcToMethod(explore, NodePath)
  421. del explore
  422. #####################################################################
  423. def rgbPanel(self, cb = None):
  424. from direct.showbase import ShowBaseGlobal
  425. ShowBaseGlobal.base.startTk()
  426. # Don't use a regular import, to prevent ModuleFinder from picking
  427. # it up as a dependency when building a .p3d package.
  428. import importlib
  429. Valuator = importlib.import_module('direct.tkwidgets.Valuator')
  430. return Valuator.rgbPanel(self, cb)
  431. Dtool_funcToMethod(rgbPanel, NodePath)
  432. del rgbPanel
  433. #####################################################################
  434. def select(self):
  435. from direct.showbase import ShowBaseGlobal
  436. base = ShowBaseGlobal.base
  437. base.startDirect(fWantTk = 0)
  438. base.direct.select(self)
  439. Dtool_funcToMethod(select, NodePath)
  440. del select
  441. #####################################################################
  442. def deselect(self):
  443. from direct.showbase import ShowBaseGlobal
  444. base = ShowBaseGlobal.base
  445. base.startDirect(fWantTk = 0)
  446. base.direct.deselect(self)
  447. Dtool_funcToMethod(deselect, NodePath)
  448. del deselect
  449. #####################################################################
  450. def showCS(self, mask = None):
  451. """
  452. Deprecated.
  453. Shows the collision solids at or below this node. If mask is
  454. not None, it is a BitMask32 object (e.g. WallBitmask,
  455. CameraBitmask) that indicates which particular collision
  456. solids should be made visible; otherwise, all of them will be.
  457. """
  458. if __debug__:
  459. warnings.warn("NodePath.showCS() is deprecated. Use findAllMatches('**/+CollisionNode').show() instead.", DeprecationWarning, stacklevel=2)
  460. npc = self.findAllMatches('**/+CollisionNode')
  461. for p in range(0, npc.getNumPaths()):
  462. np = npc[p]
  463. if mask is None or (np.node().getIntoCollideMask() & mask).getWord():
  464. np.show()
  465. Dtool_funcToMethod(showCS, NodePath)
  466. del showCS
  467. #####################################################################
  468. def hideCS(self, mask = None):
  469. """
  470. Deprecated.
  471. Hides the collision solids at or below this node. If mask is
  472. not None, it is a BitMask32 object (e.g. WallBitmask,
  473. CameraBitmask) that indicates which particular collision
  474. solids should be hidden; otherwise, all of them will be.
  475. """
  476. if __debug__:
  477. warnings.warn("NodePath.hideCS() is deprecated. Use findAllMatches('**/+CollisionNode').hide() instead.", DeprecationWarning, stacklevel=2)
  478. npc = self.findAllMatches('**/+CollisionNode')
  479. for p in range(0, npc.getNumPaths()):
  480. np = npc[p]
  481. if mask is None or (np.node().getIntoCollideMask() & mask).getWord():
  482. np.hide()
  483. Dtool_funcToMethod(hideCS, NodePath)
  484. del hideCS
  485. #####################################################################
  486. def posInterval(self, *args, **kw):
  487. from direct.interval import LerpInterval
  488. return LerpInterval.LerpPosInterval(self, *args, **kw)
  489. Dtool_funcToMethod(posInterval, NodePath)
  490. del posInterval
  491. #####################################################################
  492. def hprInterval(self, *args, **kw):
  493. from direct.interval import LerpInterval
  494. return LerpInterval.LerpHprInterval(self, *args, **kw)
  495. Dtool_funcToMethod(hprInterval, NodePath)
  496. del hprInterval
  497. #####################################################################
  498. def quatInterval(self, *args, **kw):
  499. from direct.interval import LerpInterval
  500. return LerpInterval.LerpQuatInterval(self, *args, **kw)
  501. Dtool_funcToMethod(quatInterval, NodePath)
  502. del quatInterval
  503. #####################################################################
  504. def scaleInterval(self, *args, **kw):
  505. from direct.interval import LerpInterval
  506. return LerpInterval.LerpScaleInterval(self, *args, **kw)
  507. Dtool_funcToMethod(scaleInterval, NodePath)
  508. del scaleInterval
  509. #####################################################################
  510. def shearInterval(self, *args, **kw):
  511. from direct.interval import LerpInterval
  512. return LerpInterval.LerpShearInterval(self, *args, **kw)
  513. Dtool_funcToMethod(shearInterval, NodePath)
  514. del shearInterval
  515. #####################################################################
  516. def posHprInterval(self, *args, **kw):
  517. from direct.interval import LerpInterval
  518. return LerpInterval.LerpPosHprInterval(self, *args, **kw)
  519. Dtool_funcToMethod(posHprInterval, NodePath)
  520. del posHprInterval
  521. #####################################################################
  522. def posQuatInterval(self, *args, **kw):
  523. from direct.interval import LerpInterval
  524. return LerpInterval.LerpPosQuatInterval(self, *args, **kw)
  525. Dtool_funcToMethod(posQuatInterval, NodePath)
  526. del posQuatInterval
  527. #####################################################################
  528. def hprScaleInterval(self, *args, **kw):
  529. from direct.interval import LerpInterval
  530. return LerpInterval.LerpHprScaleInterval(self, *args, **kw)
  531. Dtool_funcToMethod(hprScaleInterval, NodePath)
  532. del hprScaleInterval
  533. #####################################################################
  534. def quatScaleInterval(self, *args, **kw):
  535. from direct.interval import LerpInterval
  536. return LerpInterval.LerpQuatScaleInterval(self, *args, **kw)
  537. Dtool_funcToMethod(quatScaleInterval, NodePath)
  538. del quatScaleInterval
  539. #####################################################################
  540. def posHprScaleInterval(self, *args, **kw):
  541. from direct.interval import LerpInterval
  542. return LerpInterval.LerpPosHprScaleInterval(self, *args, **kw)
  543. Dtool_funcToMethod(posHprScaleInterval, NodePath)
  544. del posHprScaleInterval
  545. #####################################################################
  546. def posQuatScaleInterval(self, *args, **kw):
  547. from direct.interval import LerpInterval
  548. return LerpInterval.LerpPosQuatScaleInterval(self, *args, **kw)
  549. Dtool_funcToMethod(posQuatScaleInterval, NodePath)
  550. del posQuatScaleInterval
  551. #####################################################################
  552. def posHprScaleShearInterval(self, *args, **kw):
  553. from direct.interval import LerpInterval
  554. return LerpInterval.LerpPosHprScaleShearInterval(self, *args, **kw)
  555. Dtool_funcToMethod(posHprScaleShearInterval, NodePath)
  556. del posHprScaleShearInterval
  557. #####################################################################
  558. def posQuatScaleShearInterval(self, *args, **kw):
  559. from direct.interval import LerpInterval
  560. return LerpInterval.LerpPosQuatScaleShearInterval(self, *args, **kw)
  561. Dtool_funcToMethod(posQuatScaleShearInterval, NodePath)
  562. del posQuatScaleShearInterval
  563. #####################################################################
  564. def colorInterval(self, *args, **kw):
  565. from direct.interval import LerpInterval
  566. return LerpInterval.LerpColorInterval(self, *args, **kw)
  567. Dtool_funcToMethod(colorInterval, NodePath)
  568. del colorInterval
  569. #####################################################################
  570. def colorScaleInterval(self, *args, **kw):
  571. from direct.interval import LerpInterval
  572. return LerpInterval.LerpColorScaleInterval(self, *args, **kw)
  573. Dtool_funcToMethod(colorScaleInterval, NodePath)
  574. del colorScaleInterval
  575. #####################################################################
  576. def attachCollisionSphere(self, name, cx, cy, cz, r, fromCollide, intoCollide):
  577. from panda3d.core import CollisionSphere
  578. from panda3d.core import CollisionNode
  579. coll = CollisionSphere(cx, cy, cz, r)
  580. collNode = CollisionNode(name)
  581. collNode.addSolid(coll)
  582. collNode.setFromCollideMask(fromCollide)
  583. collNode.setIntoCollideMask(intoCollide)
  584. collNodePath = self.attachNewNode(collNode)
  585. return collNodePath
  586. Dtool_funcToMethod(attachCollisionSphere, NodePath)
  587. del attachCollisionSphere
  588. #####################################################################
  589. def attachCollisionSegment(self, name, ax, ay, az, bx, by, bz, fromCollide, intoCollide):
  590. from panda3d.core import CollisionSegment
  591. from panda3d.core import CollisionNode
  592. coll = CollisionSegment(ax, ay, az, bx, by, bz)
  593. collNode = CollisionNode(name)
  594. collNode.addSolid(coll)
  595. collNode.setFromCollideMask(fromCollide)
  596. collNode.setIntoCollideMask(intoCollide)
  597. collNodePath = self.attachNewNode(collNode)
  598. return collNodePath
  599. Dtool_funcToMethod(attachCollisionSegment, NodePath)
  600. del attachCollisionSegment
  601. #####################################################################
  602. def attachCollisionRay(self, name, ox, oy, oz, dx, dy, dz, fromCollide, intoCollide):
  603. from panda3d.core import CollisionRay
  604. from panda3d.core import CollisionNode
  605. coll = CollisionRay(ox, oy, oz, dx, dy, dz)
  606. collNode = CollisionNode(name)
  607. collNode.addSolid(coll)
  608. collNode.setFromCollideMask(fromCollide)
  609. collNode.setIntoCollideMask(intoCollide)
  610. collNodePath = self.attachNewNode(collNode)
  611. return collNodePath
  612. Dtool_funcToMethod(attachCollisionRay, NodePath)
  613. del attachCollisionRay
  614. #####################################################################
  615. def flattenMultitex(self, stateFrom = None, target = None,
  616. useGeom = 0, allowTexMat = 0, win = None):
  617. from panda3d.core import MultitexReducer
  618. mr = MultitexReducer()
  619. if target is not None:
  620. mr.setTarget(target)
  621. mr.setUseGeom(useGeom)
  622. mr.setAllowTexMat(allowTexMat)
  623. if win is None:
  624. from direct.showbase import ShowBaseGlobal
  625. win = ShowBaseGlobal.base.win
  626. if stateFrom is None:
  627. mr.scan(self)
  628. else:
  629. mr.scan(self, stateFrom)
  630. mr.flatten(win)
  631. Dtool_funcToMethod(flattenMultitex, NodePath)
  632. del flattenMultitex
  633. #####################################################################
  634. def getNumDescendants(self):
  635. return len(self.findAllMatches('**')) - 1
  636. Dtool_funcToMethod(getNumDescendants, NodePath)
  637. del getNumDescendants
  638. #####################################################################
  639. def removeNonCollisions(self):
  640. # remove anything that is not collision-related
  641. print("NodePath.removeNonCollisions() is deprecated")
  642. stack = [self]
  643. while len(stack) > 0:
  644. np = stack.pop()
  645. # if there are no CollisionNodes under this node, remove it
  646. if np.find('**/+CollisionNode').isEmpty():
  647. np.detachNode()
  648. else:
  649. stack.extend(np.getChildren())
  650. Dtool_funcToMethod(removeNonCollisions, NodePath)
  651. del removeNonCollisions
  652. #####################################################################
  653. def subdivideCollisions(self, numSolidsInLeaves):
  654. """
  655. expand CollisionNodes out into balanced trees, with a particular number
  656. of solids in the leaves
  657. TODO: better splitting logic at each level of the tree wrt spatial separation
  658. and cost of bounding volume tests vs. cost of collision solid tests
  659. """
  660. colNps = self.findAllMatches('**/+CollisionNode')
  661. for colNp in colNps:
  662. node = colNp.node()
  663. numSolids = node.getNumSolids()
  664. if numSolids <= numSolidsInLeaves:
  665. # this CollisionNode doesn't need to be split
  666. continue
  667. solids = []
  668. for i in range(numSolids):
  669. solids.append(node.getSolid(i))
  670. # recursively subdivide the solids into a spatial binary tree
  671. solidTree = self.r_subdivideCollisions(solids, numSolidsInLeaves)
  672. root = colNp.getParent().attachNewNode('%s-subDivRoot' % colNp.getName())
  673. self.r_constructCollisionTree(solidTree, root, colNp.getName())
  674. colNp.stash()
  675. def r_subdivideCollisions(self, solids, numSolidsInLeaves):
  676. # takes a list of solids, returns a list containing some number of lists,
  677. # with the solids evenly distributed between them (recursively nested until
  678. # the lists at the leaves contain no more than numSolidsInLeaves)
  679. # if solids is already small enough, returns solids unchanged
  680. if len(solids) <= numSolidsInLeaves:
  681. return solids
  682. origins = []
  683. avgX = 0
  684. avgY = 0
  685. avgZ = 0
  686. minX = None
  687. minY = None
  688. minZ = None
  689. maxX = None
  690. maxY = None
  691. maxZ = None
  692. for solid in solids:
  693. origin = solid.getCollisionOrigin()
  694. origins.append(origin)
  695. x = origin.getX()
  696. y = origin.getY()
  697. z = origin.getZ()
  698. avgX += x
  699. avgY += y
  700. avgZ += z
  701. if minX is None:
  702. minX = x
  703. minY = y
  704. minZ = z
  705. maxX = x
  706. maxY = y
  707. maxZ = z
  708. else:
  709. minX = min(x, minX)
  710. minY = min(y, minY)
  711. minZ = min(z, minZ)
  712. maxX = max(x, maxX)
  713. maxY = max(y, maxY)
  714. maxZ = max(z, maxZ)
  715. avgX /= len(solids)
  716. avgY /= len(solids)
  717. avgZ /= len(solids)
  718. extentX = maxX - minX
  719. extentY = maxY - minY
  720. extentZ = maxZ - minZ
  721. maxExtent = max(extentX, extentY, extentZ)
  722. # sparse octree
  723. xyzSolids = []
  724. XyzSolids = []
  725. xYzSolids = []
  726. XYzSolids = []
  727. xyZSolids = []
  728. XyZSolids = []
  729. xYZSolids = []
  730. XYZSolids = []
  731. midX = avgX
  732. midY = avgY
  733. midZ = avgZ
  734. # throw out axes that are not close to the max axis extent; try and keep
  735. # the divisions square/spherical
  736. if extentX < (maxExtent * .75) or extentX > (maxExtent * 1.25):
  737. midX += maxExtent
  738. if extentY < (maxExtent * .75) or extentY > (maxExtent * 1.25):
  739. midY += maxExtent
  740. if extentZ < (maxExtent * .75) or extentZ > (maxExtent * 1.25):
  741. midZ += maxExtent
  742. for i, solid in enumerate(solids):
  743. origin = origins[i]
  744. x = origin.getX()
  745. y = origin.getY()
  746. z = origin.getZ()
  747. if x < midX:
  748. if y < midY:
  749. if z < midZ:
  750. xyzSolids.append(solids[i])
  751. else:
  752. xyZSolids.append(solids[i])
  753. else:
  754. if z < midZ:
  755. xYzSolids.append(solids[i])
  756. else:
  757. xYZSolids.append(solids[i])
  758. else:
  759. if y < midY:
  760. if z < midZ:
  761. XyzSolids.append(solids[i])
  762. else:
  763. XyZSolids.append(solids[i])
  764. else:
  765. if z < midZ:
  766. XYzSolids.append(solids[i])
  767. else:
  768. XYZSolids.append(solids[i])
  769. newSolids = []
  770. if len(xyzSolids) > 0:
  771. newSolids.append(self.r_subdivideCollisions(xyzSolids, numSolidsInLeaves))
  772. if len(XyzSolids) > 0:
  773. newSolids.append(self.r_subdivideCollisions(XyzSolids, numSolidsInLeaves))
  774. if len(xYzSolids) > 0:
  775. newSolids.append(self.r_subdivideCollisions(xYzSolids, numSolidsInLeaves))
  776. if len(XYzSolids) > 0:
  777. newSolids.append(self.r_subdivideCollisions(XYzSolids, numSolidsInLeaves))
  778. if len(xyZSolids) > 0:
  779. newSolids.append(self.r_subdivideCollisions(xyZSolids, numSolidsInLeaves))
  780. if len(XyZSolids) > 0:
  781. newSolids.append(self.r_subdivideCollisions(XyZSolids, numSolidsInLeaves))
  782. if len(xYZSolids) > 0:
  783. newSolids.append(self.r_subdivideCollisions(xYZSolids, numSolidsInLeaves))
  784. if len(XYZSolids) > 0:
  785. newSolids.append(self.r_subdivideCollisions(XYZSolids, numSolidsInLeaves))
  786. #import pdb;pdb.set_trace()
  787. return newSolids
  788. def r_constructCollisionTree(self, solidTree, parentNode, colName):
  789. from panda3d.core import CollisionNode
  790. for item in solidTree:
  791. if isinstance(item[0], list):
  792. newNode = parentNode.attachNewNode(f'{colName}-branch')
  793. self.r_constructCollisionTree(item, newNode, colName)
  794. else:
  795. cn = CollisionNode(f'{colName}-leaf')
  796. for solid in item:
  797. cn.addSolid(solid)
  798. parentNode.attachNewNode(cn)
  799. Dtool_funcToMethod(subdivideCollisions, NodePath)
  800. Dtool_funcToMethod(r_subdivideCollisions, NodePath)
  801. Dtool_funcToMethod(r_constructCollisionTree, NodePath)
  802. del subdivideCollisions
  803. del r_subdivideCollisions
  804. del r_constructCollisionTree
  805. #####################################################################
  806. def analyze(self):
  807. """
  808. Analyzes the geometry below this node and reports the
  809. number of vertices, triangles, etc. This is the same
  810. information reported by the bam-info program.
  811. """
  812. from panda3d.core import SceneGraphAnalyzer
  813. sga = SceneGraphAnalyzer()
  814. sga.addNode(self.node())
  815. if sga.getNumLodNodes() == 0:
  816. print(sga)
  817. else:
  818. print("At highest LOD:")
  819. sga2 = SceneGraphAnalyzer()
  820. sga2.setLodMode(sga2.LMHighest)
  821. sga2.addNode(self.node())
  822. print(sga2)
  823. print("\nAt lowest LOD:")
  824. sga2.clear()
  825. sga2.setLodMode(sga2.LMLowest)
  826. sga2.addNode(self.node())
  827. print(sga2)
  828. print("\nAll nodes:")
  829. print(sga)
  830. Dtool_funcToMethod(analyze, NodePath)
  831. del analyze
  832. #####################################################################