Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
petteramland committed Jan 24, 2024
2 parents 9905c45 + b938d6e commit 789217d
Show file tree
Hide file tree
Showing 12 changed files with 184 additions and 142 deletions.
47 changes: 18 additions & 29 deletions ursina/collider.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,18 @@


class Collider(NodePath):
def __init__(self):
super().__init__('box_collider')
self._visible = False
def __init__(self, entity, shape):
super().__init__('collider')
self.collision_node = CollisionNode('CollisionNode')

self.shape = shape
self.node_path = entity.attachNewNode(self.collision_node)

if isinstance(shape, (list, tuple)):
for e in shape:
self.node_path.node().addSolid(e)
else:
self.node_path.node().addSolid(self.shape)


def remove(self):
Expand All @@ -32,54 +41,37 @@ def visible(self, value):

class BoxCollider(Collider):
def __init__(self, entity, center=(0,0,0), size=(1,1,1)):
super().__init__()
self.center = center
self.size = size

size = [e/2 for e in size]
size = [max(0.001, e) for e in size] # collider needs to have thickness
self.shape = CollisionBox(Vec3(center[0], center[1], center[2]), size[0], size[1], size[2])
# self.remove()
self.collision_node = CollisionNode('CollisionNode')
self.node_path = entity.attachNewNode(self.collision_node)
self.node_path.node().addSolid(self.shape)
self.visible = False
# self.node_path.show()
# for some reason self.node_path gets removed after this and can't be shown.
super().__init__(entity, CollisionBox(Vec3(center[0], center[1], center[2]), size[0], size[1], size[2]))


class SphereCollider(Collider):
def __init__(self, entity, center=(0,0,0), radius=.5):
self.center = center
self.radius = radius
super().__init__()
self.shape = CollisionSphere(center[0], center[1], center[2], radius)
self.node_path = entity.attachNewNode(CollisionNode('CollisionNode'))
self.node_path.node().addSolid(self.shape)
self.visible = False
super().__init__(entity, CollisionSphere(center[0], center[1], center[2], radius))


class CapsuleCollider(Collider):
def __init__(self, entity, center=(0,0,0), height=2, radius=.5):
self.center = center
self.height = height
self.radius = radius
super().__init__()
self.shape = CollisionCapsule(center[0], center[1] + radius, center[2], center[0], center[1] + height, center[2], radius)
self.node_path = entity.attachNewNode(CollisionNode('CollisionNode'))
self.node_path.node().addSolid(self.shape)
self.visible = False
super().__init__(entity, CollisionCapsule(center[0], center[1] + radius, center[2], center[0], center[1] + height, center[2], radius))


class MeshCollider(Collider):
def __init__(self, entity, mesh=None, center=(0,0,0)):
self.center = center
super().__init__()
center = Vec3(center)
if mesh is None and entity.model:
mesh = entity.model
# print('''auto generating mesh collider from entity's mesh''')

self.node_path = entity.attachNewNode(CollisionNode('CollisionNode'))
self.collision_polygons = []

if isinstance(mesh, Mesh):
Expand Down Expand Up @@ -132,11 +124,7 @@ def __init__(self, entity, mesh=None, center=(0,0,0)):
p = CollisionPolygon(Vec3(verts[i+2]), Vec3(verts[i+1]), Vec3(verts[i]))
self.collision_polygons.append(p)


node = self.node_path.node()
for poly in self.collision_polygons:
node.addSolid(poly)
self.visible = False
super().__init__(entity, self.collision_polygons)


def remove(self):
Expand All @@ -145,6 +133,7 @@ def remove(self):
self.node_path.removeNode()



if __name__ == '__main__':
from ursina import *
from ursina import Ursina, Entity, Pipe, Circle, Button, scene, EditorCamera, color
Expand Down
12 changes: 12 additions & 0 deletions ursina/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,14 @@ def set_shader_input(self, name, value):
super().set_shader_input(name, value)


def shader_input_getter(self):
return self._shader_inputs

