basilisk-engine 0.1.24__py3-none-any.whl → 0.1.25__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 (90) hide show
  1. basilisk/__init__.py +15 -15
  2. basilisk/audio/sound.py +27 -27
  3. basilisk/bsk_assets/cube.obj +48 -48
  4. basilisk/collisions/broad/broad_aabb.py +102 -102
  5. basilisk/collisions/broad/broad_bvh.py +137 -137
  6. basilisk/collisions/collider.py +95 -95
  7. basilisk/collisions/collider_handler.py +224 -224
  8. basilisk/collisions/narrow/contact_manifold.py +95 -95
  9. basilisk/collisions/narrow/dataclasses.py +34 -34
  10. basilisk/collisions/narrow/deprecated.py +46 -46
  11. basilisk/collisions/narrow/epa.py +91 -91
  12. basilisk/collisions/narrow/gjk.py +66 -66
  13. basilisk/collisions/narrow/graham_scan.py +24 -24
  14. basilisk/collisions/narrow/helper.py +29 -29
  15. basilisk/collisions/narrow/line_intersections.py +106 -106
  16. basilisk/collisions/narrow/sutherland_hodgman.py +75 -75
  17. basilisk/config.py +3 -3
  18. basilisk/draw/draw.py +100 -100
  19. basilisk/draw/draw_handler.py +175 -175
  20. basilisk/draw/font_renderer.py +28 -28
  21. basilisk/engine.py +169 -169
  22. basilisk/generic/abstract_bvh.py +15 -15
  23. basilisk/generic/abstract_custom.py +133 -133
  24. basilisk/generic/collisions.py +72 -72
  25. basilisk/generic/input_validation.py +66 -66
  26. basilisk/generic/math.py +6 -6
  27. basilisk/generic/matrices.py +35 -35
  28. basilisk/generic/meshes.py +72 -72
  29. basilisk/generic/quat.py +142 -142
  30. basilisk/generic/quat_methods.py +7 -7
  31. basilisk/generic/raycast_result.py +26 -26
  32. basilisk/generic/vec3.py +143 -143
  33. basilisk/input_output/IO_handler.py +91 -91
  34. basilisk/input_output/clock.py +49 -49
  35. basilisk/input_output/keys.py +43 -43
  36. basilisk/input_output/mouse.py +89 -89
  37. basilisk/input_output/path.py +14 -14
  38. basilisk/mesh/cube.py +33 -33
  39. basilisk/mesh/mesh.py +233 -230
  40. basilisk/mesh/mesh_from_data.py +151 -131
  41. basilisk/mesh/model.py +271 -271
  42. basilisk/mesh/narrow_aabb.py +89 -89
  43. basilisk/mesh/narrow_bvh.py +91 -91
  44. basilisk/mesh/narrow_primative.py +23 -23
  45. basilisk/nodes/helper.py +28 -28
  46. basilisk/nodes/node.py +689 -686
  47. basilisk/nodes/node_handler.py +97 -97
  48. basilisk/particles/particle_handler.py +64 -64
  49. basilisk/particles/particle_renderer.py +92 -92
  50. basilisk/physics/impulse.py +112 -112
  51. basilisk/physics/physics_body.py +43 -43
  52. basilisk/physics/physics_engine.py +35 -35
  53. basilisk/render/batch.py +103 -105
  54. basilisk/render/camera.py +257 -257
  55. basilisk/render/chunk.py +106 -106
  56. basilisk/render/chunk_handler.py +165 -165
  57. basilisk/render/frame.py +95 -95
  58. basilisk/render/framebuffer.py +289 -289
  59. basilisk/render/image.py +87 -87
  60. basilisk/render/image_handler.py +120 -120
  61. basilisk/render/light.py +96 -96
  62. basilisk/render/light_handler.py +58 -58
  63. basilisk/render/material.py +219 -219
  64. basilisk/render/material_handler.py +131 -131
  65. basilisk/render/post_process.py +139 -139
  66. basilisk/render/shader.py +118 -109
  67. basilisk/render/shader_handler.py +83 -83
  68. basilisk/render/sky.py +120 -120
  69. basilisk/scene.py +279 -279
  70. basilisk/shaders/batch.frag +276 -276
  71. basilisk/shaders/batch.vert +115 -115
  72. basilisk/shaders/crt.frag +31 -31
  73. basilisk/shaders/draw.frag +22 -22
  74. basilisk/shaders/draw.vert +25 -25
  75. basilisk/shaders/filter.frag +22 -22
  76. basilisk/shaders/frame.frag +12 -12
  77. basilisk/shaders/frame.vert +13 -13
  78. basilisk/shaders/geometry.frag +8 -8
  79. basilisk/shaders/geometry.vert +41 -41
  80. basilisk/shaders/normal.frag +59 -59
  81. basilisk/shaders/normal.vert +96 -96
  82. basilisk/shaders/particle.frag +71 -71
  83. basilisk/shaders/particle.vert +84 -84
  84. basilisk/shaders/sky.frag +9 -9
  85. basilisk/shaders/sky.vert +13 -13
  86. {basilisk_engine-0.1.24.dist-info → basilisk_engine-0.1.25.dist-info}/METADATA +45 -38
  87. basilisk_engine-0.1.25.dist-info/RECORD +106 -0
  88. {basilisk_engine-0.1.24.dist-info → basilisk_engine-0.1.25.dist-info}/WHEEL +1 -1
  89. basilisk_engine-0.1.24.dist-info/RECORD +0 -106
  90. {basilisk_engine-0.1.24.dist-info → basilisk_engine-0.1.25.dist-info}/top_level.txt +0 -0
