basilisk-engine 0.1.3__py3-none-any.whl → 0.1.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of basilisk-engine might be problematic. Click here for more details.

Files changed (86) hide show
  1. basilisk/__init__.py +13 -12
  2. basilisk/bsk_assets/cube.obj +48 -48
  3. basilisk/collisions/broad/broad_aabb.py +102 -102
  4. basilisk/collisions/broad/broad_bvh.py +137 -137
  5. basilisk/collisions/collider.py +95 -95
  6. basilisk/collisions/collider_handler.py +225 -225
  7. basilisk/collisions/narrow/contact_manifold.py +90 -90
  8. basilisk/collisions/narrow/dataclasses.py +32 -32
  9. basilisk/collisions/narrow/deprecated.py +46 -46
  10. basilisk/collisions/narrow/epa.py +91 -91
  11. basilisk/collisions/narrow/gjk.py +66 -66
  12. basilisk/collisions/narrow/graham_scan.py +24 -24
  13. basilisk/collisions/narrow/helper.py +29 -29
  14. basilisk/collisions/narrow/line_intersections.py +106 -106
  15. basilisk/collisions/narrow/sutherland_hodgman.py +75 -75
  16. basilisk/config.py +2 -2
  17. basilisk/draw/draw.py +100 -100
  18. basilisk/draw/draw_handler.py +179 -179
  19. basilisk/draw/font_renderer.py +28 -28
  20. basilisk/engine.py +200 -195
  21. basilisk/generic/abstract_bvh.py +15 -15
  22. basilisk/generic/abstract_custom.py +133 -133
  23. basilisk/generic/collisions.py +70 -70
  24. basilisk/generic/input_validation.py +66 -66
  25. basilisk/generic/math.py +6 -6
  26. basilisk/generic/matrices.py +33 -33
  27. basilisk/generic/meshes.py +72 -72
  28. basilisk/generic/quat.py +137 -137
  29. basilisk/generic/quat_methods.py +7 -7
  30. basilisk/generic/raycast_result.py +23 -23
  31. basilisk/generic/vec3.py +143 -143
  32. basilisk/input/mouse.py +61 -61
  33. basilisk/input/path.py +14 -0
  34. basilisk/mesh/cube.py +33 -33
  35. basilisk/mesh/mesh.py +230 -230
  36. basilisk/mesh/mesh_from_data.py +130 -132
  37. basilisk/mesh/model.py +271 -271
  38. basilisk/mesh/narrow_aabb.py +89 -89
  39. basilisk/mesh/narrow_bvh.py +91 -91
  40. basilisk/mesh/narrow_primative.py +23 -23
  41. basilisk/nodes/helper.py +28 -28
  42. basilisk/nodes/node.py +680 -680
  43. basilisk/nodes/node_handler.py +95 -95
  44. basilisk/particles/particle_handler.py +63 -63
  45. basilisk/particles/particle_renderer.py +87 -87
  46. basilisk/physics/impulse.py +112 -112
  47. basilisk/physics/physics_body.py +43 -43
  48. basilisk/physics/physics_engine.py +35 -35
  49. basilisk/render/batch.py +86 -86
  50. basilisk/render/camera.py +204 -204
  51. basilisk/render/chunk.py +99 -99
  52. basilisk/render/chunk_handler.py +154 -154
  53. basilisk/render/frame.py +99 -182
  54. basilisk/render/framebuffer.py +106 -0
  55. basilisk/render/image.py +87 -75
  56. basilisk/render/image_handler.py +122 -122
  57. basilisk/render/light.py +96 -96
  58. basilisk/render/light_handler.py +58 -58
  59. basilisk/render/material.py +219 -219
  60. basilisk/render/material_handler.py +135 -135
  61. basilisk/render/post_process.py +133 -0
  62. basilisk/render/shader.py +109 -109
  63. basilisk/render/shader_handler.py +79 -79
  64. basilisk/render/sky.py +120 -120
  65. basilisk/scene.py +256 -250
  66. basilisk/shaders/batch.frag +276 -276
  67. basilisk/shaders/batch.vert +115 -115
  68. basilisk/shaders/crt.frag +32 -0
  69. basilisk/shaders/draw.frag +21 -21
  70. basilisk/shaders/draw.vert +21 -21
  71. basilisk/shaders/filter.frag +22 -22
  72. basilisk/shaders/frame.frag +12 -12
  73. basilisk/shaders/frame.vert +13 -13
  74. basilisk/shaders/geometry.frag +8 -8
  75. basilisk/shaders/geometry.vert +41 -41
  76. basilisk/shaders/normal.frag +59 -59
  77. basilisk/shaders/normal.vert +96 -96
  78. basilisk/shaders/particle.frag +71 -71
  79. basilisk/shaders/particle.vert +84 -84
  80. basilisk/shaders/sky.frag +9 -9
  81. basilisk/shaders/sky.vert +13 -13
  82. {basilisk_engine-0.1.3.dist-info → basilisk_engine-0.1.5.dist-info}/METADATA +38 -45
  83. basilisk_engine-0.1.5.dist-info/RECORD +101 -0
  84. {basilisk_engine-0.1.3.dist-info → basilisk_engine-0.1.5.dist-info}/WHEEL +1 -1
  85. basilisk_engine-0.1.3.dist-info/RECORD +0 -97
  86. {basilisk_engine-0.1.3.dist-info → basilisk_engine-0.1.5.dist-info}/top_level.txt +0 -0
