Esempio n. 1
0
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
Esempio n. 2
0
    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
Esempio n. 3
0
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())
Esempio n. 4
0
    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))
Esempio n. 5
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)
Esempio n. 6
0
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())
Esempio n. 7
0
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())