Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion libs/python-ovrsdk
2 changes: 1 addition & 1 deletion modules/blendervr/loader/oculus_dk2.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const vec4 kappa = vec4(1.0,1.7,0.7,15.0);
uniform float screen_width;
uniform float screen_height;

const float scaleFactor = 0.6;
const float scaleFactor = 0.78;

const vec2 leftCenter = vec2(0.25, 0.5);
const vec2 rightCenter = vec2(0.75, 0.5);
Expand Down
135 changes: 135 additions & 0 deletions modules/blendervr/player/screen/hmd/oculus_dk2.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
##

import mathutils
from mathutils import Matrix, Quaternion

import bge
from . import base
from ... import exceptions
Expand All @@ -52,6 +54,25 @@ class Device(base.Device):
def __init__(self, parent, configuration):
super(Device, self).__init__(parent, configuration)
self._plugin = None
self._modelview_matrix = [Matrix.Identity(4), Matrix.Identity(4)]
self._projection_matrix = [Matrix.Identity(4), Matrix.Identity(4)]
self._near = -1
self._far = -1

self.checkLibraryPath()

try:
from oculusvr import Hmd
assert(Hmd)

except ImportError:
self.logger.info('Oculus DK2 plugin error: no \"oculusvr\" module available. Make sure you have the project submodules. Please refer to the BlenderVR documentation')
return

except Exception as err:
self.logger.error(err)
self._available = False
return

def start(self):
super(Device, self).start()
Expand Down Expand Up @@ -86,3 +107,117 @@ def start(self):

except Exception as err:
self.logger.error(err)

def _updateMatrixForBuffer(self, bufferName, camera, depth):

scale = self.BlenderVR.scale
user = self._buffers[bufferName]['user']

if bufferName == 'left':
near = camera.near * scale
far = camera.far * scale

self._updateProjectionMatrix(near, far)
# self._updateModelViewMatrix(user.getPosition() * user.getVehiclePosition(), camera.modelview_matrix)
self._updateModelViewMatrix(user.getVehiclePosition(), camera.modelview_matrix)

self._setModelViewMatrix(self._modelview_matrix[0])
self._setProjectionMatrix(self._projection_matrix[0])
else:
self._setModelViewMatrix(self._modelview_matrix[1])
self._setProjectionMatrix(self._projection_matrix[1])


def _updateModelViewMatrix(self, user_matrix, camera_matrix):
from oculusvr import Hmd
from bge import logic

global_dict = logic.globalDict
hmd = global_dict.get('hmd')

if hmd and Hmd.detect() == 1:
global_dict['frame'] += 1

frame = global_dict['frame']
fov_ports = global_dict['fovPorts']
eye_offsets = global_dict['eyeOffsets']

poses = hmd.get_eye_poses(frame, eye_offsets)
hmd.begin_frame(frame)

orientation = [None, None]
position = [None, None]

for eye in range(2):
orientation_raw = poses[eye].Orientation.toList()
position_raw = poses[eye].Position.toList()

orientation = Quaternion(orientation_raw).to_matrix().to_4x4()
position = Matrix.Translation(position_raw)

matrix = position * orientation
matrix.invert()

# self._modelview_matrix[eye] = user_matrix * matrix * camera_matrix
self._modelview_matrix[eye] = matrix * user_matrix * camera_matrix

# update user position to be used e.g. in processor files (arbitrary: take modelview matrix of eye 0)
if eye == 0:
try:
bufferName = 'left'
user = self._buffers[bufferName]['user']
user.setPosition(matrix)
except Exception as err:
self.logger.log_traceback(err)

def _convertMatrixTo4x4(self, value):
matrix = Matrix()

matrix[0] = value[0:4]
matrix[1] = value[4:8]
matrix[2] = value[8:12]
matrix[3] = value[12:16]

return matrix.transposed()


def _updateProjectionMatrix(self, near, far):

if not self._cameraClippingChanged(near, far):
return

from bge import logic
import oculusvr as ovr

global_dict = logic.globalDict

fov_ports = global_dict.get('fovPorts')

if fov_ports:
self._projection_matrix[0] = self._convertMatrixTo4x4(ovr.Hmd.get_perspective(fov_ports[0], near, far, True).toList())
self._projection_matrix[1] = self._convertMatrixTo4x4(ovr.Hmd.get_perspective(fov_ports[1], near, far, True).toList())

def _cameraClippingChanged(self, near, far):
"""
check if near of far values changed
"""
if near == self._near and far == self._far:
return False

self._near = near
self._far = far

return True

def checkLibraryPath(self):
"""if library exists append it to sys.path"""
import sys
import os
from .... import tools

libs_path = tools.getLibsPath()
oculus_path = os.path.join(libs_path, "python-ovrsdk")

if oculus_path not in sys.path:
sys.path.append(oculus_path)

126 changes: 77 additions & 49 deletions modules/blendervr/plugins/oculus_dk2/virtual_environment/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ def __init__(self, parent, configuration):
self._user = None
self._hmd = None
self._description = None
self._matrix = None
self._modelview_matrix = [None, None]
self._projection_matrix = [None, None]
self._near = -100.0
self._far = -100.0

self.checkLibraryPath()

