def __init__(self, add_to_scene_entities=True, **kwargs): super().__init__(self.__class__.__name__) self.name = camel_to_snake(self.type) self.enabled = True self.visible = True self.ignore = False # if True, will not try to run code self.eternal = False # eternal entities does not get destroyed on scene.clear() self.ignore_paused = False self.ignore_input = False self.parent = scene if add_to_scene_entities: scene.entities.append(self) self.model = None self.color = color.white self.texture = None self.reflection_map = scene.reflection_map self.reflectivity = 0 self.render_queue = 0 self.double_sided = False self.collision = False self.collider = None self.scripts = list() self.animations = list() self.hovered = False # self.origin = Vec3(0,0,0) self.position = Vec3(0,0,0) # can also set self.x, self.y, self.z self.rotation = Vec3(0,0,0) # can also set self.rotation_x, self.rotation_y, self.rotation_z self.scale = Vec3(1,1,1) # can also set self.scale_x, self.scale_y, self.scale_z self.line_definition = None if application.trace_entity_definition and add_to_scene_entities: from inspect import getframeinfo, stack _stack = stack() caller = getframeinfo(_stack[1][0]) if len(_stack) > 2 and _stack[1].code_context and 'super().__init__()' in _stack[1].code_context[0]: caller = getframeinfo(_stack[2][0]) self.line_definition = caller if caller.code_context: self.code_context = caller.code_context[0] if (self.code_context.count('(') == self.code_context.count(')') and ' = ' in self.code_context and not 'name=' in self.code_context and not 'Ursina()' in self.code_context): self.name = self.code_context.split(' = ')[0].strip().replace('self.', '') # print('set name to:', self.code_context.split(' = ')[0].strip().replace('self.', '')) if application.print_entity_definition: print(f'{Path(caller.filename).name} -> {caller.lineno} -> {caller.code_context}') for key, value in kwargs.items(): setattr(self, key, value)
def add_script(self, class_instance): if isinstance(class_instance, object) and type(class_instance) is not str: class_instance.entity = self class_instance.enabled = True setattr(self, camel_to_snake(class_instance.__class__.__name__), class_instance) self.scripts.append(class_instance) # print('added script:', camel_to_snake(name.__class__.__name__)) return class_instance
def add_script(self, name, path=None): # instance given if isinstance(name, object) and type(name) is not str: name.entity = self name.enabled = True setattr(self, camel_to_snake(name.__class__.__name__), name) self.scripts.append(name) # print('added script:', camel_to_snake(name.__class__.__name__)) return name
def __init__(self, add_to_scene_entities=True, **kwargs): super().__init__(self.__class__.__name__) self.name = camel_to_snake(self.type) self.enabled = True self.visible = True self.ignore = False # if True, will not try to run code self.eternal = False # eternal entities does not get destroyed on scene.clear() self.ignore_paused = False self.ignore_input = False self.parent = scene if add_to_scene_entities: scene.entities.append(self) self.model = None self.color = color.white self.texture = None # tries to set to camel_to_snake(self.type) self.reflection_map = scene.reflection_map self.reflectivity = 0 self.texture = camel_to_snake(self.type) self.render_queue = 0 self.double_sided = False self.collision = False self.collider = None self.scripts = list() self.animations = list() self.hovered = False # self.origin = Vec3(0,0,0) self.position = Vec3(0,0,0) # can also set self.x, self.y, self.z self.rotation = Vec3(0,0,0) # can also set self.rotation_x, self.rotation_y, self.rotation_z self.scale = Vec3(1,1,1) # can also set self.scale_x, self.scale_y, self.scale_z self.line_definition = None if application.trace_entity_definition: from inspect import getframeinfo, stack caller = getframeinfo(stack()[1][0]) self.line_definition = f'{Path(caller.filename).name} -> {caller.lineno} -> {caller.code_context}' for key, value in kwargs.items(): setattr(self, key, value)
def ursina_mesh_to_obj(mesh, name='', out_path=application.models_folder, max_decimals=3): from ursina.string_utilities import camel_to_snake if not name: name = camel_to_snake(mesh.__class__.__name__) obj = 'o ' + name + '\n' for v in mesh.vertices: v = [round(e, max_decimals) for e in v] obj += f'v {v[0]} {v[1]} {v[2]}\n' if mesh.uvs: for uv in mesh.uvs: uv = [round(e, max_decimals) for e in uv] obj += f'vt {uv[0]} {uv[1]}\n' obj += 's off\n' if mesh.triangles: tris = mesh.triangles if isinstance(tris[0], tuple): # convert from tuples to flat new_tris = list() for t in tris: if len(t) == 3: new_tris.extend([t[0], t[1], t[2]]) elif len(t) == 4: # turn quad into tris new_tris.extend([t[0], t[1], t[2], t[2], t[3], t[0]]) tris = new_tris if mesh.mode == 'ngon': tris = list() for i in range(1, len(mesh.vertices)-1): tris.extend((i, i+1, 0)) # tris must be a list of indices for i, t in enumerate(tris): if i % 3 == 0: obj += '\nf ' obj += str(t+1) if mesh.uvs: obj += '/'+str(t+1) obj += ' ' # print(obj) with open(out_path / (name + '.obj'), 'w') as f: f.write(obj) print('saved obj:', out_path / (name + '.obj'))
def __init__(self, add_to_scene_entities=True, **kwargs): super().__init__(self.__class__.__name__) self.name = camel_to_snake(self.type) self.enabled = True # disabled entities wil not be visible nor run code self.visible = True self.ignore = False # if True, will not try to run code self.eternal = False # eternal entities does not get destroyed on scene.clear() self.ignore_paused = False self.ignore_input = False self.parent = scene self.add_to_scene_entities = add_to_scene_entities # set to False to be ignored by the engine, but still get rendered. if add_to_scene_entities: scene.entities.append(self) self.model = None # set model with model='model_name' (without file type extention) self.color = color.white self.texture = None # set model with texture='texture_name'. requires a model to be set beforehand. self.reflection_map = scene.reflection_map self.reflectivity = 0 self.render_queue = 0 self.double_sided = False self.shader = Entity.default_shader # self.always_on_top = False self.collision = False # toggle collision without changing collider. self.collider = None # set to 'box'/'sphere'/'mesh' for auto fitted collider. self.scripts = list() # add with add_script(class_instance). will assign an 'entity' variable to the script. self.animations = list() self.hovered = False # will return True if mouse hovers entity. self.origin = Vec3(0,0,0) self.position = Vec3(0,0,0) # right, up, forward. can also set self.x, self.y, self.z self.rotation = Vec3(0,0,0) # can also set self.rotation_x, self.rotation_y, self.rotation_z self.scale = Vec3(1,1,1) # can also set self.scale_x, self.scale_y, self.scale_z self.line_definition = None # returns a Traceback(filename, lineno, function, code_context, index). if application.trace_entity_definition and add_to_scene_entities: from inspect import getframeinfo, stack _stack = stack() caller = getframeinfo(_stack[1][0]) if len(_stack) > 2 and _stack[1].code_context and 'super().__init__()' in _stack[1].code_context[0]: caller = getframeinfo(_stack[2][0]) self.line_definition = caller if caller.code_context: self.code_context = caller.code_context[0] if (self.code_context.count('(') == self.code_context.count(')') and ' = ' in self.code_context and not 'name=' in self.code_context and not 'Ursina()' in self.code_context): self.name = self.code_context.split(' = ')[0].strip().replace('self.', '') # print('set name to:', self.code_context.split(' = ')[0].strip().replace('self.', '')) if application.print_entity_definition: print(f'{Path(caller.filename).name} -> {caller.lineno} -> {caller.code_context}') for key, value in kwargs.items(): setattr(self, key, value)
def __init__(self, add_to_scene_entities=True, **kwargs): super().__init__(self.__class__.__name__) self.name = camel_to_snake(self.type) self.enabled = True # disabled entities will not be visible nor run code. self.visible = True self.ignore = False # if True, will not try to run code. self.eternal = False # eternal entities does not get destroyed on scene.clear() self.ignore_paused = False # if True, will still run when application is paused. useful when making a pause menu for example. self.ignore_input = False self.parent = scene # default parent is scene, which means it's in 3d space. to use UI space, set the parent to camera.ui instead. self.add_to_scene_entities = add_to_scene_entities # set to False to be ignored by the engine, but still get rendered. if add_to_scene_entities: scene.entities.append(self) self.model = None # set model with model='model_name' (without file type extension) self.color = color.white self.texture = None # set model with texture='texture_name'. requires a model to be set beforehand. self.render_queue = 0 self.double_sided = False if Entity.default_shader: self.shader = Entity.default_shader self.collision = False # toggle collision without changing collider. self.collider = None # set to 'box'/'sphere'/'mesh' for auto fitted collider. self.scripts = [ ] # add with add_script(class_instance). will assign an 'entity' variable to the script. self.animations = [] self.hovered = False # will return True if mouse hovers entity. self.origin = Vec3(0, 0, 0) self.position = Vec3( 0, 0, 0) # right, up, forward. can also set self.x, self.y, self.z self.rotation = Vec3( 0, 0, 0 ) # can also set self.rotation_x, self.rotation_y, self.rotation_z self.scale = Vec3( 1, 1, 1) # can also set self.scale_x, self.scale_y, self.scale_z self.line_definition = None # returns a Traceback(filename, lineno, function, code_context, index). if application.trace_entity_definition and add_to_scene_entities: from inspect import getframeinfo, stack _stack = stack() caller = getframeinfo(_stack[1][0]) if len(_stack) > 2 and _stack[ 1].code_context and 'super().__init__()' in _stack[ 1].code_context[0]: caller = getframeinfo(_stack[2][0]) self.line_definition = caller if caller.code_context: self.code_context = caller.code_context[0] if (self.code_context.count('(') == self.code_context.count(')') and ' = ' in self.code_context and not 'name=' in self.code_context and not 'Ursina()' in self.code_context): self.name = self.code_context.split( ' = ')[0].strip().replace('self.', '') # print('set name to:', self.code_context.split(' = ')[0].strip().replace('self.', '')) if application.print_entity_definition: print( f'{Path(caller.filename).name} -> {caller.lineno} -> {caller.code_context}' ) # make sure things get set in the correct order. both colliders and texture need the model to be set first. for key in ('model', 'origin', 'origin_x', 'origin_y', 'origin_z', 'collider', 'shader', 'texture', 'texture_scale', 'texture_offset'): if key in kwargs: setattr(self, key, kwargs[key]) del kwargs[key] for key, value in kwargs.items(): setattr(self, key, value) if self.enabled and hasattr(self, 'on_enable'): if isinstance(self.on_enable, Sequence): self.on_enable.start() elif callable(self.on_enable): self.on_enable() elif not self.enabled and hasattr(self, 'on_disable'): if isinstance(self.on_disable, Sequence): self.on_disable.start() elif callable(self.on_disable): self.on_disable()