DistributedCamera.py 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. from pandac.PandaModules import *
  2. from direct.fsm.FSM import FSM
  3. from direct.interval.IntervalGlobal import *
  4. from direct.distributed.DistributedObject import DistributedObject
  5. class Fixture(NodePath, FSM):
  6. def __init__(self, id, parent, pos, hpr, fov):
  7. NodePath.__init__(self, 'cam-%s' % id)
  8. FSM.__init__(self, '%s-fsm' % self.getName())
  9. self.id = id
  10. self.lens = PerspectiveLens()
  11. self.lens.setFov(base.camLens.getFov())
  12. model = loader.loadModel('models/misc/camera', okMissing = True)
  13. model.reparentTo(self)
  14. self.reparentTo(parent)
  15. self.setPos(pos)
  16. self.setHpr(hpr)
  17. self.setFov(fov)
  18. self.setLightOff(100)
  19. self.hide()
  20. self.scaleIval = None
  21. self.recordingInProgress = False
  22. self.dirty = False
  23. def __str__(self):
  24. return 'Fixture(%d, \'%s\', %s, %s, %s)' % (self.id, self.state, self.getPos(), self.getHpr(), self.getFov())
  25. def pack(self):
  26. return 'Camera(%s, %s, %s)' % (self.getPos(), self.getHpr(), self.getFov())
  27. def setId(self, id):
  28. self.id = id
  29. def setFov(self, fov):
  30. """
  31. fov should be a VBase2. Use VBase2(0) to indicate default.
  32. """
  33. if fov != VBase2(0):
  34. self.lens.setFov(fov)
  35. self.setupFrustum()
  36. def adjustFov(self, x, y):
  37. fov = self.lens.getFov()
  38. self.lens.setFov(fov[0]+x, fov[1]+y)
  39. self.dirty = True
  40. def getFov(self):
  41. return self.lens.getFov()
  42. def setupFrustum(self):
  43. oldFrustum = self.find('frustum')
  44. if oldFrustum:
  45. oldFrustum.detachNode()
  46. self.attachNewNode(GeomNode('frustum')).node().addGeom(self.lens.makeGeometry())
  47. def setRecordingInProgress(self, inProgress):
  48. self.recordingInProgress = inProgress
  49. if self.recordingInProgress and \
  50. base.config.GetInt('camera-id', -1) >= 0:
  51. self.hide()
  52. else:
  53. self.show()
  54. def show(self):
  55. if base.config.GetBool('aware-of-cameras',0) and \
  56. not self.recordingInProgress:
  57. NodePath.show(self)
  58. def getScaleIval(self):
  59. if not self.scaleIval:
  60. self.scaleIval = Sequence(LerpScaleInterval(self.getChild(0), 0.25, 2, startScale = 1, blendType = 'easeInOut'),
  61. LerpScaleInterval(self.getChild(0), 0.25, 1, startScale = 2, blendType = 'easeInOut'))
  62. return self.scaleIval
  63. def setState(self, state):
  64. self.request(state)
  65. def defaultFilter(self, request, args):
  66. if request == self.getCurrentOrNextState():
  67. return None
  68. return FSM.defaultFilter(self, request, args)
  69. def exitOff(self):
  70. self.accept('recordingInProgress', self.setRecordingInProgress)
  71. def enterOff(self):
  72. self.ignore('recordingInProgress')
  73. if self.scaleIval:
  74. self.scaleIval.finish()
  75. self.scaleIval = None
  76. self.hide()
  77. def enterStandby(self):
  78. self.show()
  79. if self.id == base.config.GetInt('camera-id', -1):
  80. self.setColorScale(3,0,0,1)
  81. self.getScaleIval().loop()
  82. else:
  83. self.setColorScale(3,3,0,1)
  84. self.getScaleIval().finish()
  85. def enterBlinking(self):
  86. self.show()
  87. self.setColorScale(0,3,0,1)
  88. self.getScaleIval().loop()
  89. def exitBlinking(self):
  90. if self.scaleIval:
  91. self.scaleIval.finish()
  92. def enterRecording(self):
  93. if base.config.GetInt('camera-id', -1) == self.id:
  94. self.demand('Using')
  95. else:
  96. self.show()
  97. self.setColorScale(3,0,0,1)
  98. self.getScaleIval().loop()
  99. def exitRecording(self):
  100. if self.scaleIval:
  101. self.scaleIval.finish()
  102. def enterUsing(self, args = []):
  103. localAvatar.b_setGameState('Camera')
  104. camera.setPosHpr(0,0,0,0,0,0)
  105. camera.reparentTo(self)
  106. self.hide()
  107. base.cam.node().setLens(self.lens)
  108. if args and args[0]:
  109. self.accept('arrow_left', self.adjustFov, [-0.5,0])
  110. self.accept('arrow_left-repeat', self.adjustFov, [-2,0])
  111. self.accept('arrow_right', self.adjustFov, [0.5,0])
  112. self.accept('arrow_right-repeat', self.adjustFov, [2,0])
  113. self.accept('arrow_down', self.adjustFov, [0,-0.5])
  114. self.accept('arrow_down-repeat', self.adjustFov, [0,-2])
  115. self.accept('arrow_up', self.adjustFov, [0,0.5])
  116. self.accept('arrow_up-repeat', self.adjustFov, [0,2])
  117. # Could be toggled on/off on a fixture by fixture basis
  118. # if added to the dc definition of the Fixture struct and
  119. # saved out to the Camera file.
  120. lodNodes = render.findAllMatches('**/+LODNode')
  121. for i in xrange(0,lodNodes.getNumPaths()):
  122. lodNodes[i].node().forceSwitch(lodNodes[i].node().getHighestSwitch())
  123. def exitUsing(self):
  124. self.ignore('arrow_left')
  125. self.ignore('arrow_left-repeat')
  126. self.ignore('arrow_right')
  127. self.ignore('arrow_right-repeat')
  128. self.ignore('arrow_down')
  129. self.ignore('arrow_down-repeat')
  130. self.ignore('arrow_up')
  131. self.ignore('arrow_up-repeat')
  132. base.cam.node().setLens(base.camLens)
  133. localAvatar.b_setGameState('LandRoam')
  134. self.show()
  135. if self.dirty:
  136. messenger.send('refresh-fixture', [self.id, self.pack()])
  137. self.dirty = False
  138. class DistributedCamera(DistributedObject):
  139. def __init__(self, cr):
  140. DistributedObject.__init__(self, cr)
  141. self.parent = None
  142. self.fixtures = {}
  143. self.cameraId = base.config.GetInt('camera-id',0)
  144. def __getitem__(self, index):
  145. return self.fixtures.get(index)
  146. def __str__(self):
  147. out = ''
  148. for fixture in self.fixtures.itervalues():
  149. out = '%s\n%s' % (out, fixture)
  150. return out[1:]
  151. def pack(self):
  152. out = ''
  153. for fixture in self.fixtures.itervalues():
  154. out = '%s\n%s' % (out, fixture.pack())
  155. return out[1:]
  156. def disable(self):
  157. self.ignore('escape')
  158. self.parent = None
  159. for fixture in self.fixtures.itervalues():
  160. fixture.cleanup()
  161. fixture.detachNode()
  162. self.fixtures = {}
  163. DistributedObject.disable(self)
  164. def getOV(self):
  165. return self.cr.doId2ownerView.get(self.getDoId())
  166. def setCamParent(self, doId):
  167. if doId != self.parent:
  168. if not doId:
  169. self.parent = render
  170. else:
  171. self.parent = self.cr.getDo(doId)
  172. for fix in self.fixtures.itervalues():
  173. fix.reparentTo(self.parent)
  174. def getCamParent(self):
  175. return self.parent
  176. def setFixtures(self, fixtures):
  177. for x in range(len(fixtures), len(self.fixtures)):
  178. fixture = self.fixtures.pop(x)
  179. fixture.cleanup()
  180. fixture.detachNode()
  181. recordingInProgress = False
  182. for x,fixture in enumerate(fixtures):
  183. pos = Point3(*(fixture[:3]))
  184. hpr = Point3(*(fixture[3:6]))
  185. fov = VBase2(*(fixture[6:8]))
  186. state = fixture[8]
  187. if x not in self.fixtures:
  188. self.fixtures[x] = Fixture(x, self.parent, Point3(0), hpr = Point3(0), fov = VBase2(0))
  189. fix = self.fixtures.get(x)
  190. fix.setId(x)
  191. fix.setPosHpr(pos,hpr)
  192. fix.setState(state)
  193. fix.setFov(fov)
  194. recordingInProgress |= state == 'Recording'
  195. messenger.send('recordingInProgress', [recordingInProgress])
  196. def testFixture(self, index):
  197. fixture = self.fixtures.get(index)
  198. if fixture:
  199. fixture.request('Using', [True])
  200. self.accept('escape', self.stopTesting, [index])
  201. def stopTesting(self, index):
  202. fixture = self.fixtures.get(index)
  203. if fixture:
  204. self.ignore('escape')
  205. fixture.request('Standby')
  206. localAvatar.b_setGameState('LandRoam')