def shader_input_setter(self, value):
for key, value in value.items():
self.set_shader_input(key, value)


def texture_getter(self):
return getattr(self, '_texture', None)

Expand Down Expand Up @@ -804,6 +812,10 @@ def unlit_getter(self):
def unlit_setter(self, value):
self._unlit = value
self.setLightOff(value)
if value:
self.hide(0b0001)
else:
self.show(0b0001)

def billboard_getter(self): # set to True to make this Entity always face the camera.
return getattr(self, '_billboard', False)
Expand Down
53 changes: 35 additions & 18 deletions ursina/input_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,29 @@ def __eq__(self, other):


def bind(original_key, alternative_key):
rebinds[original_key] = alternative_key
if not original_key in rebinds:
rebinds[original_key] = {original_key, }

rebinds[original_key].add(alternative_key)


if ' mouse ' in alternative_key:
rebinds[original_key + ' up'] = alternative_key[:-5] + ' up'
if not rebinds.get(f'{original_key} up'):
rebinds[f'{original_key} up'] = {original_key, }
rebinds[f'{original_key} up'].add(f'{alternative_key[:-5]} up')
return

rebinds[original_key + ' hold'] = alternative_key + ' hold'
rebinds[original_key + ' up'] = alternative_key + ' up'

if not rebinds.get(f'{original_key} hold'):
rebinds[f'{original_key} hold'] = {f'{original_key} hold', }
rebinds[f'{original_key} hold'].add(f'{alternative_key} hold')

if not rebinds.get(f'{original_key} up'):
rebinds[f'{original_key} up'] = {f'{original_key} up', }
rebinds[f'{original_key} up'].add(f'{alternative_key} up')

# rebinds[original_key + ' hold'] = alternative_key + ' hold'
# rebinds[original_key + ' up'] = alternative_key + ' up'

def unbind(key):
if key in rebinds:
Expand Down Expand Up @@ -144,25 +159,27 @@ def get_combined_key(key):
from ursina import *
from ursina import Ursina, input_handler

app = Ursina()
input_handler.rebind('z', 'w') # 'z'-key will now be registered as 'w'-key
app = Ursina(borderless=False)
input_handler.bind('z', 'w') # 'z'-key will now be registered as 'w'-key
input_handler.bind('left mouse down', 'attack') # 'left mouse down'-key will now send 'attack'to input functions
input_handler.bind('gamepad b', 'attack') # 'gamepad b'-key will now be registered as 'attack'-key


def test():
print('----')
# input_handler.rebind('a', 'f')
def input(key):
print(key)
if key == 'left mouse down':
print('pressed left mouse button')
print('got key:', key)
if key == 'attack':
destroy(Entity(model='cube', color=color.blue), delay=.2)
# if key == 'left mouse down':
# print('pressed left mouse button')

if key == Keys.left_mouse_down: # same as above, but with Keys enum.
print('pressed left mouse button')
# if key == Keys.left_mouse_down: # same as above, but with Keys enum.
# print('pressed left mouse button')


def update():
for key, value in held_keys.items():
if value != 0:
print(key, value)
# def update():
# for key, value in held_keys.items():
# if value != 0:
# print(key, value)



Expand Down
55 changes: 34 additions & 21 deletions ursina/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,36 +233,49 @@ def input(self, key, is_raw=False): # internal method for handling input
if key in self._input_name_changes:
key = self._input_name_changes[key]

if key in input_handler.rebinds:
key = input_handler.rebinds[key]
# since we can rebind one key to multiple, get a list of keys
bound_keys = input_handler.rebinds.get(key, (key, ))

input_handler.input(key)
for key in bound_keys:
input_handler.input(key)

if not application.paused:
if hasattr(__main__, 'input'):
__main__.input(key)

for e in scene.entities:
if e.enabled is False or e.ignore or e.ignore_input:
continue
if application.paused and e.ignore_paused is False:
continue
if e.has_disabled_ancestor():
continue
for key in bound_keys:
__main__.input(key)

