Showing a flash light in VR¶
VRFlashlightModule.py¶
1from PySide6 import QtCore,QtWidgets
2from vrScenegraph import *
3from vrController import *
4from vrNodePtr import *
5from vrNodeUtils import *
6from vrFileIO import *
7#test
8class Flashlight():
9 def __init__(self):
10 QtCore.QTimer.singleShot(0, self.init)
11 def init(self):
12 self.geo = None
13 self.on = False
14 self.createMenu()
15 pointer = vrDeviceService.getInteraction("Tools Menu")
16 start = pointer.getControllerAction("showMenu")
17 start.signal().triggered.connect(self.onMenuOpened)
18 self.handNode = vrDeviceService.getVRDevice("right-controller").getNode()
19 self.activeController = vrDeviceService.getVRDevice("right-controller")
20 vrHMDService.hmdStatusWillChange.connect(self.__onHMDStatusWillChange)
21 def onMenuOpened(self,action,device):
22 # place the flashlight on the other hand
23 if device.getName() == "left-controller":
24 self.handNode = vrDeviceService.getVRDevice("right-controller").getNode()
25 self.activeController = vrDeviceService.getVRDevice("right-controller")
26 else:
27 self.handNode = vrDeviceService.getVRDevice("left-controller").getNode()
28 self.activeController = vrDeviceService.getVRDevice("left-controller")
29 def switchOn(self):
30 if not self.on:
31 self.getGeo().setActive(True)
32 self.on = True
33 # move the flashlight with the hand
34 self.constraint = vrConstraintService.createParentConstraint([self.handNode],self.geo,False)
35 self.activeController.signal().moved.connect(self.updateFlashlight)
36 self.visualizationMode = self.activeController.getVisualizationMode()
37 self.adjustFlashlight(self.activeController)
38 def switchOff(self):
39 if self.on:
40 self.getGeo().setActive(False)
41 self.on = False
42 vrConstraintService.deleteConstraint(self.constraint)
43 self.activeController.signal().moved.disconnect(self.updateFlashlight)
44 def createMenu(self):
45 # png icons as base64 string
46 onIcon = "iVBORw0KGgoAAAANSUhEUgAAAFAAAABQCAMAAAC5zwKfAAAAilBMVEX9oRTreSj6twb3qw3ylxjtfibvlBv1pBHxjB/rfSjviiDvix/7vQPxkxvugiPtfiXwix/0nBXuhSL1oRLwjB7rfCf0qQ7ugyP8wQH4swn1pRDwix/ylBn0nBXwiCHtgST1pBHvih/7uwT5tAj4rgv7wAH1oRPvix77ugXuhCP0oBP1oxHwjh3uhCJVyFMlAAAAK3RSTlMAM/////4QJEKBpVHxjTq5FrBj8NjEG+exwjzY7eWF7tbo3eTcTFj8W26hmZCkDQAAAAlwSFlzAAAk6QAAJOkBUCTn+AAAA31JREFUWAntWO12ojAQDUkIVJRGrEpXrVq7220T3v/19uYDRIviYvqvOT1lmjA3dzKTmaGEDB8RxWCMKcUV51xXGPFwOGgeERXjWhvE+wAFEMEQFJMofUj1KIvvAyQkGTuTxSTLxaMc3Q1orVaMiWmRPYhI3w8IRHCkBGBaPP4HoBRH97VE45mZUko8wSty3uMUOZE1yoKqRk4eGtEuJ1ypfImwyZY9gCV9rgF/URrV8kpPatE9YTXgbNhcP8OSUulVM6oWXoy4LrxYP8CxDsOrYSOZqrnkVNUMJ0ovTk8R58g84nWGZMq4UxUp5R5QMDaqmR2fkb96PYApValTSqn2Jmeshj7CEURNBaPhk6smE7JWnk1OtWe4oVUbqZGTm+5yybm0Kg1gxNi5SzxmFN/AUHLvFpicWMUXxtwWHqb1SLb9JpMd21u3INScyYzNWxinYhJjnE59+Stz3oWXlWWYU5Z/eamZiPoBxWtsGUq6tWoJ3TXqHQIQO2bvmUqGALpYv7BtfZ+6l0X5+nrYvL1tnja79f5pv1otV8v9XHa/fcPsb1PWMFA0UNmYMrHLq/hCIPYDij8OzwListqMou8AJAAcz2ZUzTC4fn/fr3FZ4+EMcec7zeie7Xz1bFIs5JchZLu8nCn0/Zn6M0Rho6bZUBr9RlxlfXoX1zMHyOAV4xOX5uP4yuW7COUWxNggumbDtkM2h1aLHrUryyhT53hVvLyi0Lf0t2bIXMNm+ytfFfp0u9efwRAc7U0xRwjEewgSIhubDUUDGMvurW+dNT2lZVi7eXjM+C0Lb7H38setTC6/92mOkSqKfMP14+X3bl4Rk3JUj5fh17i1H0Can9b0cDEtMDLzqxh+6drb47ogEHGAVXW5JrcV+uSpDRwThYEADUOTbsAwhJMJsQxt0xuOIThak8MwRGRjhD3DQy5EtOTBTD64QFgFApxSl2FEHgiwpK55JSIYYP1dEghw2nxPBQIs6UKk03kezORPKlHxuU7DnaF8ZvgcnpNAJoPh1AKGY5jBZMbzHCRDjE86Flm5ysQ2kMnIh4dM4i6HytgANNnGtA1hTLaAps6HZGhLQECGtqbgX2XBTA5bRs0Z+qoXjKGt9MEK/bd5OVjYFP4M0ToM/g49SQFike+QbZAQkyDtIcBFgWTDAnTDDVFRbNYfoeg1qD/Czwl82wn8A1RuSwNXqFYLAAAAAElFTkSuQmCC"
47 offIcon = "iVBORw0KGgoAAAANSUhEUgAAAFAAAABQCAMAAAC5zwKfAAAAe1BMVEWwsbWwsrO1triwsbOur7Gmp6men6GdnqCcnp64ubu1t7ump6mkpKavr7GkpaenqKqmpqm7u72kpaesrK+jpKa0tbeztbeztLWgoaOfoKGoqaurrK+5ury6vL2vsLKnqKqcnZ+trrCbm6CjpKaxsrSmqKi6ur2ioqS5ubt/L2nWAAAAKXRSTlMAI//+/v/+/DFcLkOGZ5KkE6/qHNfsTLP9Ylbq3e7d2sTrM7jMYbN2V7lTpSMAAAAJcEhZcwAAJOkAACTpAVAk5/gAAAMoSURBVFgJ7Zh7c6MgEMBxEVPFJIh4tbVec73n9/+EtzxWc0mrNnAz/aM708AY+LkvdkkZu10yIOE8z4WVYnc7DnfezUBwvFggKz2R86qS9V4cyqKI0pAxbzXn7CilOmaHSJNnq1lT7msm83hg8KNSUgt2FNtNbtVbzpEC0GSDQVGmWNawrVuitAATsa0reuzGrAMuNabN3qxo2IChnV8A7mhuxD1N/VjllIb9soYPAKTLI0AWKK0Q5b9AJrucEnsxbSqAOmyVs4ZNLtQFkFWC28TuVzRkDXTXQM4vLLZLKmGPXr92UvAg7D0RNQwm7wFkeMv5IDsEFmsasgEOEzAExcBwDprmFQLXi8M9gM+cyYeYP0HpCRUmlV73IcPtPiwI9ORmsv0SyOSAXlwrX0+g3cYScp9BHTRXJHpQ6WK3BnwE4UAyjBim10ISkBKJRH9jVKN20cXRraj4dHhe2yH1GvC1XUvPpH/v0pJ3frfgEEtqxrEzX587YzptumdtjNb6pN75knk5VgdqGlhPODU2OuDzwq2zCQiAQM/DkndZbLbiGHPAEWBE6YZvw4AGa727Hbj91RtXqlah4EdVqSyIajO1cfv1MqzTk4SQ2Ipyu8lYEibBmLioYMlbybVrxeYnEw7gLMrUXeZ1m2cmEPmUNr0Qi6d5BY3FhZCkYS8iLGbsiYBosvdhEaMgY+oMGGIS4UHrjxci0tmLMtgS6TxjHtpUvL0wWJgTbEsoGGe8SMNRhacRg6oblKOVwyEBj1RJiCr3Zen+6jI6Ik4970T0Y14cSd+okYBYaE5RINocwmzvQt/pWdToga6lnKJAtDkArYZJgXhMimTApxfFpBF9KuDordd9qrQJXUkm82H4taKS+VB5k1kyIP2eShYUxcrGYGFIB8Tul2O3S2aywv6cYz9OB2yw0YuTSpY2Ei85QkiZrtoo+cP8ZDqZhgCP+F8Kk77aJNTQRvlD10Pb8lDBZHlo7yIWmOjo/bI8Jx8byPECm8iH3uSEffm3858LSoLrpi3+mcS7e57rP5HX69BI7ID34jxPpJ7DqodxSMk70/Vz+umB/+GBv9HkI1uzfxLJAAAAAElFTkSuQmCC"
48 self.tool = vrImmersiveUiService.createTool("vrFlashlightTool")
49 self.tool.setText("Flashlight")
50 self.tool.setCheckable(True)
51 self.tool.setOnOffIconData(onIcon,offIcon)
52 self.tool.signal().checked.connect(self.switchOn)
53 self.tool.signal().unchecked.connect(self.switchOff)
54 self.tool.hideAway(True)
55 def deleteMenu(self):
56 vrImmersiveUiService.deleteTool(self.tool)
57 def getGeo(self):
58 if not self.geo is None and self.geo.isValid():
59 return self.geo
60 self.createGeo()
61 return self.geo
62 def createGeo(self):
63 for node in findNodes("VR_Flashlight"):
64 node.getParent().subChild(node)
65 rootNode = getInternalRootNode()
66 self.geo = createNode("Transform3D","VR_Flashlight", rootNode, False)
67 self.trans = createNode("Transform3D","FlashlightPos",self.geo,False)
68 self.loadModel()
69 self.flashlightHandle = vrNodeService.findNode("Housing_02", False, False, self.trans)
70 self.geo.setActive(False)
71 setIsVRNode(self.trans, True)
72 setIsVRNode(self.geo, True)
73 def loadModel(self):
74 path = vrFileIOService.getVREDDataDir() + "/Internal/VR/Flashlight.osb"
75 files = [path]
76 nodes = loadOSB(files)
77 for node in nodes:
78 self.trans.addChild(node)
79 def removeGeo(self):
80 subChilds(self.geo.getParent(),[self.geo])
81 def updateFlashlight(self, device):
82 if device.getVisualizationMode() != self.visualizationMode:
83 self.adjustFlashlight(device)
84 self.visualizationMode = device.getVisualizationMode()
85 def adjustFlashlight(self, device):
86 if device.getVisualizationMode() == 1:
87 self.setHandTransform()
88 self.flashlightHandle.setVisibilityFlag(True)
89 else:
90 self.setControllerTransform()
91 self.flashlightHandle.setVisibilityFlag(False)
92
93 def setHandTransform(self):
94 setTransformNodeTranslation(self.trans,13,-5,60,False)
95 setTransformNodeRotation(self.trans,180,0,0)
96 def setControllerTransform(self):
97 setTransformNodeTranslation(self.trans,0,-50,50,False)
98 setTransformNodeRotation(self.trans,110,0,0)
99
100 def __onHMDStatusWillChange(self, active):
101 if not active:
102 self.tool.setChecked(False)
103 self.switchOff()
104
105flashlight = Flashlight()
106
107label = QtWidgets.QLabel(VREDPluginWidget)
108label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
109label.setScaledContents(True)
110label.setText("Python VR flashlight avatars tool\n" + __file__)
111VREDPluginWidget.layout().addWidget(label)