basilisk/scene.py CHANGED
@@ -1,251 +1,257 @@
1
- import moderngl as mgl
2
- import glm
3
-
4
- from .mesh.mesh import Mesh
5
- from .render.material import Material
6
- from .render.shader_handler import ShaderHandler
7
- from .render.material_handler import MaterialHandler
8
- from .render.light_handler import LightHandler
9
- from .render.camera import Camera, FreeCamera
10
- from .nodes.node_handler import NodeHandler
11
- from .physics.physics_engine import PhysicsEngine
12
- from .collisions.collider_handler import ColliderHandler
13
- from .draw.draw_handler import DrawHandler
14
- from .render.sky import Sky
15
- from .render.frame import Frame
16
- from .particles.particle_handler import ParticleHandler
17
- from .nodes.node import Node
18
- from .generic.collisions import moller_trumbore
19
- from .generic.raycast_result import RaycastResult
20
-
21
- class Scene():
22
- engine: any
23
- """Parent engine of the scene"""
24
- ctx: mgl.Context
25
- """Reference to the engine context"""
26
-
27
- def __init__(self) -> None:
28
- """
29
- Basilisk scene object. Contains all nodes for the scene
30
- """
31
-
32
- self.engine = None
33
- self.ctx = None
34
-
35
- self.camera = None
36
- self.shader_handler = None
37
- self.node_handler = None
38
- self.material_handler = None
39
- self.light_handler = None
40
- self.draw_handler = None
41
- self.sky = None
42
- self.frame = None
43
-
44
- def update(self) -> None:
45
- """
46
- Updates the physics and in the scene
47
- """
48
- self.particle.update()
49
- self.camera.update()
50
-
51
-
52
- self.node_handler.update()
53
- if self.engine.delta_time < 0.5: # TODO this will cause physics to slow down when on low frame rate, this is probabl;y acceptable
54
- self.collider_handler.resolve_collisions()
55
-
56
- def render(self) -> None:
57
- """
58
- Renders all the nodes with meshes in the scene
59
- """
60
-
61
- self.frame.use()
62
- self.shader_handler.write()
63
- if self.sky: self.sky.render()
64
- self.node_handler.render()
65
- self.particle.render()
66
- self.draw_handler.render()
67
-
68
- if self.engine.headless: return
69
- self.frame.render()
70
-
71
- def add(self, *objects: Node | None) -> None | Node | list:
72
- """
73
- Adds the given object(s) to the scene. Can pass in any scene objects:
74
- Argument overloads:
75
- object: Node - Adds the given node to the scene.
76
- """
77
-
78
- # List of all return values for the added objects
79
- returns = []
80
-
81
- # Loop through all objects passed in
82
- for bsk_object in objects:
83
-
84
- # Considered well defined behavior to add None
85
- if isinstance(bsk_object, type(None)):
86
- continue
87
-
88
- # Add a node to the scene
89
- elif isinstance(bsk_object, Node):
90
- returns.append(self.node_handler.add(bsk_object)); continue
91
-
92
- # Recived incompatable type
93
- else:
94
- raise ValueError(f'scene.add: Incompatable object add type {type(bsk_object)}')
95
-
96
- # Return based on what the user passed in
97
- if not returns: return None
98
- if len(returns) == 1: return returns[0]
99
- return returns
100
-
101
- def remove(self, *objects: Node | None) -> None | Node | list:
102
- """
103
- Removes the given baskilsk object from the scene
104
- """
105
-
106
- # List of all return values for the added objects
107
- returns = []
108
-
109
- # Loop through all objects passed in
110
- for bsk_object in objects:
111
-
112
- # Considered well defined behavior to remove None
113
- if isinstance(bsk_object, type(None)):
114
- continue
115
-
116
- # Remove a node from the scene
117
- elif isinstance(bsk_object, Node):
118
- returns.append(self.node_handler.remove(bsk_object)); continue
119
-
120
- # Recived incompatable type
121
- else:
122
- raise ValueError(f'scene.remove: Incompatable object remove type {type(bsk_object)}')
123
-
124
- # Return based on what the user passed in
125
- if not returns: return None
126
- if len(returns) == 1: return returns[0]
127
- return returns
128
-
129
- def set_engine(self, engine: any) -> None:
130
- """
131
- Sets the back references to the engine and creates handlers with the context
132
- """
133
-
134
- self.engine = engine
135
- self.ctx = engine.ctx
136
-
137
- self.camera = FreeCamera()
138
- self.shader_handler = ShaderHandler(self)
139
- self.material_handler = MaterialHandler(self)
140
- self.light_handler = LightHandler(self)
141
- self.physics_engine = PhysicsEngine()
142
- self.node_handler = NodeHandler(self)
143
- self.particle = ParticleHandler(self)
144
- self.collider_handler = ColliderHandler(self)
145
- self.draw_handler = DrawHandler(self)
146
- self.frame = Frame(self)
147
- self.sky = Sky(self.engine)
148
-
149
- def raycast(self, position: glm.vec3=None, forward: glm.vec3=None, max_distance: float=1e5, has_collisions: bool=None, has_physics: bool=None, tags: list[str]=[]) -> RaycastResult:
150
- """
151
- Ray cast from any posiiton and forward vector and returns a RaycastResult eith the nearest node.
152
- If no position or forward is given, uses the scene camera's current position and forward
153
- """
154
- if not position: position = self.camera.position
155
- if not forward: forward = self.camera.forward
156
- forward = glm.normalize(forward)
157
-
158
- # if we are filtering for collisions, use the broad BVH to improve performance
159
- if has_collisions:
160
- colliders = self.collider_handler.bvh.get_line_collided(position, forward)
161
- nodes = [collider.node for collider in colliders]
162
-
163
- def is_valid(node: Node) -> bool:
164
- return all([
165
- has_collisions is None or bool(node.collider) == has_collisions,
166
- has_physics is None or bool(node.physics_body) == has_physics,
167
- all(tag in node.tags for tag in tags)
168
- ])
169
-
170
- nodes: list[Node] = list(filter(lambda node: is_valid(node), nodes))
171
-
172
- # if we are not filtering for collisions, filter nodes and
173
- else: nodes = self.node_handler.get_all(collisions=has_collisions, physics=has_physics, tags=tags)
174
-
175
- # determine closest node
176
- best_distance, best_point, best_node = max_distance, None, None
177
- position_two = position + forward
178
- for node in nodes:
179
-
180
- inv_mat = glm.inverse(node.model_matrix)
181
- relative_position = inv_mat * position
182
- relative_forward = glm.normalize(inv_mat * position_two - relative_position)
183
-
184
- triangles = [node.mesh.indices[i] for i in node.mesh.get_line_collided(relative_position, relative_forward)]
185
-
186
- for triangle in triangles:
187
- intersection = moller_trumbore(relative_position, relative_forward, [node.mesh.points[i] for i in triangle])
188
- if not intersection: continue
189
- intersection = node.model_matrix * intersection
190
- distance = glm.length(intersection - position)
191
- if distance < best_distance:
192
- best_distance = distance
193
- best_point = intersection
194
- best_node = node
195
-
196
- return RaycastResult(best_node, best_point)
197
-
198
- def raycast_mouse(self, position: tuple[int, int] | glm.vec2, max_distance: float=1e5, has_collisions: bool=None, has_pshyics: bool=None, tags: list[str]=[]) -> RaycastResult:
199
- """
200
- Ray casts from the mouse position with respect to the camera. Returns the nearest node that was clicked, if none was clicked, returns None.
201
- """
202
- # derive forward vector from mouse click position
203
- position = glm.vec2(position)
204
- inv_proj, inv_view = glm.inverse(self.camera.m_proj), glm.inverse(self.camera.m_view)
205
- ndc = glm.vec4(2 * position[0] / self.engine.win_size[0] - 1, 1 - 2 * position[1] / self.engine.win_size[1], 1, 1)
206
- point = inv_proj * ndc
207
- point /= point.w
208
- forward = glm.normalize(glm.vec3(inv_view * glm.vec4(point.x, point.y, point.z, 0)))
209
-
210
- return self.raycast(
211
- position=self.camera.position,
212
- forward=forward,
213
- max_distance=max_distance,
214
- has_collisions=has_collisions,
215
- has_physics=has_pshyics,
216
- tags=tags
217
- )
218
-
219
- def get(self, position: glm.vec3=None, scale: glm.vec3=None, rotation: glm.quat=None, forward: glm.vec3=None, mesh: Mesh=None, material: Material=None, velocity: glm.vec3=None, rotational_velocity: glm.quat=None, physics: bool=None, mass: float=None, collisions: bool=None, static_friction: float=None, kinetic_friction: float=None, elasticity: float=None, collision_group: float=None, name: str=None, tags: list[str]=None,static: bool=None) -> Node:
220
- """
221
- Returns the first node with the given traits
222
- """
223
- self.node_handler.get(position, scale, rotation, forward, mesh, material, velocity, rotational_velocity, physics, mass, collisions, static_friction, kinetic_friction, elasticity, collision_group, name, tags, static)
224
-
225
- def get_all(self, position: glm.vec3=None, scale: glm.vec3=None, rotation: glm.quat=None, forward: glm.vec3=None, mesh: Mesh=None, material: Material=None, velocity: glm.vec3=None, rotational_velocity: glm.quat=None, physics: bool=None, mass: float=None, collisions: bool=None, static_friction: float=None, kinetic_friction: float=None, elasticity: float=None, collision_group: float=None, name: str=None, tags: list[str]=None,static: bool=None) -> list[Node]:
226
- """
227
- Returns all nodes with the given traits
228
- """
229
- self.node_handler.get_all(position, scale, rotation, forward, mesh, material, velocity, rotational_velocity, physics, mass, collisions, static_friction, kinetic_friction, elasticity, collision_group, name, tags, static)
230
-
231
- @property
232
- def camera(self): return self._camera
233
- @property
234
- def sky(self): return self._sky
235
- @property
236
- def nodes(self): return self.node_handler.nodes
237
-
238
- @camera.setter
239
- def camera(self, value: Camera):
240
- if not value: return
241
- if not isinstance(value, Camera):
242
- raise TypeError(f'Scene: Invalid camera type: {type(value)}. Expected type bsk.Camera')
243
- self._camera = value
244
- self._camera.scene = self
245
-
246
- @sky.setter
247
- def sky(self, value: Sky):
248
- if not isinstance(value, Sky) and not isinstance(value, type(None)):
249
- raise TypeError(f'Scene: Invalid sky type: {type(value)}. Expected type bsk.Sky or None')
250
- self._sky = value
1
+ import moderngl as mgl
2
+ import glm
3
+
4
+ from .mesh.mesh import Mesh
5
+ from .render.material import Material
6
+ from .render.shader_handler import ShaderHandler
7
+ from .render.material_handler import MaterialHandler
8
+ from .render.light_handler import LightHandler
9
+ from .render.camera import Camera, FreeCamera
10
+ from .nodes.node_handler import NodeHandler
11
+ from .physics.physics_engine import PhysicsEngine
12
+ from .collisions.collider_handler import ColliderHandler
13
+ from .draw.draw_handler import DrawHandler
14
+ from .render.sky import Sky
15
+ from .render.frame import Frame
16
+ from .particles.particle_handler import ParticleHandler
17
+ from .nodes.node import Node
18
+ from .generic.collisions import moller_trumbore
19
+ from .generic.raycast_result import RaycastResult
20
+ from .render.post_process import PostProcess
21
+
22
+ class Scene():
23
+ engine: any
24
+ """Parent engine of the scene"""
25
+ ctx: mgl.Context
26
+ """Reference to the engine context"""
27
+
28
+ def __init__(self) -> None:
29
+ """
30
+ Basilisk scene object. Contains all nodes for the scene
31
+ """
32
+
33
+ self.engine = None
34
+ self.ctx = None
35
+
36
+ self.camera = None
37
+ self.shader_handler = None
38
+ self.node_handler = None
39
+ self.material_handler = None
40
+ self.light_handler = None
41
+ self.draw_handler = None
42
+ self.sky = None
43
+ self.frame = None
44
+
45
+ def update(self) -> None:
46
+ """
47
+ Updates the physics and in the scene
48
+ """
49
+ self.particle.update()
50
+ self.camera.update()
51
+
52
+
53
+ self.node_handler.update()
54
+ if self.engine.delta_time < 0.5: # TODO this will cause physics to slow down when on low frame rate, this is probabl;y acceptable
55
+ self.collider_handler.resolve_collisions()
56
+
57
+ def render(self) -> None:
58
+ """
59
+ Renders all the nodes with meshes in the scene
60
+ """
61
+
62
+ self.frame.use()
63
+ self.shader_handler.write()
64
+ if self.sky: self.sky.render()
65
+ self.node_handler.render()
66
+ self.particle.render()
67
+ self.draw_handler.render()
68
+
69
+ if self.engine.headless: return
70
+ self.frame.render()
71
+
72
+ def add(self, *objects: Node | None) -> None | Node | list:
73
+ """
74
+ Adds the given object(s) to the scene. Can pass in any scene objects:
75
+ Argument overloads:
76
+ object: Node - Adds the given node to the scene.
77
+ """
78
+
79
+ # List of all return values for the added objects
80
+ returns = []
81
+
82
+ # Loop through all objects passed in
83
+ for bsk_object in objects:
84
+
85
+ # Considered well defined behavior to add None
86
+ if isinstance(bsk_object, type(None)):
87
+ continue
88
+
89
+ # Add a node to the scene
90
+ elif isinstance(bsk_object, Node):
91
+ returns.append(self.node_handler.add(bsk_object)); continue
92
+
93
+ # Add a node to the scene
94
+ elif isinstance(bsk_object, PostProcess):
95
+ returns.append(self.frame.add_post_process(bsk_object)); continue
96
+
97
+
98
+ # Recived incompatable type
99
+ else:
100
+ raise ValueError(f'scene.add: Incompatable object add type {type(bsk_object)}')
101
+
102
+ # Return based on what the user passed in
103
+ if not returns: return None
104
+ if len(returns) == 1: return returns[0]
105
+ return returns
106
+
107
+ def remove(self, *objects: Node | None) -> None | Node | list:
108
+ """
109
+ Removes the given baskilsk object from the scene
110
+ """
111
+
112
+ # List of all return values for the added objects
113
+ returns = []
114
+
115
+ # Loop through all objects passed in
116
+ for bsk_object in objects:
117
+
118
+ # Considered well defined behavior to remove None
119
+ if isinstance(bsk_object, type(None)):
120
+ continue
121
+
122
+ # Remove a node from the scene
123
+ elif isinstance(bsk_object, Node):
124
+ returns.append(self.node_handler.remove(bsk_object)); continue
125
+
126
+ # Recived incompatable type
127
+ else:
128
+ raise ValueError(f'scene.remove: Incompatable object remove type {type(bsk_object)}')
129
+
130
+ # Return based on what the user passed in
131
+ if not returns: return None
132
+ if len(returns) == 1: return returns[0]
133
+ return returns
134
+
135
+ def set_engine(self, engine: any) -> None:
136
+ """
137
+ Sets the back references to the engine and creates handlers with the context
138
+ """
139
+
140
+ self.engine = engine
141
+ self.ctx = engine.ctx
142
+
143
+ self.camera = FreeCamera()
144
+ self.shader_handler = ShaderHandler(self)
145
+ self.material_handler = MaterialHandler(self)
146
+ self.light_handler = LightHandler(self)
147
+ self.physics_engine = PhysicsEngine()
148
+ self.node_handler = NodeHandler(self)
149
+ self.particle = ParticleHandler(self)
150
+ self.collider_handler = ColliderHandler(self)
151
+ self.draw_handler = DrawHandler(self)
152
+ self.frame = Frame(self)
153
+ self.sky = Sky(self.engine)
154
+
155
+ def raycast(self, position: glm.vec3=None, forward: glm.vec3=None, max_distance: float=1e5, has_collisions: bool=None, has_physics: bool=None, tags: list[str]=[]) -> RaycastResult:
156
+ """
157
+ Ray cast from any posiiton and forward vector and returns a RaycastResult eith the nearest node.
158
+ If no position or forward is given, uses the scene camera's current position and forward
159
+ """
160
+ if not position: position = self.camera.position
161
+ if not forward: forward = self.camera.forward
162
+ forward = glm.normalize(forward)
163
+
164
+ # if we are filtering for collisions, use the broad BVH to improve performance
165
+ if has_collisions:
166
+ colliders = self.collider_handler.bvh.get_line_collided(position, forward)
167
+ nodes = [collider.node for collider in colliders]
168
+
169
+ def is_valid(node: Node) -> bool:
170
+ return all([
171
+ has_collisions is None or bool(node.collider) == has_collisions,
172
+ has_physics is None or bool(node.physics_body) == has_physics,
173
+ all(tag in node.tags for tag in tags)
174
+ ])
175
+
176
+ nodes: list[Node] = list(filter(lambda node: is_valid(node), nodes))
177
+
178
+ # if we are not filtering for collisions, filter nodes and
179
+ else: nodes = self.node_handler.get_all(collisions=has_collisions, physics=has_physics, tags=tags)
180
+
181
+ # determine closest node
182
+ best_distance, best_point, best_node = max_distance, None, None
183
+ position_two = position + forward
184
+ for node in nodes:
185
+
186
+ inv_mat = glm.inverse(node.model_matrix)
187
+ relative_position = inv_mat * position
188
+ relative_forward = glm.normalize(inv_mat * position_two - relative_position)
189
+
190
+ triangles = [node.mesh.indices[i] for i in node.mesh.get_line_collided(relative_position, relative_forward)]
191
+
192
+ for triangle in triangles:
193
+ intersection = moller_trumbore(relative_position, relative_forward, [node.mesh.points[i] for i in triangle])
194
+ if not intersection: continue
195
+ intersection = node.model_matrix * intersection
196
+ distance = glm.length(intersection - position)
197
+ if distance < best_distance:
198
+ best_distance = distance
199
+ best_point = intersection
200
+ best_node = node
201
+
202
+ return RaycastResult(best_node, best_point)
203
+
204
+ def raycast_mouse(self, position: tuple[int, int] | glm.vec2, max_distance: float=1e5, has_collisions: bool=None, has_pshyics: bool=None, tags: list[str]=[]) -> RaycastResult:
205
+ """
206
+ Ray casts from the mouse position with respect to the camera. Returns the nearest node that was clicked, if none was clicked, returns None.
207
+ """
208
+ # derive forward vector from mouse click position
209
+ position = glm.vec2(position)
210
+ inv_proj, inv_view = glm.inverse(self.camera.m_proj), glm.inverse(self.camera.m_view)
211
+ ndc = glm.vec4(2 * position[0] / self.engine.win_size[0] - 1, 1 - 2 * position[1] / self.engine.win_size[1], 1, 1)
212
+ point = inv_proj * ndc
213
+ point /= point.w
214
+ forward = glm.normalize(glm.vec3(inv_view * glm.vec4(point.x, point.y, point.z, 0)))
215
+
216
+ return self.raycast(
217
+ position=self.camera.position,
218
+ forward=forward,
219
+ max_distance=max_distance,
220
+ has_collisions=has_collisions,
221
+ has_physics=has_pshyics,
222
+ tags=tags
223
+ )
224
+
225
+ def get(self, position: glm.vec3=None, scale: glm.vec3=None, rotation: glm.quat=None, forward: glm.vec3=None, mesh: Mesh=None, material: Material=None, velocity: glm.vec3=None, rotational_velocity: glm.quat=None, physics: bool=None, mass: float=None, collisions: bool=None, static_friction: float=None, kinetic_friction: float=None, elasticity: float=None, collision_group: float=None, name: str=None, tags: list[str]=None,static: bool=None) -> Node:
226
+ """
227
+ Returns the first node with the given traits
228
+ """
229
+ self.node_handler.get(position, scale, rotation, forward, mesh, material, velocity, rotational_velocity, physics, mass, collisions, static_friction, kinetic_friction, elasticity, collision_group, name, tags, static)
230
+
231
+ def get_all(self, position: glm.vec3=None, scale: glm.vec3=None, rotation: glm.quat=None, forward: glm.vec3=None, mesh: Mesh=None, material: Material=None, velocity: glm.vec3=None, rotational_velocity: glm.quat=None, physics: bool=None, mass: float=None, collisions: bool=None, static_friction: float=None, kinetic_friction: float=None, elasticity: float=None, collision_group: float=None, name: str=None, tags: list[str]=None,static: bool=None) -> list[Node]:
232
+ """
233
+ Returns all nodes with the given traits
234
+ """
235
+ self.node_handler.get_all(position, scale, rotation, forward, mesh, material, velocity, rotational_velocity, physics, mass, collisions, static_friction, kinetic_friction, elasticity, collision_group, name, tags, static)
236
+
237
+ @property
238
+ def camera(self): return self._camera
239
+ @property
240
+ def sky(self): return self._sky
241
+ @property
242
+ def nodes(self): return self.node_handler.nodes
243
+
244
+ @camera.setter
245
+ def camera(self, value: Camera):
246
+ if not value: return
247
+ if not isinstance(value, Camera):
248
+ raise TypeError(f'Scene: Invalid camera type: {type(value)}. Expected type bsk.Camera')
249
+ self._camera = value
250
+ self._camera.scene = self
251
+
252
+ @sky.setter
253
+ def sky(self, value: Sky):
254
+ if not isinstance(value, Sky) and not isinstance(value, type(None)):
255
+ raise TypeError(f'Scene: Invalid sky type: {type(value)}. Expected type bsk.Sky or None')
256
+ self._sky = value
251
257
  if value: self._sky.write()