for e in scene.entities:
if e.enabled is False or e.ignore or e.ignore_input:
continue
if application.paused and e.ignore_paused is False:
continue
if e.has_disabled_ancestor():
continue


if hasattr(e, 'input') and callable(e.input):
break_outer = False
for key in bound_keys:
if break_outer:
break
if e.input(key): # if the input function returns True, eat the input
break_outer = True


if hasattr(e, 'input') and callable(e.input):
if e.input(key):
break
if hasattr(e, 'scripts'):
break_outer = False
if break_outer:
break

if hasattr(e, 'scripts'):
for script in e.scripts:
if script.enabled and hasattr(script, 'input') and callable(script.input):
if script.input(key):
break
for script in e.scripts:
if script.enabled and hasattr(script, 'input') and callable(script.input):
for key in bound_keys:
if script.input(key): # if the input function returns True, eat the input
break_outer = True
break


mouse.input(key)
mouse.input(key)


def text_input(self, key): # internal method for handling text input
Expand Down
6 changes: 4 additions & 2 deletions ursina/mesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,10 @@ def _set_array_data(self, array_handle, data, dtype_string='f'):
a = array.array(dtype_string, data)

vmem = memoryview(array_handle).cast('B').cast(dtype_string)
vmem[:] = a

try:
vmem[:] = a
except:
raise Exception(f'Error in Mesh. Ensure Mesh is valid and the inputs have same length: vertices:{len(self.vertices)}, triangles:{len(self.triangles)}, normals:{len(self.normals)}, colors:{len(self.colors)}, uvs:{len(self.uvs)}')

def generate(self):
self._generated_vertices = None
Expand Down
40 changes: 15 additions & 25 deletions ursina/prefabs/file_browser_save.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,38 @@
from ursina.prefabs.file_browser import FileBrowser


@generate_properties_for_class()
class FileBrowserSave(FileBrowser):
def __init__(self, **kwargs):
super().__init__()

self.save_button = self.open_button
self.save_button.color = color.azure
self.save_button.text = 'Save'
self.save_button.on_click = self.save
self.file_name_field = InputField(
parent = self,
scale_x = .75,
scale_y = self.save_button.scale_y,
y = self.save_button.y,
active = True,
)
# self.file_name_field.text_field.scale *= .6
self.save_button.on_click = self._save
self.file_name_field = InputField(parent=self, scale_x=.75, scale_y=self.save_button.scale_y, y=self.save_button.y, active=True)
self.save_button.y -= .075
self.cancel_button.y -= .075
self.file_name_field.text_field.text = ''
self.file_type = '' # to save as

self.data = ''
self.last_saved_file = None # gets set when you save a file
self.overwrite_prompt = WindowPanel(
content=(
Text('Overwrite?'),
Button('Yes', color=color.azure, on_click=self.save),
Button('Yes', color=color.azure, on_click=self._save),
Button('Cancel')
),
z=-1,
popup=True,
enabled=False)
), z=-1, popup=True, enabled=False)

for key, value in kwargs.items():
setattr(self, key ,value)


def file_type_setter(self, value):
self.file_types = (value, )

def save(self):

def _save(self):
file_name = self.file_name_field.text_field.text
if not file_name.endswith(self.file_type):
file_name += self.file_type
Expand All @@ -51,17 +44,14 @@ def save(self):
# print('overwrite file?')
self.overwrite_prompt.enabled = True

else:
if isinstance(self.data, str):
path.write_text(self.data)
else:
# print('write bytes')
path.write_bytes(self.data)
self.last_saved_file = path
self.overwrite_prompt.enabled = False
self.close()
self.on_submit(path)

self.last_saved_file = path
self.overwrite_prompt.enabled = False
self.close()

def on_submit(self, path): # implement .on_submit to handle saving
print('save to path:', path, 'please implement .on_submit to handle saving')



Expand Down
Loading

0 comments on commit 789217d

Please sign in to comment.