Newer
Older
# ############################################################
# Data structs
# ############################################################
def HMD(display_backend, context, error_callback):
"""
return the head mounted display device class
(defined in another file)
:param context: BPY context
:type context: bpy.types.Context
:param error_callback: error handler
:type error_callback: func(message, is_fatal)
from .debug import Debug
displays = {
'OCULUS':Oculus,
'DEBUG':Debug,
}
if display_backend not in displays:
assert False, "Display Backend \"{0}\" not implemented".format(display_backend)
return displays[display_backend](context, error_callback)
# ############################################################
# Base class inherited by HMD devices
# ############################################################
class HMD_Base:
"_head_transformation",
"_eye_pose",
"_offscreen_object",
"_framebuffer_object",
"_color_object",
"_modelview_matrix",
def __init__(self, name, context, error_callback):
self._width = [0, 0]
self._height = [0, 0]
self._projection_matrix = [Matrix.Identity(4), Matrix.Identity(4)]
self._modelview_matrix = [Matrix.Identity(4), Matrix.Identity(4)]
self._framebuffer_object = [0, 0]
self._color_object = [0, 0]
self._offscreen_object = [None, None]
self._eye_orientation_raw = [[i for i in range(4)], [i for i in range(4)]]
self._eye_position_raw = [[i for i in range(3)], [i for i in range(3)]]
self._scale = self._calculateScale(context)
return self._width[self._current_eye]
@width.setter
def width(self, value):
self._width[self._current_eye] = value
return self._height[self._current_eye]
@height.setter
def height(self, value):
self._height[self._current_eye] = value
def offscreen_object(self):
return self._offscreen_object[self._current_eye]
def framebuffer_object(self):
return self._framebuffer_object[self._current_eye]
def color_object(self):
return self._color_object[self._current_eye]
return self._projection_matrix[self._current_eye]
return self._modelview_matrix[self._current_eye]
def setEye(self, eye):
self._current_eye = int(bool(eye))
def init(self):
"""
Initialize device
:return: return True if the device was properly initialized
:rtype: bool
"""
self._offscreen_object[i] = gpu.offscreen_object_create(self._width[i], self._height[i])
self._framebuffer_object[i] = self._offscreen_object[i].framebuffer_object
self._color_object[i] = self._offscreen_object[i].color_object
except Exception as E:
print(E)
self._offscreen_object[0] = None
self._offscreen_object[1] = None
return False
else:
return True
The frame is ready to be sent to the device
assert False, "frameReady() not implemented for the \"{0}\" device".format(self._name)
def quit(self):
"""
Garbage collection
"""
if self._offscreen_object[i]:
gpu.offscreen_object_free(self._offscreen_object[i])
except Exception as E:
print(E)
def error(self, function, exception, is_fatal):
"""
Handle error messages
"""
if VERBOSE:
print("ADD-ON :: {0}() : {1}".format(function, exception))
import sys
traceback = sys.exc_info()
if traceback and traceback[0]:
print(traceback[0])
if hasattr(exception, "strerror"):
message = exception.strerror
else:
message = str(exception)
# send the error the interface
self._error_callback(message, is_fatal)
def updateMatrices(self, context):
"""
Update OpenGL drawing matrices
"""
camera_matrix = self._getCamera(context).matrix_world.copy()
camera_matrix_inv = camera_matrix.inverted()
for i in range(2):
rotation_raw = self._eye_orientation_raw[i]
position_raw = self._eye_position_raw[i]
# take scene units into consideration
position_raw = self._scaleMovement(position_raw)
rotation = Quaternion(rotation_raw).to_matrix().to_4x4()
position = Matrix.Translation(position_raw)
transformation = position * rotation
self._modelview_matrix[i] = transformation * camera_matrix_inv
def _getCamera(self, context):
return context.scene.camera
def _updateCameraClipping(self, context):
camera_ob = self._getCamera(context)
camera = camera_ob.data
self._near = camera.clip_start
self._far = camera.clip_end
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
def _calculateScale(self, context):
"""
if BU != 1 meter, scale the transformations
"""
scene = context.scene
unit_settings = scene.unit_settings
system = unit_settings.system
if system == 'NONE':
return None
elif system == 'METRIC':
return 1.0 / unit_settings.scale_length
elif system == 'IMPERIAL':
return 0.3048 / unit_settings.scale_length
else:
assert('Unit system not supported ({0})'.format(system))
def _scaleMovement(self, position):
"""
if BU != 1 meter, scale the transformations
"""
if self._scale is None:
return position
return [position[0] * self._scale,
position[1] * self._scale,
position[2] * self._scale]