Changes to reflect new specification of modifiers for mouse/kb events

Update to use new ka option of directdserver
Fix to joybox code
This commit is contained in:
Mark Mine 2002-05-22 22:46:58 +00:00
parent 8579e7c138
commit 03ec124072
17 changed files with 251 additions and 222 deletions

View File

@ -26,14 +26,19 @@ class ClusterClient(DirectObject.DirectObject):
self.daemon.listenTo(clusterDaemonPort) self.daemon.listenTo(clusterDaemonPort)
# Contact server daemons and start up remote server application # Contact server daemons and start up remote server application
for serverConfig in configList: for serverConfig in configList:
# First kill existing application
self.daemon.tellServer(serverConfig.serverName,
clusterDaemonPort,
'ka')
# Now start up new application
serverCommand = (SERVER_STARTUP_STRING % serverCommand = (SERVER_STARTUP_STRING %
(serverConfig.serverPort, (serverConfig.serverPort,
clusterSyncFlag, clusterSyncFlag,
clusterDaemonClient, clusterDaemonClient,
clusterDaemonPort)) clusterDaemonPort))
self.daemon.clientReady(serverConfig.serverName, self.daemon.tellServer(serverConfig.serverName,
clusterDaemonPort, clusterDaemonPort,
serverCommand) serverCommand)
if not self.daemon.waitForServers(len(configList)): if not self.daemon.waitForServers(len(configList)):
print 'Cluster Client, no response from servers' print 'Cluster Client, no response from servers'
self.qcm=QueuedConnectionManager() self.qcm=QueuedConnectionManager()

View File