basilisk/render/image.py CHANGED
@@ -1,88 +1,88 @@
1
- import os
2
- import sys
3
- import numpy as np
4
- import moderngl as mgl
5
- import glm
6
- import pygame as pg
7
- from PIL import Image as PIL_Image
8
-
9
-
10
- texture_sizes = (8, 64, 512, 1024, 2048)
11
-
12
-
13
- class Image():
14
- name: str
15
- """Name of the image"""
16
- index: glm.ivec2
17
- """Location of the image in the texture arrays"""
18
- data: np.ndarray
19
- """Array of the texture data"""
20
- size: int
21
- """The width and height in pixels of the image"""
22
-
23
- def __init__(self, path: str | os.PathLike | pg.Surface | mgl.Texture) -> None:
24
- """
25
- A basilisk image object that contains a moderngl texture
26
- Args:
27
- path: str | os.PathLike | pg.Surface
28
- The string path to the image. Can also read a pygame surface
29
- """
30
-
31
- # Check if the user is loading a pygame surface
32
- if isinstance(path, str) or isinstance(path, os.PathLike):
33
- return self._from_path(path)
34
- elif isinstance(path, pg.Surface):
35
- return self._from_surface(path)
36
- elif isinstance(path, mgl.Texture):
37
- return self._from_texture(path)
38
-
39
- raise TypeError(f'Invalid path type: {type(path)}. Expected a string or os.PathLike')
40
-
41
- def _from_path(self, path: str | os.PathLike) -> None:
42
- """
43
- Loads a basilisk image from a pygame surface
44
- Args:
45
- """
46
-
47
- # Get name from path
48
- self.name = path.split('/')[-1].split('\\')[-1].split('.')[0]
49
-
50
- # Load image
51
- img = PIL_Image.open(path).convert('RGBA')
52
- # Set the size in one of the size buckets
53
- size_buckets = texture_sizes
54
- self.size = size_buckets[np.argmin(np.array([abs(size - img.size[0]) for size in size_buckets]))]
55
- img = img.resize((self.size, self.size))
56
- # Get the image data
57
- self.data = img.tobytes()
58
-
59
- # Default index value (to be set by image handler)
60
- self.index = glm.ivec2(1, 1)
61
-
62
- def _from_surface(self, surf: pg.Surface) -> None:
63
- """
64
- Loads a basilisk image from a pygame surface
65
- Args:
66
- """
67
-
68
- # Set the size in one of the size buckets
69
- size_buckets = texture_sizes
70
- self.size = size_buckets[np.argmin(np.array([abs(size - surf.get_size()[0]) for size in size_buckets]))]
71
- surf = pg.transform.scale(surf, (self.size, self.size)).convert_alpha()
72
- # Get image data
73
- self.data = pg.image.tobytes(surf, 'RGBA')
74
-
75
- # Default index value (to be set by image handler)
76
- self.index = glm.ivec2(1, 1)
77
-
78
- def _from_texture(self, texture: mgl.Texture):
79
- """
80
-
81
- """
82
- ...
83
-
84
- def __repr__(self) -> str:
85
- """
86
- Returns a string representation of the object
87
- """
1
+ import os
2
+ import sys
3
+ import numpy as np
4
+ import moderngl as mgl
5
+ import glm
6
+ import pygame as pg
7
+ from PIL import Image as PIL_Image
8
+
9
+
10
+ texture_sizes = (8, 64, 512, 1024, 2048)
11
+
12
+
13
+ class Image():
14
+ name: str
15
+ """Name of the image"""
16
+ index: glm.ivec2
17
+ """Location of the image in the texture arrays"""
18
+ data: np.ndarray
19
+ """Array of the texture data"""
20
+ size: int
21
+ """The width and height in pixels of the image"""
22
+
23
+ def __init__(self, path: str | os.PathLike | pg.Surface | mgl.Texture) -> None:
24
+ """
25
+ A basilisk image object that contains a moderngl texture
26
+ Args:
27
+ path: str | os.PathLike | pg.Surface
28
+ The string path to the image. Can also read a pygame surface
29
+ """
30
+
31
+ # Check if the user is loading a pygame surface
32
+ if isinstance(path, str) or isinstance(path, os.PathLike):
33
+ return self._from_path(path)
34
+ elif isinstance(path, pg.Surface):
35
+ return self._from_surface(path)
36
+ elif isinstance(path, mgl.Texture):
37
+ return self._from_texture(path)
38
+
39
+ raise TypeError(f'Invalid path type: {type(path)}. Expected a string or os.PathLike')
40
+
41
+ def _from_path(self, path: str | os.PathLike) -> None:
42
+ """
43
+ Loads a basilisk image from a pygame surface
44
+ Args:
45
+ """
46
+
47
+ # Get name from path
48
+ self.name = path.split('/')[-1].split('\\')[-1].split('.')[0]
49
+
50
+ # Load image
51
+ img = PIL_Image.open(path).convert('RGBA')
52
+ # Set the size in one of the size buckets
53
+ size_buckets = texture_sizes
54
+ self.size = size_buckets[np.argmin(np.array([abs(size - img.size[0]) for size in size_buckets]))]
55
+ img = img.resize((self.size, self.size))
56
+ # Get the image data
57
+ self.data = img.tobytes()
58
+
59
+ # Default index value (to be set by image handler)
60
+ self.index = glm.ivec2(1, 1)
61
+
62
+ def _from_surface(self, surf: pg.Surface) -> None:
63
+ """
64
+ Loads a basilisk image from a pygame surface
65
+ Args:
66
+ """
67
+
68
+ # Set the size in one of the size buckets
69
+ size_buckets = texture_sizes
70
+ self.size = size_buckets[np.argmin(np.array([abs(size - surf.get_size()[0]) for size in size_buckets]))]
71
+ surf = pg.transform.scale(surf, (self.size, self.size)).convert_alpha()
72
+ # Get image data
73
+ self.data = pg.image.tobytes(surf, 'RGBA')
74
+
75
+ # Default index value (to be set by image handler)
76
+ self.index = glm.ivec2(1, 1)
77
+
78
+ def _from_texture(self, texture: mgl.Texture):
79
+ """
80
+
81
+ """
82
+ ...
83
+
84
+ def __repr__(self) -> str:
85
+ """
86
+ Returns a string representation of the object
87
+ """
88
88
  return f'<Basilisk Image | {self.name}, ({self.size}x{self.size}), {sys.getsizeof(self.data) / 1024 / 1024:.2} mb>'
