basilisk-engine 0.1.12__py3-none-any.whl → 0.1.13__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.
- basilisk/__init__.py +14 -14
- basilisk/audio/sound.py +27 -27
- basilisk/bsk_assets/cube.obj +48 -48
- basilisk/collisions/broad/broad_aabb.py +102 -102
- basilisk/collisions/broad/broad_bvh.py +137 -137
- basilisk/collisions/collider.py +95 -95
- basilisk/collisions/collider_handler.py +224 -224
- basilisk/collisions/narrow/contact_manifold.py +95 -95
- basilisk/collisions/narrow/dataclasses.py +34 -34
- basilisk/collisions/narrow/deprecated.py +46 -46
- basilisk/collisions/narrow/epa.py +91 -91
- basilisk/collisions/narrow/gjk.py +66 -66
- basilisk/collisions/narrow/graham_scan.py +24 -24
- basilisk/collisions/narrow/helper.py +29 -29
- basilisk/collisions/narrow/line_intersections.py +106 -106
- basilisk/collisions/narrow/sutherland_hodgman.py +75 -75
- basilisk/config.py +2 -2
- basilisk/draw/draw.py +100 -100
- basilisk/draw/draw_handler.py +179 -179
- basilisk/draw/font_renderer.py +28 -28
- basilisk/engine.py +206 -206
- basilisk/generic/abstract_bvh.py +15 -15
- basilisk/generic/abstract_custom.py +133 -133
- basilisk/generic/collisions.py +72 -72
- basilisk/generic/input_validation.py +66 -66
- basilisk/generic/math.py +6 -6
- basilisk/generic/matrices.py +35 -35
- basilisk/generic/meshes.py +72 -72
- basilisk/generic/quat.py +142 -142
- basilisk/generic/quat_methods.py +7 -7
- basilisk/generic/raycast_result.py +23 -23
- basilisk/generic/vec3.py +143 -143
- basilisk/input/mouse.py +61 -61
- basilisk/input/path.py +14 -14
- basilisk/mesh/cube.py +33 -33
- basilisk/mesh/mesh.py +230 -230
- basilisk/mesh/mesh_from_data.py +130 -130
- basilisk/mesh/model.py +271 -271
- basilisk/mesh/narrow_aabb.py +89 -89
- basilisk/mesh/narrow_bvh.py +91 -91
- basilisk/mesh/narrow_primative.py +23 -23
- basilisk/nodes/helper.py +28 -28
- basilisk/nodes/node.py +684 -684
- basilisk/nodes/node_handler.py +95 -95
- basilisk/particles/particle_handler.py +63 -63
- basilisk/particles/particle_renderer.py +87 -87
- basilisk/physics/impulse.py +112 -112
- basilisk/physics/physics_body.py +43 -43
- basilisk/physics/physics_engine.py +35 -35
- basilisk/render/batch.py +105 -105
- basilisk/render/camera.py +211 -211
- basilisk/render/chunk.py +106 -106
- basilisk/render/chunk_handler.py +165 -165
- basilisk/render/frame.py +101 -101
- basilisk/render/framebuffer.py +130 -130
- basilisk/render/image.py +87 -87
- basilisk/render/image_handler.py +122 -122
- basilisk/render/light.py +96 -96
- basilisk/render/light_handler.py +58 -58
- basilisk/render/material.py +219 -219
- basilisk/render/material_handler.py +135 -135
- basilisk/render/post_process.py +132 -132
- basilisk/render/shader.py +110 -110
- basilisk/render/shader_handler.py +79 -79
- basilisk/render/sky.py +120 -120
- basilisk/scene.py +270 -264
- basilisk/shaders/batch.frag +276 -276
- basilisk/shaders/batch.vert +115 -115
- basilisk/shaders/crt.frag +31 -31
- basilisk/shaders/draw.frag +21 -21
- basilisk/shaders/draw.vert +21 -21
- basilisk/shaders/filter.frag +22 -22
- basilisk/shaders/frame.frag +12 -12
- basilisk/shaders/frame.vert +13 -13
- basilisk/shaders/geometry.frag +8 -8
- basilisk/shaders/geometry.vert +41 -41
- basilisk/shaders/normal.frag +59 -59
- basilisk/shaders/normal.vert +96 -96
- basilisk/shaders/particle.frag +71 -71
- basilisk/shaders/particle.vert +84 -84
- basilisk/shaders/sky.frag +9 -9
- basilisk/shaders/sky.vert +13 -13
- {basilisk_engine-0.1.12.dist-info → basilisk_engine-0.1.13.dist-info}/METADATA +38 -45
- basilisk_engine-0.1.13.dist-info/RECORD +103 -0
- {basilisk_engine-0.1.12.dist-info → basilisk_engine-0.1.13.dist-info}/WHEEL +1 -1
- basilisk_engine-0.1.12.dist-info/RECORD +0 -103
- {basilisk_engine-0.1.12.dist-info → basilisk_engine-0.1.13.dist-info}/top_level.txt +0 -0
basilisk/render/image_handler.py
CHANGED
|
@@ -1,123 +1,123 @@
|
|
|
1
|
-
import moderngl as mgl
|
|
2
|
-
import glm
|
|
3
|
-
import numpy as np
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
texture_sizes = (8, 64, 512, 1024, 2048)
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class ImageHandler():
|
|
10
|
-
engine: any
|
|
11
|
-
"""Back refernce to the parent engine"""
|
|
12
|
-
scene: any
|
|
13
|
-
"""Back refernce to the parent scene"""
|
|
14
|
-
ctx: mgl.Context
|
|
15
|
-
"""Back reference to the Context used by the scene/engine"""
|
|
16
|
-
images: list
|
|
17
|
-
"""List of basilisk Images containing all the loaded images given to the scene"""
|
|
18
|
-
texture_arrays: dict
|
|
19
|
-
"""Dictionary of textures arrays for writting textures to GPU"""
|
|
20
|
-
|
|
21
|
-
def __init__(self, scene) -> None:
|
|
22
|
-
"""
|
|
23
|
-
Container for all the basilisk image objects in the scene.
|
|
24
|
-
Handles the managment and writting of all image textures.
|
|
25
|
-
"""
|
|
26
|
-
|
|
27
|
-
# Set back references
|
|
28
|
-
self.scene = scene
|
|
29
|
-
self.engine = scene.engine
|
|
30
|
-
self.ctx = scene.engine.ctx
|
|
31
|
-
|
|
32
|
-
self.images = []
|
|
33
|
-
self.texture_arrays = {size : [] for size in texture_sizes}
|
|
34
|
-
|
|
35
|
-
def add(self, image: any) -> None:
|
|
36
|
-
"""
|
|
37
|
-
Adds an existing basilisk image object to the handler for writting
|
|
38
|
-
Args:
|
|
39
|
-
image: bsk.Image
|
|
40
|
-
The existing image that is to be added to the scene.
|
|
41
|
-
"""
|
|
42
|
-
|
|
43
|
-
if image in self.images: return
|
|
44
|
-
|
|
45
|
-
self.images.append(image)
|
|
46
|
-
self.write(regenerate=True)
|
|
47
|
-
|
|
48
|
-
def generate_texture_array(self) -> None:
|
|
49
|
-
"""
|
|
50
|
-
Generates texutre arrays for all the images. Updates the index of the image instance
|
|
51
|
-
"""
|
|
52
|
-
|
|
53
|
-
# Release any existsing texture arrays
|
|
54
|
-
for texture_array in self.texture_arrays.values():
|
|
55
|
-
if not texture_array: continue
|
|
56
|
-
texture_array.release()
|
|
57
|
-
|
|
58
|
-
self.texture_arrays = {size : [] for size in texture_sizes}
|
|
59
|
-
|
|
60
|
-
for image in self.images:
|
|
61
|
-
# Add the image data to the array
|
|
62
|
-
self.texture_arrays[image.size].append(image.data)
|
|
63
|
-
# Update the image index
|
|
64
|
-
image.index = glm.ivec2(texture_sizes.index(image.size), len(self.texture_arrays[image.size]) - 1)
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
for size in self.texture_arrays:
|
|
68
|
-
# Check that there are textures in the bucket
|
|
69
|
-
if not len(self.texture_arrays[size]): continue
|
|
70
|
-
array_data = np.array(self.texture_arrays[size])
|
|
71
|
-
dim = (size, size, len(self.texture_arrays[size]))
|
|
72
|
-
|
|
73
|
-
# Make the array
|
|
74
|
-
self.texture_arrays[size] = self.ctx.texture_array(size=dim, components=4, data=array_data)
|
|
75
|
-
# Texture OpenGl settings
|
|
76
|
-
self.texture_arrays[size].build_mipmaps()
|
|
77
|
-
if size > 32: self.texture_arrays[size].filter = (mgl.LINEAR_MIPMAP_LINEAR, mgl.LINEAR)
|
|
78
|
-
else: self.texture_arrays[size].filter = (mgl.NEAREST, mgl.NEAREST)
|
|
79
|
-
self.texture_arrays[size].anisotropy = 32.0
|
|
80
|
-
|
|
81
|
-
def write(self, regenerate=False) -> None:
|
|
82
|
-
"""
|
|
83
|
-
Writes all texture arrays to shaders that use images
|
|
84
|
-
"""
|
|
85
|
-
|
|
86
|
-
if regenerate: self.generate_texture_array()
|
|
87
|
-
|
|
88
|
-
if not self.texture_arrays: return
|
|
89
|
-
|
|
90
|
-
for shader in self.engine.scene.shader_handler.shaders:
|
|
91
|
-
if 'textureArrays[5]' not in shader.uniforms: continue
|
|
92
|
-
|
|
93
|
-
for i, size in enumerate(texture_sizes):
|
|
94
|
-
if not size in self.texture_arrays: continue
|
|
95
|
-
if not self.texture_arrays[size]: continue
|
|
96
|
-
shader.program[f'textureArrays[{i}].array'] = i + 3
|
|
97
|
-
self.texture_arrays[size].use(location=i+3)
|
|
98
|
-
|
|
99
|
-
def get(self, identifier: str | int) -> any:
|
|
100
|
-
"""
|
|
101
|
-
Gets the basilisk image with the given name or index
|
|
102
|
-
Args:
|
|
103
|
-
identifier: str | int
|
|
104
|
-
The name string or index of the desired image
|
|
105
|
-
"""
|
|
106
|
-
|
|
107
|
-
# Simply use index if given
|
|
108
|
-
if isinstance(identifier, int): return self.images[identifier]
|
|
109
|
-
|
|
110
|
-
# Else, search the list for an image with the given name
|
|
111
|
-
for image in self.images:
|
|
112
|
-
if image.name != identifier: continue
|
|
113
|
-
return image
|
|
114
|
-
|
|
115
|
-
# No matching image found
|
|
116
|
-
return None
|
|
117
|
-
|
|
118
|
-
def __del__(self):
|
|
119
|
-
"""
|
|
120
|
-
Deallocates all texture arrays
|
|
121
|
-
"""
|
|
122
|
-
|
|
1
|
+
import moderngl as mgl
|
|
2
|
+
import glm
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
texture_sizes = (8, 64, 512, 1024, 2048)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ImageHandler():
|
|
10
|
+
engine: any
|
|
11
|
+
"""Back refernce to the parent engine"""
|
|
12
|
+
scene: any
|
|
13
|
+
"""Back refernce to the parent scene"""
|
|
14
|
+
ctx: mgl.Context
|
|
15
|
+
"""Back reference to the Context used by the scene/engine"""
|
|
16
|
+
images: list
|
|
17
|
+
"""List of basilisk Images containing all the loaded images given to the scene"""
|
|
18
|
+
texture_arrays: dict
|
|
19
|
+
"""Dictionary of textures arrays for writting textures to GPU"""
|
|
20
|
+
|
|
21
|
+
def __init__(self, scene) -> None:
|
|
22
|
+
"""
|
|
23
|
+
Container for all the basilisk image objects in the scene.
|
|
24
|
+
Handles the managment and writting of all image textures.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
# Set back references
|
|
28
|
+
self.scene = scene
|
|
29
|
+
self.engine = scene.engine
|
|
30
|
+
self.ctx = scene.engine.ctx
|
|
31
|
+
|
|
32
|
+
self.images = []
|
|
33
|
+
self.texture_arrays = {size : [] for size in texture_sizes}
|
|
34
|
+
|
|
35
|
+
def add(self, image: any) -> None:
|
|
36
|
+
"""
|
|
37
|
+
Adds an existing basilisk image object to the handler for writting
|
|
38
|
+
Args:
|
|
39
|
+
image: bsk.Image
|
|
40
|
+
The existing image that is to be added to the scene.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
if image in self.images: return
|
|
44
|
+
|
|
45
|
+
self.images.append(image)
|
|
46
|
+
self.write(regenerate=True)
|
|
47
|
+
|
|
48
|
+
def generate_texture_array(self) -> None:
|
|
49
|
+
"""
|
|
50
|
+
Generates texutre arrays for all the images. Updates the index of the image instance
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
# Release any existsing texture arrays
|
|
54
|
+
for texture_array in self.texture_arrays.values():
|
|
55
|
+
if not texture_array: continue
|
|
56
|
+
texture_array.release()
|
|
57
|
+
|
|
58
|
+
self.texture_arrays = {size : [] for size in texture_sizes}
|
|
59
|
+
|
|
60
|
+
for image in self.images:
|
|
61
|
+
# Add the image data to the array
|
|
62
|
+
self.texture_arrays[image.size].append(image.data)
|
|
63
|
+
# Update the image index
|
|
64
|
+
image.index = glm.ivec2(texture_sizes.index(image.size), len(self.texture_arrays[image.size]) - 1)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
for size in self.texture_arrays:
|
|
68
|
+
# Check that there are textures in the bucket
|
|
69
|
+
if not len(self.texture_arrays[size]): continue
|
|
70
|
+
array_data = np.array(self.texture_arrays[size])
|
|
71
|
+
dim = (size, size, len(self.texture_arrays[size]))
|
|
72
|
+
|
|
73
|
+
# Make the array
|
|
74
|
+
self.texture_arrays[size] = self.ctx.texture_array(size=dim, components=4, data=array_data)
|
|
75
|
+
# Texture OpenGl settings
|
|
76
|
+
self.texture_arrays[size].build_mipmaps()
|
|
77
|
+
if size > 32: self.texture_arrays[size].filter = (mgl.LINEAR_MIPMAP_LINEAR, mgl.LINEAR)
|
|
78
|
+
else: self.texture_arrays[size].filter = (mgl.NEAREST, mgl.NEAREST)
|
|
79
|
+
self.texture_arrays[size].anisotropy = 32.0
|
|
80
|
+
|
|
81
|
+
def write(self, regenerate=False) -> None:
|
|
82
|
+
"""
|
|
83
|
+
Writes all texture arrays to shaders that use images
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
if regenerate: self.generate_texture_array()
|
|
87
|
+
|
|
88
|
+
if not self.texture_arrays: return
|
|
89
|
+
|
|
90
|
+
for shader in self.engine.scene.shader_handler.shaders:
|
|
91
|
+
if 'textureArrays[5]' not in shader.uniforms: continue
|
|
92
|
+
|
|
93
|
+
for i, size in enumerate(texture_sizes):
|
|
94
|
+
if not size in self.texture_arrays: continue
|
|
95
|
+
if not self.texture_arrays[size]: continue
|
|
96
|
+
shader.program[f'textureArrays[{i}].array'] = i + 3
|
|
97
|
+
self.texture_arrays[size].use(location=i+3)
|
|
98
|
+
|
|
99
|
+
def get(self, identifier: str | int) -> any:
|
|
100
|
+
"""
|
|
101
|
+
Gets the basilisk image with the given name or index
|
|
102
|
+
Args:
|
|
103
|
+
identifier: str | int
|
|
104
|
+
The name string or index of the desired image
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
# Simply use index if given
|
|
108
|
+
if isinstance(identifier, int): return self.images[identifier]
|
|
109
|
+
|
|
110
|
+
# Else, search the list for an image with the given name
|
|
111
|
+
for image in self.images:
|
|
112
|
+
if image.name != identifier: continue
|
|
113
|
+
return image
|
|
114
|
+
|
|
115
|
+
# No matching image found
|
|
116
|
+
return None
|
|
117
|
+
|
|
118
|
+
def __del__(self):
|
|
119
|
+
"""
|
|
120
|
+
Deallocates all texture arrays
|
|
121
|
+
"""
|
|
122
|
+
|
|
123
123
|
# [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()
|
basilisk/render/light_handler.py
CHANGED
|
@@ -1,59 +1,59 @@
|
|
|
1
|
-
import moderngl as mgl
|
|
2
|
-
import glm
|
|
3
|
-
from ..render.light import DirectionalLight
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class LightHandler():
|
|
7
|
-
engine: ...
|
|
8
|
-
"""Back reference to the parent engine"""
|
|
9
|
-
scene: ...
|
|
10
|
-
"""Back reference to the parent scene"""
|
|
11
|
-
ctx: mgl.Context
|
|
12
|
-
"""Back reference to the parent context"""
|
|
13
|
-
directional_light: DirectionalLight
|
|
14
|
-
"""The directional light of the scene"""
|
|
15
|
-
point_lights: list
|
|
16
|
-
"""List of all the point lights in the scene"""
|
|
17
|
-
|
|
18
|
-
def __init__(self, scene) -> None:
|
|
19
|
-
"""
|
|
20
|
-
Handles all the lights in a Basilisk scene.
|
|
21
|
-
"""
|
|
22
|
-
|
|
23
|
-
# Back references
|
|
24
|
-
self.scene = scene
|
|
25
|
-
self.engine = scene.engine
|
|
26
|
-
self.ctx = scene.engine.ctx
|
|
27
|
-
|
|
28
|
-
# Intialize light variables
|
|
29
|
-
self.directional_lights = None
|
|
30
|
-
self.directional_lights = [DirectionalLight(self, direction=dir, intensity=intensity) for dir, intensity in zip(((1, -1, 1), (-.1, 3, -.1)), (1, .05))]
|
|
31
|
-
self.point_lights = []
|
|
32
|
-
|
|
33
|
-
# Initalize uniforms
|
|
34
|
-
self.write()
|
|
35
|
-
|
|
36
|
-
def write(self, program: mgl.Program=None, directional=True, point=False) -> None:
|
|
37
|
-
"""
|
|
38
|
-
Writes all the lights in a scene to the given shader program
|
|
39
|
-
"""
|
|
40
|
-
|
|
41
|
-
# if not program: program = self.engine.shader.program
|
|
42
|
-
|
|
43
|
-
for shader in self.scene.shader_handler.shaders:
|
|
44
|
-
if 'numDirLights' not in shader.uniforms: continue
|
|
45
|
-
|
|
46
|
-
program = shader.program
|
|
47
|
-
|
|
48
|
-
if directional and self.directional_lights and 'numDirLights' in self.engine.shader.uniforms:
|
|
49
|
-
|
|
50
|
-
program['numDirLights'].write(glm.int32(len(self.directional_lights)))
|
|
51
|
-
|
|
52
|
-
for i, light in enumerate(self.directional_lights):
|
|
53
|
-
program[f'dirLights[{i}].direction'].write(light.direction)
|
|
54
|
-
program[f'dirLights[{i}].intensity'].write(glm.float32(light.intensity))
|
|
55
|
-
program[f'dirLights[{i}].color' ].write(light.color / 255.0)
|
|
56
|
-
program[f'dirLights[{i}].ambient' ].write(glm.float32(light.ambient))
|
|
57
|
-
|
|
58
|
-
if point:
|
|
1
|
+
import moderngl as mgl
|
|
2
|
+
import glm
|
|
3
|
+
from ..render.light import DirectionalLight
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class LightHandler():
|
|
7
|
+
engine: ...
|
|
8
|
+
"""Back reference to the parent engine"""
|
|
9
|
+
scene: ...
|
|
10
|
+
"""Back reference to the parent scene"""
|
|
11
|
+
ctx: mgl.Context
|
|
12
|
+
"""Back reference to the parent context"""
|
|
13
|
+
directional_light: DirectionalLight
|
|
14
|
+
"""The directional light of the scene"""
|
|
15
|
+
point_lights: list
|
|
16
|
+
"""List of all the point lights in the scene"""
|
|
17
|
+
|
|
18
|
+
def __init__(self, scene) -> None:
|
|
19
|
+
"""
|
|
20
|
+
Handles all the lights in a Basilisk scene.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
# Back references
|
|
24
|
+
self.scene = scene
|
|
25
|
+
self.engine = scene.engine
|
|
26
|
+
self.ctx = scene.engine.ctx
|
|
27
|
+
|
|
28
|
+
# Intialize light variables
|
|
29
|
+
self.directional_lights = None
|
|
30
|
+
self.directional_lights = [DirectionalLight(self, direction=dir, intensity=intensity) for dir, intensity in zip(((1, -1, 1), (-.1, 3, -.1)), (1, .05))]
|
|
31
|
+
self.point_lights = []
|
|
32
|
+
|
|
33
|
+
# Initalize uniforms
|
|
34
|
+
self.write()
|
|
35
|
+
|
|
36
|
+
def write(self, program: mgl.Program=None, directional=True, point=False) -> None:
|
|
37
|
+
"""
|
|
38
|
+
Writes all the lights in a scene to the given shader program
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
# if not program: program = self.engine.shader.program
|
|
42
|
+
|
|
43
|
+
for shader in self.scene.shader_handler.shaders:
|
|
44
|
+
if 'numDirLights' not in shader.uniforms: continue
|
|
45
|
+
|
|
46
|
+
program = shader.program
|
|
47
|
+
|
|
48
|
+
if directional and self.directional_lights and 'numDirLights' in self.engine.shader.uniforms:
|
|
49
|
+
|
|
50
|
+
program['numDirLights'].write(glm.int32(len(self.directional_lights)))
|
|
51
|
+
|
|
52
|
+
for i, light in enumerate(self.directional_lights):
|
|
53
|
+
program[f'dirLights[{i}].direction'].write(light.direction)
|
|
54
|
+
program[f'dirLights[{i}].intensity'].write(glm.float32(light.intensity))
|
|
55
|
+
program[f'dirLights[{i}].color' ].write(light.color / 255.0)
|
|
56
|
+
program[f'dirLights[{i}].ambient' ].write(glm.float32(light.ambient))
|
|
57
|
+
|
|
58
|
+
if point:
|
|
59
59
|
...
|