mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
*** empty log message ***
This commit is contained in:
parent
705edc62dc
commit
f7f44a3e18
@ -2,6 +2,7 @@ lib
|
|||||||
lib/py
|
lib/py
|
||||||
src/actor
|
src/actor
|
||||||
src/directtools
|
src/directtools
|
||||||
|
src/directdevices
|
||||||
src/directnotify
|
src/directnotify
|
||||||
src/distributed
|
src/distributed
|
||||||
src/ffi
|
src/ffi
|
||||||
|
193
direct/src/directdevices/DirectDeviceManager.py
Normal file
193
direct/src/directdevices/DirectDeviceManager.py
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
""" Class used to create and control vrpn devices """
|
||||||
|
from PandaObject import *
|
||||||
|
|
||||||
|
class DirectDeviceManager(VrpnClient, PandaObject):
|
||||||
|
def __init__(self, server = None):
|
||||||
|
# Determine which server to use
|
||||||
|
if server != None:
|
||||||
|
# One give as constructor argument
|
||||||
|
self.server = server
|
||||||
|
else:
|
||||||
|
# Check config file, if that fails, use default
|
||||||
|
self.server = base.config.GetString('vrpn-server', 'spacedyne')
|
||||||
|
|
||||||
|
# Create a vrpn client
|
||||||
|
VrpnClient.__init__(self, self.server)
|
||||||
|
|
||||||
|
def createButtons(self, device):
|
||||||
|
return DirectButtons(self, device)
|
||||||
|
|
||||||
|
def createAnalogs(self, device):
|
||||||
|
return DirectAnalogs(self, device)
|
||||||
|
|
||||||
|
def createDials(self, device):
|
||||||
|
return DirectDials(self, device)
|
||||||
|
|
||||||
|
def createTimecodeReader(self, device):
|
||||||
|
return DirectTimecodeReader(self, device)
|
||||||
|
|
||||||
|
class DirectButtons(ButtonNode, PandaObject):
|
||||||
|
buttonCount = 0
|
||||||
|
def __init__(self, vrpnClient, device):
|
||||||
|
# Keep track of number of buttons created
|
||||||
|
DirectButtons.buttonCount += 1
|
||||||
|
# Create a unique name for this button object
|
||||||
|
self.name = 'DirectButtons-' + `DirectButtons.buttonCount`
|
||||||
|
# Create a new button node for the given device
|
||||||
|
ButtonNode.__init__(self, vrpnClient, device)
|
||||||
|
# Attach node to data graph
|
||||||
|
self.nodePath = base.dataRoot.attachNewNode(self)
|
||||||
|
|
||||||
|
def __getitem__(self, index):
|
||||||
|
if (index < 0) | (index > self.getNumButtons()):
|
||||||
|
raise IndexError
|
||||||
|
return self.getButtonState(index)
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return self.getNumButtons()
|
||||||
|
|
||||||
|
def enable(self):
|
||||||
|
self.nodePath.reparentTo(base.dataRoot)
|
||||||
|
|
||||||
|
def disable(self):
|
||||||
|
self.nodePath.reparentTo(base.dataUnused)
|
||||||
|
|
||||||
|
def getName(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
def getNodePath(self):
|
||||||
|
return self.nodePath
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
str = self.name + ': '
|
||||||
|
for val in self:
|
||||||
|
str = str + '%d' % val + ' '
|
||||||
|
return str
|
||||||
|
|
||||||
|
class DirectAnalogs(AnalogNode, PandaObject):
|
||||||
|
analogCount = 0
|
||||||
|
def __init__(self, vrpnClient, device):
|
||||||
|
# Keep track of number of analogs created
|
||||||
|
DirectAnalogs.analogCount += 1
|
||||||
|
# Create a unique name for this analog object
|
||||||
|
self.name = 'DirectAnalogs-' + `DirectAnalogs.analogCount`
|
||||||
|
# Create a new analog node for the given device
|
||||||
|
AnalogNode.__init__(self, vrpnClient, device)
|
||||||
|
# Attach node to data graph
|
||||||
|
self.nodePath = base.dataRoot.attachNewNode(self)
|
||||||
|
|
||||||
|
def __getitem__(self, index):
|
||||||
|
if (index < 0) | index > self.getNumControls():
|
||||||
|
raise IndexError
|
||||||
|
return self.getControlState(index)
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return self.getNumControls()
|
||||||
|
|
||||||
|
def enable(self):
|
||||||
|
self.nodePath.reparentTo(base.dataRoot)
|
||||||
|
|
||||||
|
def disable(self):
|
||||||
|
self.nodePath.reparentTo(base.dataUnused)
|
||||||
|
|
||||||
|
def getName(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
def getNodePath(self):
|
||||||
|
return self.nodePath
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
str = self.name + ': '
|
||||||
|
for val in self:
|
||||||
|
str = str + '%.3f' % val + ' '
|
||||||
|
return str
|
||||||
|
|
||||||
|
class DirectDials(DialNode, PandaObject):
|
||||||
|
dialCount = 0
|
||||||
|
def __init__(self, vrpnClient, device):
|
||||||
|
# Keep track of number of dials created
|
||||||
|
DirectDials.dialCount += 1
|
||||||
|
# Create a unique name for this dial object
|
||||||
|
self.name = 'DirectDials-' + `DirectDials.dialCount`
|
||||||
|
# Create a new dial node for the given device
|
||||||
|
DialNode.__init__(self, vrpnClient, device)
|
||||||
|
# Attach node to data graph
|
||||||
|
self.nodePath = base.dataRoot.attachNewNode(self)
|
||||||
|
|
||||||
|
def __getitem__(self, index):
|
||||||
|
if (index < 0) | (index > self.getNumDials()):
|
||||||
|
raise IndexError
|
||||||
|
return self.readDial(index)
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return self.getNumDials()
|
||||||
|
|
||||||
|
def enable(self):
|
||||||
|
self.nodePath.reparentTo(base.dataRoot)
|
||||||
|
|
||||||
|
def disable(self):
|
||||||
|
self.nodePath.reparentTo(base.dataUnused)
|
||||||
|
|
||||||
|
def getName(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
def getNodePath(self):
|
||||||
|
return self.nodePath
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
str = self.name + ': '
|
||||||
|
for val in self:
|
||||||
|
str = str + '%.3f' % val + ' '
|
||||||
|
return str
|
||||||
|
|
||||||
|
class DirectTimecodeReader(AnalogNode, PandaObject):
|
||||||
|
timecodeReaderCount = 0
|
||||||
|
def __init__(self, vrpnClient, device):
|
||||||
|
# Keep track of number of timecodeReader created
|
||||||
|
DirectTimecodeReader.timecodeReaderCount += 1
|
||||||
|
# Create a unique name for this dial object
|
||||||
|
self.name = ('DirectTimecodeReader-' +
|
||||||
|
`DirectTimecodeReader.timecodeReaderCount`)
|
||||||
|
# Initialize components of timecode
|
||||||
|
self.frames = 0
|
||||||
|
self.seconds = 0
|
||||||
|
self.minutes = 0
|
||||||
|
self.hours = 0
|
||||||
|
# Create a new dial node for the given device
|
||||||
|
AnalogNode.__init__(self, vrpnClient, device)
|
||||||
|
# Attach node to data graph
|
||||||
|
self.nodePath = base.dataRoot.attachNewNode(self)
|
||||||
|
|
||||||
|
def enable(self):
|
||||||
|
self.nodePath.reparentTo(base.dataRoot)
|
||||||
|
|
||||||
|
def disable(self):
|
||||||
|
self.nodePath.reparentTo(base.dataUnused)
|
||||||
|
|
||||||
|
def getName(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
def getNodePath(self):
|
||||||
|
return self.nodePath
|
||||||
|
|
||||||
|
def getTime(self):
|
||||||
|
# Assume only one card, use channel 0
|
||||||
|
timeBits = int(self.getControlState(0))
|
||||||
|
self.frames = ((timeBits & 0xF) +
|
||||||
|
(((timeBits & 0xF0) >> 4) * 10))
|
||||||
|
self.seconds = (((timeBits & 0x0F00) >> 8) +
|
||||||
|
(((timeBits & 0xF000) >> 12) * 10))
|
||||||
|
self.minutes = ((((timeBits & 0x0F0000) >> 16) * 10) +
|
||||||
|
((timeBits & 0xF00000) >> 20))
|
||||||
|
self.hours = ((((timeBits & 0xF0000000) >> 24) * 10) +
|
||||||
|
((timeBits & 0xF0000000) >> 28))
|
||||||
|
self.totalSeconds = ((self.hours * 3600) +
|
||||||
|
(self.minutes * 60) +
|
||||||
|
self.seconds +
|
||||||
|
(self.frames / 30.0))
|
||||||
|
return (self.hours, self.minutes, self.seconds, self.frames,
|
||||||
|
self.totalSeconds)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
str = ('%s: %d:%d:%d:%d' % ((self.name,) + self.getTime()[:-1]))
|
||||||
|
return str
|
209
direct/src/directdevices/DirectJoybox.py
Normal file
209
direct/src/directdevices/DirectJoybox.py
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
""" Class used to create and control joybox device """
|
||||||
|
from PandaObject import *
|
||||||
|
from DirectDeviceManager import *
|
||||||
|
from DirectGeometry import CLAMP
|
||||||
|
import OnscreenText
|
||||||
|
|
||||||
|
JOY_MIN = -0.95
|
||||||
|
JOY_MAX = 0.95
|
||||||
|
JOY_RANGE = JOY_MAX - JOY_MIN
|
||||||
|
JOY_DEADBAND = 0.05
|
||||||
|
# BUTTONS
|
||||||
|
L_STICK = 0
|
||||||
|
L_UPPER = 1
|
||||||
|
L_LOWER = 2
|
||||||
|
R_STICK = 3
|
||||||
|
R_UPPER = 4
|
||||||
|
R_LOWER = 5
|
||||||
|
# ANALOGS
|
||||||
|
L_LEFT_RIGHT = 0
|
||||||
|
L_FWD_BACK = 1
|
||||||
|
L_TWIST = 2
|
||||||
|
L_SLIDE = 3
|
||||||
|
R_LEFT_RIGHT = 4
|
||||||
|
R_FWD_BACK = 5
|
||||||
|
R_TWIST = 6
|
||||||
|
R_SLIDE = 7
|
||||||
|
|
||||||
|
class DirectJoybox(PandaObject):
|
||||||
|
joyboxCount = 0
|
||||||
|
xyzScale = 1.0
|
||||||
|
hprScale = 1.0
|
||||||
|
def __init__(self, nodePath = direct.camera):
|
||||||
|
# See if device manager has been initialized
|
||||||
|
if direct.deviceManager == None:
|
||||||
|
direct.deviceManager = DirectDeviceManager()
|
||||||
|
# Set name
|
||||||
|
self.name = 'Joybox-' + `DirectJoybox.joyboxCount`
|
||||||
|
# Get buttons and analogs
|
||||||
|
self.device = base.config.GetString('joybox-device', 'CerealBox')
|
||||||
|
self.analogs = direct.deviceManager.createAnalogs(self.device)
|
||||||
|
self.buttons = direct.deviceManager.createButtons(self.device)
|
||||||
|
self.aList = [0,0,0,0,0,0,0,0]
|
||||||
|
self.bList = [0,0,0,0,0,0,0,0]
|
||||||
|
self.mapping = [0,1,2,4,5,6]
|
||||||
|
self.modifier = [1,1,1,1,1,1]
|
||||||
|
# Button registry
|
||||||
|
self.addButtonEvents()
|
||||||
|
# Initialize time
|
||||||
|
self.lastTime = globalClock.getTime()
|
||||||
|
# Record node path
|
||||||
|
self.nodePath = nodePath
|
||||||
|
# Text object to display current mode
|
||||||
|
self.readout = OnscreenText.OnscreenText( '', -0.9, -0.95 )
|
||||||
|
# Pick initial mode
|
||||||
|
self.updateFunc = self.joeFly
|
||||||
|
# Spawn update task
|
||||||
|
self.enable()
|
||||||
|
|
||||||
|
def enable(self):
|
||||||
|
taskMgr.spawnMethodNamed(self.updateTask, self.name + '-updateTask')
|
||||||
|
|
||||||
|
def disable(self):
|
||||||
|
taskMgr.removeTasksNamed(self.name + '-updateTask')
|
||||||
|
|
||||||
|
def addButtonEvents(self):
|
||||||
|
self.breg = ButtonRegistry.ptr()
|
||||||
|
# MRM: Hard coded!
|
||||||
|
for i in range(8):
|
||||||
|
self.buttons.setButtonMap(
|
||||||
|
i, self.breg.getButton(self.getEventName(i)))
|
||||||
|
self.eventThrower = self.buttons.getNodePath().attachNewNode(
|
||||||
|
ButtonThrower())
|
||||||
|
|
||||||
|
def setNodePath(self, nodePath):
|
||||||
|
self.nodePath = nodePath
|
||||||
|
def getNodePath(self):
|
||||||
|
return self.nodePath
|
||||||
|
def getEventName(self, index):
|
||||||
|
return self.name + '-button-' + `index`
|
||||||
|
|
||||||
|
def updateTask(self, state):
|
||||||
|
self.updateVals()
|
||||||
|
self.updateFunc()
|
||||||
|
return Task.cont
|
||||||
|
|
||||||
|
def updateVals(self):
|
||||||
|
# Update delta time
|
||||||
|
cTime = globalClock.getTime()
|
||||||
|
self.deltaTime = cTime - self.lastTime
|
||||||
|
self.lastTime = cTime
|
||||||
|
# Update analogs
|
||||||
|
for i in range(len(self.analogs)):
|
||||||
|
try:
|
||||||
|
self.aList[i] = self.normalizeAnalogChannel(i)
|
||||||
|
except IndexError:
|
||||||
|
# That channel may not have been updated yet
|
||||||
|
pass
|
||||||
|
# Update buttons
|
||||||
|
for i in range(len(self.buttons)):
|
||||||
|
try:
|
||||||
|
self.bList[i] = self.buttons[i]
|
||||||
|
except IndexError:
|
||||||
|
# That channel may not have been updated yet
|
||||||
|
pass
|
||||||
|
|
||||||
|
def normalizeAnalog(self, val, min = -1, max = -1):
|
||||||
|
val = CLAMP(val, JOY_MIN, JOY_MAX)
|
||||||
|
if abs(val) < JOY_DEADBAND:
|
||||||
|
val = 0.0
|
||||||
|
return ((max - min) * ((val - JOY_MIN) / JOY_RANGE)) + min
|
||||||
|
|
||||||
|
def normalizeAnalogChannel(self, chan, min = -1, max = 1):
|
||||||
|
if (chan == 2) | (chan == 6):
|
||||||
|
return self.normalizeAnalog(self.analogs[chan] * 3.0, min, max)
|
||||||
|
else:
|
||||||
|
return self.normalizeAnalog(self.analogs[chan], min, max)
|
||||||
|
|
||||||
|
def showMode(self, modeText):
|
||||||
|
def hideText(state, s = self):
|
||||||
|
s.readout.setText('')
|
||||||
|
return Task.done
|
||||||
|
taskMgr.removeTasksNamed(self.name + '-showMode')
|
||||||
|
# Update display
|
||||||
|
self.readout.setText(modeText)
|
||||||
|
t = taskMgr.doMethodLater(3.0, hideText, self.name + '-showMode')
|
||||||
|
t.uponDeath = hideText
|
||||||
|
|
||||||
|
def setMode(self, func, name):
|
||||||
|
self.disable()
|
||||||
|
self.updateFunc = func
|
||||||
|
self.showMode(name)
|
||||||
|
self.enable()
|
||||||
|
|
||||||
|
def joeMode(self):
|
||||||
|
self.setMode(self.joeFly, 'Joe Mode')
|
||||||
|
|
||||||
|
def joeFly(self):
|
||||||
|
hprScale = (self.normalizeAnalogChannel(3, 0.1, 200) *
|
||||||
|
DirectJoybox.hprScale)
|
||||||
|
posScale = (self.normalizeAnalogChannel(7, 0.1, 100) *
|
||||||
|
DirectJoybox.xyzScale)
|
||||||
|
# XYZ
|
||||||
|
x = self.aList[4]
|
||||||
|
y = self.aList[5]
|
||||||
|
if self.bList[L_STICK]:
|
||||||
|
z = 0.0
|
||||||
|
else:
|
||||||
|
z = self.aList[L_FWD_BACK]
|
||||||
|
pos = Vec3(x,y,z) * (posScale * self.deltaTime)
|
||||||
|
# HPR
|
||||||
|
h = -1 * self.aList[R_TWIST]
|
||||||
|
if self.bList[L_STICK]:
|
||||||
|
p = -1 * self.aList[L_FWD_BACK]
|
||||||
|
else:
|
||||||
|
p = 0.0
|
||||||
|
r = 0.0
|
||||||
|
hpr = Vec3(h,p,r) * (hprScale * self.deltaTime)
|
||||||
|
# Move node path
|
||||||
|
self.nodePath.setPosHpr(self.nodePath, pos, hpr)
|
||||||
|
|
||||||
|
def joyboxFly(self):
|
||||||
|
hprScale = (self.normalizeAnalogChannel(3, 0.1, 200) *
|
||||||
|
DirectJoybox.hprScale)
|
||||||
|
posScale = (self.normalizeAnalogChannel(7, 0.1, 100) *
|
||||||
|
DirectJoybox.xyzScale)
|
||||||
|
x = self.analogs[self.mapping[0]] * self.modifier[0]
|
||||||
|
y = self.analogs[self.mapping[1]] * self.modifier[1]
|
||||||
|
z = self.analogs[self.mapping[2]] * self.modifier[2]
|
||||||
|
pos = Vec3(x,y,z) * (posScale * self.deltaTime)
|
||||||
|
|
||||||
|
h = self.analogs[self.mapping[3]] * self.modifier[3]
|
||||||
|
p = self.analogs[self.mapping[4]] * self.modifier[4]
|
||||||
|
r = self.analogs[self.mapping[5]] * self.modifier[5]
|
||||||
|
hpr = Vec3(h,p,r) * (hprScale * self.deltaTime)
|
||||||
|
# Move node path
|
||||||
|
self.nodePath.setPosHpr(self.nodePath, pos, hpr)
|
||||||
|
|
||||||
|
def demoMode(self):
|
||||||
|
self.mapping = [4,5,1,6,0,0]
|
||||||
|
self.modifier = [1,1,1,-1,0,0]
|
||||||
|
self.setMode(self.joyboxFly, 'Demo Mode')
|
||||||
|
|
||||||
|
def driveMode(self):
|
||||||
|
self.mapping = [0,5,1,4,1,0]
|
||||||
|
self.modifier = [1,1,1,-1,0,0]
|
||||||
|
self.setMode(self.joyboxFly, 'Drive Mode')
|
||||||
|
|
||||||
|
def hprXyzMode(self):
|
||||||
|
self.mapping = [4,5,6,2,1,0]
|
||||||
|
self.modifier = [1,1,-1,-1,-1,1]
|
||||||
|
self.setMode(self.joyboxFly, 'HprXyz Mode')
|
||||||
|
|
||||||
|
def lookaroundMode(self):
|
||||||
|
self.mapping = [0,0,0,4,5,0]
|
||||||
|
self.modifier = [0,0,0,-1,-1,0]
|
||||||
|
self.setMode(self.joyboxFly, 'Lookaround Mode')
|
||||||
|
|
||||||
|
def walkthruMode(self):
|
||||||
|
self.mapping = [4,5,2,6,1,0]
|
||||||
|
self.modifier = [1,1,-1,-1,-1, 1]
|
||||||
|
self.setMode(self.joyboxFly, 'Walkthru Mode')
|
||||||
|
|
||||||
|
def jbTest():
|
||||||
|
jb = DirectJoybox()
|
||||||
|
jb.joeMode()
|
||||||
|
jb.accept(jb.getEventName(R_UPPER), jb.joeMode)
|
||||||
|
direct.cameraControl.accept(jb.getEventName(L_UPPER),
|
||||||
|
direct.cameraControl.orbitUprightCam)
|
||||||
|
return jb
|
@ -6,6 +6,7 @@ from DirectGrid import *
|
|||||||
from DirectGeometry import *
|
from DirectGeometry import *
|
||||||
from DirectLights import *
|
from DirectLights import *
|
||||||
from DirectSessionPanel import *
|
from DirectSessionPanel import *
|
||||||
|
from DirectDeviceManager import *
|
||||||
import Placer
|
import Placer
|
||||||
import OnscreenText
|
import OnscreenText
|
||||||
import types
|
import types
|
||||||
@ -50,6 +51,12 @@ class DirectSession(PandaObject):
|
|||||||
# self.readout.textNode.setCardColor(0.5, 0.5, 0.5, 0.5)
|
# self.readout.textNode.setCardColor(0.5, 0.5, 0.5, 0.5)
|
||||||
self.readout.reparentTo( hidden )
|
self.readout.reparentTo( hidden )
|
||||||
|
|
||||||
|
# Create a vrpn client vrpn-server or default
|
||||||
|
if base.config.GetBool('want-vrpn', 0):
|
||||||
|
self.deviceManager = DirectDeviceManager()
|
||||||
|
else:
|
||||||
|
self.deviceManager = None
|
||||||
|
|
||||||
self.fControl = 0
|
self.fControl = 0
|
||||||
self.fAlt = 0
|
self.fAlt = 0
|
||||||
self.fShift = 0
|
self.fShift = 0
|
||||||
|
@ -71,6 +71,8 @@ class ForceGroup(DirectObject):
|
|||||||
# Utility functions
|
# Utility functions
|
||||||
def __getitem__(self, index):
|
def __getitem__(self, index):
|
||||||
"""__getItem__(self, index)"""
|
"""__getItem__(self, index)"""
|
||||||
|
if (index < 0) | (index > self.node.getNumForces()):
|
||||||
|
raise IndexError
|
||||||
return self.node.getForce(index)
|
return self.node.getForce(index)
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
|
@ -49,8 +49,7 @@ class ParticleEffect(NodePath):
|
|||||||
self.forceGroupDict[forceGroup.getName()] = forceGroup
|
self.forceGroupDict[forceGroup.getName()] = forceGroup
|
||||||
|
|
||||||
# Associate the force group with all particles
|
# Associate the force group with all particles
|
||||||
flist = forceGroup.asList()
|
for f in forceGroup:
|
||||||
for f in flist:
|
|
||||||
self.addForce(f)
|
self.addForce(f)
|
||||||
|
|
||||||
def addForce(self, force):
|
def addForce(self, force):
|
||||||
@ -65,8 +64,7 @@ class ParticleEffect(NodePath):
|
|||||||
self.forceGroupDict[forceGroup.getName()] = None
|
self.forceGroupDict[forceGroup.getName()] = None
|
||||||
|
|
||||||
# Remove forces from all particles
|
# Remove forces from all particles
|
||||||
flist = forceGroup.asList()
|
for f in forceGroup:
|
||||||
for f in flist:
|
|
||||||
self.removeForce(f)
|
self.removeForce(f)
|
||||||
|
|
||||||
def removeForce(self, force):
|
def removeForce(self, force):
|
||||||
@ -81,8 +79,7 @@ class ParticleEffect(NodePath):
|
|||||||
|
|
||||||
# Associate all forces in all force groups with the particles
|
# Associate all forces in all force groups with the particles
|
||||||
for fg in self.forceGroupDict.values():
|
for fg in self.forceGroupDict.values():
|
||||||
flist = fg.asList()
|
for f in fg:
|
||||||
for f in flist:
|
|
||||||
particles.addForce(f)
|
particles.addForce(f)
|
||||||
|
|
||||||
def removeParticles(self, particles):
|
def removeParticles(self, particles):
|
||||||
@ -92,8 +89,7 @@ class ParticleEffect(NodePath):
|
|||||||
|
|
||||||
# Remove all forces from the particles
|
# Remove all forces from the particles
|
||||||
for fg in self.forceGroupDict.values():
|
for fg in self.forceGroupDict.values():
|
||||||
flist = fg.asList()
|
for f in fg:
|
||||||
for f in flist:
|
|
||||||
particles.removeForce(f)
|
particles.removeForce(f)
|
||||||
|
|
||||||
def getParticlesList(self):
|
def getParticlesList(self):
|
||||||
|
@ -1627,7 +1627,7 @@ class ParticlePanel(AppShell):
|
|||||||
forceGroup.getName())
|
forceGroup.getName())
|
||||||
self.forcePage = self.forceGroupNotebook.add(self.forcePageName)
|
self.forcePage = self.forceGroupNotebook.add(self.forcePageName)
|
||||||
self.forcePagesDict[self.forcePageName] = self.forcePage
|
self.forcePagesDict[self.forcePageName] = self.forcePage
|
||||||
for force in forceGroup.asList():
|
for force in forceGroup:
|
||||||
self.addForceWidget(forceGroup, force)
|
self.addForceWidget(forceGroup, force)
|
||||||
|
|
||||||
def addForceWidget(self, forceGroup, force):
|
def addForceWidget(self, forceGroup, force):
|
||||||
@ -1635,7 +1635,7 @@ class ParticlePanel(AppShell):
|
|||||||
pageName = self.forcePageName
|
pageName = self.forcePageName
|
||||||
# How many forces of the same type in the force group object
|
# How many forces of the same type in the force group object
|
||||||
count = 0
|
count = 0
|
||||||
for f in forceGroup.asList():
|
for f in forceGroup:
|
||||||
if f.getClassType().eq(force.getClassType()):
|
if f.getClassType().eq(force.getClassType()):
|
||||||
count += 1
|
count += 1
|
||||||
if isinstance(force, LinearVectorForce):
|
if isinstance(force, LinearVectorForce):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user