class MaterialUpdater(avango.script.Script): PickedNodes = avango.gua.MFPickResult() OldNodes = avango.gua.MFPickResult() DefaultMaterial = avango.SFString() TargetMaterial = avango.SFString() @field_has_changed(PickedNodes) def update_materials(self): for i in range(0, len(self.OldNodes.value)): if isinstance(self.OldNodes.value[i].Object.value, avango.gua.GeometryNode): self.OldNodes.value[ i].Object.value.Material.value = self.DefaultMaterial.value for i in range(0, len(self.PickedNodes.value)): if isinstance(self.PickedNodes.value[i].Object.value, avango.gua.GeometryNode): self.PickedNodes.value[ i].Object.value.Material.value = self.TargetMaterial.value avango.gua.set_material_uniform( self.TargetMaterial.value, "pointer_pos", self.PickedNodes.value[i].TextureCoords.value) avango.gua.set_material_uniform( self.TargetMaterial.value, "color", self.PickedNodes.value[i].WorldNormal.value) self.OldNodes.value = self.PickedNodes.value
class Shot(avango.script.Script): ## @var sf_abs_mat # Field representing the translation and rotation matrix of this shot. sf_abs_mat = avango.gua.SFMatrix4() ## @var sf_scale # Field representing the scaling of this shot. sf_scale = avango.SFFloat() ## @var sf_viewing_mode # Field representing the viewing mode of this shot. sf_viewing_mode = avango.SFString() ## @var sf_camera_mode # Field representing the camera mode of this shot. sf_camera_mode = avango.SFString() ## @var sf_negative_parallax # Field representing the negative parallax state of this shot. sf_negative_parallax = avango.SFString() ## Default constructor. def __init__(self): self.super(Shot).__init__() ## Custom constructor. def my_constructor(self, ABS_MAT, SCALE, VIEWING_MODE, CAMERA_MODE, NEGATIVE_PARALLAX): self.sf_abs_mat.value = ABS_MAT self.sf_scale.value = SCALE self.sf_viewing_mode.value = VIEWING_MODE self.sf_camera_mode.value = CAMERA_MODE self.sf_negative_parallax.value = NEGATIVE_PARALLAX
class NetInit(avango.script.Script): NetChildren = avango.gua.MFNode() WindowName = avango.SFString() Viewer = avango.gua.nodes.Viewer() def __init__(self): self.super(NetInit).__init__() self.always_evaluate(True) self.is_initialized = False def my_constructor(self, scenegraph): self.scenegraph = scenegraph def evaluate(self): if len(self.NetChildren.value) > 0 and self.is_initialized: node = self.scenegraph["/net/group/lines"] #node.clear_vertices() #node.push_vertex(1, 0, 0, 1, 0, 0) #node.push_vertex(-1, 0, 0, 1, 0, 0) @field_has_changed(NetChildren) def update(self): if len(self.NetChildren.value) > 0 and not self.is_initialized: node = self.scenegraph["/net/group/lines"] print(node.Name.value) node.RenderVolumetric.value = False self.is_initialized = True
class Picker(avango.script.Script): SceneGraph = avango.gua.SFSceneGraph() Ray = avango.gua.SFRayNode() Options = avango.SFInt() Mask = avango.SFString() Results = avango.gua.MFPickResult() def __init__(self): self.super(Picker).__init__() self.always_evaluate(True) self.SceneGraph.value = avango.gua.nodes.SceneGraph() self.Ray.value = avango.gua.nodes.RayNode() self.Options.value = avango.gua.PickingOptions.PICK_ONLY_FIRST_OBJECT \ | avango.gua.PickingOptions.GET_TEXTURE_COORDS \ | avango.gua.PickingOptions.GET_WORLD_NORMALS \ | avango.gua.PickingOptions.INTERPOLATE_NORMALS \ | avango.gua.PickingOptions.PICK_ONLY_FIRST_FACE self.Mask.value = "" def evaluate(self): results = self.SceneGraph.value.ray_test(self.Ray.value, self.Options.value, self.Mask.value) self.Results.value = results.value
class AInputNode(connect.InputNode): anint = avango.SFInt() astring = avango.SFString() morestrings = avango.MFString() def __init__(self): self.super(AInputNode).__init__() self.anint.value = 0
class TimedMaterialUniformUpdate(avango.script.Script): ## @var TimeIn # Field containing the current time in milliseconds. TimeIn = avango.SFFloat() ## @var MaterialName # Field containing the name of the material to be updated MaterialName = avango.SFString() ## @var UniformName # Field containing the name of the uniform value to be updated UniformName = avango.SFString() ## Called whenever TimeIn changes. @field_has_changed(TimeIn) def update(self): avango.gua.set_material_uniform(self.MaterialName.value, self.UniformName.value, self.TimeIn.value)
class FloatXBase(avango.script.Script): "Base for sequential operations on floats" BaseFieldName = avango.SFString() NumFieldsOut = avango.SFInt() Output = avango.SFFloat() def __init__(self): self.super(FloatXBase).__init__() self.Name.value = "FloatXBase" self.Output.value = 0 self.BaseFieldName.value = "Input" self.NumFieldsOut.value = 0 self._actual_id = 0 def add_and_connect_float_field(self,field): field_name = self.BaseFieldName.value + str(self._actual_id) if self.has_field(field_name): return #create and add the new field self.add_and_init_field(avango.SFFloat(), field_name, 0) #connect the field with the given field getattr(self, field_name).connect_from(field) self._actual_id += 1 self.NumFieldsOut.value = self._actual_id def evaluate(self): self.on_calculate() def on_calculate(self): pass
class ManipulatorPicker(avango.script.Script): SceneGraph = avango.gua.SFSceneGraph() Ray = avango.gua.SFRayNode() Options = avango.SFInt() Mask = avango.SFString() Results = avango.gua.MFPickResult() def __init__(self): self.super(ManipulatorPicker).__init__() self.always_evaluate(True) self.SceneGraph.value = avango.gua.nodes.SceneGraph() self.Ray.value = avango.gua.nodes.RayNode() self.Options.value = avango.gua.PickingOptions.PICK_ONLY_FIRST_OBJECT \ | avango.gua.PickingOptions.PICK_ONLY_FIRST_FACE\ | avango.gua.PickingOptions.GET_POSITIONS self.Mask.value = "" def evaluate(self): results = self.SceneGraph.value.ray_test(self.Ray.value, self.Options.value, self.Mask.value) self.Results.value = results.value
class NetInit(avango.script.Script): NetChildren = avango.gua.MFNode() WindowName = avango.SFString() Viewer = avango.gua.nodes.Viewer() """
def read(self, line): field = avango.SFString() field.value = line[0] return field
class GuaVE(avango.script.Script): Prompt = avango.SFString() HistoryFile = avango.SFString() def __init__(self): self.super(GuaVE).__init__() self.always_evaluate(True) self.__input_queue = queue.Queue() self.__input_lock = threading.Lock() self.__vars = {} self.Prompt.value = "gua> " self.HistoryFile.value = os.path.expanduser("~/.guahistory") def start(self, locals, globals, show_banner=True): self.__vars = globals.copy() self.__vars.update(locals) self.__shell = code.InteractiveConsole(self.__vars) print("") if show_banner: print("") print(" _ ") print(" | | ") print(" __ _ _ _ __ _ ___ __ _ _ __ ___ ___ | | ___ ") print(" / _` | | | |/ _` |/ __/ _` | '_ ` _ \ / _ \| |/ _ \ ") print("| (_| | |_| | (_| | (_| (_| | | | | | | (_) | | __/ ") print(" \__, |\__,_|\__,_|\___\__,_|_| |_| |_|\___/|_|\___| ") print(" __/ | ") print(" |___/ ") print("") print("") print("") print(print_green + "Welcome to GuaVE, the guacamole virtual environment!" + print_reset) print("") print("Press Ctrl-D to exit to exit GuaVE.") print("----------------------------------------------------") self.__input_thread = threading.Thread(target=self.__read_input) self.__input_thread.daemon = True self.__input_thread.start() signal.signal(signal.SIGINT, self.__signal_handler) def list_variables(self): vars = self.__vars.keys() vars.sort() for v in vars: print(v) def evaluate(self): while (not self.__input_queue.empty()): # clear line sys.stdout.write('\r\033[2K') sys.stdout.flush() self.__shell.push(self.__input_queue.get()) #write new prompt sys.stdout.write(print_green + self.Prompt.value + print_reset) sys.stdout.flush() readline.write_history_file(self.HistoryFile.value) def __signal_handler(self, signal, frame): print("Bye!") sys.exit(0) def __read_input(self): readline.set_completer(rlcompleter.Completer(self.__vars).complete) readline.parse_and_bind("tab: complete") if os.path.exists(self.HistoryFile.value): readline.read_history_file(self.HistoryFile.value) while (True): try: line = input('\001' + print_green + '\002' + self.Prompt.value + '\001' + print_reset + '\002') self.__input_queue.put(line) except EOFError: print("Bye") #, press Ctrl-C to kill guacamole...") os._exit(0) except IOError as err: print("I/O error: {0}".format(err)) os._exit(1) except: print("Unexpected error:", sys.exc_info()[0]) os._exit(1)
class XML_Projector(avango.script.Script): Texture = avango.SFString() Material = avango.gua.SFMaterial() Image_View_Mat = avango.gua.SFMatrix4() Enable = avango.SFBool() def __init__(self): self.super(XML_Projector).__init__() loader = avango.gua.nodes.TriMeshLoader() # setup node and frame geometry self.group_node = avango.gua.nodes.TransformNode( Name="projector_group") self.geometry = loader.create_geometry_from_file( "frame", "data/objects/frame.obj", avango.gua.LoaderFlags.DEFAULTS, ) self.geometry.Material.value.set_uniform( "Color", avango.gua.Vec4(0.7, 0.7, 0.7, 1.0), ) self.geometry.Material.value.set_uniform("Emissivity", 1.0) self.group_node.Children.value.append(self.geometry) # setup Material self.Material.value = avango.gua.nodes.Material(ShaderName="proj_mat") proj_mat_desc = avango.gua.nodes.MaterialShaderDescription() proj_mat_desc.load_from_file( "data/materials/Projective_Texture_pbr.gmd") avango.gua.register_material_shader(proj_mat_desc, "proj_mat") self.Material.value.set_uniform("Emissivity", 1.0) def load_XML(self, XML_path, parent): xml = ET.parse(XML_path).getroot() # load Transformation from XML self.group_node.Transform.value = self.load_transform(xml) parent.Children.value.append(self.group_node) # set Matrix self.Image_View_Mat.value =\ avango.gua.make_inverse_mat(self.group_node.Transform.value) self.Material.value.set_uniform( "Image_View_Mat", self.Image_View_Mat.value, ) def load_transform(self, xml): trans = xml.find("Transformation") position = parse_vec3(trans.find("Position").text, faktor=0.001) rot_x = parse_vec3(trans.find("Direction").find("X").text) rot_y = parse_vec3(trans.find("Direction").find("Y").text) rot_z = parse_vec3(trans.find("Direction").find("Z").text) pxl = xml.find("Image").find("Pixel") pxl_size = float(pxl.find("Size").text) pxl_x = float(pxl.find("Width").text) pxl_y = float(pxl.find("Height").text) scale_x = pxl_x * pxl_size scale_y = pxl_y * pxl_size depth = float(xml.find("Depth").find("Range").text) transform =\ build_matrix(position, rot_x, rot_y, rot_z) *\ avango.gua.make_scale_mat(scale_x, scale_y, depth) # avango.gua.make_scale_mat(0.1) return transform @field_has_changed(Enable) def update_enable_uniform(self): self.Material.value.set_uniform("EnableProjection", self.Enable.value) @field_has_changed(Texture) def update_texture(self): self.Material.value.set_uniform( "projective_texture", self.Texture.value, )
class BoolXBase(avango.script.Script): "Base for sequential operations on bools" BaseFieldName = avango.SFString() NumFieldsIn = avango.SFInt() Output = avango.SFBool() def __init__(self): self.super(BoolXBase).__init__() self.Output.value = False self.BaseFieldName.value = "Input" self.NumFieldsIn.value = 0 self._actual_id = 0 self.Name.value = "BoolXBase" def add_and_connect_bool_field(self, field): field_name = self.BaseFieldName.value + str(self._actual_id) if self.has_field(field_name): return #create and add the new field self.add_and_init_field(avango.SFBool(), field_name, False) #connect the field with the given field getattr(self, field_name).connect_from(field) self._actual_id += 1 self.NumFieldsIn.value = self._actual_id def remove_and_disconnect_all_fields(self): for field_id in range(0, self._actual_id): field_name = self.BaseFieldName.value + str(field_id) field = self.get_field(field_name) if not field: continue field.disconnect() self.remove_field(field_name) self._actual_id = 0 def remove_and_disconnect_field(self, field_number): if self._actual_id >= field_number: field_name = self.BaseFieldName.value + str(field_number) field = self.get_field(field_name) if not field: return field.disconnect() self.remove_field(field_name) def evaluate(self): self.on_calculate() def on_calculate(self): pass def cleanup(self): self.remove_and_disconnect_all_fields()
def testWriteSFString(self): sfstring = avango.SFString() sfstring.value = "Test Number One" hout = StringIO.StringIO() connect.write("B", sfstring, hout) self.assertEqual("B\x00SFString\x00Test Number One\n", hout.getvalue())
class View(avango.script.Script): ## @var sf_pipeline_string # String field containing the concatenated pipeline values. sf_pipeline_string = avango.SFString() ## Default constructor. def __init__(self): self.super(View).__init__() ## @var portal_pre_views # A list of all PortalPreView instances for this view. self.portal_pre_views = [] ## Custom constructor. # @param SCENEGRAPH Reference to the scenegraph to be displayed. # @param VIEWER Reference to the viewer to which the created pipeline will be appended to. # @param DISPLAY_INSTANCE An instance of Display to represent the values. # @param WORKSPACE_ID ID of the workspace to deal with. # @param DISPLAY_GROUP_ID ID of the display group to deal with. # @param SCREEN_ID ID of the screen to deal with. # @param USER_ID ID of the user to deal with. def my_constructor(self, SCENEGRAPH, VIEWER, DISPLAY_INSTANCE, WORKSPACE_ID, DISPLAY_GROUP_ID, SCREEN_ID, USER_ID): ## @var SCENEGRAPH # Reference to the scenegraph. self.SCENEGRAPH = SCENEGRAPH ## @var is_stereo # Boolean indicating if the view to be constructed is stereo or mono. self.is_stereo = DISPLAY_INSTANCE.stereo ## @var workspace_id # ID of the workspace to deal with. self.workspace_id = WORKSPACE_ID ## @var display_group_id # ID of the display group to deal with. self.display_group_id = DISPLAY_GROUP_ID ## @var screen_id # ID of the screen to deal with. self.screen_id = SCREEN_ID ## @var user_id # ID of the user to deal with. self.user_id = USER_ID # retrieve the needed values from display ## @var display_values # Values that are retrieved from the display. Vary for each view on this display. self.display_values = DISPLAY_INSTANCE.register_view() ## @var display_render_mask # Additional render mask contraints given by the display. self.display_render_mask = DISPLAY_INSTANCE.render_mask # check if no more users allowed at this screen if not self.display_values: # TODO better handling of this case? print_error( 'Error: no more users allowed at display "' + DISPLAY_INSTANCE.name + '"!', False) return ## @var window_size # Size of the window in which this View will be rendered. self.window_size = avango.gua.Vec2ui(DISPLAY_INSTANCE.resolution[0], DISPLAY_INSTANCE.resolution[1]) # create camera ## @var camera # The camera from which this View will be rendered. self.camera = avango.gua.nodes.Camera() self.camera.SceneGraph.value = SCENEGRAPH.Name.value self.camera.Mode.value = DISPLAY_INSTANCE.cameramode # set render mask for camera _render_mask = "(main_scene | w" + str(WORKSPACE_ID) + "_dg" + str( DISPLAY_GROUP_ID) + "_u" + str( USER_ID ) + ") && !do_not_display_group && !portal_invisible_group" self.camera.RenderMask.value = _render_mask #print repr(self.camera.RenderMask.value) # create pipeline ## @var pipeline # The pipeline used to render this View. self.pipeline = avango.gua.nodes.Pipeline() self.pipeline.Enabled.value = True ''' Standard View ''' self.camera.LeftScreen.value = "/net/w" + str( self.workspace_id) + "_dg" + str( self.display_group_id) + "_u" + str( self.user_id) + "/screen_" + str(self.screen_id) self.camera.RightScreen.value = "/net/w" + str( self.workspace_id) + "_dg" + str( self.display_group_id) + "_u" + str( self.user_id) + "/screen_" + str(self.screen_id) self.camera.LeftEye.value = "/net/w" + str( self.workspace_id) + "_dg" + str( self.display_group_id) + "_u" + str( self.user_id) + "/head/eyeL" self.camera.RightEye.value = "/net/w" + str( self.workspace_id) + "_dg" + str( self.display_group_id) + "_u" + str( self.user_id) + "/head/eyeR" # create window ## @var window # The window in which this View will be rendered to. self.window = avango.gua.nodes.Window() self.window.Display.value = self.display_values[0] # GPU-ID self.window.Title.value = "Display: " + str( DISPLAY_INSTANCE.name) + "; User: "******"SIDE_BY_SIDE": self.window.Size.value = avango.gua.Vec2ui(self.window_size.x * 2, self.window_size.y) self.window.LeftPosition.value = avango.gua.Vec2ui(0, 0) self.window.RightPosition.value = avango.gua.Vec2ui( self.window_size.x, 0) self.window.StereoMode.value = avango.gua.StereoMode.SIDE_BY_SIDE elif DISPLAY_INSTANCE.stereomode == "ANAGLYPH_RED_CYAN" or DISPLAY_INSTANCE.stereomode == "CHECKERBOARD": self.window.Size.value = self.window_size self.window.LeftPosition.value = avango.gua.Vec2ui(0, 0) self.window.RightPosition.value = avango.gua.Vec2ui(0, 0) if DISPLAY_INSTANCE.stereomode == "ANAGLYPH_RED_CYAN": self.window.StereoMode.value = avango.gua.StereoMode.ANAGLYPH_RED_CYAN elif DISPLAY_INSTANCE.stereomode == "CHECKERBOARD": self.window.StereoMode.value = avango.gua.StereoMode.CHECKERBOARD self.pipeline.LeftResolution.value = self.window.LeftResolution.value self.pipeline.RightResolution.value = self.window.RightResolution.value if self.is_stereo: self.pipeline.EnableStereo.value = True else: self.pipeline.EnableStereo.value = False self.pipeline.Window.value = self.window self.pipeline.Camera.value = self.camera self.pipeline.EnableFPSDisplay.value = True ''' General user settings ''' # set display string and warpmatrices as given by the display if len(self.display_values) > 1: self.set_warpmatrices(self.window, self.display_values[1]) # append pipeline to the viewer VIEWER.Pipelines.value.append(self.pipeline) ## @var frame_trigger # Triggers framewise evaluation of frame_callback method. self.frame_trigger = avango.script.nodes.Update( Callback=self.frame_callback, Active=True) ## Sets the warp matrices if there is a correct amount of them. # @param WINDOW The window instance to apply the warp matrices to. # @param WARPMATRICES A list of warp matrices to be applied if there are enough of them. def set_warpmatrices(self, WINDOW, WARPMATRICES): if len(WARPMATRICES) == 6: WINDOW.WarpMatrixRedRight.value = WARPMATRICES[0] WINDOW.WarpMatrixGreenRight.value = WARPMATRICES[1] WINDOW.WarpMatrixBlueRight.value = WARPMATRICES[2] WINDOW.WarpMatrixRedLeft.value = WARPMATRICES[3] WINDOW.WarpMatrixGreenLeft.value = WARPMATRICES[4] WINDOW.WarpMatrixBlueLeft.value = WARPMATRICES[5] ## Creates a PortalPreView instance for the portal copied at LOCAL_PORTAL_NODE. # @param SERVER_PORTAL_NODE Server portal grouping node. def create_portal_preview(self, SERVER_PORTAL_NODE): _pre_view = PortalPreView() _pre_view.my_constructor(SERVER_PORTAL_NODE, self) self.portal_pre_views.append(_pre_view) ## Removes the PortalPreView instance of LOCAL_PORTAL_NODE. # @param LOCAL_PORTAL_NODE The client portal node to remove the PreView for. def remove_portal_preview(self, LOCAL_PORTAL_NODE): _pre_views_to_remove = [] for _pre_view in self.portal_pre_views: if _pre_view.compare_portal_node(LOCAL_PORTAL_NODE) == True: _pre_views_to_remove.append(_pre_view) for _pre_view in _pre_views_to_remove: print("Remove a pre view") _pre_view.deactivate() self.portal_pre_views.remove(_pre_view) del _pre_view print("New list of pre views", self.portal_pre_views) ## Called whenever sf_pipeline_string changes. @field_has_changed(sf_pipeline_string) def sf_pipeline_string_changed(self): _splitted_string = self.sf_pipeline_string.value.split("#") print_message("w" + str(self.workspace_id) + "_dg" + str(self.display_group_id) + "_u" + str(self.user_id) + ": Set pipeline values to " + str(_splitted_string)) # Note: Calling avango.gua.create_texture during runtime causes the application # to crash. All textures have to be preloaded, for example in ClientPipelineValues.py # avango.gua.create_texture(_splitted_string[0]) if self.display_render_mask == "!main_scene": self.pipeline.BackgroundMode.value = avango.gua.BackgroundMode.COLOR self.pipeline.BackgroundColor.value = avango.gua.Color( 0.2, 0.45, 0.6) else: self.pipeline.BackgroundMode.value = avango.gua.BackgroundMode.SKYMAP_TEXTURE self.pipeline.BackgroundTexture.value = _splitted_string[0] self.pipeline.FogTexture.value = _splitted_string[0] if _splitted_string[1] == "True": self.pipeline.EnableBloom.value = True else: self.pipeline.EnableBloom.value = False self.pipeline.BloomIntensity.value = float(_splitted_string[2]) self.pipeline.BloomThreshold.value = float(_splitted_string[3]) self.pipeline.BloomRadius.value = float(_splitted_string[4]) if _splitted_string[5] == "True": self.pipeline.EnableSsao.value = True else: self.pipeline.EnableSsao.value = False self.pipeline.SsaoRadius.value = float(_splitted_string[6]) self.pipeline.SsaoIntensity.value = float(_splitted_string[7]) if _splitted_string[8] == "True": self.pipeline.EnableBackfaceCulling.value = True else: self.pipeline.EnableBackfaceCulling.value = False if _splitted_string[9] == "True": self.pipeline.EnableFrustumCulling.value = True else: self.pipeline.EnableFrustumCulling.value = False if _splitted_string[10] == "True": self.pipeline.EnableFXAA.value = True else: self.pipeline.EnableFXAA.value = False _ambient_color_values = _splitted_string[11].split(",") _ambient_color = avango.gua.Color(float(_ambient_color_values[0]), float(_ambient_color_values[1]), float(_ambient_color_values[2])) self.pipeline.AmbientColor.value = _ambient_color if _splitted_string[12] == "True": self.pipeline.EnableFog.value = True else: self.pipeline.EnableFog.value = False self.pipeline.FogStart.value = float(_splitted_string[13]) self.pipeline.FogEnd.value = float(_splitted_string[14]) self.pipeline.NearClip.value = float(_splitted_string[15]) self.pipeline.FarClip.value = float(_splitted_string[16]) #avango.gua.reload_materials() ## Evaluated every frame until connection is setup. def frame_callback(self): try: _pipeline_info_node = self.SCENEGRAPH[ "/net/pipeline_values"].Children.value[0] except: return # connect sf_pipeline_string with Name field of info node once if _pipeline_info_node != None and self.sf_pipeline_string.value == "": self.sf_pipeline_string.connect_from(_pipeline_info_node.Name) self.frame_trigger.Active.value = False