-
Notifications
You must be signed in to change notification settings - Fork 41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TypeError when passing HmdMatrix34_t to setOverlayTransformTrackedDeviceRelative #88
Comments
I think @matEhickey got overlays working at one point in issue #44. @matEhickey do you have any suggestions? |
I would love to see a working example of |
Hi, sorry for the delay, I just retrieve some code related to this usage, but it's old code, maybe there were breaking changes since.. import os
import time
import math
import openvr
import vrutils
dirname = os.getcwd()
overlaysPath = []
for i in range(1,4):
path = os.path.join(dirname, "imgTimer/"+str(4-i)+'.png')
print(path)
overlaysPath.append(openvr.c_char_p(path.encode('utf-8')))
def switch_generator(ov):
i = 0
while(True):
print("switch : "+str(i))
overlay.setOverlayFromFile(ov,overlaysPath[i])
i = i+1 if(i < len(overlaysPath)-1) else 0
yield
if(__name__=="__main__"):
try:
openvr.init(openvr.VRApplication_Overlay)
except openvr.OpenVRError as e:
print("Error, HMD probably not connected")
print(str(e))
quit()
overlay=openvr.VROverlay()
overlayKey = openvr.c_char_p("overlayKey".encode('utf-8'))
overlayTitle = openvr.c_char_p("overlayTitle".encode('utf-8'))
res, ov = overlay.createOverlay(overlayKey, overlayTitle)
switcher = switch_generator(ov)
overlay.showOverlay(ov)
poses_t = openvr.TrackedDevicePose_t * openvr.k_unMaxTrackedDeviceCount
poses = poses_t()
l, r = None, None
while(r is None):
openvr.VRCompositor().waitGetPoses(poses, len(poses), None, 0)
l,r = vrutils.get_controller_ids()
print("Right-controller : "+str(r))
matrixTransformation = openvr.HmdMatrix34_t()
# identity
matrixTransformation[0][0] = 0.1
matrixTransformation[1][1] = 0.1
matrixTransformation[2][2] = 0.1
## Position
# matrixTransformation[0][3] = 0.1
matrixTransformation[1][3] = 0.02
matrixTransformation[2][3] = 0.05
rotmat = vrutils.rotationXMatrix(math.radians(-90))
matrixTransformation = vrutils.numpyToMatrix34(vrutils.appliRotationMatrixToAxis(matrixTransformation, rotmat))
res = openvr.VROverlay().setOverlayTransformTrackedDeviceRelative(ov, r, matrixTransformation)
# res = openvr.VROverlay().setOverlayTransformAbsolute(ov,openvr.TrackingUniverseStanding, matrixTransformation)
# res = openvr.VROverlay().setOverlayTransformTrackedDeviceRelative(ov, 3, matrixTransformation)
while(True):
next(switcher)
time.sleep(3)
# input("Enter a key to return") The example above was kind of a boilerplate (that only "switch" between differents images) on the right controller. Integrated code may help you too, but will be harder to decode (It was a app that added a clock on your wrist, so you can know how many time remain in your game session), there were many overlays, and one is rotating according on time: import sys
import time
import os
import openvr
from math import sin, cos, radians
from colour import Color
class PersonalOverlay:
"""
An overlay abstraction which aim to be eassily manipulable
Ex:
overlay_Clock = PersonalOverlay('Clock', 'OVC', textureClockPath)
overlay_Clock.setTransform(0, 0.01, 0.1, -85, 0, -10, 0.07, 0.07, 0.07)
overlay_Clock.changeTexture(pathToFile)
overlay_Clock.show()
overlay_Clock.hide()
"""
def __init__(self, key="0", title="", texturePath=""):
self.overlayKey = openvr.c_char_p(key.encode('utf8'))
self.overlayTitle = openvr.c_char_p(title.encode('utf8'))
self.texturePath = openvr.c_char_p(texturePath.encode('utf8'))
self.transform = openvr.HmdMatrix34_t()
self.transform[0][0] = 1
self.transform[1][1] = 1
self.transform[2][2] = 1
vroverlay = openvr.VROverlay()
res, self.ov = vroverlay.createOverlay(self.overlayKey, self.overlayTitle)
vroverlay.setOverlayFromFile(self.ov, self.texturePath)
def setTransform(self, x=0, y=0, z=0, a=0, b=0, c=0, scaleX=1, scaleY=1, scaleZ=1):
vroverlay = openvr.VROverlay()
_, orig, _ = vroverlay.getOverlayTransformAbsolute(self.ov)
self.transform = getTransformMatrix(x, y, z, a, b, c, scaleX, scaleY, scaleZ)
vroverlay.setOverlayTransformAbsolute(self.ov, orig, self.transform)
def getTransform(self):
return self.transform
def changeTexture(self, texturePath):
self.texturePath = openvr.c_char_p(texturePath.encode('utf8'))
openvr.VROverlay().setOverlayFromFile(self.ov, self.texturePath)
def hide(self):
openvr.VROverlay().hideOverlay(self.ov)
def show(self):
openvr.VROverlay().showOverlay(self.ov)
class PersonalClock :
debug = False
def __init__(self, startTime, eventEndTimer=None):
self.currentTime = startTime
self.eventEndTimer = eventEndTimer
#State 0 (> 3min); State 1 (< 1min); State 2 (< 2min); State 3 (< 3min)
self.currentState = 0
self.initGradient()
self.initOverlays()
def initGradient(self):
"""
Set the color gradient
"""
self.gradient = list(Color("#aa0000").range_to(Color("#aa0000"), 30))
self.gradient = self.gradient + list(Color("#aa0000").range_to(Color("#ff0000"), 30))
self.gradient = self.gradient + list(Color("#ff0000").range_to(Color("#ffaa00"), 45))
self.gradient = self.gradient + list(Color("#ffaa00").range_to(Color("#ffff00"), 15))
self.gradient = self.gradient + list(Color("#ffff00").range_to(Color("#00ff00"), 30))
self.gradient = self.gradient + list(Color("#00ff00").range_to(Color("#00aa00"), 30))
def initOverlays(self):
"""
Create the overlays with corresponding textures
"""
# Textures loading
dir_name = os.path.join(os.path.join(os.getcwd(),"timer_overlay"),"imgs")
textureHandPath = os.path.join(dir_name, 'hand.png')
textureClockPath = os.path.join(dir_name, 'clock.png')
self.textureTxt01Path = os.path.join(dir_name, 'txtminInf1.png')
self.textureTxt02Path = os.path.join(dir_name, 'txtminInf2.png')
self.textureTxt03Path = os.path.join(dir_name, 'txtminInf3.png')
#Create overlays and set their transform
self.overlay_Hand = PersonalOverlay('Hand', 'OVH', textureHandPath)
self.overlay_Clock = PersonalOverlay('Clock', 'OVC', textureClockPath)
self.overlay_Clock.setTransform(0, 0.01, 0.1, -85, 0, -10, 0.07, 0.07, 0.07)
self.overlay_TxtMin = PersonalOverlay('TxtMin', 'OVTM', self.textureTxt03Path)
self.overlay_TxtMin.setTransform(0, 0.009, 0.145, -85, 0, -10, 0.07, 0.07, 0.07)
def setRemainingTime (self, remainingTime):
"""
Set the remaining time in second
"""
if(PersonalClock.debug): print("Clock timer : update remaining time")
self.currentTime = remainingTime
if(self.currentTime > 0):
self.show()
def updateTimer(self, controllerIndice):
"""
Update the display of the timer
"""
if(PersonalClock.debug): print("updatetimer: ",self.currentTime)
if (self.currentTime > 0.0) :
self.show()
#Change the texture for the text
if (self.currentState != 1 and 0.0 < self.currentTime and self.currentTime < 60.0) :
self.currentState = 1
self.overlay_TxtMin.changeTexture(self.textureTxt01Path)
if(PersonalClock.debug): print("Clock current state : 1 (< 1min)")
elif (self.currentState != 2 and 60.0 < self.currentTime and self.currentTime < 120.0):
self.currentState = 2
self.overlay_TxtMin.changeTexture(self.textureTxt02Path)
if(PersonalClock.debug):print("Clock current state : 2 (< 2min)")
elif (self.currentState != 3 and 120.0 < self.currentTime and self.currentTime < 180.0):
self.currentState = 3
self.overlay_TxtMin.changeTexture(self.textureTxt03Path)
if(PersonalClock.debug): print("Clock current state : 3 (< 3min)")
elif (self.currentState != 0 and 180.0 < self.currentTime):
self.currentState = 0
self.hide()
if(PersonalClock.debug): print("Clock current state : 0 (> 3min)")
if (not self.currentState == 0) :
#Rotate the hand of the clock
self.overlay_Hand.setTransform(0, 0.011, 0.1, -85, -self.currentTime * 6.0, -10, 0.07, 0.07, 0.07)
#Change the color of the color
red = self.gradient[int(self.currentTime)].red
green = self.gradient[int(self.currentTime)].green
blue = self.gradient[int(self.currentTime)].blue
vroverlay = openvr.VROverlay()
vroverlay.setOverlayColor(self.overlay_Clock.ov, red, green, blue)
#Update transform of the overlays
vroverlay.setOverlayTransformTrackedDeviceRelative(self.overlay_Clock.ov, openvr.c_ulong(controllerIndice), self.overlay_Clock.getTransform())
vroverlay.setOverlayTransformTrackedDeviceRelative(self.overlay_Hand.ov, openvr.c_ulong(controllerIndice), self.overlay_Hand.getTransform())
vroverlay.setOverlayTransformTrackedDeviceRelative(self.overlay_TxtMin.ov, openvr.c_ulong(controllerIndice), self.overlay_TxtMin.getTransform())
else :
if(PersonalClock.debug): print("Clock timer : ENDED")
self.hide()
self.isOver = True
if(self.eventEndTimer):
self.eventEndTimer()
def hide(self):
self.overlay_Hand.hide()
self.overlay_Clock.hide()
self.overlay_TxtMin.hide()
def show(self):
self.overlay_Hand.show()
self.overlay_Clock.show()
self.overlay_TxtMin.show()
def getTransformMatrix(x=0, y=0, z=0, a=0, b=0, c=0, scaleX=1, scaleY=1, scaleZ=1):
result = openvr.HmdMatrix34_t()
#Translation
result[0][3] = x
result[1][3] = y
result[2][3] = z
#Rotations....
a = radians(a)
b = radians(b)
c = radians(c)
result[0][0] = cos(c) * cos(b)
result[0][1] = cos(c) * sin(b) * sin(a) - sin(c) * cos(a)
result[0][2] = cos(c) * sin(b) * cos(a) + sin(c) * sin(a)
result[1][0] = sin(c) * cos(b)
result[1][1] = sin(c) * sin(b) * sin(a) + cos(c) * cos(a)
result[1][2] = sin(c) * sin(b) * cos(a) - cos(c) * sin(a)
result[2][0] = - sin(b)
result[2][1] = cos(b) * sin(a)
result[2][2] = cos(b) * cos(a)
#Scale
result[0][0] = result[0][0] * scaleX
result[0][1] = result[0][1] * scaleY
result[0][2] = result[0][2] * scaleZ
result[1][0] = result[1][0] * scaleX
result[1][1] = result[1][1] * scaleY
result[1][2] = result[1][2] * scaleZ
result[2][0] = result[2][0] * scaleX
result[2][1] = result[2][1] * scaleY
result[2][2] = result[2][2] * scaleZ
return result
def getControllerIDs():
left, right = None, None
vrsystem = openvr.VRSystem()
while(right is None or left is None):
poses_t = openvr.TrackedDevicePose_t * openvr.k_unMaxTrackedDeviceCount
poses = poses_t()
openvr.VRCompositor().waitGetPoses(poses, len(poses), None, 0)
for i in range(openvr.k_unMaxTrackedDeviceCount):
device_class = vrsystem.getTrackedDeviceClass(i)
if device_class == openvr.TrackedDeviceClass_Controller:
role = vrsystem.getControllerRoleForTrackedDeviceIndex(i)
if role == openvr.TrackedControllerRole_RightHand:
right = i
if role == openvr.TrackedControllerRole_LeftHand:
left = i
return left, right
if(__name__=="__main__"):
try:
openvr.init(openvr.VRApplication_Overlay)
except openvr.OpenVRError as e:
print("Error, HMD probably not connected")
print(str(e))
quit()
# Get the right controller ID
left, right = getControllerIDs()
print("Right-controller ID : "+str(right))
####-------------------------------------------------------------
myClock = PersonalClock(3.25 * 60.0, eventEndTimer=lambda : print("ENDTIMER"))
current = 200
while(current > 0):
time.sleep(0.02)
current -= 1
myClock.setRemainingTime(current)
myClock.updateTimer(right) Sorry for some of the bad code (I promise it's very old haha), and I can't tweak it now or I could break it since I can't test it anymore. Hope this help ! |
TLDR: matrixTransformation = openvr.HmdMatrix34_t()
rotmat = vrutils.rotationXMatrix(math.radians(-90))
matrixTransformation = vrutils.numpyToMatrix34(vrutils.appliRotationMatrixToAxis(matrixTransformation, rotmat))
openvr.VROverlay().setOverlayTransformTrackedDeviceRelative(ov, r, matrixTransformation) |
Oups, didn't saw my vrutils dependencies.. here it is: # vrutils
import openvr
import math
import time
import numpy as np
import transformations
def get_controller_ids(vrsys=None):
# return the ids of the controllers by checking the type of each tracked devices
if vrsys is None:
vrsys = openvr.VRSystem()
else:
vrsys = vrsys
left, right = None, None
for i in range(openvr.k_unMaxTrackedDeviceCount):
device_class = vrsys.getTrackedDeviceClass(i)
if device_class == openvr.TrackedDeviceClass_Controller:
role = vrsys.getControllerRoleForTrackedDeviceIndex(i)
if role == openvr.TrackedControllerRole_RightHand:
right = i
if role == openvr.TrackedControllerRole_LeftHand:
left = i
return left, right
def from_controller_state_to_dict(pControllerState):
# docs: https://github.com/ValveSoftware/openvr/wiki/IVRSystem::GetControllerState
d = {}
# d['ulButtonPressed'] = pControllerState.ulButtonPressed
# d['ulButtonTouched'] = pControllerState.ulButtonTouched -> to use with bitmask
d['unPacketNum'] = pControllerState.unPacketNum
d['trigger'] = pControllerState.rAxis[1].x
d['trackpad_x'] = pControllerState.rAxis[0].x
d['trackpad_y'] = pControllerState.rAxis[0].y
d['menu_button'] = bool(pControllerState.ulButtonPressed >> 1 & 1)
d['trackpad_pressed'] = bool(pControllerState.ulButtonPressed >> 32 & 1)
d['trackpad_touched'] = bool(pControllerState.ulButtonTouched >> 32 & 1)
d['grip_button'] = bool(pControllerState.ulButtonPressed >> 2 & 1)
# System button can't be read, if you press it
# the controllers stop reporting
return d
def showInputs():
import pprint
vrsystem = openvr.VRSystem()
left_id, right_id = get_controller_ids(vrsystem)
print("Left controller ID: " + str(left_id))
print("Right controller ID: " + str(right_id))
print("===========================")
try:
while True:
time.sleep(0.2)
if(left_id):
result, pControllerState = vrsystem.getControllerState(left_id)
pprint.pprint(from_controller_state_to_dict(pControllerState))
if(right_id):
result, pControllerState = vrsystem.getControllerState(right_id)
pprint.pprint(from_controller_state_to_dict(pControllerState))
except KeyboardInterrupt:
print("Control+C pressed, shutting down...")
def identityMatrix():
m = openvr.HmdMatrix34_t()
m[0][0] = m[1][1] = m[2][2] = 1
return(m)
def getPosition(matrix):
x = matrix[0][3]
y = matrix[1][3]
z = matrix[2][3]
return(x,y,z)
def getQuaternion(matrix):
w = math.sqrt(max(0, 1 + matrix[0][0] + matrix[1][1]+ matrix[2][2])) / 2;
x = math.sqrt(max(0, 1 + matrix[0][0] - matrix[1][1] - matrix[2][2])) / 2;
y = math.sqrt(max(0, 1 - matrix[0][0] + matrix[1][1] - matrix[2][2])) / 2;
z = math.sqrt(max(0, 1 - matrix[0][0] - matrix[1][1] + matrix[2][2])) / 2;
x = x if(matrix[2][1] - matrix[1][2] > 0) else -x
y = y if(matrix[0][2] - matrix[2][0] > 0) else -y
z = z if(matrix[1][0] - matrix[0][1] > 0) else -z
return(w,x,y,z)
def rotationXMatrix(angle):
xaxis = [1, 0, 0]
return(transformations.rotation_matrix(angle, xaxis))
def rotationYMatrix(angle):
yaxis = [0, 1, 0]
return(transformations.rotation_matrix(angle, yaxis))
def rotationZMatrix(angle):
zaxis = [0, 0, 1]
return(transformations.rotation_matrix(angle, zaxis))
def translationMatrix(x,y,z):
return(transformations.translation_matrix((x,y,z)))
def appliRotationMatrixToAxis(hmdMatrix, rotationMatrix):
# rotate an transform on himself (dont change his position)
h = matrix34ToNumpy(hmdMatrix)
r = rotationMatrix
return(h.dot(r))
def npArray(obj):
return(np.array(obj))
def appliRotationMatrixToAxisOrigin(hmdMatrix, rotationMatrix):
# rotate the transform origin base on point (0.0.0)
# consider the transform has a vector, so it modify the position of his origin, but not the orientation
mat = matrix34ToNumpy(hmdMatrix) # only the position (so we consider a vector)
h = npArray(list(map(lambda x:x[3], mat)))
h = np.append(h,[0]) #add last attribute to have a 1*4 multiply by a 4*4
r = rotationMatrix
res = h.dot(r)
# set back the rotation to the matrix
for i in range(3):
mat[i][3] = res[i]
return(mat)
def matrix34ToNumpy(mat):
n = npArray(mat.m)
return(n)
def numpyToMatrix34(nparray):
hmd = openvr.HmdMatrix34_t()
for i in range(3):
for j in range(4):
hmd[i][j] = nparray[i][j]
return(hmd) transformations lib is the well known transformations.py |
I'm trying to bind an overlay to a user's hand. For this I'm using the following code:
When trying this though, I'm getting the following error:
TypeError: byref() argument must be a ctypes instance, not 'CArgObject'
I'm not exactly sure what other type might be expected there.
The text was updated successfully, but these errors were encountered: