mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
303 lines
14 KiB
Python
303 lines
14 KiB
Python
#################################################################
|
|
# collisionWindow.py
|
|
# Written by Yi-Hong Lin, yihhongl@andrew.cmu.edu, 2004
|
|
#################################################################
|
|
# Import Tkinter, Pmw, and the floater code from this directory tree.
|
|
from direct.tkwidgets.AppShell import *
|
|
from direct.showbase.TkGlobal import *
|
|
from seColorEntry import *
|
|
from direct.tkwidgets import VectorWidgets
|
|
from direct.tkwidgets import Floater
|
|
from direct.tkwidgets import Slider
|
|
import string
|
|
import math
|
|
import types
|
|
|
|
|
|
class collisionWindow(AppShell):
|
|
#################################################################
|
|
# This will open a talk window for user to set the collision object
|
|
# In here, we won't finish the whole process to generate the
|
|
# collision object, half of process will be finished by dataHolder.
|
|
#################################################################
|
|
# Override class variables
|
|
appname = 'Creating Collision Object'
|
|
frameWidth = 600
|
|
frameHeight = 300
|
|
|
|
widgetsDict = {}
|
|
|
|
# Define the types of collision we take care here
|
|
collisionType = ['collisionPolygon',
|
|
'collisionSphere',
|
|
'collisionSegment',
|
|
'collisionRay']
|
|
|
|
def __init__(self, nodePath, parent = None, **kw):
|
|
|
|
self.nodePath = nodePath
|
|
self.objType = 'collisionSphere' # set default type to Collision Sphere
|
|
|
|
INITOPT = Pmw.INITOPT
|
|
optiondefs = (
|
|
('title', self.appname, None),
|
|
)
|
|
self.defineoptions(kw, optiondefs)
|
|
|
|
# Initialize the superclass
|
|
AppShell.__init__(self)
|
|
|
|
# Execute option callbacks
|
|
self.initialiseoptions(collisionWindow)
|
|
|
|
self.parent.resizable(False,False) ## Disable the ability to resize for this Window.
|
|
|
|
def createInterface(self):
|
|
# Handle to the toplevels interior
|
|
interior = self.interior()
|
|
menuBar = self.menuBar
|
|
self.menuBar.destroy()
|
|
|
|
# Create a frame to hold all stuff
|
|
mainFrame = Frame(interior)
|
|
|
|
frame = Frame(mainFrame)
|
|
|
|
self.collisionTypeEntry = self.createcomponent(
|
|
'Collision Type', (), None,
|
|
Pmw.ComboBox, (frame,),
|
|
labelpos = W, label_text='Collision Object Type:', entry_width = 20,
|
|
selectioncommand = self.setObjectType,
|
|
scrolledlist_items = self.collisionType)
|
|
self.collisionTypeEntry.pack(side=LEFT, padx=3)
|
|
|
|
label = Label(frame, text='Parent NodePath: '+ self.nodePath.getName(), font=('MSSansSerif', 12),
|
|
relief = RIDGE)
|
|
label.pack(side=LEFT,expand=0,fill=X, padx=20)
|
|
|
|
frame.pack(side=TOP, fill=X, expand=True, padx=3)
|
|
self.collisionTypeEntry.selectitem('collisionSphere', setentry=True)
|
|
|
|
self.inputZone = Pmw.Group(mainFrame, tag_pyclass = None)
|
|
self.inputZone.pack(fill='both',expand=1)
|
|
settingFrame = self.inputZone.interior()
|
|
|
|
############################################
|
|
# Notebook pages for specific object setting
|
|
############################################
|
|
self.objNotebook = Pmw.NoteBook(settingFrame, tabpos = None,
|
|
borderwidth = 0)
|
|
PolygonPage = self.objNotebook.add('Polygon')
|
|
SpherePage = self.objNotebook.add('Sphere')
|
|
SegmentPage = self.objNotebook.add('Segment')
|
|
RayPage = self.objNotebook.add('Ray')
|
|
self.objNotebook.selectpage('Sphere')
|
|
# Put this here so it isn't called right away
|
|
self.objNotebook['raisecommand'] = self.updateObjInfo
|
|
|
|
# Polygon object setting
|
|
|
|
Interior = Frame(PolygonPage)
|
|
label = Label(Interior, text='Attention! All Coordinates Are Related To Its Parent Node!')
|
|
label.pack(side=LEFT,expand=0,fill=X, padx=1)
|
|
Interior.pack(side=TOP, expand=0,fill=X)
|
|
|
|
self.createPosEntry(PolygonPage, catagory='Polygon', id='Point A')
|
|
self.createPosEntry(PolygonPage, catagory='Polygon', id='Point B')
|
|
self.createPosEntry(PolygonPage, catagory='Polygon', id='Point C')
|
|
|
|
# Sphere object setting
|
|
|
|
Interior = Frame(SpherePage)
|
|
label = Label(Interior, text='Attention! All Coordinates Are Related To Its Parent Node!')
|
|
label.pack(side=LEFT,expand=0,fill=X, padx=1)
|
|
Interior.pack(side=TOP, expand=0,fill=X)
|
|
|
|
self.createPosEntry(SpherePage, catagory='Sphere', id='Center Point')
|
|
|
|
self.createEntryField(SpherePage,catagory='Sphere', id='Size',
|
|
value = 1.0,
|
|
command = None,
|
|
initialState='normal',
|
|
side = 'top')
|
|
|
|
# Segment object setting
|
|
|
|
Interior = Frame(SegmentPage)
|
|
label = Label(Interior, text='Attention! All Coordinates Are Related To Its Parent Node!')
|
|
label.pack(side=LEFT,expand=0,fill=X, padx=1)
|
|
Interior.pack(side=TOP, expand=0,fill=X)
|
|
|
|
self.createPosEntry(SegmentPage, catagory='Segment', id='Point A')
|
|
self.createPosEntry(SegmentPage, catagory='Segment', id='Point B')
|
|
|
|
# Ray object setting
|
|
|
|
Interior = Frame(RayPage)
|
|
label = Label(Interior, text='Attention! All Coordinates Are Related To Its Parent Node!')
|
|
label.pack(side=LEFT,expand=0,fill=X, padx=1)
|
|
Interior.pack(side=TOP, expand=0,fill=X)
|
|
|
|
self.createPosEntry(RayPage, catagory='Ray', id='Origin')
|
|
self.createPosEntry(RayPage, catagory='Ray', id='Direction')
|
|
|
|
|
|
|
|
self.objNotebook.setnaturalsize()
|
|
self.objNotebook.pack(expand = 1, fill = BOTH)
|
|
|
|
self.okButton = Button(mainFrame, text="OK", command=self.okPress,width=10)
|
|
self.okButton.pack(fill=BOTH,expand=0,side=RIGHT)
|
|
|
|
mainFrame.pack(expand=1, fill = BOTH)
|
|
|
|
def onDestroy(self, event):
|
|
messenger.send('CW_close')
|
|
'''
|
|
If you have open any thing, please rewrite here!
|
|
'''
|
|
pass
|
|
|
|
def setObjectType(self, typeName = 'collisionSphere'):
|
|
#################################################################
|
|
# setObjectType(self, typeName = 'collisionSphere')
|
|
# Call back function
|
|
# This function will be called when user select target collision
|
|
# type on the combo box on the panel.
|
|
# Basically, this function's job is to switch the notebook page to right one.
|
|
#################################################################
|
|
self.objType = typeName
|
|
if self.objType=='collisionPolygon':
|
|
self.objNotebook.selectpage('Polygon')
|
|
elif self.objType=='collisionSphere':
|
|
self.objNotebook.selectpage('Sphere')
|
|
elif self.objType=='collisionSegment':
|
|
self.objNotebook.selectpage('Segment')
|
|
elif self.objType=='collisionRay':
|
|
self.objNotebook.selectpage('Ray')
|
|
|
|
return
|
|
|
|
def updateObjInfo(self, page=None):
|
|
#################################################################
|
|
# Nothing. Unlike in the lighting panel, we don't have to keep data
|
|
# once user switch the page.
|
|
#################################################################
|
|
return
|
|
|
|
def okPress(self):
|
|
#################################################################
|
|
# okPress(self)
|
|
# This function will be called when user click on the Ok button.
|
|
# Then this function will collect all parameters that we need to create
|
|
# a collision Object from the panel and generate the colision Object.
|
|
# In the last, it will send the object out with a message to dataHolder to
|
|
# put the object into a CollisionNode and attach it to the target nodePath
|
|
#################################################################
|
|
collisionObject = None
|
|
print self.objType
|
|
if self.objType=='collisionPolygon':
|
|
pointA = Point3(float(self.widgetDict['PolygonPoint A'][0]._entry.get()),
|
|
float(self.widgetDict['PolygonPoint A'][1]._entry.get()),
|
|
float(self.widgetDict['PolygonPoint A'][2]._entry.get()))
|
|
pointB = Point3(float(self.widgetDict['PolygonPoint B'][0]._entry.get()),
|
|
float(self.widgetDict['PolygonPoint B'][1]._entry.get()),
|
|
float(self.widgetDict['PolygonPoint B'][2]._entry.get()))
|
|
pointC = Point3(float(self.widgetDict['PolygonPoint C'][0]._entry.get()),
|
|
float(self.widgetDict['PolygonPoint C'][1]._entry.get()),
|
|
float(self.widgetDict['PolygonPoint C'][2]._entry.get()))
|
|
collisionObject = CollisionPolygon(pointA, pointB, pointC)
|
|
|
|
elif self.objType=='collisionSphere':
|
|
collisionObject = CollisionSphere(float(self.widgetDict['SphereCenter Point'][0]._entry.get()),
|
|
float(self.widgetDict['SphereCenter Point'][1]._entry.get()),
|
|
float(self.widgetDict['SphereCenter Point'][2]._entry.get()),
|
|
float(self.widgetDict['SphereSize'].getvalue()))
|
|
|
|
elif self.objType=='collisionSegment':
|
|
pointA = Point3(float(self.widgetDict['SegmentPoint A'][0]._entry.get()),
|
|
float(self.widgetDict['SegmentPoint A'][1]._entry.get()),
|
|
float(self.widgetDict['SegmentPoint A'][2]._entry.get()))
|
|
pointB = Point3(float(self.widgetDict['SegmentPoint B'][0]._entry.get()),
|
|
float(self.widgetDict['SegmentPoint B'][1]._entry.get()),
|
|
float(self.widgetDict['SegmentPoint B'][2]._entry.get()))
|
|
|
|
collisionObject = CollisionSegment()
|
|
collisionObject.setPointA(pointA)
|
|
collisionObject.setFromLens(base.cam.node(), Point2( -1, 1 )) ## You must set up the camera lensNode before you set point B....
|
|
collisionObject.setPointB(pointB)
|
|
|
|
elif self.objType=='collisionRay':
|
|
point = Point3(float(self.widgetDict['RayOrigin'][0]._entry.get()),
|
|
float(self.widgetDict['RayOrigin'][1]._entry.get()),
|
|
float(self.widgetDict['RayOrigin'][2]._entry.get()))
|
|
|
|
vector = Vec3(float(self.widgetDict['RayDirection'][0]._entry.get()),
|
|
float(self.widgetDict['RayDirection'][1]._entry.get()),
|
|
float(self.widgetDict['RayDirection'][2]._entry.get()))
|
|
|
|
print vector, point
|
|
|
|
collisionObject = CollisionRay()
|
|
collisionObject.setOrigin(point)
|
|
collisionObject.setDirection(vector)
|
|
#collisionObject.setFromLens(base.cam.node(), Point2( -1, 1 )) ## You must set up the camera lensNode before you set up others...
|
|
|
|
if self.objType=='collisionPolygon':
|
|
messenger.send('CW_addCollisionObj', [collisionObject, self.nodePath, pointA, pointB, pointC])
|
|
else:
|
|
messenger.send('CW_addCollisionObj', [collisionObject, self.nodePath])
|
|
|
|
self.quit()
|
|
|
|
return
|
|
|
|
def createPosEntry(self, contentFrame, catagory, id):
|
|
posInterior = Frame(contentFrame)
|
|
label = Label(posInterior, text=id+':')
|
|
label.pack(side=LEFT,expand=0,fill=X, padx=1)
|
|
self.posX = self.createcomponent('posX'+catagory+id, (), None,
|
|
Floater.Floater, (posInterior,),
|
|
text = 'X', relief = FLAT,
|
|
value = 0.0,
|
|
entry_width = 6)
|
|
|
|
self.posX.pack(side=LEFT,expand=0,fill=X, padx=1)
|
|
|
|
self.posY = self.createcomponent('posY'+catagory+id, (), None,
|
|
Floater.Floater, (posInterior,),
|
|
text = 'Y', relief = FLAT,
|
|
value = 0.0,
|
|
entry_width = 6)
|
|
self.posY.pack(side=LEFT, expand=0,fill=X, padx=1)
|
|
|
|
self.posZ = self.createcomponent('posZ'+catagory+id, (), None,
|
|
Floater.Floater, (posInterior,),
|
|
text = 'Z', relief = FLAT,
|
|
value = 0.0,
|
|
entry_width = 6)
|
|
self.posZ.pack(side=LEFT, expand=0,fill=X, padx=1)
|
|
self.widgetDict[catagory+id]=[self.posX, self.posY, self.posZ]
|
|
posInterior.pack(side=TOP, expand=0,fill=X, padx=3, pady=3)
|
|
return
|
|
|
|
def createEntryField(self, parent, catagory, id, value,
|
|
command, initialState, labelWidth = 6,
|
|
side = 'left', fill = X, expand = 0,
|
|
validate = None,
|
|
defaultButton = False, buttonText = 'Default',defaultFunction = None ):
|
|
frame = Frame(parent)
|
|
widget = Pmw.EntryField(frame, labelpos='w', label_text = id+':',
|
|
value = value, entry_font=('MSSansSerif', 10),label_font=('MSSansSerif', 10),
|
|
modifiedcommand=command, validate = validate,
|
|
label_width = labelWidth)
|
|
widget.configure(entry_state = initialState)
|
|
widget.pack(side=LEFT)
|
|
self.widgetDict[catagory+id] = widget
|
|
if defaultButton and (defaultFunction!=None):
|
|
widget = Button(frame, text=buttonText, font=('MSSansSerif', 10), command = defaultFunction)
|
|
widget.pack(side=LEFT, padx=3)
|
|
self.widgetDict[catagory+id+'-'+'DefaultButton']=widget
|
|
|
|
frame.pack(side = side, fill = fill, expand = expand,pady=3)
|