@ -39,29 +39,29 @@ ClientConfigs = {
'pos' : Vec3(0), 'pos' : Vec3(0),
'hpr' : Vec3(0)} 'hpr' : Vec3(0)}
], ],
'cavetestsmall' : [{'display name' : 'la', 'cavetest3' : [{'display name' : 'la',
'pos' : Vec3(-0.105, -0.020, 5.000), 'pos' : Vec3(-0.105, -0.020, 5.000),
'hpr' : Vec3(51.213, 0.000, 0.000), 'hpr' : Vec3(51.213, 0.000, 0.000),
'focal length' : 0.809, 'focal length' : 0.809,
'film size' : (1.000, 0.831), 'film size' : (1.000, 0.831),
'film offset' : (0.000, 0.173), 'film offset' : (0.000, 0.173),
}, },
{'display name' : 'lb', {'display name' : 'lb',
'display mode' : 'client', 'display mode' : 'client',
'pos' : Vec3(-0.105, -0.020, 5.000), 'pos' : Vec3(-0.105, -0.020, 5.000),
'hpr' : Vec3(-0.370, 0.000, 0.000), 'hpr' : Vec3(-0.370, 0.000, 0.000),
'focal length' : 0.815, 'focal length' : 0.815,
'film size' : (1.000, 0.831), 'film size' : (1.000, 0.831),
'film offset' : (0.000, 0.173), 'film offset' : (0.000, 0.173),
}, },
{'display name' : 'lc', {'display name' : 'lc',
'pos' : Vec3(-0.105, -0.020, 5.000), 'pos' : Vec3(-0.105, -0.020, 5.000),
'hpr' : Vec3(-51.675, 0.000, 0.000), 'hpr' : Vec3(-51.675, 0.000, 0.000),
'focal length' : 0.820, 'focal length' : 0.820,
'film size' : (1.000, 0.830), 'film size' : (1.000, 0.830),
'film offset' : (-0.000, 0.173), 'film offset' : (-0.000, 0.173),
}, },
], ],
'cavetest' : [{'display name' : 'la', 'cavetest' : [{'display name' : 'la',
'pos' : Vec3(-0.105, -0.020, 5.000), 'pos' : Vec3(-0.105, -0.020, 5.000),
'hpr' : Vec3(51.213, 0.000, 0.000), 'hpr' : Vec3(51.213, 0.000, 0.000),

View File

@ -22,8 +22,9 @@ CLUSTER_EXIT = 100
CLUSTER_SERVER_PORT = 1970 CLUSTER_SERVER_PORT = 1970
CLUSTER_DAEMON_PORT = 8001 CLUSTER_DAEMON_PORT = 8001
# Precede command string with ! to tell server to execute command string
SERVER_STARTUP_STRING = ( SERVER_STARTUP_STRING = (
'bash ppython -c ' + '!bash ppython -c ' +
'"import __builtin__; ' + '"import __builtin__; ' +
'__builtin__.clusterServerPort = %s;' + '__builtin__.clusterServerPort = %s;' +
'__builtin__.clusterSyncFlag = %d;' + '__builtin__.clusterSyncFlag = %d;' +

View File

@ -93,13 +93,13 @@ class DirectAnalogs(AnalogNode, DirectObject):
self.nodePath = myBase.dataRoot.attachNewNode(self) self.nodePath = myBase.dataRoot.attachNewNode(self)
# See if any of the general analog parameters are dconfig'd # See if any of the general analog parameters are dconfig'd
self.analogDeadband = myBase.config.GetFloat('vrpn-analog-deadband', self.analogDeadband = myBase.config.GetFloat('vrpn-analog-deadband',
ANALOG_DEADBAND) ANALOG_DEADBAND)
self.analogMin = myBase.config.GetFloat('vrpn-analog-min', self.analogMin = myBase.config.GetFloat('vrpn-analog-min',
ANALOG_MIN) ANALOG_MIN)
self.analogMax = myBase.config.GetFloat('vrpn-analog-max', self.analogMax = myBase.config.GetFloat('vrpn-analog-max',
ANALOG_MAX) ANALOG_MAX)
self.analogMax = myBase.config.GetFloat('vrpn-analog-center', self.analogCenter = myBase.config.GetFloat('vrpn-analog-center',
ANALOG_CENTER) ANALOG_CENTER)
self.analogRange = self.analogMax - self.analogMin self.analogRange = self.analogMax - self.analogMin

View File

@ -1,7 +1,7 @@
""" Class used to create and control joybox device """ """ Class used to create and control joybox device """
from PandaObject import * from PandaObject import *
from DirectDeviceManager import * from DirectDeviceManager import *
from DirectGeometry import * from DirectUtil import *
import OnscreenText import OnscreenText
""" """
@ -162,8 +162,7 @@ class DirectJoybox(PandaObject):
else: else:
val = max(val - ANALOG_DEADBAND, 0.0) val = max(val - ANALOG_DEADBAND, 0.0)
# Scale up rotating knob values # Scale up rotating knob values
if (chan == 2) or (chan == 6): if (chan == L_TWIST) or (chan == R_TWIST):
print "got twist in unrolled!"
val *= 3.0 val *= 3.0
# Now clamp value between minVal and maxVal # Now clamp value between minVal and maxVal
val = CLAMP(val, JOYBOX_MIN, JOYBOX_MAX) val = CLAMP(val, JOYBOX_MIN, JOYBOX_MAX)
@ -219,14 +218,10 @@ class DirectJoybox(PandaObject):
# Do nothing if no nodePath selected # Do nothing if no nodePath selected
if self.nodePath == None: if self.nodePath == None:
return return
""" hprScale = ((self.aList[L_SLIDE] + 1.0) *
hprScale = (self.normalizeChannel(L_SLIDE, 0.1, 100) * 50.0 * DirectJoybox.hprMultiplier)
DirectJoybox.hprMultiplier) posScale = ((self.aList[R_SLIDE] + 1.0) *
posScale = (self.normalizeChannel(R_SLIDE, 0.1, 100) * 50.0 * DirectJoybox.xyzMultiplier)
DirectJoybox.xyzMultiplier)
"""
hprScale = (self.aList[L_SLIDE] + 1.0) * 50.0 * DirectJoybox.hprMultiplier
posScale = (self.aList[R_SLIDE] + 1.0) * 50.0 * DirectJoybox.xyzMultiplier
def getAxisVal(index, s = self): def getAxisVal(index, s = self):
try: try:
return s.aList[s.mapping[index]] return s.aList[s.mapping[index]]
@ -412,12 +407,12 @@ class DirectJoybox(PandaObject):
def normalizeChannel(self, chan, minVal = -1, maxVal = 1): def normalizeChannel(self, chan, minVal = -1, maxVal = 1):
try: try:
if (chan == L_TWIST) or (chan == R_TWIST): if (chan == L_TWIST) or (chan == R_TWIST):
print "in Joybox normalize channel: got *_TWIST!"
# These channels have reduced range # These channels have reduced range
return self.analogs.normalize(self.analogs.getControlState(chan) * 3.0, minVal, maxVal) return self.analogs.normalize(
self.analogs.getControlState(chan) * 3.0, minVal, maxVal)
else: else:
print "in Joybox normalize channel..." return self.analogs.normalize(
return self.analogs.normalize(self.analogs.getControlState(chan), minVal, maxVal) self.analogs.getControlState(chan), minVal, maxVal)
except IndexError: except IndexError:
return 0.0 return 0.0

View File

@ -1,4 +1,5 @@
from PandaObject import * from PandaObject import *
from DirectUtil import *
from DirectGeometry import * from DirectGeometry import *
CAM_MOVE_DURATION = 1.2 CAM_MOVE_DURATION = 1.2
@ -16,7 +17,7 @@ class DirectCameraControl(PandaObject):
self.coaMarker = loader.loadModel('models/misc/sphere') self.coaMarker = loader.loadModel('models/misc/sphere')
self.coaMarker.setName('DirectCameraCOAMarker') self.coaMarker.setName('DirectCameraCOAMarker')
self.coaMarker.setTransparency(1) self.coaMarker.setTransparency(1)
self.coaMarker.setColor(1,0,0) self.coaMarker.setColor(1,0,0,0)
self.coaMarker.setPos(0,100,0) self.coaMarker.setPos(0,100,0)
useDirectRenderStyle(self.coaMarker) useDirectRenderStyle(self.coaMarker)
self.coaMarkerPos = Point3(0) self.coaMarkerPos = Point3(0)
@ -27,8 +28,8 @@ class DirectCameraControl(PandaObject):
self.camManipRef = direct.group.attachNewNode('camManipRef') self.camManipRef = direct.group.attachNewNode('camManipRef')
t = CAM_MOVE_DURATION t = CAM_MOVE_DURATION
self.actionEvents = [ self.actionEvents = [
['DIRECT_mouse2', self.mouseFlyStart], ['DIRECT-mouse2', self.mouseFlyStart],
['DIRECT_mouse2Up', self.mouseFlyStop], ['DIRECT-mouse2Up', self.mouseFlyStop],
['c', self.centerCamIn, 0.5], ['c', self.centerCamIn, 0.5],
['f', self.fitOnWidget], ['f', self.fitOnWidget],
['h', self.homeCam], ['h', self.homeCam],
@ -60,7 +61,7 @@ class DirectCameraControl(PandaObject):
else: else:
direct.cameraControl.coaMarker.hide() direct.cameraControl.coaMarker.hide()
def mouseFlyStart(self): def mouseFlyStart(self, modifiers):
# Record undo point # Record undo point
direct.pushUndo([direct.camera]) direct.pushUndo([direct.camera])
# Where are we in the display region? # Where are we in the display region?

View File

@ -1,17 +1,9 @@
from PandaModules import * from PandaModules import *
from PandaObject import * from PandaObject import *
from DirectGlobals import *
from DirectUtil import *
import math import math
X_AXIS = Vec3(1,0,0)
Y_AXIS = Vec3(0,1,0)
Z_AXIS = Vec3(0,0,1)
NEG_X_AXIS = Vec3(-1,0,0)
NEG_Y_AXIS = Vec3(0,-1,0)
NEG_Z_AXIS = Vec3(0,0,-1)
ZERO_VEC = ORIGIN = Vec3(0)
UNIT_VEC = Vec3(1)
ZERO_POINT = Point3(0)
class LineNodePath(NodePath): class LineNodePath(NodePath):
def __init__(self, parent = None, name = None, def __init__(self, parent = None, name = None,
thickness = 1.0, colorVec = VBase4(1)): thickness = 1.0, colorVec = VBase4(1)):
@ -141,18 +133,6 @@ def planeIntersect (lineOrigin, lineDir, planeOrigin, normal):
hitPt = lineDir * t hitPt = lineDir * t
return hitPt + lineOrigin return hitPt + lineOrigin
def ROUND_TO(value, divisor):
return round(value/float(divisor)) * divisor
def ROUND_INT(val):
return int(round(val))
def CLAMP(val, min, max):
if val < min:
return min
elif val > max:
return max
else:
return val
def getNearProjectionPoint(nodePath): def getNearProjectionPoint(nodePath):
# Find the position of the projection of the specified node path # Find the position of the projection of the specified node path
# on the near plane # on the near plane
@ -207,8 +187,57 @@ def relHpr(nodePath, base, h, p, r):
CSDefault) CSDefault)
nodePath.setHpr(hpr) nodePath.setHpr(hpr)
# Set direct drawing style for an object # Quaternion interpolation
# Never light object or draw in wireframe def qSlerp(startQuat, endQuat, t):
def useDirectRenderStyle(nodePath): startQ = Quat(startQuat)
nodePath.node().setAttrib(LightAttrib.makeAllOff()) destQuat = Quat.identQuat()
nodePath.setRenderModeFilled() # Calc dot product
cosOmega = (startQ.getI() * endQuat.getI() +
startQ.getJ() * endQuat.getJ() +
startQ.getK() * endQuat.getK() +
startQ.getR() * endQuat.getR())
# If the above dot product is negative, it would be better to
# go between the negative of the initial and the final, so that
# we take the shorter path.
if ( cosOmega < 0.0 ):
cosOmega *= -1
startQ.setI(-1 * startQ.getI())
startQ.setJ(-1 * startQ.getJ())
startQ.setK(-1 * startQ.getK())
startQ.setR(-1 * startQ.getR())
if ((1.0 + cosOmega) > Q_EPSILON):
# usual case
if ((1.0 - cosOmega) > Q_EPSILON):
# usual case
omega = math.acos(cosOmega)
sinOmega = math.sin(omega)
startScale = math.sin((1.0 - t) * omega)/sinOmega
endScale = math.sin(t * omega)/sinOmega
else:
# ends very close
startScale = 1.0 - t
endScale = t
destQuat.setI(startScale * startQ.getI() +
endScale * endQuat.getI())
destQuat.setJ(startScale * startQ.getJ() +
endScale * endQuat.getJ())
destQuat.setK(startScale * startQ.getK() +
endScale * endQuat.getK())
destQuat.setR(startScale * startQ.getR() +
endScale * endQuat.getR())
else:
# ends nearly opposite
destQuat.setI(-startQ.getJ())
destQuat.setJ(startQ.getI())
destQuat.setK(-startQ.getR())
destQuat.setR(startQ.getK())
startScale = math.sin((0.5 - t) * math.pi)
endScale = math.sin(t * math.pi)
destQuat.setI(startScale * startQ.getI() +
endScale * endQuat.getI())
destQuat.setJ(startScale * startQ.getJ() +
endScale * endQuat.getJ())
destQuat.setK(startScale * startQ.getK() +
endScale * endQuat.getK())
return destQuat

View File

@ -1,4 +1,5 @@
from PandaObject import * from PandaObject import *
from DirectUtil import *
from DirectGeometry import * from DirectGeometry import *
class DirectGrid(NodePath,PandaObject): class DirectGrid(NodePath,PandaObject):

View File

@ -1,5 +1,4 @@
from PandaObject import * from PandaObject import *
from DirectGeometry import *
from string import lower from string import lower
class DirectLight(NodePath): class DirectLight(NodePath):

View File

@ -1,8 +1,8 @@
from PandaObject import * from PandaObject import *
from DirectGlobals import *
from DirectUtil import *
from DirectGeometry import * from DirectGeometry import *
MANIPULATION_MOVE_DELAY = 0.65
class DirectManipulationControl(PandaObject): class DirectManipulationControl(PandaObject):
def __init__(self): def __init__(self):
# Create the grid # Create the grid
@ -24,8 +24,8 @@ class DirectManipulationControl(PandaObject):
self.fScaling = 0 self.fScaling = 0
self.mode = None self.mode = None
self.actionEvents = [ self.actionEvents = [
['DIRECT_mouse1', self.manipulationStart], ['DIRECT-mouse1', self.manipulationStart],
['DIRECT_mouse1Up', self.manipulationStop], ['DIRECT-mouse1Up', self.manipulationStop],
['tab', self.toggleObjectHandlesMode], ['tab', self.toggleObjectHandlesMode],
['.', self.objectHandles.multiplyScalingFactorBy, 2.0], ['.', self.objectHandles.multiplyScalingFactorBy, 2.0],
['>', self.objectHandles.multiplyScalingFactorBy, 2.0], ['>', self.objectHandles.multiplyScalingFactorBy, 2.0],
@ -35,12 +35,11 @@ class DirectManipulationControl(PandaObject):
['i', self.plantSelectedNodePath], ['i', self.plantSelectedNodePath],
] ]
def manipulationStart(self): def manipulationStart(self, modifiers):
# Start out in select mode # Start out in select mode
self.mode = 'select' self.mode = 'select'
# Check for a widget hit point # Check for a widget hit point
node, hitPt, hitPtDist = direct.iRay.pickWidget() node, hitPt, hitPtDist = direct.iRay.pickWidget()
print node, hitPt, hitPtDist
# Did we hit a widget? # Did we hit a widget?
if node: if node:
# Yes! # Yes!

View File

@ -1,11 +1,10 @@
from PandaObject import * from PandaObject import *
from DirectGlobals import *
from DirectUtil import *
from DirectGeometry import * from DirectGeometry import *
from DirectSelection import * from DirectSelection import *
import __builtin__ import __builtin__
UNPICKABLE = ['x-disc-visible', 'y-disc-visible', 'z-disc-visible',
'gridBack', 'unpickable']
# MRM: To do: handle broken node paths in selected and deselected dicts # MRM: To do: handle broken node paths in selected and deselected dicts
class DirectNodePath(NodePath): class DirectNodePath(NodePath):
# A node path augmented with info, bounding box, and utility methods # A node path augmented with info, bounding box, and utility methods

View File

@ -1,4 +1,5 @@
from PandaObject import * from PandaObject import *
from DirectGlobals import *
from DirectUtil import* from DirectUtil import*
from DirectCameraControl import * from DirectCameraControl import *
from DirectManipulation import * from DirectManipulation import *
@ -18,8 +19,6 @@ import types
import string import string
import __builtin__ import __builtin__
DIRECT_FLASH_DURATION = 1.5
class DirectSession(PandaObject): class DirectSession(PandaObject):
def __init__(self): def __init__(self):
@ -156,11 +155,19 @@ class DirectSession(PandaObject):
'[', '{', ']', '}', '[', '{', ']', '}',
'shift-a', 'b', 'l', 'shift-l', 'o', 'p', 'r', 'shift-a', 'b', 'l', 'shift-l', 'o', 'p', 'r',
'shift-r', 's', 't', 'v', 'w'] 'shift-r', 's', 't', 'v', 'w']
self.mouseEvents = ['mouse1', 'shift-mouse1', 'control-mouse1', self.mouseEvents = ['mouse1', 'mouse1-up',
'alt-mouse1', 'mouse1-up', 'shift-mouse1', 'shift-mouse1-up',
'mouse2', 'shift-mouse2', 'control-mouse2', 'control-mouse1', 'control-mouse1-up',
'alt-mouse2', 'mouse2-up', 'alt-mouse1', 'alt-mouse1-up',
'mouse3', 'mouse3-up'] 'mouse2', 'mouse2-up',
'shift-mouse2', 'shift-mouse2-up',
'control-mouse2', 'control-mouse2-up',
'alt-mouse2', 'alt-mouse2-up',
'mouse3', 'mouse3-up',
'shift-mouse3', 'shift-mouse3-up',
'control-mouse3', 'control-mouse3-up',
'alt-mouse3', 'alt-mouse3-up',
]
if base.wantTk: if base.wantTk:
import TkGlobal import TkGlobal
@ -321,20 +328,21 @@ class DirectSession(PandaObject):
def inputHandler(self, input): def inputHandler(self, input):
# Deal with keyboard and mouse input # Deal with keyboard and mouse input
if ((input == 'mouse1') or (input == 'shift-mouse1') or if input == 'mouse1-up':
(input == 'control-mouse1') or (input == 'alt-mouse1')): messenger.send('DIRECT-mouse1Up')
messenger.send('DIRECT_mouse1') elif input.find('mouse1') != -1:
elif input == 'mouse1-up': modifiers = self.getModifiers(input, 'mouse1')
messenger.send('DIRECT_mouse1Up') messenger.send('DIRECT-mouse1', sentArgs = [modifiers])
elif ((input == 'mouse2') or (input == 'shift-mouse2') or
(input == 'control-mouse2') or (input == 'alt-mouse2')):
messenger.send('DIRECT_mouse2')
elif input == 'mouse2-up': elif input == 'mouse2-up':
messenger.send('DIRECT_mouse2Up') messenger.send('DIRECT-mouse2Up')
elif input == 'mouse3': elif input.find('mouse2') != -1:
messenger.send('DIRECT_mouse3') modifiers = self.getModifiers(input, 'mouse2')
messenger.send('DIRECT-mouse2', sentArgs = [modifiers])
elif input == 'mouse3-up': elif input == 'mouse3-up':
messenger.send('DIRECT_mouse3Up') messenger.send('DIRECT-mouse3Up')
elif input.find('mouse3') != -1:
modifiers = self.getModifiers(input, 'mouse3')
messenger.send('DIRECT-mouse3', sentArgs = [modifiers])
elif input == 'shift': elif input == 'shift':
self.fShift = 1 self.fShift = 1
elif input == 'shift-up': elif input == 'shift-up':
@ -396,6 +404,26 @@ class DirectSession(PandaObject):
'shift-a', 'w'): 'shift-a', 'w'):
self.cluster.cmd('messenger.send("%s")' % input,0) self.cluster.cmd('messenger.send("%s")' % input,0)
def getModifiers(self, input, base):
modifiers = DIRECT_NO_MOD
modifierString = input[: input.find(base)]
if modifierString.find('shift') != -1:
modifiers |= DIRECT_SHIFT_MOD
if modifierString.find('control') != -1:
modifiers |= DIRECT_CONTROL_MOD
if modifierString.find('alt') != -1:
modifiers |= DIRECT_ALT_MOD
return modifiers
def gotShift(self, modifiers):
return modifiers & DIRECT_SHIFT_MOD
def gotControl(self, modifiers):
return modifiers & DIRECT_CONTROL_MOD
def gotAlt(self, modifiers):
return modifiers & DIRECT_ALT_MOD
def select(self, nodePath, fMultiSelect = 0, fResetAncestry = 1): def select(self, nodePath, fMultiSelect = 0, fResetAncestry = 1):
dnp = self.selected.select(nodePath, fMultiSelect) dnp = self.selected.select(nodePath, fMultiSelect)
if dnp: if dnp:
@ -761,12 +789,12 @@ class DisplayRegionList(PandaObject):
self.displayRegionLookup[camera.getName()]=i self.displayRegionLookup[camera.getName()]=i
i = i + 1 i = i + 1
self.accept("CamChange",self.camUpdate) self.accept("CamChange",self.camUpdate)
self.accept("DIRECT_mouse1",self.mouseUpdate) self.accept("DIRECT-mouse1",self.mouseUpdate)
self.accept("DIRECT_mouse2",self.mouseUpdate) self.accept("DIRECT-mouse2",self.mouseUpdate)
self.accept("DIRECT_mouse3",self.mouseUpdate) self.accept("DIRECT-mouse3",self.mouseUpdate)
self.accept("DIRECT_mouse1Up",self.mouseUpdate) self.accept("DIRECT-mouse1Up",self.mouseUpdate)
self.accept("DIRECT_mouse2Up",self.mouseUpdate) self.accept("DIRECT-mouse2Up",self.mouseUpdate)
self.accept("DIRECT_mouse3Up",self.mouseUpdate) self.accept("DIRECT-mouse3Up",self.mouseUpdate)
#setting up array of camera nodes #setting up array of camera nodes
cameraList = [] cameraList = []
@ -813,7 +841,7 @@ class DisplayRegionList(PandaObject):
for dr in self.displayRegionList: for dr in self.displayRegionList:
dr.camUpdate() dr.camUpdate()
def mouseUpdate(self): def mouseUpdate(self, modifiers = DIRECT_NO_MOD):
for dr in self.displayRegionList: for dr in self.displayRegionList:
dr.mouseUpdate() dr.mouseUpdate()
direct.dr = self.getCurrentDr() direct.dr = self.getCurrentDr()

View File

@ -1,23 +1,42 @@
from PandaObject import * from PandaObject import *
from DirectGlobals import *
# Routines to adjust values
def ROUND_TO(value, divisor):
return round(value/float(divisor)) * divisor
def ROUND_INT(val):
return int(round(val))
def CLAMP(val, min, max):
if val < min:
return min
elif val > max:
return max
else:
return val
# Create a tk compatible color string # Create a tk compatible color string
def getTkColorString(color): def getTkColorString(color):
def toHex(intVal): """ Print out a Tk compatible version of a color string """
val = int(round(intVal)) def toHex(intVal):
if val < 16: val = int(round(intVal))
return "0" + hex(val)[2:] if val < 16:
else: return "0" + hex(val)[2:]
return hex(val)[2:] else:
r = toHex(color[0]) return hex(val)[2:]
g = toHex(color[1]) r = toHex(color[0])
b = toHex(color[2]) g = toHex(color[1])
return "#" + r + g + b b = toHex(color[2])
return "#" + r + g + b
## Background Color ## ## Background Color ##
def setBackgroundColor(r,g,b): def setBackgroundColor(r,g,b):
""" Wrapper function to set background color """
base.win.getGsg().setColorClearValue(VBase4(r, g, b, 1.0)) base.win.getGsg().setColorClearValue(VBase4(r, g, b, 1.0))
def lerpBackgroundColor(r,g,b,duration): def lerpBackgroundColor(r,g,b,duration):
""" Function to lerp background color to a new value """
def lerpColor(state): def lerpColor(state):
dt = globalClock.getDt() dt = globalClock.getDt()
state.time += dt state.time += dt
@ -38,61 +57,15 @@ def lerpBackgroundColor(r,g,b,duration):
t.sc = base.win.getGsg().getColorClearValue() t.sc = base.win.getGsg().getColorClearValue()
t.ec = VBase4(r,g,b,1) t.ec = VBase4(r,g,b,1)
Q_EPSILON = 1e-10 # Set direct drawing style for an object
# Never light object or draw in wireframe
# Quaternion interpolation def useDirectRenderStyle(nodePath):
def qSlerp(startQuat, endQuat, t): """
startQ = Quat(startQuat) Function to force a node path to use direct render style:
destQuat = Quat.identQuat() no lighting, and no wireframe
# Calc dot product """
cosOmega = (startQ.getI() * endQuat.getI() + nodePath.node().setAttrib(LightAttrib.makeAllOff())
startQ.getJ() * endQuat.getJ() + nodePath.setRenderModeFilled()
startQ.getK() * endQuat.getK() +
startQ.getR() * endQuat.getR())
# If the above dot product is negative, it would be better to
# go between the negative of the initial and the final, so that
# we take the shorter path.
if ( cosOmega < 0.0 ):
cosOmega *= -1
startQ.setI(-1 * startQ.getI())
startQ.setJ(-1 * startQ.getJ())
startQ.setK(-1 * startQ.getK())
startQ.setR(-1 * startQ.getR())
if ((1.0 + cosOmega) > Q_EPSILON):
# usual case
if ((1.0 - cosOmega) > Q_EPSILON):
# usual case
omega = math.acos(cosOmega)
sinOmega = math.sin(omega)
startScale = math.sin((1.0 - t) * omega)/sinOmega
endScale = math.sin(t * omega)/sinOmega
else:
# ends very close
startScale = 1.0 - t
endScale = t
destQuat.setI(startScale * startQ.getI() +
endScale * endQuat.getI())
destQuat.setJ(startScale * startQ.getJ() +
endScale * endQuat.getJ())
destQuat.setK(startScale * startQ.getK() +
endScale * endQuat.getK())
destQuat.setR(startScale * startQ.getR() +
endScale * endQuat.getR())
else:
# ends nearly opposite
destQuat.setI(-startQ.getJ())
destQuat.setJ(startQ.getI())
destQuat.setK(-startQ.getR())
destQuat.setR(startQ.getK())
startScale = math.sin((0.5 - t) * math.pi)
endScale = math.sin(t * math.pi)
destQuat.setI(startScale * startQ.getI() +
endScale * endQuat.getI())
destQuat.setJ(startScale * startQ.getJ() +
endScale * endQuat.getJ())
destQuat.setK(startScale * startQ.getK() +
endScale * endQuat.getK())
return destQuat
# File data util # File data util
def getFileData(filename, separator = ','): def getFileData(filename, separator = ','):

View File

@ -1,5 +1,5 @@
from DirectGuiGlobals import * from DirectGuiGlobals import *
from DirectGeometry import ROUND_TO from DirectUtil import ROUND_TO
import PandaObject import PandaObject
import Task import Task
import string import string

View File

@ -3,6 +3,7 @@ from PandaObject import *
from PieMenu import * from PieMenu import *
from DirectGuiGlobals import * from DirectGuiGlobals import *
from Tkinter import * from Tkinter import *
from DirectUtil import *
from DirectGeometry import * from DirectGeometry import *
from SceneGraphExplorer import * from SceneGraphExplorer import *
from tkMessageBox import showinfo from tkMessageBox import showinfo
@ -494,10 +495,14 @@ class LevelEditor(NodePath, PandaObject):
# Hot key actions # Hot key actions
('a', self.autoPositionGrid), ('a', self.autoPositionGrid),
('j', self.jumpToInsertionPoint), ('j', self.jumpToInsertionPoint),
('left', self.keyboardXformSelected, ['left']), ('left', self.keyboardXformSelected, ['left', 'xlate']),
('right', self.keyboardXformSelected, ['right']), ('right', self.keyboardXformSelected, ['right', 'xlate']),
('up', self.keyboardXformSelected, ['up']), ('up', self.keyboardXformSelected, ['up','xlate']),
('down', self.keyboardXformSelected, ['down']), ('down', self.keyboardXformSelected, ['down','xlate']),
('control-left', self.keyboardXformSelected, ['left', 'rotate']),
('control-right', self.keyboardXformSelected, ['right', 'rotate']),
('control-up', self.keyboardXformSelected, ['up', 'rotate']),
('control-down', self.keyboardXformSelected, ['down', 'rotate']),
('shift-s', self.placeSuitPoint), ('shift-s', self.placeSuitPoint),
('shift-c', self.placeBattleCell), ('shift-c', self.placeBattleCell),
('o', self.addToLandmarkBlock), ('o', self.addToLandmarkBlock),
@ -967,14 +972,14 @@ class LevelEditor(NodePath, PandaObject):
# Turn off player camera control # Turn off player camera control
base.disableMouse() base.disableMouse()
# Handle mouse events for pie menus # Handle mouse events for pie menus
self.accept('DIRECT_mouse3',self.levelHandleMouse3) self.accept('DIRECT-mouse3',self.levelHandleMouse3)
self.accept('DIRECT_mouse3Up',self.levelHandleMouse3Up) self.accept('DIRECT-mouse3Up',self.levelHandleMouse3Up)
def disableMouse(self): def disableMouse(self):
""" Disable Pie Menu interaction """ """ Disable Pie Menu interaction """
# Disable handling of mouse events # Disable handling of mouse events
self.ignore('DIRECT_mouse3') self.ignore('DIRECT-mouse3')
self.ignore('DIRECT_mouse3Up') self.ignore('DIRECT-mouse3Up')
# LEVEL OBJECT MANAGEMENT FUNCTIONS # LEVEL OBJECT MANAGEMENT FUNCTIONS
def findDNANode(self, nodePath): def findDNANode(self, nodePath):
@ -1571,7 +1576,7 @@ class LevelEditor(NodePath, PandaObject):
DNARemoveChildOfClass(parent, DNA_WINDOWS) DNARemoveChildOfClass(parent, DNA_WINDOWS)
# LEVEL-OBJECT MODIFICATION FUNCTIONS # LEVEL-OBJECT MODIFICATION FUNCTIONS
def levelHandleMouse3(self): def levelHandleMouse3(self, modifiers):
# Initialize dna target # Initialize dna target
self.DNATarget = None self.DNATarget = None
@ -1588,7 +1593,7 @@ class LevelEditor(NodePath, PandaObject):
# Pick a menu based upon object type # Pick a menu based upon object type
if DNAClassEqual(dnaObject, DNA_FLAT_BUILDING): if DNAClassEqual(dnaObject, DNA_FLAT_BUILDING):
# FLAT BUILDING OPERATIONS # FLAT BUILDING OPERATIONS
menuMode, wallNum = self.getFlatBuildingMode(dnaObject) menuMode, wallNum = self.getFlatBuildingMode(dnaObject, modifiers)
# Check menuMode # Check menuMode
if menuMode == None: if menuMode == None:
return return
@ -1614,11 +1619,11 @@ class LevelEditor(NodePath, PandaObject):
elif DNAClassEqual(dnaObject, DNA_PROP): elif DNAClassEqual(dnaObject, DNA_PROP):
# PROP OPERATIONS # PROP OPERATIONS
self.DNATarget = dnaObject self.DNATarget = dnaObject
if direct.fControl: if direct.gotControl(modifiers):
menuMode = 'prop_color' menuMode = 'prop_color'
elif direct.fAlt and self.panel.currentBaselineDNA: elif direct.gotAlt(modifiers) and self.panel.currentBaselineDNA:
menuMode = 'baseline_style' menuMode = 'baseline_style'
elif direct.fShift: elif direct.gotShift(modifiers):
menuMode = 'sign_texture' menuMode = 'sign_texture'
self.DNATarget = DNAGetChildOfClass(dnaObject, DNA_SIGN) self.DNATarget = DNAGetChildOfClass(dnaObject, DNA_SIGN)
self.DNATargetParent = dnaObject self.DNATargetParent = dnaObject
@ -1627,7 +1632,7 @@ class LevelEditor(NodePath, PandaObject):
elif DNAClassEqual(dnaObject, DNA_LANDMARK_BUILDING): elif DNAClassEqual(dnaObject, DNA_LANDMARK_BUILDING):
# INSERT HERE # INSERT HERE
# LANDMARK BUILDING OPERATIONS # LANDMARK BUILDING OPERATIONS
menuMode = self.getLandmarkBuildingMode(dnaObject) menuMode = self.getLandmarkBuildingMode(dnaObject, modifiers)
if string.find(menuMode, 'door') >= 0: if string.find(menuMode, 'door') >= 0:
self.DNATarget = DNAGetChildOfClass(dnaObject, DNA_DOOR) self.DNATarget = DNAGetChildOfClass(dnaObject, DNA_DOOR)
self.DNATargetParent = dnaObject self.DNATargetParent = dnaObject
@ -1677,41 +1682,36 @@ class LevelEditor(NodePath, PandaObject):
# Spawn active menu's task # Spawn active menu's task
self.activeMenu.spawnPieMenuTask() self.activeMenu.spawnPieMenuTask()
def getLandmarkBuildingMode(self, dnaObject): def getLandmarkBuildingMode(self, dnaObject, modifiers):
# Where are we hitting the building? # Where are we hitting the building?
hitPt = self.getWallIntersectionPoint(self.selectedNPRoot) hitPt = self.getWallIntersectionPoint(self.selectedNPRoot)
if hitPt[2] < 10.0: if hitPt[2] < 10.0:
# Do door operations # Do door operations
if direct.fControl: if direct.gotControl(modifiers):
menuMode = 'door_color' menuMode = 'door_color'
elif direct.fAlt: elif direct.gotAlt(modifiers):
menuMode = 'door_orientation' menuMode = 'door_orientation'
else: else:
menuMode = 'door_texture' menuMode = 'door_texture'
else: else:
# Do sign operations # Do sign operations
if direct.fControl: if direct.gotControl(modifiers):
menuMode = 'sign_color' menuMode = 'sign_color'
elif direct.fAlt and self.panel.currentBaselineDNA: elif direct.gotAlt(modifiers) and self.panel.currentBaselineDNA:
menuMode = 'baseline_style' menuMode = 'baseline_style'
elif direct.fAlt: elif direct.gotAlt(modifiers):
menuMode = 'sign_orientation' menuMode = 'sign_orientation'
else: else:
menuMode = 'sign_texture' menuMode = 'sign_texture'
return menuMode return menuMode
def getFlatBuildingMode(self, dnaObject): def getFlatBuildingMode(self, dnaObject, modifiers):
# Where are we hitting the building? # Where are we hitting the building?
hitPt = self.getWallIntersectionPoint(self.selectedNPRoot) hitPt = self.getWallIntersectionPoint(self.selectedNPRoot)
wallNum = self.computeWallNum(dnaObject, hitPt) wallNum = self.computeWallNum(dnaObject, hitPt)
if wallNum < 0: if wallNum < 0:
# Do building related operations # Do building related operations
""" if direct.gotAlt(modifiers):
if direct.fShift:
menuMode = 'building_type'
elif direct.fAlt:
"""
if direct.fAlt:
menuMode = 'building_width' menuMode = 'building_width'
else: else:
menuMode = 'building_style_all' menuMode = 'building_style_all'
@ -1729,37 +1729,37 @@ class LevelEditor(NodePath, PandaObject):
# Determine which zone you are pointing at # Determine which zone you are pointing at
if (zPt > 0.8): if (zPt > 0.8):
# Do cornice operations # Do cornice operations
if direct.fControl: if direct.gotControl(modifiers):
menuMode = 'cornice_color' menuMode = 'cornice_color'
elif direct.fAlt: elif direct.gotAlt(modifiers):
menuMode = 'cornice_orientation' menuMode = 'cornice_orientation'
else: else:
menuMode = 'cornice_texture' menuMode = 'cornice_texture'
elif ((xPt < 0.3) or (xPt > 0.7)): elif ((xPt < 0.3) or (xPt > 0.7)):
# Do wall operations # Do wall operations
if direct.fControl: if direct.gotControl(modifiers):
menuMode = 'wall_color' menuMode = 'wall_color'
elif direct.fAlt: elif direct.gotAlt(modifiers):
menuMode = 'wall_orientation' menuMode = 'wall_orientation'
elif direct.fShift: elif direct.gotShift(modifiers):
menuMode = 'wall_texture' menuMode = 'wall_texture'
else: else:
menuMode = 'wall_style' menuMode = 'wall_style'
elif (zPt < 0.4): elif (zPt < 0.4):
# Do door operations # Do door operations
if direct.fControl: if direct.gotControl(modifiers):
menuMode = 'door_color' menuMode = 'door_color'
elif direct.fAlt: elif direct.gotAlt(modifiers):
menuMode = 'door_orientation' menuMode = 'door_orientation'
else: else:
menuMode = 'door_texture' menuMode = 'door_texture'
else: else:
# Do window operations # Do window operations
if direct.fControl: if direct.gotControl(modifiers):
menuMode = 'window_color' menuMode = 'window_color'
elif direct.fAlt: elif direct.gotAlt(modifiers):
menuMode = 'window_orientation' menuMode = 'window_orientation'
elif direct.fShift: elif direct.gotShift(modifiers):
menuMode = 'window_count' menuMode = 'window_count'
else: else:
menuMode = 'window_texture' menuMode = 'window_texture'
@ -2019,7 +2019,6 @@ class LevelEditor(NodePath, PandaObject):
oldSnapAngle = direct.grid.snapAngle oldSnapAngle = direct.grid.snapAngle
direct.grid.setSnapAngle(1.0) direct.grid.setSnapAngle(1.0)
snapAngle = direct.grid.snapAngle snapAngle = direct.grid.snapAngle
print direct.fShift, snapAngle
# Compute new angle # Compute new angle
if ((arrowDirection == 'left') or (arrowDirection == 'up')): if ((arrowDirection == 'left') or (arrowDirection == 'up')):
self.setLastAngle(self.getLastAngle() + snapAngle) self.setLastAngle(self.getLastAngle() + snapAngle)
@ -2091,8 +2090,8 @@ class LevelEditor(NodePath, PandaObject):
# Use back door to set grid spacing to avoid grid update # Use back door to set grid spacing to avoid grid update
direct.grid.gridSpacing = oldGridSpacing direct.grid.gridSpacing = oldGridSpacing
def keyboardXformSelected(self, arrowDirection): def keyboardXformSelected(self, arrowDirection, mode):
if direct.fControl: if mode == 'rotate':
self.keyboardRotateSelected(arrowDirection) self.keyboardRotateSelected(arrowDirection)
else: else:
self.keyboardTranslateSelected(arrowDirection) self.keyboardTranslateSelected(arrowDirection)

View File

@ -4,9 +4,10 @@
from PandaObject import * from PandaObject import *
from Tkinter import * from Tkinter import *
from AppShell import * from AppShell import *
from DirectGlobals import *
from DirectUtil import *
from DirectGeometry import * from DirectGeometry import *
from DirectSelection import * from DirectSelection import *
from DirectUtil import *
from tkFileDialog import * from tkFileDialog import *
import os import os
import string import string

View File

@ -4,7 +4,6 @@
from PandaObject import * from PandaObject import *
from Tkinter import * from Tkinter import *
from AppShell import * from AppShell import *
from DirectGeometry import *
import Pmw import Pmw
import Dial import Dial
import Floater import Floater