class ManipulationManager(avango.script.Script): ### input fields sf_key_1 = avango.SFBool() sf_key_2 = avango.SFBool() sf_key_3 = avango.SFBool() sf_key_4 = avango.SFBool() sf_key_5 = avango.SFBool() sf_key_6 = avango.SFBool() sf_key_7 = avango.SFBool() sf_key_8 = avango.SFBool() sf_hand_mat = avango.gua.SFMatrix4() sf_dragging_trigger = avango.SFBool() # constructor def __init__(self): self.super(ManipulationManager).__init__() def my_constructor(self, PARENT_NODE = None, SCENE_ROOT = None, TARGET_LIST = [], ): ### external references ### self.SCENE_ROOT = SCENE_ROOT self.TARGET_LIST = TARGET_LIST ### variables ### self.dragged_objects_list = [] self.lf_hand_mat = avango.gua.make_identity_mat() # last frame hand matrix ## init hand geometry _loader = avango.gua.nodes.TriMeshLoader() # init trimesh loader to load external meshes self.hand_geometry = _loader.create_geometry_from_file("hand_geometry", "data/objects/hand.obj", avango.gua.LoaderFlags.DEFAULTS) self.hand_geometry.Transform.value = \ avango.gua.make_rot_mat(45.0,1,0,0) * \ avango.gua.make_rot_mat(180.0,0,1,0) * \ avango.gua.make_scale_mat(0.06) self.hand_geometry.Material.value.set_uniform("Color", avango.gua.Vec4(1.0, 0.86, 0.54, 1.0)) self.hand_geometry.Material.value.set_uniform("Emissivity", 0.9) self.hand_geometry.Material.value.set_uniform("Metalness", 0.1) self.hand_transform = avango.gua.nodes.TransformNode(Name = "hand_transform") self.hand_transform.Children.value = [self.hand_geometry] PARENT_NODE.Children.value.append(self.hand_transform) self.hand_transform.Transform.connect_from(self.sf_hand_mat) ### init sub-classes ### ## init inputs self.mouseInput = MouseInput() self.mouseInput.my_constructor("gua-device-mouse") if SPACEMOUSE_TYPE == "Spacemouse": self.spacemouseInput = SpacemouseInput() self.spacemouseInput.my_constructor("gua-device-spacemouse") elif SPACEMOUSE_TYPE == "Blue Spacemouse": self.spacemouseInput = NewSpacemouseInput() self.spacemouseInput.my_constructor("gua-device-spacemouse") ## init manipulation techniques self.IPCManipulation = IsotonicPositionControlManipulation() self.IPCManipulation.my_constructor(self.mouseInput.mf_dof, self.mouseInput.mf_buttons) self.EPCManipulation = ElasticPositionControlManipulation() self.EPCManipulation.my_constructor(self.spacemouseInput.mf_dof, self.spacemouseInput.mf_buttons) self.IRCManipulation = IsotonicRateControlManipulation() self.IRCManipulation.my_constructor(self.mouseInput.mf_dof, self.mouseInput.mf_buttons) self.ERCManipulation = ElasticRateControlManipulation() self.ERCManipulation.my_constructor(self.spacemouseInput.mf_dof, self.spacemouseInput.mf_buttons) self.IACManipulation = IsotonicAccelerationControlManipulation() self.IACManipulation.my_constructor(self.mouseInput.mf_dof, self.mouseInput.mf_buttons) self.EACManipulation = ElasticAccelerationControlManipulation() self.EACManipulation.my_constructor(self.spacemouseInput.mf_dof, self.spacemouseInput.mf_buttons) self.NIIPCManipulation = NonIsomorphicIsotonicPositionControlManipulation() self.NIIPCManipulation.my_constructor(self.mouseInput.mf_dof, self.mouseInput.mf_buttons) self.NIERCManipulation = NonIsomorphicElasticRateControlManipulation() self.NIERCManipulation.my_constructor(self.spacemouseInput.mf_dof, self.spacemouseInput.mf_buttons) ## init keyboard sensor for system control self.keyboard_sensor = avango.daemon.nodes.DeviceSensor(DeviceService = avango.daemon.DeviceService()) self.keyboard_sensor.Station.value = "gua-device-keyboard0" self.sf_key_1.connect_from(self.keyboard_sensor.Button16) # key 1 self.sf_key_2.connect_from(self.keyboard_sensor.Button17) # key 2 self.sf_key_3.connect_from(self.keyboard_sensor.Button18) # key 3 self.sf_key_4.connect_from(self.keyboard_sensor.Button19) # key 4 self.sf_key_5.connect_from(self.keyboard_sensor.Button20) # key 5 self.sf_key_6.connect_from(self.keyboard_sensor.Button21) # key 6 self.sf_key_7.connect_from(self.keyboard_sensor.Button22) # key 7 self.sf_key_8.connect_from(self.keyboard_sensor.Button23) # key 8 ### set initial states ### self.set_manipulation_technique(1) # switch to isotonic position control ### functions ### def set_manipulation_technique(self, INT): self.manipulation_technique = INT # disable prior manipulation technique self.IPCManipulation.enable_manipulation(False) self.EPCManipulation.enable_manipulation(False) self.IRCManipulation.enable_manipulation(False) self.ERCManipulation.enable_manipulation(False) self.IACManipulation.enable_manipulation(False) self.EACManipulation.enable_manipulation(False) self.NIIPCManipulation.enable_manipulation(False) self.NIERCManipulation.enable_manipulation(False) # remove existing field connections self.sf_hand_mat.disconnect() self.sf_dragging_trigger.disconnect() if self.manipulation_technique == 1: # isotonic position control self.IPCManipulation.enable_manipulation(True) # init field connections self.sf_hand_mat.connect_from(self.IPCManipulation.sf_mat) self.sf_dragging_trigger.connect_from(self.IPCManipulation.sf_action_trigger) elif self.manipulation_technique == 2: # elastic position control self.EPCManipulation.enable_manipulation(True) # init field connections self.sf_hand_mat.connect_from(self.EPCManipulation.sf_mat) self.sf_dragging_trigger.connect_from(self.EPCManipulation.sf_action_trigger) elif self.manipulation_technique == 3: # isotonic rate control self.IRCManipulation.enable_manipulation(True) # init field connections self.sf_hand_mat.connect_from(self.IRCManipulation.sf_mat) self.sf_dragging_trigger.connect_from(self.IRCManipulation.sf_action_trigger) elif self.manipulation_technique == 4: # elastic rate control self.ERCManipulation.enable_manipulation(True) # init field connections self.sf_hand_mat.connect_from(self.ERCManipulation.sf_mat) self.sf_dragging_trigger.connect_from(self.ERCManipulation.sf_action_trigger) elif self.manipulation_technique == 5: # isotonic acceleration control self.IACManipulation.enable_manipulation(True) # init field connections self.sf_hand_mat.connect_from(self.IACManipulation.sf_mat) self.sf_dragging_trigger.connect_from(self.IACManipulation.sf_action_trigger) elif self.manipulation_technique == 6: # elastic acceleration control self.EACManipulation.enable_manipulation(True) # init field connections self.sf_hand_mat.connect_from(self.EACManipulation.sf_mat) self.sf_dragging_trigger.connect_from(self.EACManipulation.sf_action_trigger) elif self.manipulation_technique == 7: self.NIIPCManipulation.enable_manipulation(True) # init field connections self.sf_hand_mat.connect_from(self.NIIPCManipulation.sf_mat) self.sf_dragging_trigger.connect_from(self.NIIPCManipulation.sf_action_trigger) elif self.manipulation_technique == 8: self.NIERCManipulation.enable_manipulation(True) # init field connections self.sf_hand_mat.connect_from(self.NIERCManipulation.sf_mat) self.sf_dragging_trigger.connect_from(self.NIERCManipulation.sf_action_trigger) def start_dragging(self): _hand_mat = self.hand_transform.WorldTransform.value for _node in self.TARGET_LIST: if self.is_highlight_material(_node.CurrentColor.value) == True: # a monkey node in close proximity _node.CurrentColor.value = avango.gua.Vec4(1.0, 0.0, 0.0, 1.0) _node.Material.value.set_uniform("Color", _node.CurrentColor.value) # switch to dragging material self.dragged_objects_list.append(_node) # add node for dragging ## dragging without snapping # clac tool-hand offset _dragging_offset_mat = avango.gua.make_inverse_mat(_hand_mat) * _node.Transform.value # object transformation in hand coordinate system _node.DraggingOffsetMatrix.value = _dragging_offset_mat # here you can store node dependent dragging transformations def update_dragging_candidates(self): _hand_pos = self.hand_transform.WorldTransform.value.get_translate() for _node in self.TARGET_LIST: _pos = _node.Transform.value.get_translate() # a monkey position _dist = (_hand_pos - _pos).length() # hand-object distance _color = _node.CurrentColor.value ## toggle object highlight if _dist < 0.025 and self.is_default_material(_color) == True: _node.CurrentColor.value = avango.gua.Vec4(0.0, 1.0, 0.0, 1.0) _node.Material.value.set_uniform("Color", _node.CurrentColor.value) # switch to highlight material elif _dist > 0.03 and self.is_highlight_material(_color) == True: _node.CurrentColor.value = avango.gua.Vec4(1.0, 1.0, 1.0, 1.0) _node.Material.value.set_uniform("Color", _node.CurrentColor.value) # switch to default material def object_dragging(self): # apply hand movement to (all) dragged objects for _node in self.dragged_objects_list: _node.Transform.value = self.hand_transform.WorldTransform.value * _node.DraggingOffsetMatrix.value # apply tool-hand offset to absolute hand transformation def stop_dragging(self): ## handle all dragged objects for _node in self.dragged_objects_list: _node.CurrentColor.value = avango.gua.Vec4(0.0, 1.0, 0.0, 1.0) _node.Material.value.set_uniform("Color", _node.CurrentColor.value) # switch to highlight material self.dragged_objects_list = [] # clear list def is_default_material(self, VEC4): return VEC4.x == 1.0 and VEC4.y == 1.0 and VEC4.z == 1.0 and VEC4.w == 1.0 def is_highlight_material(self, VEC4): return VEC4.x == 0.0 and VEC4.y == 1.0 and VEC4.z == 0.0 and VEC4.w == 1.0 def is_dragging_material(self, VEC4): return VEC4.x == 1.0 and VEC4.y == 0.0 and VEC4.z == 0.0 and VEC4.w == 1.0 ### callback functions ### @field_has_changed(sf_key_1) def sf_key_1_changed(self): if self.sf_key_1.value == True: # key is pressed self.set_manipulation_technique(1) # switch to isotonic position control @field_has_changed(sf_key_2) def sf_key_2_changed(self): if self.sf_key_2.value == True: # key is pressed self.set_manipulation_technique(2) # switch to elastic position control @field_has_changed(sf_key_3) def sf_key_3_changed(self): if self.sf_key_3.value == True: # key is pressed self.set_manipulation_technique(3) # switch to isotonic rate control @field_has_changed(sf_key_4) def sf_key_4_changed(self): if self.sf_key_4.value == True: # key is pressed self.set_manipulation_technique(4) # switch to elastic rate control @field_has_changed(sf_key_5) def sf_key_5_changed(self): if self.sf_key_5.value == True: # key is pressed self.set_manipulation_technique(5) # switch to isotonic acceleration control @field_has_changed(sf_key_6) def sf_key_6_changed(self): if self.sf_key_6.value == True: # key is pressed self.set_manipulation_technique(6) # switch to elastic acceleration control @field_has_changed(sf_key_7) def sf_key_7_changed(self): print("field_has_changed") if self.sf_key_7.value == True: # key is pressed self.set_manipulation_technique(7) # switch to elastic acceleration control @field_has_changed(sf_key_8) def sf_key_8_changed(self): if self.sf_key_8.value == True: # key is pressed self.set_manipulation_technique(8) # switch to elastic acceleration control @field_has_changed(sf_dragging_trigger) def sf_dragging_trigger_changed(self): if self.sf_dragging_trigger.value == True: self.start_dragging() else: self.stop_dragging() def evaluate(self): # evaluated every frame if any input field has changed (incl. dependency evaluation) self.update_dragging_candidates() self.object_dragging() # possibly drag object with hand input ## print covered distance and hand velocity as debug output _distance = (self.sf_hand_mat.value.get_translate() - self.lf_hand_mat.get_translate()).length() _velocity = _distance * 60.0 # application loop runs with 60Hz self.lf_hand_mat = self.sf_hand_mat.value
def my_constructor(self, PARENT_NODE = None, SCENE_ROOT = None, TARGET_LIST = [], ): ### external references ### self.SCENE_ROOT = SCENE_ROOT self.TARGET_LIST = TARGET_LIST ### variables ### self.dragged_objects_list = [] self.lf_hand_mat = avango.gua.make_identity_mat() # last frame hand matrix ## init hand geometry _loader = avango.gua.nodes.TriMeshLoader() # init trimesh loader to load external meshes self.hand_geometry = _loader.create_geometry_from_file("hand_geometry", "data/objects/hand.obj", avango.gua.LoaderFlags.DEFAULTS) self.hand_geometry.Transform.value = \ avango.gua.make_rot_mat(45.0,1,0,0) * \ avango.gua.make_rot_mat(180.0,0,1,0) * \ avango.gua.make_scale_mat(0.06) self.hand_geometry.Material.value.set_uniform("Color", avango.gua.Vec4(1.0, 0.86, 0.54, 1.0)) self.hand_geometry.Material.value.set_uniform("Emissivity", 0.9) self.hand_geometry.Material.value.set_uniform("Metalness", 0.1) self.hand_transform = avango.gua.nodes.TransformNode(Name = "hand_transform") self.hand_transform.Children.value = [self.hand_geometry] PARENT_NODE.Children.value.append(self.hand_transform) self.hand_transform.Transform.connect_from(self.sf_hand_mat) ### init sub-classes ### ## init inputs self.mouseInput = MouseInput() self.mouseInput.my_constructor("gua-device-mouse") if SPACEMOUSE_TYPE == "Spacemouse": self.spacemouseInput = SpacemouseInput() self.spacemouseInput.my_constructor("gua-device-spacemouse") elif SPACEMOUSE_TYPE == "Blue Spacemouse": self.spacemouseInput = NewSpacemouseInput() self.spacemouseInput.my_constructor("gua-device-spacemouse") ## init manipulation techniques self.IPCManipulation = IsotonicPositionControlManipulation() self.IPCManipulation.my_constructor(self.mouseInput.mf_dof, self.mouseInput.mf_buttons) self.EPCManipulation = ElasticPositionControlManipulation() self.EPCManipulation.my_constructor(self.spacemouseInput.mf_dof, self.spacemouseInput.mf_buttons) self.IRCManipulation = IsotonicRateControlManipulation() self.IRCManipulation.my_constructor(self.mouseInput.mf_dof, self.mouseInput.mf_buttons) self.ERCManipulation = ElasticRateControlManipulation() self.ERCManipulation.my_constructor(self.spacemouseInput.mf_dof, self.spacemouseInput.mf_buttons) self.IACManipulation = IsotonicAccelerationControlManipulation() self.IACManipulation.my_constructor(self.mouseInput.mf_dof, self.mouseInput.mf_buttons) self.EACManipulation = ElasticAccelerationControlManipulation() self.EACManipulation.my_constructor(self.spacemouseInput.mf_dof, self.spacemouseInput.mf_buttons) self.NIIPCManipulation = NonIsomorphicIsotonicPositionControlManipulation() self.NIIPCManipulation.my_constructor(self.mouseInput.mf_dof, self.mouseInput.mf_buttons) self.NIERCManipulation = NonIsomorphicElasticRateControlManipulation() self.NIERCManipulation.my_constructor(self.spacemouseInput.mf_dof, self.spacemouseInput.mf_buttons) ## init keyboard sensor for system control self.keyboard_sensor = avango.daemon.nodes.DeviceSensor(DeviceService = avango.daemon.DeviceService()) self.keyboard_sensor.Station.value = "gua-device-keyboard0" self.sf_key_1.connect_from(self.keyboard_sensor.Button16) # key 1 self.sf_key_2.connect_from(self.keyboard_sensor.Button17) # key 2 self.sf_key_3.connect_from(self.keyboard_sensor.Button18) # key 3 self.sf_key_4.connect_from(self.keyboard_sensor.Button19) # key 4 self.sf_key_5.connect_from(self.keyboard_sensor.Button20) # key 5 self.sf_key_6.connect_from(self.keyboard_sensor.Button21) # key 6 self.sf_key_7.connect_from(self.keyboard_sensor.Button22) # key 7 self.sf_key_8.connect_from(self.keyboard_sensor.Button23) # key 8 ### set initial states ### self.set_manipulation_technique(1) # switch to isotonic position control
def start(): ## create scenegraph scenegraph = avango.gua.nodes.SceneGraph(Name = "scenegraph") #physics = avango.gua.nodes.Physics() ## init scene scene = Scene(PARENT_NODE = scenegraph.Root.value) #scene.Physics.value = physics ## init navigation technique deviceInput = NewSpacemouseInput() deviceInput.my_constructor("gua-device-spacemouse") steeringNavigation = SteeringNavigation() steeringNavigation.my_constructor(deviceInput.mf_dof, deviceInput.mf_buttons, 0.15, 1.0) # connect navigation with spacemouse input steeringNavigation.set_start_matrix(avango.gua.make_trans_mat(-2.1, 0.96, 0.705)) ## init viewing setup ## init viewing and interaction setups hostname = open('/etc/hostname', 'r').readline() hostname = hostname.strip(" \n") print("wokstation:", hostname) if hostname == "medusa": # Samsung 3D-TV workstation _tracking_transmitter_offset = avango.gua.make_trans_mat(-2.1, 0.96, 0.705) * avango.gua.make_rot_mat(90.0, 0, 1, 0) * avango.gua.make_rot_mat(90.0, -1, 0, 0) # transformation into tracking coordinate system viewingSetup = MultiUserViewingSetup( SCENEGRAPH = scenegraph, WINDOW_RESOLUTION = avango.gua.Vec2ui(1400, 1050), SCREEN_DIMENSIONS = avango.gua.Vec2(1.135, 0.85), SCREEN_MATRIX = avango.gua.make_trans_mat(-2.1, 0.96, 0.705) * avango.gua.make_rot_mat(90.0, 0, 1, 0) * avango.gua.make_rot_mat(90.0, -1, 0, 0), # TRACKING_TRANSMITTER_OFFSET = _tracking_transmitter_offset, LEFT_POSITION = avango.gua.Vec2ui(0, 0), LEFT_RESOLUTION = avango.gua.Vec2ui(1400, 1050), RIGHT_POSITION = avango.gua.Vec2ui(1400, 0), RIGHT_RESOLUTION = avango.gua.Vec2ui(1400, 1050), DISPLAY_STRING_LIST = [[":0.0"], [":0.1"], [":0.2"]], # 3 user slots (left and right eye on same GPU) WARP_MATRIX_RED_RIGHT = "/opt/dlp-warpmatrices/dlp_6_warp_P1.warp", WARP_MATRIX_GREEN_RIGHT = "/opt/dlp-warpmatrices/dlp_6_warp_P2.warp", WARP_MATRIX_BLUE_RIGHT = "/opt/dlp-warpmatrices/dlp_6_warp_P3.warp", WARP_MATRIX_RED_LEFT = "/opt/dlp-warpmatrices/dlp_6_warp_P1.warp", WARP_MATRIX_GREEN_LEFT = "/opt/dlp-warpmatrices/dlp_6_warp_P2.warp", WARP_MATRIX_BLUE_LEFT = "/opt/dlp-warpmatrices/dlp_6_warp_P3.warp", ) viewingSetup.init_user(HEADTRACKING_SENSOR_STATION = "tracking-dlp-glasses-1") viewingSetup.init_user(HEADTRACKING_SENSOR_STATION = "tracking-dlp-glasses-2") viewingSetup.init_user(HEADTRACKING_SENSOR_STATION = "tracking-dlp-glasses-3") # manipulationManager = ManipulationManager() # manipulationManager.my_constructor( # SCENEGRAPH = scenegraph, # NAVIGATION_NODE = viewingSetup.navigation_node, # POINTER_TRACKING_STATION = "tracking-pst-pointer-1", # TRACKING_TRANSMITTER_OFFSET = _tracking_transmitter_offset, # POINTER_DEVICE_STATION = "device-pointer-1", # HEAD_NODE = viewingSetup.head_node, # ) else: print("No Viewing Setup available for this workstation") quit() # viewingSetup.connect_navigation_matrix(steeringNavigation.sf_nav_mat) # steeringNavigation.set_rotation_center_offset(viewingSetup.get_head_position()) print_graph(scenegraph.Root.value) # leap = LeapSensor() # leap.my_constructor(SCENE = scene, SCENEGRAPH = scenegraph, TRACKING_TRANSMITTER_OFFSET = _tracking_transmitter_offset) ## start application/render loop viewingSetup.run(locals(), globals())
def my_constructor(self, SCENEGRAPH = None, NAVIGATION_NODE = None, POINTER_TRACKING_STATION = "", TRACKING_TRANSMITTER_OFFSET = avango.gua.make_identity_mat(), POINTER_DEVICE_STATION = "", ): ### external references ### self.SCENEGRAPH = SCENEGRAPH self.NAVIGATION_NODE = NAVIGATION_NODE ### parameters ### self.ray_length = 15.0 # in meter self.ray_thickness = 0.015 # in meter self.intersection_point_size = 0.02 # in meter ### variables ### self.active_navigation_technique = None ## picking stuff self.pick_result = None self.white_list = [] self.black_list = ["invisible"] self.pick_options = avango.gua.PickingOptions.PICK_ONLY_FIRST_OBJECT \ | avango.gua.PickingOptions.GET_POSITIONS \ | avango.gua.PickingOptions.GET_NORMALS \ | avango.gua.PickingOptions.GET_WORLD_POSITIONS \ | avango.gua.PickingOptions.GET_WORLD_NORMALS ### resources ### ## init sensors self.keyboard_sensor = avango.daemon.nodes.DeviceSensor(DeviceService = avango.daemon.DeviceService()) self.keyboard_sensor.Station.value = "gua-device-keyboard0" self.sf_key_1.connect_from(self.keyboard_sensor.Button16) # key 1 self.sf_key_2.connect_from(self.keyboard_sensor.Button17) # key 2 self.sf_key_3.connect_from(self.keyboard_sensor.Button18) # key 3 self.pointer_tracking_sensor = avango.daemon.nodes.DeviceSensor(DeviceService = avango.daemon.DeviceService()) self.pointer_tracking_sensor.Station.value = POINTER_TRACKING_STATION self.pointer_tracking_sensor.TransmitterOffset.value = TRACKING_TRANSMITTER_OFFSET self.pointer_device_sensor = avango.daemon.nodes.DeviceSensor(DeviceService = avango.daemon.DeviceService()) self.pointer_device_sensor.Station.value = POINTER_DEVICE_STATION self.spacemouseInput = NewSpacemouseInput() self.spacemouseInput.my_constructor("gua-device-spacemouse") ## init nodes self.pointer_node = avango.gua.nodes.TransformNode(Name = "pointer_node") self.pointer_node.Transform.connect_from(self.pointer_tracking_sensor.Matrix) NAVIGATION_NODE.Children.value.append(self.pointer_node) _loader = avango.gua.nodes.TriMeshLoader() self.ray_geometry = _loader.create_geometry_from_file("ray_geometry", "data/objects/cylinder.obj", avango.gua.LoaderFlags.DEFAULTS) self.ray_geometry.Material.value.set_uniform("Color", avango.gua.Vec4(1.0,0.0,0.0,1.0)) self.ray_geometry.Tags.value = ["invisible"] self.pointer_node.Children.value.append(self.ray_geometry) self.intersection_geometry = _loader.create_geometry_from_file("intersection_geometry", "data/objects/sphere.obj", avango.gua.LoaderFlags.DEFAULTS) self.intersection_geometry.Material.value.set_uniform("Color", avango.gua.Vec4(1.0,0.0,0.0,1.0)) self.intersection_geometry.Tags.value = ["invisible"] SCENEGRAPH.Root.value.Children.value.append(self.intersection_geometry) ## init manipulation techniques self.steeringNavigation = SteeringNavigation() self.steeringNavigation.my_constructor(self, self.spacemouseInput.mf_dof) self.cameraInHandNavigation = CameraInHandNavigation() self.cameraInHandNavigation.my_constructor(self) self.navidgetNavigation = NavidgetNavigation() self.navidgetNavigation.my_constructor(self, SCENEGRAPH) self.ray = avango.gua.nodes.Ray() # required for trimesh intersection NAVIGATION_NODE.Transform.connect_from(self.sf_nav_mat) ### set initial states ### self.set_navigation_technique(0) self.set_navigation_matrix(avango.gua.make_trans_mat(0.0,1.2,0.0))
class NavigationManager(avango.script.Script): ## input fields sf_key_1 = avango.SFBool() sf_key_2 = avango.SFBool() sf_key_3 = avango.SFBool() ## output fields sf_nav_mat = avango.gua.SFMatrix4() sf_nav_mat.value = avango.gua.make_identity_mat() ## constructor def __init__(self): self.super(NavigationManager).__init__() def my_constructor(self, SCENEGRAPH = None, NAVIGATION_NODE = None, POINTER_TRACKING_STATION = "", TRACKING_TRANSMITTER_OFFSET = avango.gua.make_identity_mat(), POINTER_DEVICE_STATION = "", ): ### external references ### self.SCENEGRAPH = SCENEGRAPH self.NAVIGATION_NODE = NAVIGATION_NODE ### parameters ### self.ray_length = 15.0 # in meter self.ray_thickness = 0.015 # in meter self.intersection_point_size = 0.02 # in meter ### variables ### self.active_navigation_technique = None ## picking stuff self.pick_result = None self.white_list = [] self.black_list = ["invisible"] self.pick_options = avango.gua.PickingOptions.PICK_ONLY_FIRST_OBJECT \ | avango.gua.PickingOptions.GET_POSITIONS \ | avango.gua.PickingOptions.GET_NORMALS \ | avango.gua.PickingOptions.GET_WORLD_POSITIONS \ | avango.gua.PickingOptions.GET_WORLD_NORMALS ### resources ### ## init sensors self.keyboard_sensor = avango.daemon.nodes.DeviceSensor(DeviceService = avango.daemon.DeviceService()) self.keyboard_sensor.Station.value = "gua-device-keyboard0" self.sf_key_1.connect_from(self.keyboard_sensor.Button16) # key 1 self.sf_key_2.connect_from(self.keyboard_sensor.Button17) # key 2 self.sf_key_3.connect_from(self.keyboard_sensor.Button18) # key 3 self.pointer_tracking_sensor = avango.daemon.nodes.DeviceSensor(DeviceService = avango.daemon.DeviceService()) self.pointer_tracking_sensor.Station.value = POINTER_TRACKING_STATION self.pointer_tracking_sensor.TransmitterOffset.value = TRACKING_TRANSMITTER_OFFSET self.pointer_device_sensor = avango.daemon.nodes.DeviceSensor(DeviceService = avango.daemon.DeviceService()) self.pointer_device_sensor.Station.value = POINTER_DEVICE_STATION self.spacemouseInput = NewSpacemouseInput() self.spacemouseInput.my_constructor("gua-device-spacemouse") ## init nodes self.pointer_node = avango.gua.nodes.TransformNode(Name = "pointer_node") self.pointer_node.Transform.connect_from(self.pointer_tracking_sensor.Matrix) NAVIGATION_NODE.Children.value.append(self.pointer_node) _loader = avango.gua.nodes.TriMeshLoader() self.ray_geometry = _loader.create_geometry_from_file("ray_geometry", "data/objects/cylinder.obj", avango.gua.LoaderFlags.DEFAULTS) self.ray_geometry.Material.value.set_uniform("Color", avango.gua.Vec4(1.0,0.0,0.0,1.0)) self.ray_geometry.Tags.value = ["invisible"] self.pointer_node.Children.value.append(self.ray_geometry) self.intersection_geometry = _loader.create_geometry_from_file("intersection_geometry", "data/objects/sphere.obj", avango.gua.LoaderFlags.DEFAULTS) self.intersection_geometry.Material.value.set_uniform("Color", avango.gua.Vec4(1.0,0.0,0.0,1.0)) self.intersection_geometry.Tags.value = ["invisible"] SCENEGRAPH.Root.value.Children.value.append(self.intersection_geometry) ## init manipulation techniques self.steeringNavigation = SteeringNavigation() self.steeringNavigation.my_constructor(self, self.spacemouseInput.mf_dof) self.cameraInHandNavigation = CameraInHandNavigation() self.cameraInHandNavigation.my_constructor(self) self.navidgetNavigation = NavidgetNavigation() self.navidgetNavigation.my_constructor(self, SCENEGRAPH) self.ray = avango.gua.nodes.Ray() # required for trimesh intersection NAVIGATION_NODE.Transform.connect_from(self.sf_nav_mat) ### set initial states ### self.set_navigation_technique(0) self.set_navigation_matrix(avango.gua.make_trans_mat(0.0,1.2,0.0)) ### functions ### def set_navigation_technique(self, INT): # possibly disable prior technique if self.active_navigation_technique is not None: self.active_navigation_technique.enable(False) # enable new technique if INT == 0: # Steering Navigation self.active_navigation_technique = self.steeringNavigation print("Switch to Steering Navigation") elif INT == 1: # Camera-in-Hand Navigation self.active_navigation_technique = self.cameraInHandNavigation print("Switch to Camera-In-Hand Navigation") elif INT == 2: # Navidget Navigation self.active_navigation_technique = self.navidgetNavigation print("Switch to Navidget Navigation") self.active_navigation_technique.enable(True) def set_navigation_matrix(self, MAT4): self.sf_nav_mat.value = MAT4 def get_navigation_matrix(self): return self.sf_nav_mat.value def calc_pick_result(self): # update ray parameters self.ray.Origin.value = self.pointer_node.WorldTransform.value.get_translate() _vec = avango.gua.make_rot_mat(self.pointer_node.WorldTransform.value.get_rotate()) * avango.gua.Vec3(0.0,0.0,-1.0) _vec = avango.gua.Vec3(_vec.x,_vec.y,_vec.z) self.ray.Direction.value = _vec * self.ray_length # intersect _mf_pick_result = self.SCENEGRAPH.ray_test(self.ray, self.pick_options, self.white_list, self.black_list) if len(_mf_pick_result.value) > 0: # intersection found self.pick_result = _mf_pick_result.value[0] # get first pick result else: # nothing hit self.pick_result = None def update_ray_visualization(self): if self.pick_result is not None: # something hit _pick_world_pos = self.pick_result.WorldPosition.value # pick position in world coordinate system _distance = self.pick_result.Distance.value * self.ray_length # pick distance in ray coordinate system self.ray_geometry.Transform.value = \ avango.gua.make_trans_mat(0.0,0.0,_distance * -0.5) * \ avango.gua.make_rot_mat(-90.0,1,0,0) * \ avango.gua.make_scale_mat(self.ray_thickness, _distance, self.ray_thickness) self.intersection_geometry.Tags.value = [] # set intersection point visible self.intersection_geometry.Transform.value = avango.gua.make_trans_mat(_pick_world_pos) * avango.gua.make_scale_mat(self.intersection_point_size) else: # nothing hit --> apply default ray visualization self.ray_geometry.Transform.value = \ avango.gua.make_trans_mat(0.0,0.0,self.ray_length * -0.5) * \ avango.gua.make_rot_mat(-90.0,1,0,0) * \ avango.gua.make_scale_mat(self.ray_thickness, self.ray_length, self.ray_thickness) self.intersection_geometry.Tags.value = ["invisible"] # set intersection point invisible ### callback functions ### @field_has_changed(sf_key_1) def sf_key_1_changed(self): if self.sf_key_1.value == True: # key is pressed self.set_navigation_technique(0) @field_has_changed(sf_key_2) def sf_key_2_changed(self): if self.sf_key_2.value == True: # key is pressed self.set_navigation_technique(1) @field_has_changed(sf_key_3) def sf_key_3_changed(self): if self.sf_key_3.value == True: # key is pressed self.set_navigation_technique(2)
def start(): ## create scenegraph scenegraph = avango.gua.nodes.SceneGraph(Name="scenegraph") ## init scene scene = Scene(PARENT_NODE=scenegraph.Root.value) ## init navigation technique deviceInput = NewSpacemouseInput() deviceInput.my_constructor("gua-device-spacemouse") steeringNavigation = SteeringNavigation() steeringNavigation.my_constructor( deviceInput.mf_dof, deviceInput.mf_buttons, 0.15, 1.0) # connect navigation with spacemouse input steeringNavigation.set_start_matrix( avango.gua.make_trans_mat(0.0, 0.2, 0.25)) ## init viewing setup ## init viewing and interaction setups hostname = open('/etc/hostname', 'r').readline() hostname = hostname.strip(" \n") print("wokstation:", hostname) if hostname == "orestes": # Mitsubishi 3D-TV workstation _tracking_transmitter_offset = avango.gua.make_trans_mat( -0.98, -(0.58 + 0.975), 0.27 + 3.48) * avango.gua.make_rot_mat( 90.0, 0, 1, 0) # transformation into tracking coordinate system viewingSetup = StereoViewingSetup( SCENEGRAPH=scenegraph, WINDOW_RESOLUTION=avango.gua.Vec2ui(1920, 1080), SCREEN_DIMENSIONS=avango.gua.Vec2(1.445, 0.81), LEFT_SCREEN_RESOLUTION=avango.gua.Vec2ui(1920, 1080), RIGHT_SCREEN_RESOLUTION=avango.gua.Vec2ui(1920, 1080), STEREO_FLAG=True, STEREO_MODE=avango.gua.StereoMode.CHECKERBOARD, HEADTRACKING_FLAG=True, HEADTRACKING_STATION= "tracking-art-glasses-1", # wired 3D-TV glasses on Mitsubishi 3D-TV workstation TRACKING_TRANSMITTER_OFFSET=_tracking_transmitter_offset, ) manipulationManager = ManipulationManager() manipulationManager.my_constructor( SCENEGRAPH=scenegraph, NAVIGATION_NODE=viewingSetup.navigation_node, POINTER_TRACKING_STATION="tracking-art-pointer-3", TRACKING_TRANSMITTER_OFFSET=_tracking_transmitter_offset, POINTER_DEVICE_STATION="device-pointer-3", # gyromouse HEAD_NODE=viewingSetup.head_node, ) elif hostname == "athena": # small powerwall workstation _tracking_transmitter_offset = avango.gua.make_trans_mat( 0.0, -1.42, 1.6) # transformation into tracking coordinate system viewingSetup = StereoViewingSetup( SCENEGRAPH=scenegraph, WINDOW_RESOLUTION=avango.gua.Vec2ui(1920 * 2, 1200), SCREEN_DIMENSIONS=avango.gua.Vec2(3.0, 2.0), LEFT_SCREEN_POSITION=avango.gua.Vec2ui(140, 0), LEFT_SCREEN_RESOLUTION=avango.gua.Vec2ui(1780, 1185), RIGHT_SCREEN_POSITION=avango.gua.Vec2ui(1920, 0), RIGHT_SCREEN_RESOLUTION=avango.gua.Vec2ui(1780, 1185), STEREO_FLAG=True, STEREO_MODE=avango.gua.StereoMode.SIDE_BY_SIDE, HEADTRACKING_FLAG=True, HEADTRACKING_STATION= "tracking-art-glasses-2", # small powerwall polarization glasses TRACKING_TRANSMITTER_OFFSET=_tracking_transmitter_offset, ) manipulationManager = ManipulationManager() manipulationManager.my_constructor( SCENEGRAPH=scenegraph, NAVIGATION_NODE=viewingSetup.navigation_node, POINTER_TRACKING_STATION="tracking-art-pointer-2", TRACKING_TRANSMITTER_OFFSET=_tracking_transmitter_offset, POINTER_DEVICE_STATION="device-pointer-2", HEAD_NODE=viewingSetup.head_node, ) elif hostname == "kronos": # Samsung 3D-TV workstation _tracking_transmitter_offset = avango.gua.make_trans_mat( 0.0, -0.5, 0.6) # transformation into tracking coordinate system viewingSetup = StereoViewingSetup( SCENEGRAPH=scenegraph, WINDOW_RESOLUTION=avango.gua.Vec2ui(1920, 1080), SCREEN_DIMENSIONS=avango.gua.Vec2(1.235, 0.7), LEFT_SCREEN_RESOLUTION=avango.gua.Vec2ui(1920, 1080), RIGHT_SCREEN_RESOLUTION=avango.gua.Vec2ui(1920, 1080), STEREO_FLAG=True, STEREO_MODE=avango.gua.StereoMode.CHECKERBOARD, HEADTRACKING_FLAG=True, HEADTRACKING_STATION= "tracking-pst-glasses-1", # wired 3D-TV glasses on Samsung 3D-TV workstation TRACKING_TRANSMITTER_OFFSET=_tracking_transmitter_offset, ) manipulationManager = ManipulationManager() manipulationManager.my_constructor( SCENEGRAPH=scenegraph, NAVIGATION_NODE=viewingSetup.navigation_node, POINTER_TRACKING_STATION="tracking-pst-pointer-1", TRACKING_TRANSMITTER_OFFSET=_tracking_transmitter_offset, POINTER_DEVICE_STATION="device-pointer-1", HEAD_NODE=viewingSetup.head_node, ) else: print("No Viewing Setup available for this workstation") quit() viewingSetup.connect_navigation_matrix(steeringNavigation.sf_nav_mat) steeringNavigation.set_rotation_center_offset( viewingSetup.get_head_position()) print_graph(scenegraph.Root.value) ## start application/render loop viewingSetup.run(locals(), globals())
def start(): ## create scenegraph scenegraph = avango.gua.nodes.SceneGraph(Name="scenegraph") ## init scene scene = Scene(PARENT_NODE=scenegraph.Root.value) ## init navigation technique deviceInput = NewSpacemouseInput() deviceInput.my_constructor("gua-device-spacemouse") navigation = SpacemouseNavigation() navigation.my_constructor(deviceInput.mf_dof, deviceInput.mf_buttons, 0.15, 1.0) # connect navigation with spacemouse input navigation.set_start_matrix(avango.gua.make_trans_mat(0.0, 0.2, 0.25)) ## init viewing and interaction setups hostname = open('/etc/hostname', 'r').readline() hostname = hostname.strip(" \n") print("wokstation:", hostname) if hostname == "perseus": # Mitsubishi 3D-TV workstation _tracking_transmitter_offset = avango.gua.make_trans_mat( -0.98, -(0.58 + 0.975), 0.27 + 3.48) * avango.gua.make_rot_mat( 90.0, 0, 1, 0) # transformation into tracking coordinate system viewingSetup = StereoViewingSetup( SCENEGRAPH=scenegraph, WINDOW_RESOLUTION=avango.gua.Vec2ui(1920, 1080), SCREEN_DIMENSIONS=avango.gua.Vec2(1.445, 0.81), LEFT_SCREEN_RESOLUTION=avango.gua.Vec2ui(1920, 1080), RIGHT_SCREEN_RESOLUTION=avango.gua.Vec2ui(1920, 1080), STEREO_FLAG=True, STEREO_MODE=avango.gua.StereoMode.CHECKERBOARD, HEADTRACKING_FLAG=True, HEADTRACKING_STATION= "tracking-glasses-1", # wired 3D-TV glasses on Mitsubishi 3D-TV workstation TRACKING_TRANSMITTER_OFFSET=_tracking_transmitter_offset, ) pointerInput = PointerInput() pointerInput.init_art_pointer( POINTER_DEVICE_STATION="device-pointer-2", # gyromouse pointer POINTER_TRACKING_STATION="tracking-pointer-2", # gyromouse pointer TRACKING_TRANSMITTER_OFFSET=_tracking_transmitter_offset, KEYBOARD_STATION="gua-device-keyboard", ) manipulationManager = ManipulationManager() manipulationManager.my_constructor( SCENEGRAPH=scenegraph, NAVIGATION_NODE=viewingSetup.navigation_node, HEAD_NODE=viewingSetup.head_node, POINTER_INPUT=pointerInput, ) elif hostname == "andromeda": # ASUS 3D mirror display _tracking_transmitter_offset = avango.gua.make_rot_mat( 12.46, 1, 0, 0) * avango.gua.make_trans_mat( 0.5, -(0.22 + 0.975), 0.39 + 3.48) * avango.gua.make_rot_mat( 90.0, 0, 1, 0) # transformation into tracking coordinate system viewingSetup = StereoViewingSetup( SCENEGRAPH=scenegraph, WINDOW_RESOLUTION=avango.gua.Vec2ui(2560 * 2, 1440), SCREEN_DIMENSIONS=avango.gua.Vec2(0.595, 0.335), LEFT_SCREEN_POSITION=avango.gua.Vec2ui(0, 0), LEFT_SCREEN_RESOLUTION=avango.gua.Vec2ui(2560, 1440), RIGHT_SCREEN_RESOLUTION=avango.gua.Vec2ui(2560, 1440), RIGHT_SCREEN_POSITION=avango.gua.Vec2ui(2560, 0), STEREO_FLAG=True, STEREO_MODE=avango.gua.StereoMode.SIDE_BY_SIDE, HEADTRACKING_FLAG=True, HEADTRACKING_STATION= "tracking-glasses-4", # ASUS 3D mirror display glasses TRACKING_TRANSMITTER_OFFSET=_tracking_transmitter_offset, ) pointerInput = PointerInput() pointerInput.init_art_pointer( POINTER_DEVICE_STATION="device-pointer-1", # HAS POINTER_TRACKING_STATION="tracking-pointer-1", # HAS TRACKING_TRANSMITTER_OFFSET=_tracking_transmitter_offset, KEYBOARD_STATION="gua-device-keyboard", ) manipulationManager = ManipulationManager() manipulationManager.my_constructor( SCENEGRAPH=scenegraph, NAVIGATION_NODE=viewingSetup.navigation_node, HEAD_NODE=viewingSetup.head_node, POINTER_INPUT=pointerInput, ) elif hostname == "athena": # small powerwall workstation _tracking_transmitter_offset = avango.gua.make_trans_mat( 0.0, -1.42, 1.6) # transformation into tracking coordinate system viewingSetup = StereoViewingSetup( SCENEGRAPH=scenegraph, WINDOW_RESOLUTION=avango.gua.Vec2ui(1920 * 2, 1200), SCREEN_DIMENSIONS=avango.gua.Vec2(3.0, 2.0), LEFT_SCREEN_POSITION=avango.gua.Vec2ui(134, 1), LEFT_SCREEN_RESOLUTION=avango.gua.Vec2ui(1770, 1175), RIGHT_SCREEN_POSITION=avango.gua.Vec2ui(1934, 0), RIGHT_SCREEN_RESOLUTION=avango.gua.Vec2ui(1765, 1165), STEREO_FLAG=True, STEREO_MODE=avango.gua.StereoMode.SIDE_BY_SIDE, HEADTRACKING_FLAG=True, HEADTRACKING_STATION= "tracking-glasses-2", # wired 3D-TV glasses on Samsung 3D-TV workstation TRACKING_TRANSMITTER_OFFSET=_tracking_transmitter_offset, ) pointerInput = PointerInput() pointerInput.init_art_pointer( POINTER_DEVICE_STATION="device-pointer-3", # 2.4G pointer (green) POINTER_TRACKING_STATION= "tracking-pointer-3", # 2.4G pointer (green) TRACKING_TRANSMITTER_OFFSET=_tracking_transmitter_offset, KEYBOARD_STATION="gua-device-keyboard", ) manipulationManager = ManipulationManager() manipulationManager.my_constructor( SCENEGRAPH=scenegraph, NAVIGATION_NODE=viewingSetup.navigation_node, HEAD_NODE=viewingSetup.head_node, POINTER_INPUT=pointerInput, ) elif hostname == "boreas": # Samsung 3D-TV workstation _tracking_transmitter_offset = avango.gua.make_trans_mat( 0.0, -1.3, 1.45) # transformation into tracking coordinate system viewingSetup = StereoViewingSetup( SCENEGRAPH=scenegraph, WINDOW_RESOLUTION=avango.gua.Vec2ui(1920, 1080), SCREEN_DIMENSIONS=avango.gua.Vec2(1.24, 0.69), LEFT_SCREEN_RESOLUTION=avango.gua.Vec2ui(1920, 1080), RIGHT_SCREEN_RESOLUTION=avango.gua.Vec2ui(1920, 1080), STEREO_FLAG=True, STEREO_MODE=avango.gua.StereoMode.CHECKERBOARD, HEADTRACKING_FLAG=True, HEADTRACKING_STATION="tracking-glasses-3", TRACKING_TRANSMITTER_OFFSET=_tracking_transmitter_offset, ) pointerInput = PointerInput() pointerInput.init_art_pointer( POINTER_DEVICE_STATION="device-pointer-3", # 2.4G Mouse POINTER_TRACKING_STATION="tracking-pointer-3", # 2.4G Mouse TRACKING_TRANSMITTER_OFFSET=_tracking_transmitter_offset, KEYBOARD_STATION="gua-device-keyboard", ) manipulationManager = ManipulationManager() manipulationManager.my_constructor( SCENEGRAPH=scenegraph, NAVIGATION_NODE=viewingSetup.navigation_node, HEAD_NODE=viewingSetup.head_node, POINTER_INPUT=pointerInput, ) else: print("No Viewing Setup available for this workstation") quit() viewingSetup.connect_navigation_matrix(navigation.sf_nav_mat) navigation.set_rotation_center_offset(viewingSetup.get_head_position()) print_graph(scenegraph.Root.value) ## start application/render loop viewingSetup.run(locals(), globals())