mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
1457 lines
69 KiB
Python
1457 lines
69 KiB
Python
#################################################################
|
|
# propertyWindow.py
|
|
# Written by Yi-Hong Lin, yihhongl@andrew.cmu.edu, 2004
|
|
#################################################################
|
|
from direct.tkwidgets.AppShell import *
|
|
from direct.showbase.TkGlobal import *
|
|
|
|
from seColorEntry import *
|
|
|
|
from direct.tkwidgets import Floater
|
|
from direct.tkwidgets import Dial
|
|
from direct.tkwidgets import Slider
|
|
from direct.tkwidgets import VectorWidgets
|
|
from pandac.PandaModules import *
|
|
from Tkinter import *
|
|
import Pmw
|
|
|
|
class propertyWindow(AppShell,Pmw.MegaWidget):
|
|
#################################################################
|
|
# propertyWindow(AppShell,Pmw.MegaWidget)
|
|
# This class will create a widow to show the object property and
|
|
# let user can change shoe of them.
|
|
#################################################################
|
|
appversion = '1.0'
|
|
appname = 'Property Window'
|
|
frameWidth = 400
|
|
frameHeight = 400
|
|
padx = 0
|
|
pady = 0
|
|
usecommandarea = 0
|
|
usestatusarea = 0
|
|
widgetsDict = {}
|
|
|
|
|
|
def __init__(self, target, type, info, parent = None, nodePath = render, **kw):
|
|
self.nodePath = target
|
|
self.name = target.getName()
|
|
self.type = type
|
|
self.info = info
|
|
|
|
|
|
# Initialise superclass
|
|
Pmw.MegaWidget.__init__(self, parent)
|
|
|
|
# Define the megawidget options.
|
|
optiondefs = (
|
|
('title', self.appname, None),
|
|
)
|
|
self.defineoptions(kw, optiondefs)
|
|
|
|
if parent == None:
|
|
self.parent = Toplevel()
|
|
AppShell.__init__(self, self.parent)
|
|
|
|
self.parent.resizable(False,False) ## Disable the ability to resize for this Window.
|
|
|
|
def appInit(self):
|
|
return
|
|
|
|
def createInterface(self):
|
|
# The interior of the toplevel panel
|
|
interior = self.interior()
|
|
mainFrame = Frame(interior)
|
|
name_label = Label(mainFrame, text= self.name,font=('MSSansSerif', 15),
|
|
relief = RIDGE, borderwidth=5)
|
|
name_label.pack()
|
|
outFrame = Frame(mainFrame, relief = RIDGE, borderwidth=3)
|
|
self.contentWidge = self.createcomponent(
|
|
'scrolledFrame',
|
|
(), None,
|
|
Pmw.ScrolledFrame, (outFrame,),
|
|
hull_width = 200, hull_height = 300,
|
|
usehullsize = 1)
|
|
self.contentFrame = self.contentWidge.component('frame')
|
|
self.contentWidge.pack(fill = 'both', expand = 1,padx = 3, pady = 5)
|
|
outFrame.pack(fill = 'both', expand = 1)
|
|
|
|
# Creating different interface depands on object's type
|
|
if self.type == 'camera':
|
|
self.cameraInterface(self.contentFrame)
|
|
self.accept('forPorpertyWindow'+self.name, self.trackDataFromSceneCamera)
|
|
elif self.type == 'Model':
|
|
self.modelInterface(self.contentFrame)
|
|
self.accept('forPorpertyWindow'+self.name, self.trackDataFromSceneModel)
|
|
elif self.type == 'Actor':
|
|
self.modelInterface(self.contentFrame)
|
|
self.actorInterface(self.contentFrame)
|
|
self.accept('forPorpertyWindow'+self.name, self.trackDataFromSceneActor)
|
|
pass
|
|
elif self.type == 'Light':
|
|
self.lightInterface(self.contentFrame)
|
|
self.accept('forPorpertyWindow'+self.name, self.trackDataFromSceneLight)
|
|
pass
|
|
elif self.type == 'dummy':
|
|
self.dummyInterface(self.contentFrame)
|
|
self.accept('forPorpertyWindow'+self.name, self.trackDataFromSceneDummy)
|
|
pass
|
|
elif self.type == 'collisionNode':
|
|
self.collisionInterface(self.contentFrame)
|
|
self.accept('forPorpertyWindow'+self.name, self.trackDataFromSceneCollision)
|
|
pass
|
|
elif self.type == 'Special':
|
|
# If user try to open the property window for node "SEditor"
|
|
# It will show the grid property.
|
|
self.gridInterface(self.contentFrame)
|
|
self.accept('forPorpertyWindow'+self.name, None)
|
|
pass
|
|
|
|
self.curveFrame = None
|
|
#### If nodePath has been binded with any curves
|
|
if self.info.has_key('curveList'):
|
|
self.createCurveFrame(self.contentFrame)
|
|
|
|
## Set all stuff done
|
|
mainFrame.pack(fill = 'both', expand = 1)
|
|
|
|
|
|
def createMenuBar(self):
|
|
# we don't need menu bar here.
|
|
self.menuBar.destroy()
|
|
|
|
def onDestroy(self, event):
|
|
self.ignore('forPorpertyWindow'+self.name)
|
|
messenger.send('PW_close', [self.name])
|
|
'''
|
|
If you have open any thing, please rewrite here!
|
|
'''
|
|
pass
|
|
|
|
def createEntryField(self, parent,text, value,
|
|
command, initialState, labelWidth = 12,
|
|
side = 'left', fill = X, expand = 0,
|
|
validate = None,
|
|
defaultButton = False, buttonText = 'Default',defaultFunction = None ):
|
|
#################################################################
|
|
# createEntryField(self, parent,text, value,
|
|
# command, initialState, labelWidth = 12,
|
|
# side = 'left', fill = X, expand = 0,
|
|
# validate = None,
|
|
# defaultButton = False, buttonText = 'Default',defaultFunction = None ):
|
|
# This function will create a Entry on the frame "parent"
|
|
# Also, if user has enabled the "defaultButton," it will create a button right after the entry.
|
|
#################################################################
|
|
frame = Frame(parent)
|
|
widget = Pmw.EntryField(frame, labelpos='w', label_text = text,
|
|
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.widgetsDict[text] = widget
|
|
if defaultButton and (defaultFunction!=None):
|
|
# create a button if they need.
|
|
widget = Button(frame, text=buttonText, font=('MSSansSerif', 10), command = defaultFunction)
|
|
widget.pack(side=LEFT, padx=3)
|
|
self.widgetsDict[text+'-'+'DefaultButton']=widget
|
|
|
|
frame.pack(side = side, fill = fill, expand = expand,pady=3)
|
|
|
|
|
|
def createPosEntry(self, contentFrame):
|
|
#################################################################
|
|
# createPosEntry(self, contentFrame)
|
|
# This function will create three entries for setting position for the objects.
|
|
# the entry type is Floater.
|
|
# And, it will set the call back function to setNodePathPosHprScale()
|
|
#################################################################
|
|
posInterior = Frame(contentFrame)
|
|
self.posX = self.createcomponent('posX', (), None,
|
|
Floater.Floater, (posInterior,),
|
|
text = 'X', relief = FLAT,
|
|
value = self.nodePath.getX(),
|
|
label_foreground = 'Red',
|
|
entry_width = 9)
|
|
self.posX['commandData'] = ['x']
|
|
self.posX['command'] = self.setNodePathPosHprScale
|
|
self.posX.pack(side=LEFT,expand=0,fill=X, padx=1)
|
|
|
|
self.posY = self.createcomponent('posY', (), None,
|
|
Floater.Floater, (posInterior,),
|
|
text = 'Y', relief = FLAT,
|
|
value = self.nodePath.getY(),
|
|
label_foreground = '#00A000',
|
|
entry_width = 9)
|
|
self.posY['commandData'] = ['y']
|
|
self.posY['command'] = self.setNodePathPosHprScale
|
|
self.posY.pack(side=LEFT, expand=0,fill=X, padx=1)
|
|
|
|
self.posZ = self.createcomponent('posZ', (), None,
|
|
Floater.Floater, (posInterior,),
|
|
text = 'Z', relief = FLAT,
|
|
value = self.nodePath.getZ(),
|
|
label_foreground = 'Blue',
|
|
entry_width = 9)
|
|
self.posZ['commandData'] = ['z']
|
|
self.posZ['command'] = self.setNodePathPosHprScale
|
|
self.posZ.pack(side=LEFT, expand=0,fill=X, padx=1)
|
|
posInterior.pack(side=TOP, expand=0,fill=X, padx=3, pady=3)
|
|
|
|
def createHprEntry(self, contentFrame):
|
|
#################################################################
|
|
# createHprEntry(self, contentFrame)
|
|
# This function will create three entries for setting orientation for the objects.
|
|
# the entry type is Floater.
|
|
# And, it will set the call back function to setNodePathPosHprScale()
|
|
#################################################################
|
|
hprInterior = Frame(contentFrame)
|
|
self.hprH = self.createcomponent('hprH', (), None,
|
|
Dial.AngleDial, (hprInterior,),
|
|
style = 'mini',
|
|
text = 'H', value = self.nodePath.getH(),
|
|
relief = FLAT,
|
|
label_foreground = 'blue',
|
|
entry_width = 9)
|
|
self.hprH['commandData'] = ['h']
|
|
self.hprH['command'] = self.setNodePathPosHprScale
|
|
self.hprH.pack(side = LEFT, expand=0,fill=X)
|
|
|
|
self.hprP = self.createcomponent('hprP', (), None,
|
|
Dial.AngleDial, (hprInterior,),
|
|
style = 'mini',
|
|
text = 'P', value = self.nodePath.getP(),
|
|
relief = FLAT,
|
|
label_foreground = 'red',
|
|
entry_width = 9)
|
|
self.hprP['commandData'] = ['p']
|
|
self.hprP['command'] = self.setNodePathPosHprScale
|
|
self.hprP.pack(side = LEFT, expand=0,fill=X)
|
|
|
|
self.hprR = self.createcomponent('hprR', (), None,
|
|
Dial.AngleDial, (hprInterior,),
|
|
style = 'mini',
|
|
text = 'R', value = self.nodePath.getR(),
|
|
relief = FLAT,
|
|
label_foreground = '#00A000',
|
|
entry_width = 9)
|
|
self.hprR['commandData'] = ['r']
|
|
self.hprR['command'] = self.setNodePathPosHprScale
|
|
self.hprR.pack(side = LEFT, expand=0,fill=X)
|
|
|
|
hprInterior.pack(side=TOP, expand=0,fill=X, padx=3, pady=3)
|
|
|
|
|
|
def createScaleEntry(self, contentFrame):
|
|
#################################################################
|
|
# createScaleEntry(self, contentFrame)
|
|
# This function will create three entries for setting scale for the objects.
|
|
# the entry type is Floater.
|
|
# And, it will set the call back function to setNodePathPosHprScale()
|
|
#################################################################
|
|
scaleInterior = Frame(contentFrame)
|
|
|
|
self.scale = self.createcomponent('scale', (), None,
|
|
Floater.Floater, (scaleInterior,),
|
|
text = 'Scale',
|
|
relief = FLAT,
|
|
min = 0.0001, value = self.nodePath.getScale().getX(),
|
|
resetValue = 1.0,
|
|
label_foreground = 'Blue')
|
|
self.scale['commandData'] = ['s']
|
|
self.scale['command'] = self.setNodePathPosHprScale
|
|
self.scale.pack(side=LEFT,expand=0,fill=X)
|
|
|
|
scaleInterior.pack(side=TOP,expand=0,fill=X, padx=3, pady=3)
|
|
|
|
def createColorEntry(self, contentFrame):
|
|
#################################################################
|
|
# createColorEntry(self, contentFrame)
|
|
# This function will create three entries for setting color for the objects.
|
|
# the entry type is Floater.
|
|
# And, it will set the call back function to setNodeColorVec()
|
|
#################################################################
|
|
color = self.nodePath.getColor()
|
|
print color
|
|
self.nodeColor = VectorWidgets.ColorEntry(
|
|
contentFrame, text = 'Node Color', value=[color.getX()*255,
|
|
color.getY()*255,
|
|
color.getZ()*255,
|
|
color.getW()*255])
|
|
self.nodeColor['command'] = self.setNodeColorVec
|
|
self.nodeColor['resetValue'] = [255,255,255,255]
|
|
self.nodeColor.place(anchor=NW,y=235)
|
|
self.bind(self.nodeColor, 'Set nodePath color')
|
|
self.nodeColor.pack(side=TOP,expand=0,fill=X, padx=3, pady=3)
|
|
return
|
|
|
|
def setNodeColorVec(self, color):
|
|
#################################################################
|
|
# setNodeColorVec(self, color)
|
|
# This function will set the color of the object
|
|
#################################################################
|
|
self.nodePath.setColor(color[0]/255.0,
|
|
color[1]/255.0,
|
|
color[2]/255.0,
|
|
color[3]/255.0)
|
|
return
|
|
|
|
|
|
def setNodePathPosHprScale(self, data, axis):
|
|
#################################################################
|
|
# setNodePathPosHprScale(self, data, axis)
|
|
# This function will set the postion, orientation or scale of the object
|
|
# use the "axis" parameter to decide which property should be set.
|
|
#################################################################
|
|
if axis == 'x':
|
|
self.nodePath.setX(data)
|
|
elif axis == 'y':
|
|
self.nodePath.setY(data)
|
|
elif axis == 'z':
|
|
self.nodePath.setZ(data)
|
|
elif axis == 'h':
|
|
self.nodePath.setH(data)
|
|
elif axis == 'p':
|
|
self.nodePath.setP(data)
|
|
elif axis == 'r':
|
|
self.nodePath.setR(data)
|
|
elif axis == 's':
|
|
self.nodePath.setScale(data)
|
|
|
|
|
|
#### Curve property
|
|
def createCurveFrame(self, contentFrame):
|
|
#################################################################
|
|
# createCurveFrame(self, contentFrame)
|
|
# Draw the curve property frame
|
|
# This function will draw the property frame and content of curves
|
|
# pass the target frame as a variable
|
|
#################################################################
|
|
if self.curveFrame==None:
|
|
self.curveFrame = Frame(contentFrame)
|
|
group = Pmw.Group(self.curveFrame,
|
|
tag_text='Motion Path List for this Node',
|
|
tag_font=('MSSansSerif', 10))
|
|
innerFrame = group.interior()
|
|
n = 0
|
|
for curve in self.info['curveList']:
|
|
n += 1
|
|
self.createEntryField(innerFrame,'Curve %d:' %n,
|
|
value = curve.getCurve(0).getName(),
|
|
command = None,
|
|
initialState='disabled',
|
|
side = 'top',
|
|
defaultButton = True,
|
|
buttonText = 'delete',
|
|
defaultFunction = lambda a = n, b = self : b.deleteCurve(a))
|
|
group.pack(side = TOP, fill = X, expand = 0,pady=3, padx=3)
|
|
self.curveFrame.pack(side = TOP, fill = X, expand = 0,pady=3, padx=3)
|
|
|
|
return
|
|
|
|
def deleteCurve(self, number = 0):
|
|
#################################################################
|
|
# deleteCurve(self, number = 0)
|
|
# Call back function, will be called when user click on the "delete" button beside the curve name.
|
|
# This function will send the message to sceneEditor to remove the target curve
|
|
# and will set a callback function waitting the result.
|
|
#################################################################
|
|
widget = self.widgetsDict['Curve %d:' %number]
|
|
curveName = widget.getvalue()
|
|
self.accept('curveRemovedFromNode',self.redrawCurveProperty)
|
|
messenger.send('PW_removeCurveFromNode',[self.nodePath, curveName])
|
|
return
|
|
|
|
def redrawCurveProperty(self, nodePath, curveList):
|
|
#################################################################
|
|
# redrawCurveProperty(self, nodePath, curveList)
|
|
# Callback function, will be called once get the result from dataHolder.
|
|
# It will check the target nodePath first, then check the curve list is empty or not.
|
|
# If yes, then delete whole curve frame. If not, then renew the data and redraw the curve frame again.
|
|
#################################################################
|
|
self.name = self.nodePath.getName()
|
|
if self.name != nodePath.getName():
|
|
messenger.send('curveRemovedFromNode',[nodePath, curveList])
|
|
return
|
|
else:
|
|
self.ignore('curveRemovedFromNode')
|
|
|
|
if curveList!= None:
|
|
del self.info['curveList']
|
|
self.info['curveList'] = curveList
|
|
self.curveFrame.destroy()
|
|
del self.curveFrame
|
|
self.curveFrame = None
|
|
self.createCurveFrame(self.contentFrame)
|
|
else:
|
|
del self.info['curveList']
|
|
self.curveFrame.destroy()
|
|
del self.curveFrame
|
|
self.curveFrame = None
|
|
return
|
|
|
|
####
|
|
#### Anything about Camera will be here!
|
|
####
|
|
def cameraInterface(self, contentFrame):
|
|
#################################################################
|
|
# cameraInterface(self, interior, mainFrame)
|
|
# Create the interface for camera node.
|
|
#################################################################
|
|
|
|
## Type entry : unchageable
|
|
widget = self.createEntryField(contentFrame,'Type:',
|
|
value = self.type,
|
|
command = None,
|
|
initialState='disabled',
|
|
side = 'top')
|
|
|
|
## lens Type entry
|
|
widget = self.createEntryField(contentFrame, 'Lens Type:',
|
|
value = self.info['lensType'],
|
|
command = None,
|
|
initialState='disabled',
|
|
side = 'top')
|
|
|
|
## Pos
|
|
group = Pmw.Group(contentFrame,tag_text='Position',
|
|
tag_font=('MSSansSerif', 10))
|
|
self.createPosEntry(group.interior())
|
|
group.pack(side=TOP,fill = X, expand = 0, pady=3)
|
|
|
|
## Orientation
|
|
group = Pmw.Group(contentFrame,tag_text='Orientation',
|
|
tag_font=('MSSansSerif', 10))
|
|
self.createHprEntry(group.interior())
|
|
group.pack(side=TOP,fill = X, expand = 0, pady=3)
|
|
|
|
## near entry
|
|
group = Pmw.Group(contentFrame,tag_text='Lens Property',
|
|
tag_font=('MSSansSerif', 10))
|
|
lensFrame = group.interior()
|
|
widget = self.createEntryField(lensFrame, 'Near:',value = self.info['near'],
|
|
command = self.setCameraNear,
|
|
initialState='normal',
|
|
validate = Pmw.realvalidator,
|
|
side = 'top',
|
|
defaultButton = True,
|
|
defaultFunction = self.defaultCameraNear)
|
|
|
|
## far entry
|
|
widget = self.createEntryField(lensFrame, 'Far:',
|
|
value = self.info['far'],
|
|
command = self.setCameraFar,
|
|
initialState='normal',
|
|
side = 'top',
|
|
validate = Pmw.realvalidator,
|
|
defaultButton = True,
|
|
defaultFunction = self.defaultCameraFar)
|
|
|
|
## Hfov entry
|
|
widget = self.createEntryField(lensFrame, 'H.F.O.V.:',
|
|
value = self.info['hFov'],
|
|
command = self.setCameraFov,
|
|
validate = Pmw.realvalidator,
|
|
initialState='normal',
|
|
side = 'top',
|
|
defaultButton = True,
|
|
defaultFunction = self.defaultCameraHfov)
|
|
|
|
## Vfov entry
|
|
widget = self.createEntryField(lensFrame, 'V.F.O.V.:',
|
|
value = self.info['vFov'],
|
|
command = self.setCameraFov,
|
|
validate = Pmw.realvalidator,
|
|
initialState='normal',
|
|
side = 'top',
|
|
defaultButton = True,
|
|
defaultFunction = self.defaultCameraVfov)
|
|
|
|
## Film Size entry
|
|
frame = Frame(lensFrame)
|
|
widget = Label(frame, text = "Film Size:", font=('MSSansSerif', 10),width=12)
|
|
widget.pack(side=LEFT)
|
|
frame.pack(side = TOP, fill = X, expand = 0, pady=3)
|
|
|
|
frame = Frame(lensFrame)
|
|
widget = Pmw.EntryField(frame, labelpos='w', label_text = ' ',
|
|
value = self.info['FilmSize'].getX(),
|
|
entry_font=('MSSansSerif', 10),
|
|
label_font=('MSSansSerif', 10),
|
|
modifiedcommand=self.setCameraFilmSize, validate = Pmw.realvalidator,
|
|
entry_width = 8)
|
|
self.widgetsDict['FilmSizeX']=widget
|
|
widget.pack(side=LEFT, padx=3)
|
|
widget = Pmw.EntryField(frame, labelpos='w', label_text = ': ', value = self.info['FilmSize'].getY() ,
|
|
label_font=('MSSansSerif', 10),
|
|
entry_font=('MSSansSerif', 10),
|
|
modifiedcommand=self.setCameraFilmSize, validate = Pmw.realvalidator,
|
|
entry_width = 8)
|
|
self.widgetsDict['FilmSizeY']=widget
|
|
widget.pack(side=LEFT, padx=3)
|
|
widget = Button(frame, text='Default', font=('MSSansSerif', 10), command = self.defaultCameraFilmSize)
|
|
widget.pack(side=LEFT, padx=3)
|
|
self.widgetsDict['FilmSize'+'-'+'DefaultButton']=widget
|
|
frame.pack(side = TOP, fill = X, expand = 0,pady=0)
|
|
|
|
## Focal Length entry
|
|
widget = self.createEntryField(lensFrame, 'Focal Length:',
|
|
value = self.info['focalLength'],
|
|
command = self.setCameraFocalLength,
|
|
validate = Pmw.realvalidator,
|
|
initialState='normal',
|
|
side = 'top',
|
|
defaultButton = True,
|
|
defaultFunction = self.defaultCameraFocalLength)
|
|
group.pack(side = TOP, fill = X, expand = 0,pady=2)
|
|
|
|
|
|
def defaultCameraFar(self):
|
|
#################################################################
|
|
# defaultCameraFar(self)
|
|
# set the camera "Far" value back to default.
|
|
#################################################################
|
|
widget = self.widgetsDict['Far:']
|
|
widget.setvalue(base.cam.node().getLens().getDefaultFar())
|
|
return
|
|
|
|
def setCameraFar(self):
|
|
#################################################################
|
|
# setCameraFar(self)
|
|
# set the camera "Far" value to what now user has typed in the entry
|
|
#################################################################
|
|
if self.widgetsDict['Far:'].getvalue() != '':
|
|
value = float(self.widgetsDict['Far:'].getvalue())
|
|
else:
|
|
value = 0
|
|
camera.getChild(0).node().getLens().setFar(value)
|
|
return
|
|
|
|
def defaultCameraNear(self):
|
|
#################################################################
|
|
# defaultCameraNear(self)
|
|
# set the camera "Near" value back to default.
|
|
#################################################################
|
|
widget = self.widgetsDict['Near:']
|
|
widget.setvalue(base.cam.node().getLens().getDefaultNear())
|
|
return
|
|
|
|
def setCameraNear(self):
|
|
#################################################################
|
|
# setCameraNear(self)
|
|
# set the camera "Near" value to what now user has typed in the entry
|
|
#################################################################
|
|
if self.widgetsDict['Near:'].getvalue() != '':
|
|
value = float(self.widgetsDict['Near:'].getvalue())
|
|
else:
|
|
value = 0
|
|
camera.getChild(0).node().getLens().setNear(value)
|
|
return
|
|
|
|
def defaultCameraHfov(self):
|
|
#################################################################
|
|
# defaultCameraHfov(self)
|
|
# set the camera "Hfov" value back to default.
|
|
#################################################################
|
|
widget = self.widgetsDict['H.F.O.V.:']
|
|
widget.setvalue(45.0)
|
|
return
|
|
|
|
def setCameraFov(self):
|
|
#################################################################
|
|
# setCameraFov(self)
|
|
# set the camera "Fov" value to what now user has typed in the entry
|
|
#################################################################
|
|
if self.widgetsDict['H.F.O.V.:'].getvalue() != '':
|
|
value1 = float(self.widgetsDict['H.F.O.V.:'].getvalue())
|
|
else:
|
|
value1 = 0
|
|
if self.widgetsDict['V.F.O.V.:'].getvalue() != '':
|
|
value2 = float(self.widgetsDict['V.F.O.V.:'].getvalue())
|
|
else:
|
|
value2 = 0
|
|
camera.getChild(0).node().getLens().setFov(VBase2(value1,value2))
|
|
return
|
|
|
|
def defaultCameraVfov(self):
|
|
#################################################################
|
|
# defaultCameraVfov(self)
|
|
# set the camera "Vfov" value back to default.
|
|
#################################################################
|
|
widget = self.widgetsDict['V.F.O.V.:']
|
|
widget.setvalue(34.51587677)
|
|
return
|
|
|
|
def defaultCameraFocalLength(self):
|
|
#################################################################
|
|
# defaultCameraFocalLength(self)
|
|
# set the camera "Focal Length" value back to default.
|
|
#################################################################
|
|
widget = self.widgetsDict['Focal Length:']
|
|
widget.setvalue(1.20710682869)
|
|
return
|
|
|
|
def setCameraFocalLength(self):
|
|
#################################################################
|
|
# setCameraFocalLength(self)
|
|
# set the camera "Focal Length" value to what now user has typed in the entry
|
|
#################################################################
|
|
if self.widgetsDict['Focal Length:'].getvalue() != '':
|
|
value = float(self.widgetsDict['Focal Length:'].getvalue())
|
|
else:
|
|
value = 0
|
|
camera.getChild(0).node().getLens().setFocalLength(value)
|
|
camera.getChild(0).node().getLens().setFilmSize(VBase2(float(self.widgetsDict['FilmSizeX'].getvalue()),float(self.widgetsDict['FilmSizeY'].getvalue())))
|
|
return
|
|
|
|
def defaultCameraFilmSize(self):
|
|
#################################################################
|
|
# defaultCameraFilmSize(self)
|
|
# set the camera "Film Size" value back to default.
|
|
#################################################################
|
|
widget = self.widgetsDict['FilmSizeX']
|
|
widget.setvalue(1)
|
|
widget = self.widgetsDict['FilmSizeY']
|
|
widget.setvalue(0.75)
|
|
return
|
|
|
|
def setCameraFilmSize(self):
|
|
#################################################################
|
|
# setCameraFilmSize(self)
|
|
# set the camera "Film Size" value to what now user has typed in the entry
|
|
#################################################################
|
|
if self.widgetsDict['FilmSizeX'].getvalue() != '':
|
|
value1 = float(self.widgetsDict['FilmSizeX'].getvalue())
|
|
else:
|
|
value1 = 0
|
|
if self.widgetsDict['FilmSizeY'].getvalue() != '':
|
|
value2 = float(self.widgetsDict['FilmSizeY'].getvalue())
|
|
else:
|
|
value2 = 0
|
|
camera.getChild(0).node().getLens().setFilmSize(VBase2(value1,value2))
|
|
return
|
|
|
|
####
|
|
#### Anything about Model & Actor will be here!
|
|
####
|
|
def modelInterface(self, contentFrame):
|
|
#################################################################
|
|
# modelInterface(self, contentFrame)
|
|
# Create the basic interface for ModelRoot Type Node
|
|
#################################################################
|
|
widget = self.createEntryField(contentFrame,'Type:',
|
|
value = self.type,
|
|
command = None,
|
|
initialState='disabled',
|
|
side = 'top')
|
|
widget = self.createEntryField(contentFrame,'Model File:',
|
|
value = self.info['filePath'].getFullpath(),
|
|
command = None,
|
|
initialState='disabled',
|
|
side = 'top',
|
|
defaultButton = False,
|
|
buttonText = 'Change',
|
|
defaultFunction = None)
|
|
group = Pmw.Group(contentFrame,tag_text='Position',
|
|
tag_font=('MSSansSerif', 10))
|
|
self.createPosEntry(group.interior())
|
|
group.pack(side=TOP,fill = X, expand = 0, pady=3)
|
|
|
|
group = Pmw.Group(contentFrame,tag_text='Orientation',
|
|
tag_font=('MSSansSerif', 10))
|
|
self.createHprEntry(group.interior())
|
|
group.pack(side=TOP,fill = X, expand = 0, pady=3)
|
|
|
|
self.createScaleEntry(contentFrame)
|
|
|
|
group = Pmw.Group(contentFrame,tag_text='Color',
|
|
tag_font=('MSSansSerif', 10))
|
|
frame = group.interior()
|
|
self.createColorEntry(frame)
|
|
self.varAlpha = IntVar()
|
|
self.varAlpha.set(self.nodePath.hasTransparency())
|
|
checkButton = Checkbutton(frame, text='Enable Alpha',
|
|
variable=self.varAlpha, command=self.toggleAlpha)
|
|
checkButton.pack(side=RIGHT,pady=3)
|
|
group.pack(side=TOP,fill = X, expand = 0, pady=3)
|
|
return
|
|
|
|
def toggleAlpha(self):
|
|
#################################################################
|
|
# toggleAlpha(self)
|
|
# This funtion will toggle the objects alpha value
|
|
# And, it will also reset the "Bin" to
|
|
# "fixed" if user enable the alpha for this object.
|
|
#################################################################
|
|
if self.nodePath.hasTransparency():
|
|
self.nodePath.clearTransparency()
|
|
self.nodePath.setBin("default", 0)
|
|
else:
|
|
self.nodePath.setTransparency(True)
|
|
self.nodePath.setBin("fixed", 1)
|
|
return
|
|
|
|
def actorInterface(self, contentFrame):
|
|
#################################################################
|
|
# actorInterface(self, contentFrame)
|
|
# Create the basic interface for Actor Type Node
|
|
#################################################################
|
|
self.animFrame = None
|
|
animeDict = self.info['animDict']
|
|
if len(animeDict)==0:
|
|
return
|
|
|
|
self.animFrame = Frame(contentFrame)
|
|
group = Pmw.Group(self.animFrame,tag_text='Animations',
|
|
tag_font=('MSSansSerif', 10))
|
|
innerFrame = group.interior()
|
|
for name in animeDict:
|
|
self.createEntryField(innerFrame, name,
|
|
value = animeDict[name],
|
|
command = None,
|
|
initialState='disabled',
|
|
side = 'top',
|
|
defaultButton = True,
|
|
buttonText = 'Remove',
|
|
defaultFunction = lambda a = name, b = self : b.deleteAnimation(a))
|
|
group.pack(side=TOP,fill = X, expand = 0, pady=3)
|
|
self.animFrame.pack(side=TOP,fill = X, expand = 0, pady=3)
|
|
return
|
|
|
|
|
|
def deleteAnimation(self, anim):
|
|
#################################################################
|
|
# deleteAnimation(self, anim)
|
|
# This function will delete the animation named "anim" in this actor
|
|
# But, not directly removed be this function.
|
|
# This function will send out a message to notice dataHolder to remove this animation
|
|
#################################################################
|
|
print anim
|
|
widget = self.widgetsDict[anim]
|
|
self.accept('animRemovedFromNode',self.redrawAnimProperty)
|
|
messenger.send('PW_removeAnimFromNode',[self.name, anim])
|
|
return
|
|
|
|
def redrawAnimProperty(self, nodePath, animDict):
|
|
#################################################################
|
|
# redrawCurveProperty(self, nodePath, curveList)
|
|
# Callback function, will be called once get the result from dataHolder.
|
|
# It will check the target nodePath first, then check the curve list is empty or not.
|
|
# If yes, then delete whole curve frame. If not, then renew the data and redraw the curve frame again.
|
|
#################################################################
|
|
self.name = self.nodePath.getName()
|
|
if self.name != nodePath.getName():
|
|
messenger.send('animRemovedFromNode',[nodePath, animDict])
|
|
return
|
|
else:
|
|
self.ignore('animRemovedFromNode')
|
|
|
|
if len(animDict)!= 0:
|
|
del self.info['animDict']
|
|
self.info['animDict'] = animDict
|
|
self.animFrame.destroy()
|
|
del self.animFrame
|
|
self.animFrame = None
|
|
self.actorInterface(self.contentFrame)
|
|
else:
|
|
del self.info['animDict']
|
|
self.animFrame.destroy()
|
|
del self.animFrame
|
|
self.animFrame = None
|
|
return
|
|
|
|
####
|
|
#### Anything about Light will be here!
|
|
####
|
|
def lightInterface(self, contentFrame):
|
|
#################################################################
|
|
# lightInterface(self, contentFrame)
|
|
# Create the basic interface for light Type Node
|
|
#################################################################
|
|
widget = self.createEntryField(contentFrame,'Type:',
|
|
value = self.nodePath.node().getType().getName(),
|
|
command = None,
|
|
initialState='disabled',
|
|
side = 'top')
|
|
|
|
self.lightNode = self.info['lightNode']
|
|
|
|
lightingGroup = Pmw.Group(contentFrame,tag_pyclass=None)
|
|
frame = lightingGroup.interior()
|
|
self.lightColor = seColorEntry(
|
|
frame, text = 'Light Color', label_font=('MSSansSerif', 10),
|
|
value=[self.lightNode.lightcolor.getX()*255, self.lightNode.lightcolor.getY()*255,self.lightNode.lightcolor.getZ()*255,0])
|
|
self.lightColor['command'] = self.setLightingColorVec
|
|
self.lightColor['resetValue'] = [0.3*255,0.3*255,0.3*255,0]
|
|
self.lightColor.pack(side=TOP, fill=X,expand=1, padx = 2, pady =2)
|
|
self.bind(self.lightColor, 'Set light color')
|
|
|
|
self.varActive = IntVar()
|
|
self.varActive.set(self.lightNode.active)
|
|
checkButton = Checkbutton(frame, text='Enable This Light',
|
|
variable=self.varActive, command=self.toggleLight)
|
|
checkButton.pack(side=RIGHT,pady=3)
|
|
lightingGroup.pack(side=TOP, fill = X, expand =1)
|
|
|
|
# Directional light controls
|
|
if self.lightNode.type == 'directional':
|
|
lightingGroup = Pmw.Group(contentFrame,tag_pyclass=None)
|
|
directionalPage = lightingGroup.interior()
|
|
self.dSpecularColor = seColorEntry(
|
|
directionalPage, text = 'Specular Color', label_font=('MSSansSerif', 10),value = [self.lightNode.specularColor.getX()*255,self.lightNode.specularColor.getY()*255,self.lightNode.specularColor.getZ()*255,0])
|
|
self.dSpecularColor['command'] = self.setSpecularColor
|
|
self.dSpecularColor.pack(fill = X, expand = 1)
|
|
self.bind(self.dSpecularColor,
|
|
'Set directional light specular color')
|
|
self.dPosition = VectorWidgets.Vector3Entry(
|
|
directionalPage, text = 'Position', label_font=('MSSansSerif', 10),value = [self.lightNode.getPosition().getX(),self.lightNode.getPosition().getY(),self.lightNode.getPosition().getZ()])
|
|
self.dPosition['command'] = self.setPosition
|
|
self.dPosition['resetValue'] = [0,0,0,0]
|
|
self.dPosition.pack(fill = X, expand = 1)
|
|
self.bind(self.dPosition, 'Set directional light position')
|
|
self.dOrientation = VectorWidgets.Vector3Entry(
|
|
directionalPage, text = 'Orientation', label_font=('MSSansSerif', 10),
|
|
value = [self.lightNode.getOrientation().getX(),self.lightNode.getOrientation().getY(),self.lightNode.getOrientation().getZ(),0])
|
|
self.dOrientation['command'] = self.setOrientation
|
|
self.dOrientation['resetValue'] = [0,0,0,0]
|
|
self.dOrientation.pack(fill = X, expand = 1)
|
|
self.bind(self.dOrientation, 'Set directional light orientation')
|
|
|
|
lightingGroup.pack(side=TOP, fill = X, expand =1)
|
|
|
|
|
|
elif self.lightNode.type == 'point':
|
|
# Point light controls
|
|
lightingGroup = Pmw.Group(contentFrame,tag_pyclass=None)
|
|
pointPage = lightingGroup.interior()
|
|
self.pSpecularColor = seColorEntry(
|
|
pointPage, text = 'Specular Color', label_font=('MSSansSerif', 10),
|
|
value = [self.lightNode.specularColor.getX(),self.lightNode.specularColor.getY(),self.lightNode.specularColor.getZ(),0])
|
|
self.pSpecularColor['command'] = self.setSpecularColor
|
|
self.pSpecularColor.pack(fill = X, expand = 1)
|
|
self.bind(self.pSpecularColor,
|
|
'Set point light specular color')
|
|
|
|
self.pPosition = VectorWidgets.Vector3Entry(
|
|
pointPage, text = 'Position', label_font=('MSSansSerif', 10),
|
|
value = [self.lightNode.getPosition().getX(),self.lightNode.getPosition().getY(),self.lightNode.getPosition().getZ(),0])
|
|
self.pPosition['command'] = self.setPosition
|
|
self.pPosition['resetValue'] = [0,0,0,0]
|
|
self.pPosition.pack(fill = X, expand = 1)
|
|
self.bind(self.pPosition, 'Set point light position')
|
|
|
|
self.pConstantAttenuation = Slider.Slider(
|
|
pointPage,
|
|
text = 'Constant Attenuation', label_font=('MSSansSerif', 10),
|
|
max = 1.0,
|
|
value = self.lightNode.constant)
|
|
self.pConstantAttenuation['command'] = self.setConstantAttenuation
|
|
self.pConstantAttenuation.pack(fill = X, expand = 1)
|
|
self.bind(self.pConstantAttenuation,
|
|
'Set point light constant attenuation')
|
|
|
|
self.pLinearAttenuation = Slider.Slider(
|
|
pointPage,
|
|
text = 'Linear Attenuation', label_font=('MSSansSerif', 10),
|
|
max = 1.0,
|
|
value = self.lightNode.linear)
|
|
self.pLinearAttenuation['command'] = self.setLinearAttenuation
|
|
self.pLinearAttenuation.pack(fill = X, expand = 1)
|
|
self.bind(self.pLinearAttenuation,
|
|
'Set point light linear attenuation')
|
|
|
|
self.pQuadraticAttenuation = Slider.Slider(
|
|
pointPage,
|
|
text = 'Quadratic Attenuation', label_font=('MSSansSerif', 10),
|
|
max = 1.0,
|
|
value = self.lightNode.quadratic)
|
|
self.pQuadraticAttenuation['command'] = self.setQuadraticAttenuation
|
|
self.pQuadraticAttenuation.pack(fill = X, expand = 1)
|
|
self.bind(self.pQuadraticAttenuation,
|
|
'Set point light quadratic attenuation')
|
|
|
|
lightingGroup.pack(side=TOP, fill = X, expand =1)
|
|
|
|
|
|
elif self.lightNode.type == 'spot':
|
|
# Spot light controls
|
|
lightingGroup = Pmw.Group(contentFrame,tag_pyclass=None)
|
|
spotPage = lightingGroup.interior()
|
|
self.sSpecularColor = seColorEntry(
|
|
spotPage, text = 'Specular Color', label_font=('MSSansSerif', 10),
|
|
value = [self.lightNode.specularColor.getX()*255,self.lightNode.specularColor.getY()*255,self.lightNode.specularColor.getZ()*255,0])
|
|
self.sSpecularColor['command'] = self.setSpecularColor
|
|
self.sSpecularColor.pack(fill = X, expand = 1)
|
|
self.bind(self.sSpecularColor,
|
|
'Set spot light specular color')
|
|
|
|
self.sConstantAttenuation = Slider.Slider(
|
|
spotPage,
|
|
text = 'Constant Attenuation', label_font=('MSSansSerif', 10),
|
|
max = 1.0,
|
|
value = self.lightNode.constant)
|
|
self.sConstantAttenuation['command'] = self.setConstantAttenuation
|
|
self.sConstantAttenuation.pack(fill = X, expand = 1)
|
|
self.bind(self.sConstantAttenuation,
|
|
'Set spot light constant attenuation')
|
|
|
|
self.sLinearAttenuation = Slider.Slider(
|
|
spotPage,
|
|
text = 'Linear Attenuation', label_font=('MSSansSerif', 10),
|
|
max = 1.0,
|
|
value = self.lightNode.linear)
|
|
self.sLinearAttenuation['command'] = self.setLinearAttenuation
|
|
self.sLinearAttenuation.pack(fill = X, expand = 1)
|
|
self.bind(self.sLinearAttenuation,
|
|
'Set spot light linear attenuation')
|
|
|
|
self.sQuadraticAttenuation = Slider.Slider(
|
|
spotPage,
|
|
text = 'Quadratic Attenuation', label_font=('MSSansSerif', 10),
|
|
max = 1.0,
|
|
value = self.lightNode.quadratic)
|
|
self.sQuadraticAttenuation['command'] = self.setQuadraticAttenuation
|
|
self.sQuadraticAttenuation.pack(fill = X, expand = 1)
|
|
self.bind(self.sQuadraticAttenuation,
|
|
'Set spot light quadratic attenuation')
|
|
|
|
self.sExponent = Slider.Slider(
|
|
spotPage,
|
|
text = 'Exponent', label_font=('MSSansSerif', 10),
|
|
max = 1.0,
|
|
value = self.lightNode.exponent)
|
|
self.sExponent['command'] = self.setExponent
|
|
self.sExponent.pack(fill = X, expand = 1)
|
|
self.bind(self.sExponent,
|
|
'Set spot light exponent')
|
|
lightingGroup.pack(side=TOP, fill = X, expand =1)
|
|
|
|
return
|
|
|
|
def setLightingColorVec(self,color):
|
|
if self.lightNode==None:
|
|
return
|
|
self.lightNode.setColor(VBase4((color[0]/255),(color[1]/255),(color[2]/255),1))
|
|
return
|
|
|
|
def setSpecularColor(self,color):
|
|
if self.lightNode==None:
|
|
return
|
|
self.lightNode.setSpecColor(VBase4((color[0]/255),(color[1]/255),(color[2]/255),1))
|
|
return
|
|
|
|
def setPosition(self,position):
|
|
if self.lightNode==None:
|
|
return
|
|
self.lightNode.setPosition(Point3(position[0],position[1],position[2]))
|
|
return
|
|
|
|
def setOrientation(self, orient):
|
|
if self.lightNode==None:
|
|
return
|
|
self.lightNode.setOrientation(Vec3(orient[0],orient[1],orient[2]))
|
|
return
|
|
|
|
def setConstantAttenuation(self, value):
|
|
self.lightNode.setConstantAttenuation(value)
|
|
return
|
|
|
|
def setLinearAttenuation(self, value):
|
|
self.lightNode.setLinearAttenuation(value)
|
|
return
|
|
|
|
def setQuadraticAttenuation(self, value):
|
|
self.lightNode.setQuadraticAttenuation(value)
|
|
return
|
|
|
|
def setExponent(self, value):
|
|
self.lightNode.setExponent(value)
|
|
return
|
|
|
|
def toggleLight(self):
|
|
messenger.send('PW_toggleLight',[self.lightNode])
|
|
return
|
|
|
|
|
|
####
|
|
#### Anything about Dummy will be here!
|
|
####
|
|
def dummyInterface(self, contentFrame):
|
|
#################################################################
|
|
# dummyInterface(self, contentFrame)
|
|
# Create the basic interface for dummy Type Node
|
|
#################################################################
|
|
'''dummyInterface(self, contentFrame)
|
|
Create the basic interface for dummy Node
|
|
'''
|
|
widget = self.createEntryField(contentFrame,'Type:',
|
|
value = 'Dummy Nodepath',
|
|
command = None,
|
|
initialState='disabled',
|
|
side = 'top')
|
|
|
|
group = Pmw.Group(contentFrame,tag_text='Position',
|
|
tag_font=('MSSansSerif', 10))
|
|
self.createPosEntry(group.interior())
|
|
group.pack(side=TOP,fill = X, expand = 0, pady=3)
|
|
|
|
group = Pmw.Group(contentFrame,tag_text='Orientation',
|
|
tag_font=('MSSansSerif', 10))
|
|
self.createHprEntry(group.interior())
|
|
group.pack(side=TOP,fill = X, expand = 0, pady=3)
|
|
|
|
self.createScaleEntry(contentFrame)
|
|
|
|
group = Pmw.Group(contentFrame,tag_text='Color',
|
|
tag_font=('MSSansSerif', 10))
|
|
frame = group.interior()
|
|
self.createColorEntry(frame)
|
|
self.varAlpha = IntVar()
|
|
self.varAlpha.set(self.nodePath.hasTransparency())
|
|
checkButton = Checkbutton(frame, text='Enable Alpha',
|
|
variable=self.varAlpha, command=self.toggleAlpha)
|
|
checkButton.pack(side=RIGHT,pady=3)
|
|
group.pack(side=TOP,fill = X, expand = 0, pady=3)
|
|
return
|
|
|
|
|
|
#########
|
|
####### This will be called when user try to open property window for SEditor Node
|
|
#########
|
|
def gridInterface(self, contentFrame):
|
|
#################################################################
|
|
# gridInterface(self, contentFrame)
|
|
# Create the basic interface for grid (Which is stolen from directGrid)
|
|
#################################################################
|
|
group = Pmw.Group(contentFrame,tag_text='Grid Property',
|
|
tag_font=('MSSansSerif', 10))
|
|
group.pack(side=TOP,fill = X, expand = 0, padx = 3, pady=3)
|
|
|
|
gridPage = group.interior()
|
|
|
|
self.xyzSnap = BooleanVar()
|
|
self.xyzSnapButton = Checkbutton(
|
|
gridPage,
|
|
text = 'XYZ Snap',
|
|
anchor = 'w', justify = LEFT,
|
|
variable = self.xyzSnap,
|
|
command = self.toggleXyzSnap)
|
|
self.xyzSnapButton.pack(fill = X, expand = 0, pady=3)
|
|
|
|
self.hprSnap = BooleanVar()
|
|
self.hprSnapButton = Checkbutton(
|
|
gridPage,
|
|
text = 'HPR Snap',
|
|
anchor = 'w', justify = LEFT,
|
|
variable = self.hprSnap,
|
|
command = self.toggleHprSnap)
|
|
self.hprSnapButton.pack(fill = X, expand = 0, pady=3)
|
|
|
|
self.xyzSnap.set(SEditor.grid.getXyzSnap())
|
|
self.hprSnap.set(SEditor.grid.getHprSnap())
|
|
|
|
self.gridSpacing = Floater.Floater(
|
|
gridPage,
|
|
text = 'Grid Spacing',
|
|
min = 0.1,
|
|
value = SEditor.grid.getGridSpacing())
|
|
self.gridSpacing['command'] = SEditor.grid.setGridSpacing
|
|
self.gridSpacing.pack(fill = X, expand = 0, pady=3)
|
|
|
|
self.gridSize = Floater.Floater(
|
|
gridPage,
|
|
text = 'Grid Size',
|
|
min = 1.0,
|
|
value = SEditor.grid.getGridSize())
|
|
self.gridSize['command'] = SEditor.grid.setGridSize
|
|
self.gridSize.pack(fill = X, expand = 0, pady=3)
|
|
|
|
self.gridSnapAngle = Dial.AngleDial(
|
|
gridPage,
|
|
text = 'Snap Angle',
|
|
style = 'mini',
|
|
value = SEditor.grid.getSnapAngle())
|
|
self.gridSnapAngle['command'] = SEditor.grid.setSnapAngle
|
|
self.gridSnapAngle.pack(fill = X, expand = 0, pady=3)
|
|
|
|
return
|
|
|
|
def toggleXyzSnap(self):
|
|
SEditor.grid.setXyzSnap(self.xyzSnap.get())
|
|
return
|
|
|
|
def toggleHprSnap(self):
|
|
SEditor.grid.setHprSnap(self.hprSnap.get())
|
|
return
|
|
|
|
|
|
|
|
###### Collision Section!!!!
|
|
def collisionInterface(self, contentFrame):
|
|
#################################################################
|
|
# collisionInterface(self, contentFrame)
|
|
# Create the basic interface for CollisionNode Type Node
|
|
#################################################################
|
|
collisionNode = self.info['collisionNode']
|
|
self.collisionObj = collisionNode.node().getSolid(0)
|
|
widget = self.createEntryField(contentFrame,'Node Type:',
|
|
value = self.type,
|
|
command = None,
|
|
initialState='disabled',
|
|
side = 'top')
|
|
cType = self.collisionObj.getType().getName()
|
|
widget = self.createEntryField(contentFrame,'Object Type:',
|
|
value = cType,
|
|
command = None,
|
|
initialState='disabled',
|
|
side = 'top')
|
|
group = Pmw.Group(contentFrame,tag_text='Position',
|
|
tag_font=('MSSansSerif', 10))
|
|
self.createPosEntry(group.interior())
|
|
group.pack(side=TOP,fill = X, expand = 0, pady=3)
|
|
|
|
group = Pmw.Group(contentFrame,tag_text='Orientation',
|
|
tag_font=('MSSansSerif', 10))
|
|
self.createHprEntry(group.interior())
|
|
group.pack(side=TOP,fill = X, expand = 0, pady=3)
|
|
|
|
self.createScaleEntry(contentFrame)
|
|
|
|
collisionGroup = Pmw.Group(contentFrame,tag_text='Collision Object Properties',
|
|
tag_font=('MSSansSerif', 10))
|
|
cObjFrame = collisionGroup.interior()
|
|
|
|
### Generate different Interface for each different kinds of Collision Objects
|
|
### Yeah, yeah. I know this part of code looks so ugly...
|
|
if cType == 'CollisionSphere':
|
|
centerPos = self.collisionObj.getCenter()
|
|
radius = self.collisionObj.getRadius()
|
|
group = Pmw.Group(cObjFrame,tag_text='Origin',
|
|
tag_font=('MSSansSerif', 10))
|
|
|
|
|
|
posInterior = Frame(group.interior())
|
|
self.cPosX = self.createcomponent('originX', (), None,
|
|
Floater.Floater, (posInterior,),
|
|
text = 'X', relief = FLAT,
|
|
value = centerPos.getX(),
|
|
label_foreground = 'Red',
|
|
entry_width = 9)
|
|
self.cPosX['commandData'] = ['sphere-o']
|
|
self.cPosX['command'] = self.setCollisionPosHprScale
|
|
self.cPosX.pack(side=LEFT,expand=0,fill=X, padx=1)
|
|
|
|
self.cPosY = self.createcomponent('originY', (), None,
|
|
Floater.Floater, (posInterior,),
|
|
text = 'Y', relief = FLAT,
|
|
value = centerPos.getY(),
|
|
label_foreground = '#00A000',
|
|
entry_width = 9)
|
|
self.cPosY['commandData'] = ['sphere-o']
|
|
self.cPosY['command'] = self.setCollisionPosHprScale
|
|
self.cPosY.pack(side=LEFT, expand=0,fill=X, padx=1)
|
|
|
|
self.cPosZ = self.createcomponent('originZ', (), None,
|
|
Floater.Floater, (posInterior,),
|
|
text = 'Z', relief = FLAT,
|
|
value = centerPos.getZ(),
|
|
label_foreground = 'Blue',
|
|
entry_width = 9)
|
|
self.cPosZ['commandData'] = ['sphere-o']
|
|
self.cPosZ['command'] = self.setCollisionPosHprScale
|
|
self.cPosZ.pack(side=LEFT, expand=0,fill=X, padx=1)
|
|
posInterior.pack(side=TOP, expand=0,fill=X, padx=3, pady=3)
|
|
|
|
group.pack(side=TOP,fill = X, expand = 0, pady=3)
|
|
|
|
scaleInterior = Frame(cObjFrame)
|
|
|
|
self.scaleS = self.createcomponent('radius', (), None,
|
|
Floater.Floater, (scaleInterior,),
|
|
text = 'Radius',
|
|
relief = FLAT,
|
|
min = 0.0001, value = radius,
|
|
resetValue = 1.0,
|
|
label_foreground = 'Blue')
|
|
self.scaleS['commandData'] = ['sphere-radius']
|
|
self.scaleS['command'] = self.setCollisionPosHprScale
|
|
self.scaleS.pack(side=LEFT,expand=0,fill=X)
|
|
|
|
scaleInterior.pack(side=TOP,expand=0,fill=X, padx=3, pady=3)
|
|
pass
|
|
|
|
elif cType == 'CollisionPolygon':
|
|
frame = Frame(cObjFrame)
|
|
label = Label(frame, text= "Sorry!",font=('MSSansSerif', 10),
|
|
borderwidth=5)
|
|
label.pack(side=LEFT)
|
|
frame.pack(side=TOP, fill=X, expand=True)
|
|
frame = Frame(cObjFrame)
|
|
label = Label(frame, text= "There is no way to change",font=('MSSansSerif', 10),
|
|
borderwidth=5)
|
|
label.pack(side=LEFT)
|
|
frame.pack(side=TOP, fill=X, expand=True)
|
|
frame = Frame(cObjFrame)
|
|
label = Label(frame, text= "the basic properties of Collision Polygon!",font=('MSSansSerif', 10),
|
|
borderwidth=5)
|
|
label.pack(side=LEFT)
|
|
frame.pack(side=TOP, fill=X, expand=True)
|
|
frame = Frame(cObjFrame)
|
|
label = Label(frame, text= "If you really need to change, recreate one...",font=('MSSansSerif', 10),
|
|
borderwidth=5)
|
|
label.pack(side=LEFT)
|
|
frame.pack(side=TOP, fill=X, expand=True)
|
|
pass
|
|
|
|
elif cType == 'CollisionSegment':
|
|
pointA = self.collisionObj.getPointA()
|
|
pointB = self.collisionObj.getPointB()
|
|
group = Pmw.Group(cObjFrame,tag_text='Point A',
|
|
tag_font=('MSSansSerif', 10))
|
|
posInterior = Frame(group.interior())
|
|
self.cPosX = self.createcomponent('pointA-X', (), None,
|
|
Floater.Floater, (posInterior,),
|
|
text = 'X', relief = FLAT,
|
|
value = pointA.getX(),
|
|
label_foreground = 'Red',
|
|
entry_width = 9)
|
|
self.cPosX['commandData'] = ['segment-A']
|
|
self.cPosX['command'] = self.setCollisionPosHprScale
|
|
self.cPosX.pack(side=LEFT,expand=0,fill=X, padx=1)
|
|
|
|
self.cPosY = self.createcomponent('pointA-Y', (), None,
|
|
Floater.Floater, (posInterior,),
|
|
text = 'Y', relief = FLAT,
|
|
value = pointA.getY(),
|
|
label_foreground = '#00A000',
|
|
entry_width = 9)
|
|
self.cPosY['commandData'] = ['segment-A']
|
|
self.cPosY['command'] = self.setCollisionPosHprScale
|
|
self.cPosY.pack(side=LEFT, expand=0,fill=X, padx=1)
|
|
|
|
self.cPosZ = self.createcomponent('pointA-Z', (), None,
|
|
Floater.Floater, (posInterior,),
|
|
text = 'Z', relief = FLAT,
|
|
value = pointA.getZ(),
|
|
label_foreground = 'Blue',
|
|
entry_width = 9)
|
|
self.cPosZ['commandData'] = ['segment-A']
|
|
self.cPosZ['command'] = self.setCollisionPosHprScale
|
|
self.cPosZ.pack(side=LEFT, expand=0,fill=X, padx=1)
|
|
posInterior.pack(side=TOP, expand=0,fill=X, padx=3, pady=3)
|
|
group.pack(side=TOP,fill = X, expand = 0, pady=3)
|
|
group = Pmw.Group(cObjFrame,tag_text='Point B',
|
|
tag_font=('MSSansSerif', 10))
|
|
posInterior = Frame(group.interior())
|
|
self.cPosXB = self.createcomponent('pointB-X', (), None,
|
|
Floater.Floater, (posInterior,),
|
|
text = 'X', relief = FLAT,
|
|
value = pointB.getX(),
|
|
label_foreground = 'Red',
|
|
entry_width = 9)
|
|
self.cPosXB['commandData'] = ['segment-B']
|
|
self.cPosXB['command'] = self.setCollisionPosHprScale
|
|
self.cPosXB.pack(side=LEFT,expand=0,fill=X, padx=1)
|
|
|
|
self.cPosYB = self.createcomponent('pointB-Y', (), None,
|
|
Floater.Floater, (posInterior,),
|
|
text = 'Y', relief = FLAT,
|
|
value = pointB.getY(),
|
|
label_foreground = '#00A000',
|
|
entry_width = 9)
|
|
self.cPosYB['commandData'] = ['segment-B']
|
|
self.cPosYB['command'] = self.setCollisionPosHprScale
|
|
self.cPosYB.pack(side=LEFT, expand=0,fill=X, padx=1)
|
|
|
|
self.cPosZB = self.createcomponent('pointB-Z', (), None,
|
|
Floater.Floater, (posInterior,),
|
|
text = 'Z', relief = FLAT,
|
|
value = pointB.getZ(),
|
|
label_foreground = 'Blue',
|
|
entry_width = 9)
|
|
self.cPosZB['commandData'] = ['segment-B']
|
|
self.cPosZB['command'] = self.setCollisionPosHprScale
|
|
self.cPosZB.pack(side=LEFT, expand=0,fill=X, padx=1)
|
|
posInterior.pack(side=TOP, expand=0,fill=X, padx=3, pady=3)
|
|
group.pack(side=TOP,fill = X, expand = 0, pady=3)
|
|
pass
|
|
elif cType == 'CollisionRay':
|
|
origin = self.collisionObj.getOrigin()
|
|
direction = self.collisionObj.getDirection()
|
|
group = Pmw.Group(cObjFrame,tag_text='Origin Point',
|
|
tag_font=('MSSansSerif', 10))
|
|
posInterior = Frame(group.interior())
|
|
self.cPosX = self.createcomponent('origin-X', (), None,
|
|
Floater.Floater, (posInterior,),
|
|
text = 'X', relief = FLAT,
|
|
value = origin.getX(),
|
|
label_foreground = 'Red',
|
|
entry_width = 9)
|
|
self.cPosX['commandData'] = ['ray-A']
|
|
self.cPosX['command'] = self.setCollisionPosHprScale
|
|
self.cPosX.pack(side=LEFT,expand=0,fill=X, padx=1)
|
|
|
|
self.cPosY = self.createcomponent('origin-Y', (), None,
|
|
Floater.Floater, (posInterior,),
|
|
text = 'Y', relief = FLAT,
|
|
value = origin.getY(),
|
|
label_foreground = '#00A000',
|
|
entry_width = 9)
|
|
self.cPosY['commandData'] = ['ray-A']
|
|
self.cPosY['command'] = self.setCollisionPosHprScale
|
|
self.cPosY.pack(side=LEFT, expand=0,fill=X, padx=1)
|
|
|
|
self.cPosZ = self.createcomponent('origin-Z', (), None,
|
|
Floater.Floater, (posInterior,),
|
|
text = 'Z', relief = FLAT,
|
|
value = origin.getZ(),
|
|
label_foreground = 'Blue',
|
|
entry_width = 9)
|
|
self.cPosZ['commandData'] = ['ray-A']
|
|
self.cPosZ['command'] = self.setCollisionPosHprScale
|
|
self.cPosZ.pack(side=LEFT, expand=0,fill=X, padx=1)
|
|
posInterior.pack(side=TOP, expand=0,fill=X, padx=3, pady=3)
|
|
group.pack(side=TOP,fill = X, expand = 0, pady=3)
|
|
group = Pmw.Group(cObjFrame,tag_text='Direction',
|
|
tag_font=('MSSansSerif', 10))
|
|
posInterior = Frame(group.interior())
|
|
self.cPosXB = self.createcomponent('direction-X', (), None,
|
|
Floater.Floater, (posInterior,),
|
|
text = 'X', relief = FLAT,
|
|
value = direction.getX(),
|
|
label_foreground = 'Red',
|
|
entry_width = 9)
|
|
self.cPosXB['commandData'] = ['ray-B']
|
|
self.cPosXB['command'] = self.setCollisionPosHprScale
|
|
self.cPosXB.pack(side=LEFT,expand=0,fill=X, padx=1)
|
|
|
|
self.cPosYB = self.createcomponent('direction-Y', (), None,
|
|
Floater.Floater, (posInterior,),
|
|
text = 'Y', relief = FLAT,
|
|
value = direction.getY(),
|
|
label_foreground = '#00A000',
|
|
entry_width = 9)
|
|
self.cPosYB['commandData'] = ['ray-B']
|
|
self.cPosYB['command'] = self.setCollisionPosHprScale
|
|
self.cPosYB.pack(side=LEFT, expand=0,fill=X, padx=1)
|
|
|
|
self.cPosZB = self.createcomponent('direction-Z', (), None,
|
|
Floater.Floater, (posInterior,),
|
|
text = 'Z', relief = FLAT,
|
|
value = direction.getZ(),
|
|
label_foreground = 'Blue',
|
|
entry_width = 9)
|
|
self.cPosZB['commandData'] = ['ray-B']
|
|
self.cPosZB['command'] = self.setCollisionPosHprScale
|
|
self.cPosZB.pack(side=LEFT, expand=0,fill=X, padx=1)
|
|
posInterior.pack(side=TOP, expand=0,fill=X, padx=3, pady=3)
|
|
group.pack(side=TOP,fill = X, expand = 0, pady=3)
|
|
pass
|
|
|
|
collisionGroup.pack(side=TOP,fill = X, expand = 0, pady=3)
|
|
|
|
return
|
|
|
|
def setCollisionPosHprScale(self, data, dataType):
|
|
#################################################################
|
|
# setCollisionPosHprScale(self, data, dataType)
|
|
# Well, the reason that we didn't use the same one with other nodePath
|
|
# is that each tyoe of collsion objects has its unique properties and way to set value.
|
|
# So, they have to be separated from other nodePath
|
|
#################################################################
|
|
if dataType == 'sphere-o':
|
|
origin = Point3(float(self.cPosX._entry.get()),
|
|
float(self.cPosY._entry.get()),
|
|
float(self.cPosZ._entry.get()))
|
|
self.collisionObj.setCenter(origin)
|
|
elif dataType == 'sphere-radius':
|
|
self.collisionObj.setRadius(data)
|
|
elif dataType == 'segment-A':
|
|
pointA = Point3(float(self.cPosX._entry.get()),
|
|
float(self.cPosY._entry.get()),
|
|
float(self.cPosZ._entry.get()))
|
|
self.collisionObj.setPointA(pointA)
|
|
elif dataType == 'segment-B':
|
|
pointB = Point3(float(self.cPosXB._entry.get()),
|
|
float(self.cPosYB._entry.get()),
|
|
float(self.cPosZB._entry.get()))
|
|
self.collisionObj.setPointB(pointB)
|
|
elif dataType == 'ray-A':
|
|
pointA = Point3(float(self.cPosX._entry.get()),
|
|
float(self.cPosY._entry.get()),
|
|
float(self.cPosZ._entry.get()))
|
|
self.collisionObj.setOrigin(pointA)
|
|
elif dataType == 'ray-B':
|
|
pointB = Vec3(float(self.cPosXB._entry.get()),
|
|
float(self.cPosYB._entry.get()),
|
|
float(self.cPosZB._entry.get()))
|
|
self.collisionObj.setDirection(pointB)
|
|
return
|
|
|
|
#################################################################
|
|
#################################################################
|
|
# Functions below are all call back function
|
|
# They will be called when user has manipulated its node on the screen
|
|
# The message itself is sent by a task called monitorSelectedNode in the sceneEditor.
|
|
#################################################################
|
|
#################################################################
|
|
def trackDataFromSceneCamera(self, pos=Point3(0,0,0), hpr=Vec3(0,0,0), scale=Point3(0,0,0)):
|
|
self.posX.set(pos.getX())
|
|
self.posY.set(pos.getY())
|
|
self.posZ.set(pos.getZ())
|
|
self.hprH.set(hpr.getX())
|
|
self.hprP.set(hpr.getY())
|
|
self.hprR.set(hpr.getZ())
|
|
return
|
|
|
|
def trackDataFromSceneModel(self, pos=Point3(0,0,0), hpr=Vec3(0,0,0), scale=Point3(0,0,0)):
|
|
self.posX.set(pos.getX())
|
|
self.posY.set(pos.getY())
|
|
self.posZ.set(pos.getZ())
|
|
self.hprH.set(hpr.getX())
|
|
self.hprP.set(hpr.getY())
|
|
self.hprR.set(hpr.getZ())
|
|
self.scale.set(scale.getX())
|
|
return
|
|
|
|
def trackDataFromSceneActor(self, pos=Point3(0,0,0), hpr=Vec3(0,0,0), scale=Point3(0,0,0)):
|
|
self.posX.set(pos.getX())
|
|
self.posY.set(pos.getY())
|
|
self.posZ.set(pos.getZ())
|
|
self.hprH.set(hpr.getX())
|
|
self.hprP.set(hpr.getY())
|
|
self.hprR.set(hpr.getZ())
|
|
self.scale.set(scale.getX())
|
|
return
|
|
|
|
def trackDataFromSceneLight(self, pos=Point3(0,0,0), hpr=Vec3(0,0,0), scale=Point3(0,0,0)):
|
|
if self.lightNode.type == 'directional':
|
|
self.dPosition.set([pos.getX(),pos.getY(),pos.getZ()])
|
|
self.dOrientation.set([hpr.getX(),hpr.getY(),hpr.getZ()])
|
|
pass
|
|
|
|
elif self.lightNode.type == 'point':
|
|
self.pPosition.set([pos.getX(),pos.getY(),pos.getZ()])
|
|
pass
|
|
return
|
|
|
|
def trackDataFromSceneDummy(self, pos=Point3(0,0,0), hpr=Vec3(0,0,0), scale=Point3(0,0,0)):
|
|
self.posX.set(pos.getX())
|
|
self.posY.set(pos.getY())
|
|
self.posZ.set(pos.getZ())
|
|
self.hprH.set(hpr.getX())
|
|
self.hprP.set(hpr.getY())
|
|
self.hprR.set(hpr.getZ())
|
|
self.scale.set(scale.getX())
|
|
return
|
|
|
|
def trackDataFromSceneCollision(self, pos=Point3(0,0,0), hpr=Vec3(0,0,0), scale=Point3(0,0,0)):
|
|
self.posX.set(pos.getX())
|
|
self.posY.set(pos.getY())
|
|
self.posZ.set(pos.getZ())
|
|
self.hprH.set(hpr.getX())
|
|
self.hprP.set(hpr.getY())
|
|
self.hprR.set(hpr.getZ())
|
|
self.scale.set(scale.getX())
|
|
return
|
|
|