@@ -1,121 +1,121 @@
1
- import moderngl as mgl
2
- import glm
3
- import numpy as np
4
-
5
- texture_sizes = (8, 64, 512, 1024, 2048)
6
-
7
-
8
- class ImageHandler():
9
- engine: ...
10
- """Back refernce to the parent engine"""
11
- ctx: mgl.Context
12
- """Back reference to the Context used by the scene/engine"""
13
- images: list
14
- """List of basilisk Images containing all the loaded images given to the scene"""
15
- texture_arrays: dict
16
- """Dictionary of textures arrays for writting textures to GPU"""
17
-
18
- def __init__(self, engine) -> None:
19
- """
20
- Container for all the basilisk image objects in the scene.
21
- Handles the managment and writting of all image textures.
22
- """
23
-
24
- # Set back references
25
- self.engine = engine
26
- self.ctx = engine.ctx
27
-
28
- self.images = []
29
- self.texture_arrays = {size : [] for size in texture_sizes}
30
-
31
- def add(self, image: any) -> None:
32
- """
33
- Adds an existing basilisk image object to the handler for writting
34
- Args:
35
- image: bsk.Image
36
- The existing image that is to be added to the scene.
37
- """
38
-
39
- if image in self.images: return
40
-
41
- self.images.append(image)
42
- self.write(regenerate=True)
43
-
44
- def generate_texture_array(self) -> None:
45
- """
46
- Generates texutre arrays for all the images. Updates the index of the image instance
47
- """
48
-
49
- # Release any existsing texture arrays
50
- for texture_array in self.texture_arrays.values():
51
- if not texture_array: continue
52
- texture_array.release()
53
-
54
- self.texture_arrays = {size : [] for size in texture_sizes}
55
-
56
- for image in self.images:
57
- # Add the image data to the array
58
- self.texture_arrays[image.size].append(image.data)
59
- # Update the image index
60
- image.index = glm.ivec2(texture_sizes.index(image.size), len(self.texture_arrays[image.size]) - 1)
61
-
62
-
63
- for size in self.texture_arrays:
64
- # Check that there are textures in the bucket
65
- if not len(self.texture_arrays[size]): continue
66
- array_data = np.array(self.texture_arrays[size])
67
- dim = (size, size, len(self.texture_arrays[size]))
68
-
69
- # Make the array
70
- self.texture_arrays[size] = self.ctx.texture_array(size=dim, components=4, data=array_data)
71
- # Texture OpenGl settings
72
- self.texture_arrays[size].build_mipmaps()
73
- if size > 32: self.texture_arrays[size].filter = (mgl.LINEAR_MIPMAP_LINEAR, mgl.LINEAR)
74
- else: self.texture_arrays[size].filter = (mgl.NEAREST, mgl.NEAREST)
75
- self.texture_arrays[size].anisotropy = 32.0
76
-
77
- def write(self, regenerate=False) -> None:
78
- """
79
- Writes all texture arrays to shaders that use images
80
- """
81
-
82
- if not self.engine.shader_handler: return
83
-
84
- if regenerate: self.generate_texture_array()
85
-
86
- if not self.texture_arrays: return
87
-
88
- for shader in self.engine.shader_handler.shaders:
89
- if 'textureArrays[5]' not in shader.uniforms: continue
90
-
91
- for i, size in enumerate(texture_sizes):
92
- if not size in self.texture_arrays: continue
93
- if not self.texture_arrays[size]: continue
94
- shader.program[f'textureArrays[{i}].array'] = i + 3
95
- self.texture_arrays[size].use(location=i+3)
96
-
97
- def get(self, identifier: str | int) -> any:
98
- """
99
- Gets the basilisk image with the given name or index
100
- Args:
101
- identifier: str | int
102
- The name string or index of the desired image
103
- """
104
-
105
- # Simply use index if given
106
- if isinstance(identifier, int): return self.images[identifier]
107
-
108
- # Else, search the list for an image with the given name
109
- for image in self.images:
110
- if image.name != identifier: continue
111
- return image
112
-
113
- # No matching image found
114
- return None
115
-
116
- def __del__(self):
117
- """
118
- Deallocates all texture arrays
119
- """
120
-
1
+ import moderngl as mgl
2
+ import glm
3
+ import numpy as np
4
+
5
+ texture_sizes = (8, 64, 512, 1024, 2048)
6
+
7
+
8
+ class ImageHandler():
9
+ engine: ...
10
+ """Back refernce to the parent engine"""
11
+ ctx: mgl.Context
12
+ """Back reference to the Context used by the scene/engine"""
13
+ images: list
14
+ """List of basilisk Images containing all the loaded images given to the scene"""
15
+ texture_arrays: dict
16
+ """Dictionary of textures arrays for writting textures to GPU"""
17
+
18
+ def __init__(self, engine) -> None:
19
+ """
20
+ Container for all the basilisk image objects in the scene.
21
+ Handles the managment and writting of all image textures.
22
+ """
23
+
24
+ # Set back references
25
+ self.engine = engine
26
+ self.ctx = engine.ctx
27
+
28
+ self.images = []
29
+ self.texture_arrays = {size : [] for size in texture_sizes}
30
+
31
+ def add(self, image: any) -> None:
32
+ """
33
+ Adds an existing basilisk image object to the handler for writting
34
+ Args:
35
+ image: bsk.Image
36
+ The existing image that is to be added to the scene.
37
+ """
38
+
39
+ if image in self.images: return
40
+
41
+ self.images.append(image)
42
+ self.write(regenerate=True)
43
+
44
+ def generate_texture_array(self) -> None:
45
+ """
46
+ Generates texutre arrays for all the images. Updates the index of the image instance
47
+ """
48
+
49
+ # Release any existsing texture arrays
50
+ for texture_array in self.texture_arrays.values():
51
+ if not texture_array: continue
52
+ texture_array.release()
53
+
54
+ self.texture_arrays = {size : [] for size in texture_sizes}
55
+
56
+ for image in self.images:
57
+ # Add the image data to the array
58
+ self.texture_arrays[image.size].append(image.data)
59
+ # Update the image index
60
+ image.index = glm.ivec2(texture_sizes.index(image.size), len(self.texture_arrays[image.size]) - 1)
61
+
62
+
63
+ for size in self.texture_arrays:
64
+ # Check that there are textures in the bucket
65
+ if not len(self.texture_arrays[size]): continue
66
+ array_data = np.array(self.texture_arrays[size])
67
+ dim = (size, size, len(self.texture_arrays[size]))
68
+
69
+ # Make the array
70
+ self.texture_arrays[size] = self.ctx.texture_array(size=dim, components=4, data=array_data)
71
+ # Texture OpenGl settings
72
+ self.texture_arrays[size].build_mipmaps()
73
+ if size > 32: self.texture_arrays[size].filter = (mgl.LINEAR_MIPMAP_LINEAR, mgl.LINEAR)
74
+ else: self.texture_arrays[size].filter = (mgl.NEAREST, mgl.NEAREST)
75
+ self.texture_arrays[size].anisotropy = 32.0
76
+
77
+ def write(self, regenerate=False) -> None:
78
+ """
79
+ Writes all texture arrays to shaders that use images
80
+ """
81
+
82
+ if not self.engine.shader_handler: return
83
+
84
+ if regenerate: self.generate_texture_array()
85
+
86
+ if not self.texture_arrays: return
87
+
88
+ for shader in self.engine.shader_handler.shaders:
89
+ if 'textureArrays[5]' not in shader.uniforms: continue
90
+
91
+ for i, size in enumerate(texture_sizes):
92
+ if not size in self.texture_arrays: continue
93
+ if not self.texture_arrays[size]: continue
94
+ shader.program[f'textureArrays[{i}].array'] = i + 3
95
+ self.texture_arrays[size].use(location=i+3)
96
+
97
+ def get(self, identifier: str | int) -> any:
98
+ """
99
+ Gets the basilisk image with the given name or index
100
+ Args:
101
+ identifier: str | int
102
+ The name string or index of the desired image
103
+ """
104
+
105
+ # Simply use index if given
106
+ if isinstance(identifier, int): return self.images[identifier]
107
+
108
+ # Else, search the list for an image with the given name
109
+ for image in self.images:
110
+ if image.name != identifier: continue
111
+ return image
112
+
113
+ # No matching image found
114
+ return None
115
+
116
+ def __del__(self):
117
+ """
118
+ Deallocates all texture arrays
119
+ """
120
+
121
121
  # [texture_array.release() for texture_array in self.texture_arrays]
