collisionWindow.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. #################################################################
  2. # collisionWindow.py
  3. # Written by Yi-Hong Lin, [email protected], 2004
  4. #################################################################
  5. # Import Tkinter, Pmw, and the floater code from this directory tree.
  6. from direct.tkwidgets.AppShell import *
  7. from direct.showbase.TkGlobal import *
  8. from seColorEntry import *
  9. from direct.tkwidgets import VectorWidgets
  10. from direct.tkwidgets import Floater
  11. from direct.tkwidgets import Slider
  12. from Tkinter import *
  13. import string, math, types
  14. from pandac.PandaModules import *
  15. class collisionWindow(AppShell):
  16. #################################################################
  17. # This will open a talk window for user to set the collision object
  18. # In here, we won't finish the whole process to generate the
  19. # collision object, half of process will be finished by dataHolder.
  20. #################################################################
  21. # Override class variables
  22. appname = 'Creating Collision Object'
  23. frameWidth = 600
  24. frameHeight = 300
  25. widgetsDict = {}
  26. # Define the types of collision we take care here
  27. collisionType = ['collisionPolygon',
  28. 'collisionSphere',
  29. 'collisionSegment',
  30. 'collisionRay']
  31. def __init__(self, nodePath, parent = None, **kw):
  32. self.nodePath = nodePath
  33. self.objType = 'collisionSphere' # set default type to Collision Sphere
  34. INITOPT = Pmw.INITOPT
  35. optiondefs = (
  36. ('title', self.appname, None),
  37. )
  38. self.defineoptions(kw, optiondefs)
  39. # Initialize the superclass
  40. AppShell.__init__(self)
  41. # Execute option callbacks
  42. self.initialiseoptions(collisionWindow)
  43. self.parent.resizable(False,False) ## Disable the ability to resize for this Window.
  44. def createInterface(self):
  45. # Handle to the toplevels interior
  46. interior = self.interior()
  47. menuBar = self.menuBar
  48. self.menuBar.destroy()
  49. # Create a frame to hold all stuff
  50. mainFrame = Frame(interior)
  51. frame = Frame(mainFrame)
  52. self.collisionTypeEntry = self.createcomponent(
  53. 'Collision Type', (), None,
  54. Pmw.ComboBox, (frame,),
  55. labelpos = W, label_text='Collision Object Type:', entry_width = 20,
  56. selectioncommand = self.setObjectType,
  57. scrolledlist_items = self.collisionType)
  58. self.collisionTypeEntry.pack(side=LEFT, padx=3)
  59. label = Label(frame, text='Parent NodePath: '+ self.nodePath.getName(), font=('MSSansSerif', 12),
  60. relief = RIDGE)
  61. label.pack(side=LEFT,expand=0,fill=X, padx=20)
  62. frame.pack(side=TOP, fill=X, expand=True, padx=3)
  63. self.collisionTypeEntry.selectitem('collisionSphere', setentry=True)
  64. self.inputZone = Pmw.Group(mainFrame, tag_pyclass = None)
  65. self.inputZone.pack(fill='both',expand=1)
  66. settingFrame = self.inputZone.interior()
  67. ############################################
  68. # Notebook pages for specific object setting
  69. ############################################
  70. self.objNotebook = Pmw.NoteBook(settingFrame, tabpos = None,
  71. borderwidth = 0)
  72. PolygonPage = self.objNotebook.add('Polygon')
  73. SpherePage = self.objNotebook.add('Sphere')
  74. SegmentPage = self.objNotebook.add('Segment')
  75. RayPage = self.objNotebook.add('Ray')
  76. self.objNotebook.selectpage('Sphere')
  77. # Put this here so it isn't called right away
  78. self.objNotebook['raisecommand'] = self.updateObjInfo
  79. # Polygon object setting
  80. Interior = Frame(PolygonPage)
  81. label = Label(Interior, text='Attention! All Coordinates Are Related To Its Parent Node!')
  82. label.pack(side=LEFT,expand=0,fill=X, padx=1)
  83. Interior.pack(side=TOP, expand=0,fill=X)
  84. self.createPosEntry(PolygonPage, catagory='Polygon', id='Point A')
  85. self.createPosEntry(PolygonPage, catagory='Polygon', id='Point B')
  86. self.createPosEntry(PolygonPage, catagory='Polygon', id='Point C')
  87. # Sphere object setting
  88. Interior = Frame(SpherePage)
  89. label = Label(Interior, text='Attention! All Coordinates Are Related To Its Parent Node!')
  90. label.pack(side=LEFT,expand=0,fill=X, padx=1)
  91. Interior.pack(side=TOP, expand=0,fill=X)
  92. self.createPosEntry(SpherePage, catagory='Sphere', id='Center Point')
  93. self.createEntryField(SpherePage,catagory='Sphere', id='Size',
  94. value = 1.0,
  95. command = None,
  96. initialState='normal',
  97. side = 'top')
  98. # Segment object setting
  99. Interior = Frame(SegmentPage)
  100. label = Label(Interior, text='Attention! All Coordinates Are Related To Its Parent Node!')
  101. label.pack(side=LEFT,expand=0,fill=X, padx=1)
  102. Interior.pack(side=TOP, expand=0,fill=X)
  103. self.createPosEntry(SegmentPage, catagory='Segment', id='Point A')
  104. self.createPosEntry(SegmentPage, catagory='Segment', id='Point B')
  105. # Ray object setting
  106. Interior = Frame(RayPage)
  107. label = Label(Interior, text='Attention! All Coordinates Are Related To Its Parent Node!')
  108. label.pack(side=LEFT,expand=0,fill=X, padx=1)
  109. Interior.pack(side=TOP, expand=0,fill=X)
  110. self.createPosEntry(RayPage, catagory='Ray', id='Origin')
  111. self.createPosEntry(RayPage, catagory='Ray', id='Direction')
  112. self.objNotebook.setnaturalsize()
  113. self.objNotebook.pack(expand = 1, fill = BOTH)
  114. self.okButton = Button(mainFrame, text="OK", command=self.okPress,width=10)
  115. self.okButton.pack(fill=BOTH,expand=0,side=RIGHT)
  116. mainFrame.pack(expand=1, fill = BOTH)
  117. def onDestroy(self, event):
  118. messenger.send('CW_close')
  119. '''
  120. If you have open any thing, please rewrite here!
  121. '''
  122. pass
  123. def setObjectType(self, typeName = 'collisionSphere'):
  124. #################################################################
  125. # setObjectType(self, typeName = 'collisionSphere')
  126. # Call back function
  127. # This function will be called when user select target collision
  128. # type on the combo box on the panel.
  129. # Basically, this function's job is to switch the notebook page to right one.
  130. #################################################################
  131. self.objType = typeName
  132. if self.objType=='collisionPolygon':
  133. self.objNotebook.selectpage('Polygon')
  134. elif self.objType=='collisionSphere':
  135. self.objNotebook.selectpage('Sphere')
  136. elif self.objType=='collisionSegment':
  137. self.objNotebook.selectpage('Segment')
  138. elif self.objType=='collisionRay':
  139. self.objNotebook.selectpage('Ray')
  140. return
  141. def updateObjInfo(self, page=None):
  142. #################################################################
  143. # Nothing. Unlike in the lighting panel, we don't have to keep data
  144. # once user switch the page.
  145. #################################################################
  146. return
  147. def okPress(self):
  148. #################################################################
  149. # okPress(self)
  150. # This function will be called when user click on the Ok button.
  151. # Then this function will collect all parameters that we need to create
  152. # a collision Object from the panel and generate the colision Object.
  153. # In the last, it will send the object out with a message to dataHolder to
  154. # put the object into a CollisionNode and attach it to the target nodePath
  155. #################################################################
  156. collisionObject = None
  157. print self.objType
  158. if self.objType=='collisionPolygon':
  159. pointA = Point3(float(self.widgetDict['PolygonPoint A'][0]._entry.get()),
  160. float(self.widgetDict['PolygonPoint A'][1]._entry.get()),
  161. float(self.widgetDict['PolygonPoint A'][2]._entry.get()))
  162. pointB = Point3(float(self.widgetDict['PolygonPoint B'][0]._entry.get()),
  163. float(self.widgetDict['PolygonPoint B'][1]._entry.get()),
  164. float(self.widgetDict['PolygonPoint B'][2]._entry.get()))
  165. pointC = Point3(float(self.widgetDict['PolygonPoint C'][0]._entry.get()),
  166. float(self.widgetDict['PolygonPoint C'][1]._entry.get()),
  167. float(self.widgetDict['PolygonPoint C'][2]._entry.get()))
  168. collisionObject = CollisionPolygon(pointA, pointB, pointC)
  169. elif self.objType=='collisionSphere':
  170. collisionObject = CollisionSphere(float(self.widgetDict['SphereCenter Point'][0]._entry.get()),
  171. float(self.widgetDict['SphereCenter Point'][1]._entry.get()),
  172. float(self.widgetDict['SphereCenter Point'][2]._entry.get()),
  173. float(self.widgetDict['SphereSize'].getvalue()))
  174. elif self.objType=='collisionSegment':
  175. pointA = Point3(float(self.widgetDict['SegmentPoint A'][0]._entry.get()),
  176. float(self.widgetDict['SegmentPoint A'][1]._entry.get()),
  177. float(self.widgetDict['SegmentPoint A'][2]._entry.get()))
  178. pointB = Point3(float(self.widgetDict['SegmentPoint B'][0]._entry.get()),
  179. float(self.widgetDict['SegmentPoint B'][1]._entry.get()),
  180. float(self.widgetDict['SegmentPoint B'][2]._entry.get()))
  181. collisionObject = CollisionSegment()
  182. collisionObject.setPointA(pointA)
  183. collisionObject.setFromLens(base.cam.node(), Point2( -1, 1 )) ## You must set up the camera lensNode before you set point B....
  184. collisionObject.setPointB(pointB)
  185. elif self.objType=='collisionRay':
  186. point = Point3(float(self.widgetDict['RayOrigin'][0]._entry.get()),
  187. float(self.widgetDict['RayOrigin'][1]._entry.get()),
  188. float(self.widgetDict['RayOrigin'][2]._entry.get()))
  189. vector = Vec3(float(self.widgetDict['RayDirection'][0]._entry.get()),
  190. float(self.widgetDict['RayDirection'][1]._entry.get()),
  191. float(self.widgetDict['RayDirection'][2]._entry.get()))
  192. print vector, point
  193. collisionObject = CollisionRay()
  194. collisionObject.setOrigin(point)
  195. collisionObject.setDirection(vector)
  196. #collisionObject.setFromLens(base.cam.node(), Point2( -1, 1 )) ## You must set up the camera lensNode before you set up others...
  197. if self.objType=='collisionPolygon':
  198. messenger.send('CW_addCollisionObj', [collisionObject, self.nodePath, pointA, pointB, pointC])
  199. else:
  200. messenger.send('CW_addCollisionObj', [collisionObject, self.nodePath])
  201. self.quit()
  202. return
  203. def createPosEntry(self, contentFrame, catagory, id):
  204. posInterior = Frame(contentFrame)
  205. label = Label(posInterior, text=id+':')
  206. label.pack(side=LEFT,expand=0,fill=X, padx=1)
  207. self.posX = self.createcomponent('posX'+catagory+id, (), None,
  208. Floater.Floater, (posInterior,),
  209. text = 'X', relief = FLAT,
  210. value = 0.0,
  211. entry_width = 6)
  212. self.posX.pack(side=LEFT,expand=0,fill=X, padx=1)
  213. self.posY = self.createcomponent('posY'+catagory+id, (), None,
  214. Floater.Floater, (posInterior,),
  215. text = 'Y', relief = FLAT,
  216. value = 0.0,
  217. entry_width = 6)
  218. self.posY.pack(side=LEFT, expand=0,fill=X, padx=1)
  219. self.posZ = self.createcomponent('posZ'+catagory+id, (), None,
  220. Floater.Floater, (posInterior,),
  221. text = 'Z', relief = FLAT,
  222. value = 0.0,
  223. entry_width = 6)
  224. self.posZ.pack(side=LEFT, expand=0,fill=X, padx=1)
  225. self.widgetDict[catagory+id]=[self.posX, self.posY, self.posZ]
  226. posInterior.pack(side=TOP, expand=0,fill=X, padx=3, pady=3)
  227. return
  228. def createEntryField(self, parent, catagory, id, value,
  229. command, initialState, labelWidth = 6,
  230. side = 'left', fill = X, expand = 0,
  231. validate = None,
  232. defaultButton = False, buttonText = 'Default',defaultFunction = None ):
  233. frame = Frame(parent)
  234. widget = Pmw.EntryField(frame, labelpos='w', label_text = id+':',
  235. value = value, entry_font=('MSSansSerif', 10),label_font=('MSSansSerif', 10),
  236. modifiedcommand=command, validate = validate,
  237. label_width = labelWidth)
  238. widget.configure(entry_state = initialState)
  239. widget.pack(side=LEFT)
  240. self.widgetDict[catagory+id] = widget
  241. if defaultButton and (defaultFunction!=None):
  242. widget = Button(frame, text=buttonText, font=('MSSansSerif', 10), command = defaultFunction)
  243. widget.pack(side=LEFT, padx=3)
  244. self.widgetDict[catagory+id+'-'+'DefaultButton']=widget
  245. frame.pack(side = side, fill = fill, expand = expand,pady=3)