Expand All @@ -56,7 +59,7 @@ def __init__(self, parent, configuration):
assert(Hmd)

except ImportError:
self.logger.info('Oculus DK2 plugin error: no \"oculusvr\" module available. Make sure you have the projec submodules. Please refer to the BlenderVR documentation')
self.logger.info('Oculus DK2 plugin error: no \"oculusvr\" module available. Make sure you have the project submodules. Please refer to the BlenderVR documentation')
self._available = False
return

Expand Down Expand Up @@ -84,31 +87,17 @@ def start(self):
super(OculusDK2, self).start()
from mathutils import Matrix

self.logger.debug("Start Oculus DK2 plugin")

try:
self._matrix = Matrix.Identity(4)
self._startOculus()

except Exception:
self._available = False

def run(self):
super(OculusDK2, self).run()

try:
self._updateMatrix()
info = {'matrix' : self._matrix}
self._user.run(info)

except Exception as err:
self.logger.log_traceback(err)

def _updateMatrix(self):
try:
matrix = self._getMatrix()
if matrix:
self._matrix = matrix
except Exception as err:
self.logger.log_traceback(err)

def checkMethods(self):
if not self._available:
self.logger.info('Oculus DK2 python module not available !')
Expand Down Expand Up @@ -139,6 +128,8 @@ def checkLibraryPath(self):
sys.path.append(oculus_path)

def _startOculus(self):
from time import sleep
import oculusvr as ovr
from oculusvr import (
Hmd,
cast,
Expand All @@ -152,44 +143,81 @@ def _startOculus(self):
except SystemError as err:
self.logger.error("Oculus initialization failed, check the physical connections and run again")

if Hmd.detect() == 1:
self._hmd = Hmd()
self._description = cast(self._hmd.hmd, POINTER(ovrHmdDesc)).contents
self._frame = 0
self._eyes_offset = [ ovrVector3f(), ovrVector3f() ]
self._eyes_offset[0] = 0.0, 0.0, 0.0
self._eyes_offset[1] = 0.0, 0.0, 0.0
"""
self._hmd = Hmd()
self._description = cast(self._hmd.hmd, POINTER(ovrHmdDesc)).contents
self._frame = 0
self._eyes_offset = [ ovrVector3f(), ovrVector3f() ]
self._eyes_offset[0] = 0.0, 0.0, 0.0
self._eyes_offset[1] = 0.0, 0.0, 0.0

self._hmd.configure_tracking()
self.logger.info(self._description.ProductName)
"""

try:
debug = not Hmd.detect()

if debug:
self.logger.error("Oculus not connected")

try:
self._hmd = Hmd()
except:
self._hmd = Hmd(debug=True)

desc = self._hmd.hmd.contents
self._frame = -1

sleep(0.1)
self._hmd.configure_tracking()
self.logger.info(self._description.ProductName)

else:
self.logger.error("Oculus not connected")
raise Exception

def _getMatrix(self):
from oculusvr import Hmd
from mathutils import (
Quaternion,
Matrix,
self._fovPorts = (
desc.DefaultEyeFov[0],
desc.DefaultEyeFov[1],
)

if self._hmd and Hmd.detect() == 1:
self._frame += 1
#self._eyeTextures = [ ovrGLTexture(), ovrGLTexture() ]
self._eyeOffsets = [ ovrVector3f(), ovrVector3f() ]
self._width = [-1, -1]
self._height = [-1, -1]

poses = self._hmd.get_eye_poses(self._frame, self._eyes_offset)
rc = ovr.ovrRenderAPIConfig()
header = rc.Header
header.API = ovr.ovrRenderAPI_OpenGL
header.BackBufferSize = desc.Resolution
header.Multisample = 1

# oculus may be returning the matrix for both eyes
# but we are using a single eye without offset
for i in range(8):
rc.PlatformData[i] = 0

rotation_raw = poses[0].Orientation.toList()
position_raw = poses[0].Position.toList()
self._eyeRenderDescs = self._hmd.configure_rendering(rc, self._fovPorts)

rotation = Quaternion(rotation_raw).to_matrix().to_4x4()
position = Matrix.Translation(position_raw)
for eye in range(2):
size = self._hmd.get_fov_texture_size(eye, self._fovPorts[eye])
self._width[eye], self._height[eye] = size.w, size.h
#eyeTexture = self._eyeTextures[eye]
#eyeTexture.API = ovr.ovrRenderAPI_OpenGL
#header = eyeTexture.Texture.Header
#header.TextureSize = size
#vp = header.RenderViewport
#vp.Size = size
#vp.Pos.x = 0
#vp.Pos.y = 0

matrix = position * rotation
matrix.invert()
self._eyeOffsets[eye] = self._eyeRenderDescs[eye].HmdToEyeViewOffset

return matrix
return None

# store the data globally, to access it in screen
from bge import logic
global_dict = logic.globalDict

global_dict['hmd'] = self._hmd
global_dict['frame'] = self._frame
global_dict['eyeOffsets'] = self._eyeOffsets
global_dict['fovPorts'] = self._fovPorts

except Exception as err:
self.logger.error("Error initializing Oculus", str(err))
else:
self.logger.info("Oculus properly initialized")