basilisk/render/light.py CHANGED
@@ -1,97 +1,97 @@
1
- import glm
2
- import numpy as np
3
-
4
-
5
- class Light():
6
- light_handler: ...
7
- """Back reference to the parent light handler"""
8
- intensity: float
9
- """The brightness of the light"""
10
- color: glm.vec3
11
- """The color of the light"""
12
-
13
- def __init__(self, light_handler, intensity: float=1.0, color: tuple=(255, 255, 255)):
14
- """
15
- Abstract light class for Basilisk Engine.
16
- Cannot be added to a scene.
17
- """
18
-
19
- # Back References
20
- self.light_handler = light_handler
21
-
22
- # Light attributes
23
- self.intensity = intensity
24
- self.color = color
25
-
26
- @property
27
- def intensity(self): return self._intensity
28
- @property
29
- def color(self): return self._color
30
-
31
- @intensity.setter
32
- def intensity(self, value: float | int):
33
- if isinstance(value, float) or isinstance(value, int):
34
- self._intensity = value
35
- else:
36
- raise TypeError(f"Light: Invalid intensity value type {type(value)}. Expected float or int")
37
- self.light_handler.write()
38
-
39
- @color.setter
40
- def color(self, value: tuple | list | glm.vec3 | np.ndarray):
41
- if isinstance(value, tuple) or isinstance(value, list) or isinstance(value, np.ndarray):
42
- if len(value) != 3: raise ValueError(f"Light: Invalid number of values for color. Expected 3 values, got {len(value)} values")
43
- self._color = glm.vec3(value)
44
- elif isinstance(value, glm.vec3):
45
- self._color = glm.vec3(value)
46
- else:
47
- raise TypeError(f"Light: Invalid color value type {type(value)}. Expected tuple, list, glm.vec3, or numpy array")
48
- self.light_handler.write()
49
-
50
- class DirectionalLight(Light):
51
- direction: glm.vec3
52
- """The direction that the light is applied to objects"""
53
- ambient: float
54
- """Base value of light that is applied at all locations, regardless of direction"""
55
-
56
- def __init__(self, light_handler, direction: tuple=(1.5, -2.0, 1.0), intensity:float=1.0, color: tuple=(255, 255, 255), ambient: float=0.0):
57
- """
58
- Diractional/Global light for Basilisk Engine.
59
- Has same intensity and direction everywhere.
60
- Args:
61
- direction: tuple
62
- The direction that the light is applied to objects
63
- intensity: float
64
- The brightness of the light
65
- color: tuple
66
- The color of the light
67
- ambient: float
68
- Base value of light that is applied at all locations, regardless of direction
69
- """
70
-
71
- super().__init__(light_handler, intensity, color)
72
- self.direction = direction
73
- self.ambient = ambient
74
-
75
- @property
76
- def direction(self): return self._direction
77
- @property
78
- def ambient(self): return self._ambient
79
-
80
- @direction.setter
81
- def direction(self, value: tuple | list | glm.vec3 | np.ndarray):
82
- if isinstance(value, tuple) or isinstance(value, list) or isinstance(value, np.ndarray):
83
- if len(value) != 3: raise ValueError(f"Light: Invalid number of values for direction. Expected 3 values, got {len(value)} values")
84
- self._direction = glm.normalize(glm.vec3(value))
85
- elif isinstance(value, glm.vec3):
86
- self._direction = glm.normalize(glm.vec3(value))
87
- else:
88
- raise TypeError(f"Light: Invalid direction value type {type(value)}. Expected tuple, list, glm.vec3, or numpy array")
89
- self.light_handler.write()
90
-
91
- @ambient.setter
92
- def ambient(self, value: float | int):
93
- if isinstance(value, float) or isinstance(value, int):
94
- self._ambient = value
95
- else:
96
- raise TypeError(f"Light: Invalid ambient value type {type(value)}. Expected float or int")
1
+ import glm
2
+ import numpy as np
3
+
4
+
5
+ class Light():
6
+ light_handler: ...
7
+ """Back reference to the parent light handler"""
8
+ intensity: float
9
+ """The brightness of the light"""
10
+ color: glm.vec3
11
+ """The color of the light"""
12
+
13
+ def __init__(self, light_handler, intensity: float=1.0, color: tuple=(255, 255, 255)):
14
+ """
15
+ Abstract light class for Basilisk Engine.
16
+ Cannot be added to a scene.
17
+ """
18
+
19
+ # Back References
20
+ self.light_handler = light_handler
21
+
22
+ # Light attributes
23
+ self.intensity = intensity
24
+ self.color = color
25
+
26
+ @property
27
+ def intensity(self): return self._intensity
28
+ @property
29
+ def color(self): return self._color
30
+
31
+ @intensity.setter
32
+ def intensity(self, value: float | int):
33
+ if isinstance(value, float) or isinstance(value, int):
34
+ self._intensity = value
35
+ else:
36
+ raise TypeError(f"Light: Invalid intensity value type {type(value)}. Expected float or int")
37
+ self.light_handler.write()
38
+
39
+ @color.setter
40
+ def color(self, value: tuple | list | glm.vec3 | np.ndarray):
41
+ if isinstance(value, tuple) or isinstance(value, list) or isinstance(value, np.ndarray):
42
+ if len(value) != 3: raise ValueError(f"Light: Invalid number of values for color. Expected 3 values, got {len(value)} values")
43
+ self._color = glm.vec3(value)
44
+ elif isinstance(value, glm.vec3):
45
+ self._color = glm.vec3(value)
46
+ else:
47
+ raise TypeError(f"Light: Invalid color value type {type(value)}. Expected tuple, list, glm.vec3, or numpy array")
48
+ self.light_handler.write()
49
+
50
+ class DirectionalLight(Light):
51
+ direction: glm.vec3
52
+ """The direction that the light is applied to objects"""
53
+ ambient: float
54
+ """Base value of light that is applied at all locations, regardless of direction"""
55
+
56
+ def __init__(self, light_handler, direction: tuple=(1.5, -2.0, 1.0), intensity:float=1.0, color: tuple=(255, 255, 255), ambient: float=0.0):
57
+ """
58
+ Diractional/Global light for Basilisk Engine.
59
+ Has same intensity and direction everywhere.
60
+ Args:
61
+ direction: tuple
62
+ The direction that the light is applied to objects
63
+ intensity: float
64
+ The brightness of the light
65
+ color: tuple
66
+ The color of the light
67
+ ambient: float
68
+ Base value of light that is applied at all locations, regardless of direction
69
+ """
70
+
71
+ super().__init__(light_handler, intensity, color)
72
+ self.direction = direction
73
+ self.ambient = ambient
74
+
75
+ @property
76
+ def direction(self): return self._direction
77
+ @property
78
+ def ambient(self): return self._ambient
79
+
80
+ @direction.setter
81
+ def direction(self, value: tuple | list | glm.vec3 | np.ndarray):
82
+ if isinstance(value, tuple) or isinstance(value, list) or isinstance(value, np.ndarray):
83
+ if len(value) != 3: raise ValueError(f"Light: Invalid number of values for direction. Expected 3 values, got {len(value)} values")
84
+ self._direction = glm.normalize(glm.vec3(value))
85
+ elif isinstance(value, glm.vec3):
86
+ self._direction = glm.normalize(glm.vec3(value))
87
+ else:
88
+ raise TypeError(f"Light: Invalid direction value type {type(value)}. Expected tuple, list, glm.vec3, or numpy array")
89
+ self.light_handler.write()
90
+
91
+ @ambient.setter
92
+ def ambient(self, value: float | int):
93
+ if isinstance(value, float) or isinstance(value, int):
94
+ self._ambient = value
95
+ else:
96
+ raise TypeError(f"Light: Invalid ambient value type {type(value)}. Expected float or int")
97
97
  self.light_handler.write()