basilisk-engine 0.1.0__py3-none-any.whl → 0.1.2__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/collisions/broad/broad_aabb.py +8 -1
- basilisk/collisions/broad/broad_bvh.py +8 -1
- basilisk/collisions/collider.py +15 -6
- basilisk/collisions/collider_handler.py +70 -68
- basilisk/collisions/narrow/contact_manifold.py +9 -10
- basilisk/collisions/narrow/dataclasses.py +27 -0
- basilisk/collisions/narrow/deprecated.py +47 -0
- basilisk/collisions/narrow/epa.py +11 -10
- basilisk/collisions/narrow/gjk.py +15 -14
- basilisk/collisions/narrow/helper.py +8 -7
- basilisk/collisions/narrow/sutherland_hodgman.py +52 -0
- basilisk/draw/draw_handler.py +5 -3
- basilisk/engine.py +14 -5
- basilisk/generic/abstract_custom.py +134 -0
- basilisk/generic/collisions.py +46 -0
- basilisk/generic/quat.py +77 -66
- basilisk/generic/vec3.py +91 -67
- basilisk/mesh/cube.py +20 -2
- basilisk/mesh/mesh.py +69 -54
- basilisk/mesh/mesh_from_data.py +106 -21
- basilisk/mesh/narrow_aabb.py +10 -1
- basilisk/mesh/narrow_bvh.py +9 -1
- basilisk/nodes/node.py +169 -30
- basilisk/nodes/node_handler.py +51 -30
- basilisk/particles/__init__.py +0 -0
- basilisk/particles/particle_handler.py +55 -0
- basilisk/particles/particle_renderer.py +87 -0
- basilisk/physics/impulse.py +7 -13
- basilisk/physics/physics_body.py +10 -2
- basilisk/physics/physics_engine.py +1 -2
- basilisk/render/batch.py +2 -2
- basilisk/render/camera.py +5 -0
- basilisk/render/chunk.py +19 -4
- basilisk/render/chunk_handler.py +33 -26
- basilisk/render/image.py +1 -1
- basilisk/render/image_handler.py +7 -5
- basilisk/render/light_handler.py +16 -11
- basilisk/render/material.py +25 -1
- basilisk/render/material_handler.py +22 -13
- basilisk/render/shader.py +7 -7
- basilisk/render/shader_handler.py +13 -12
- basilisk/render/sky.py +5 -3
- basilisk/scene.py +114 -32
- basilisk/shaders/batch.frag +40 -11
- basilisk/shaders/batch.vert +14 -7
- basilisk/shaders/normal.frag +5 -5
- basilisk/shaders/normal.vert +8 -3
- basilisk/shaders/particle.frag +72 -0
- basilisk/shaders/particle.vert +85 -0
- {basilisk_engine-0.1.0.dist-info → basilisk_engine-0.1.2.dist-info}/METADATA +5 -5
- basilisk_engine-0.1.2.dist-info/RECORD +95 -0
- basilisk/shaders/image.png +0 -0
- basilisk_engine-0.1.0.dist-info/RECORD +0 -88
- {basilisk_engine-0.1.0.dist-info → basilisk_engine-0.1.2.dist-info}/WHEEL +0 -0
- {basilisk_engine-0.1.0.dist-info → basilisk_engine-0.1.2.dist-info}/top_level.txt +0 -0
basilisk/physics/physics_body.py
CHANGED
|
@@ -6,8 +6,8 @@ class PhysicsBody():
|
|
|
6
6
|
mass: float
|
|
7
7
|
"""The mass of the physics body in kg"""
|
|
8
8
|
|
|
9
|
-
def __init__(self,
|
|
10
|
-
self.physics_engine =
|
|
9
|
+
def __init__(self, mass:float=1.0) -> None:
|
|
10
|
+
self.physics_engine = None
|
|
11
11
|
self.mass = mass
|
|
12
12
|
|
|
13
13
|
def get_delta_velocity(self, dt: float) -> glm.vec3:
|
|
@@ -32,5 +32,13 @@ class PhysicsBody():
|
|
|
32
32
|
# TODO add torques
|
|
33
33
|
return dw
|
|
34
34
|
|
|
35
|
+
@property
|
|
36
|
+
def physics_engine(self): return self._physics_engine
|
|
37
|
+
|
|
38
|
+
@physics_engine.setter
|
|
39
|
+
def physics_engine(self, value):
|
|
40
|
+
self._physics_engine = value
|
|
41
|
+
if value: value.add(self)
|
|
42
|
+
|
|
35
43
|
def __repr__(self) -> str:
|
|
36
44
|
return f'<Physics Body| {self.mass}>'
|
|
@@ -20,11 +20,10 @@ class PhysicsEngine():
|
|
|
20
20
|
self.forces = forces if forces else []
|
|
21
21
|
self.torques = torques if torques else []
|
|
22
22
|
|
|
23
|
-
def add(self,
|
|
23
|
+
def add(self, physics_body: PhysicsBody) -> PhysicsBody:
|
|
24
24
|
"""
|
|
25
25
|
Adds a physics body to the physics engine and returns it
|
|
26
26
|
"""
|
|
27
|
-
physics_body = PhysicsBody(self, mass)
|
|
28
27
|
self.physics_bodies.append(physics_body)
|
|
29
28
|
return physics_body
|
|
30
29
|
|
basilisk/render/batch.py
CHANGED
|
@@ -23,7 +23,7 @@ class Batch():
|
|
|
23
23
|
# Back references
|
|
24
24
|
self.chunk = chunk
|
|
25
25
|
self.ctx = chunk.chunk_handler.engine.ctx
|
|
26
|
-
self.program = chunk.
|
|
26
|
+
self.program = self.chunk.get_program()
|
|
27
27
|
|
|
28
28
|
# Set intial values
|
|
29
29
|
self.vbo = None
|
|
@@ -35,7 +35,7 @@ class Batch():
|
|
|
35
35
|
Returns True if batch was successful.
|
|
36
36
|
"""
|
|
37
37
|
|
|
38
|
-
self.program = self.chunk.
|
|
38
|
+
self.program = self.chunk.get_program()
|
|
39
39
|
|
|
40
40
|
# Empty list to contain all vertex data of models in the chunk
|
|
41
41
|
batch_data = []
|
basilisk/render/camera.py
CHANGED
|
@@ -85,6 +85,11 @@ class Camera:
|
|
|
85
85
|
def get_params(self) -> tuple:
|
|
86
86
|
return self.engine, self.position, self.yaw, self.pitch
|
|
87
87
|
|
|
88
|
+
def look_at(self, other) -> None:
|
|
89
|
+
forward = glm.normalize(other.position - self.position)
|
|
90
|
+
self.yaw = np.degrees(np.arctan2(forward.z, forward.x))
|
|
91
|
+
self.pitch = np.degrees(np.arctan2(forward.y, np.sqrt(forward.x ** 2 + forward.z ** 2)))
|
|
92
|
+
|
|
88
93
|
def __repr__(self):
|
|
89
94
|
return f'<Basilisk Camera | Position: {self.position}, Direction: {self.forward}>'
|
|
90
95
|
|
basilisk/render/chunk.py
CHANGED
|
@@ -4,7 +4,7 @@ from .batch import Batch
|
|
|
4
4
|
class Chunk():
|
|
5
5
|
chunk_handler: ...
|
|
6
6
|
"""Back refrence to the parent chunk handler"""
|
|
7
|
-
|
|
7
|
+
position: tuple
|
|
8
8
|
"""The position of the chunk. Used as a key in the chunk handler"""
|
|
9
9
|
batch: Batch
|
|
10
10
|
"""Batched mesh of the chunk"""
|
|
@@ -13,7 +13,7 @@ class Chunk():
|
|
|
13
13
|
static: bool
|
|
14
14
|
"""Type of node that the chunk recognizes"""
|
|
15
15
|
|
|
16
|
-
def __init__(self, chunk_handler,
|
|
16
|
+
def __init__(self, chunk_handler, position: tuple, static: bool, shader=None) -> None:
|
|
17
17
|
"""
|
|
18
18
|
Basilisk chunk object.
|
|
19
19
|
Contains references to all nodes in the chunk.
|
|
@@ -22,9 +22,11 @@ class Chunk():
|
|
|
22
22
|
|
|
23
23
|
# Back references
|
|
24
24
|
self.chunk_handler = chunk_handler
|
|
25
|
-
self.chunk_key = chunk_key
|
|
26
25
|
|
|
26
|
+
# Chunk Attrbiutes
|
|
27
|
+
self.position = position
|
|
27
28
|
self.static = static
|
|
29
|
+
self.shader = shader
|
|
28
30
|
|
|
29
31
|
# Create empty batch
|
|
30
32
|
self.batch = Batch(self)
|
|
@@ -70,12 +72,25 @@ class Chunk():
|
|
|
70
72
|
Removes a node from the chunk
|
|
71
73
|
"""
|
|
72
74
|
|
|
75
|
+
if node == None: return
|
|
76
|
+
|
|
73
77
|
self.nodes.remove(node)
|
|
78
|
+
if self.batch and self.batch.vbo: self.batch.vbo.clear()
|
|
74
79
|
|
|
75
80
|
return node
|
|
76
81
|
|
|
82
|
+
def get_program(self):
|
|
83
|
+
"""
|
|
84
|
+
Gets the program of the chunks nodes' shader
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
shader = self.shader
|
|
88
|
+
|
|
89
|
+
if shader: return shader.program
|
|
90
|
+
return self.chunk_handler.engine.shader.program
|
|
91
|
+
|
|
77
92
|
def __repr__(self) -> str:
|
|
78
|
-
return f'<Basilisk Chunk | {self.
|
|
93
|
+
return f'<Basilisk Chunk | {self.position}, {len(self.nodes)} nodes, {"static" if self.static else "dynamic"}>'
|
|
79
94
|
|
|
80
95
|
def __del__(self) -> None:
|
|
81
96
|
"""
|
basilisk/render/chunk_handler.py
CHANGED
|
@@ -15,8 +15,8 @@ class ChunkHandler():
|
|
|
15
15
|
"""Reference to the shader program used by batches"""
|
|
16
16
|
chunks: list[dict]
|
|
17
17
|
"""List containing two dictionaries for dynamic and static chunks repsectivly"""
|
|
18
|
-
updated_chunks:
|
|
19
|
-
"""
|
|
18
|
+
updated_chunks: set
|
|
19
|
+
"""Set containing recently updated chunks"""
|
|
20
20
|
|
|
21
21
|
def __init__(self, scene) -> None:
|
|
22
22
|
# Reference to the scene hadlers and variables
|
|
@@ -31,8 +31,9 @@ class ChunkHandler():
|
|
|
31
31
|
self.program = scene.engine.shader.program
|
|
32
32
|
|
|
33
33
|
# List for the dynamic and static chunk dictionaries | [dyanmic: dict, static: dict]
|
|
34
|
-
self.
|
|
35
|
-
self.
|
|
34
|
+
self.shader_groups = {None : ({}, {})}
|
|
35
|
+
# self.chunks = [{}, {}]
|
|
36
|
+
self.updated_chunks = set()
|
|
36
37
|
|
|
37
38
|
|
|
38
39
|
def render(self) -> None:
|
|
@@ -47,10 +48,12 @@ class ChunkHandler():
|
|
|
47
48
|
chunk_keys = [(x, y, z) for x in range(*render_range_x) for y in range(*render_range_y) for z in range(*render_range_z)]
|
|
48
49
|
|
|
49
50
|
# Loop through all chunks in view and render
|
|
50
|
-
for
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
for shader, group in self.shader_groups.items():
|
|
52
|
+
if shader == None: shader = self.engine.shader
|
|
53
|
+
for chunk in chunk_keys:
|
|
54
|
+
# Render the chunk if it exists
|
|
55
|
+
if chunk in group[0]: group[0][chunk].render()
|
|
56
|
+
if chunk in group[1]: group[1][chunk].render()
|
|
54
57
|
|
|
55
58
|
|
|
56
59
|
def update(self) -> None:
|
|
@@ -63,27 +66,24 @@ class ChunkHandler():
|
|
|
63
66
|
# Loop through the set of updated chunk keys and update the chunk
|
|
64
67
|
removes = []
|
|
65
68
|
|
|
66
|
-
for chunk in self.updated_chunks
|
|
69
|
+
for chunk in self.updated_chunks:
|
|
67
70
|
if chunk.update(): continue
|
|
68
|
-
removes.append(
|
|
69
|
-
for chunk in self.updated_chunks[1]:
|
|
70
|
-
if chunk.update(): continue
|
|
71
|
-
removes.append((1, chunk))
|
|
71
|
+
removes.append(chunk)
|
|
72
72
|
|
|
73
73
|
# Remove any empty chunks
|
|
74
|
-
for
|
|
75
|
-
|
|
76
|
-
del self.chunks[chunk_tuple[0]][chunk_tuple[1]]
|
|
74
|
+
for chunk in removes:
|
|
75
|
+
del self.shader_groups[chunk.shader][chunk.static][chunk.position]
|
|
77
76
|
|
|
78
77
|
# Clears the set of updated chunks so that they are not updated unless they are updated again
|
|
79
|
-
self.updated_chunks
|
|
78
|
+
self.updated_chunks.clear()
|
|
80
79
|
|
|
81
80
|
def update_all(self):
|
|
82
81
|
self.program = self.scene.engine.shader.program
|
|
83
|
-
for
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
82
|
+
for shader in self.shader_groups.values():
|
|
83
|
+
for chunk in shader[0].values():
|
|
84
|
+
self.updated_chunks.add(chunk)
|
|
85
|
+
for chunk in shader[1].values():
|
|
86
|
+
self.updated_chunks.add(chunk)
|
|
87
87
|
|
|
88
88
|
def add(self, node: Node) -> Node:
|
|
89
89
|
"""
|
|
@@ -93,24 +93,31 @@ class ChunkHandler():
|
|
|
93
93
|
# The key of the chunk the node will be added to
|
|
94
94
|
chunk_size = self.engine.config.chunk_size
|
|
95
95
|
chunk_key = (int(node.x // chunk_size), int(node.y // chunk_size), int(node.z // chunk_size))
|
|
96
|
+
shader = node.shader
|
|
97
|
+
|
|
98
|
+
if shader not in self.shader_groups:
|
|
99
|
+
self.shader_groups[shader] = ({}, {})
|
|
96
100
|
|
|
97
101
|
# Ensure that the chunk exists
|
|
98
|
-
if chunk_key not in self.
|
|
99
|
-
|
|
102
|
+
if chunk_key not in self.shader_groups[shader][node.static]:
|
|
103
|
+
chunk = Chunk(self, chunk_key, node.static, shader)
|
|
104
|
+
self.shader_groups[shader][node.static][chunk_key] = chunk
|
|
100
105
|
|
|
101
106
|
# Add the node to the chunk
|
|
102
|
-
self.
|
|
107
|
+
self.shader_groups[shader][node.static][chunk_key].add(node)
|
|
103
108
|
|
|
104
109
|
# Update the chunk
|
|
105
|
-
self.updated_chunks
|
|
110
|
+
self.updated_chunks.add(self.shader_groups[shader][node.static][chunk_key])
|
|
106
111
|
|
|
107
112
|
return Node
|
|
108
113
|
|
|
109
|
-
def remove(self, node) -> None:
|
|
114
|
+
def remove(self, node: Node) -> None:
|
|
110
115
|
"""
|
|
111
116
|
Removes a node from the its chunk
|
|
112
117
|
"""
|
|
113
118
|
|
|
119
|
+
if node == None: return
|
|
120
|
+
|
|
114
121
|
# Remove the node
|
|
115
122
|
chunk = node.chunk
|
|
116
123
|
chunk.remove(node)
|
basilisk/render/image.py
CHANGED
basilisk/render/image_handler.py
CHANGED
|
@@ -3,7 +3,7 @@ import glm
|
|
|
3
3
|
import numpy as np
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
texture_sizes = (
|
|
6
|
+
texture_sizes = (8, 64, 512, 1024, 2048)
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class ImageHandler():
|
|
@@ -65,15 +65,17 @@ class ImageHandler():
|
|
|
65
65
|
|
|
66
66
|
|
|
67
67
|
for size in self.texture_arrays:
|
|
68
|
-
#
|
|
68
|
+
# Check that there are textures in the bucket
|
|
69
|
+
if not len(self.texture_arrays[size]): continue
|
|
69
70
|
array_data = np.array(self.texture_arrays[size])
|
|
70
71
|
dim = (size, size, len(self.texture_arrays[size]))
|
|
71
|
-
|
|
72
|
+
|
|
72
73
|
# Make the array
|
|
73
74
|
self.texture_arrays[size] = self.ctx.texture_array(size=dim, components=4, data=array_data)
|
|
74
75
|
# Texture OpenGl settings
|
|
75
76
|
self.texture_arrays[size].build_mipmaps()
|
|
76
|
-
self.texture_arrays[size].filter = (mgl.LINEAR_MIPMAP_LINEAR, mgl.LINEAR)
|
|
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)
|
|
77
79
|
self.texture_arrays[size].anisotropy = 32.0
|
|
78
80
|
|
|
79
81
|
def write(self, regenerate=False) -> None:
|
|
@@ -85,7 +87,7 @@ class ImageHandler():
|
|
|
85
87
|
|
|
86
88
|
if not self.texture_arrays: return
|
|
87
89
|
|
|
88
|
-
for shader in self.engine.scene.shader_handler.shaders
|
|
90
|
+
for shader in self.engine.scene.shader_handler.shaders:
|
|
89
91
|
if 'textureArrays[5]' not in shader.uniforms: continue
|
|
90
92
|
|
|
91
93
|
for i, size in enumerate(texture_sizes):
|
basilisk/render/light_handler.py
CHANGED
|
@@ -38,17 +38,22 @@ class LightHandler():
|
|
|
38
38
|
Writes all the lights in a scene to the given shader program
|
|
39
39
|
"""
|
|
40
40
|
|
|
41
|
-
if not program: program = self.engine.shader.program
|
|
41
|
+
# if not program: program = self.engine.shader.program
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
for shader in self.scene.shader_handler.shaders:
|
|
44
|
+
if 'numDirLights' not in shader.uniforms: continue
|
|
45
|
+
|
|
46
|
+
program = shader.program
|
|
44
47
|
|
|
45
|
-
|
|
48
|
+
if directional and self.directional_lights and 'numDirLights' in self.engine.shader.uniforms:
|
|
46
49
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
+
...
|
basilisk/render/material.py
CHANGED
|
@@ -41,7 +41,7 @@ class Material():
|
|
|
41
41
|
clearcoat_gloss: float
|
|
42
42
|
"""The glossiness of the clearcoat layer. 0 For a satin appearance, 1 for a gloss appearance"""
|
|
43
43
|
|
|
44
|
-
def __init__(self, name: str=None, color: tuple=(255.0, 255.0, 255.0), texture: Image=None, normal: Image=None,
|
|
44
|
+
def __init__(self, name: str=None, color: tuple=(255.0, 255.0, 255.0), texture: Image=None, normal: Image=None, roughness_map: Image=None, ao_map: Image=None,
|
|
45
45
|
roughness: float=0.7, subsurface: float=0.2, sheen: float=0.5, sheen_tint: float=0.5,
|
|
46
46
|
anisotropic: float=0.0, specular: float=1.0, metallicness: float=0.0, specular_tint: float=0.0,
|
|
47
47
|
clearcoat: float=0.5, clearcoat_gloss: float=0.25) -> None:
|
|
@@ -67,6 +67,8 @@ class Material():
|
|
|
67
67
|
self.color = color
|
|
68
68
|
self.texture = texture
|
|
69
69
|
self.normal = normal
|
|
70
|
+
self.roughness_map = roughness_map
|
|
71
|
+
self.ao_map = ao_map
|
|
70
72
|
self.roughness = roughness
|
|
71
73
|
self.subsurface = subsurface
|
|
72
74
|
self.sheen = sheen
|
|
@@ -96,6 +98,14 @@ class Material():
|
|
|
96
98
|
if self.normal: data.extend([1, self.normal.index.x, self.normal.index.y])
|
|
97
99
|
else: data.extend([0, 0, 0])
|
|
98
100
|
|
|
101
|
+
# Add roughness data
|
|
102
|
+
if self.roughness_map: data.extend([1, self.roughness_map.index.x, self.roughness_map.index.y])
|
|
103
|
+
else: data.extend([0, 0, 0])
|
|
104
|
+
|
|
105
|
+
# Add ao data
|
|
106
|
+
if self.ao_map: data.extend([1, self.ao_map.index.x, self.ao_map.index.y])
|
|
107
|
+
else: data.extend([0, 0, 0])
|
|
108
|
+
|
|
99
109
|
return data
|
|
100
110
|
|
|
101
111
|
def __repr__(self) -> str:
|
|
@@ -109,6 +119,10 @@ class Material():
|
|
|
109
119
|
@property
|
|
110
120
|
def normal(self): return self._normal
|
|
111
121
|
@property
|
|
122
|
+
def roughness_map(self): return self._roughness_map
|
|
123
|
+
@property
|
|
124
|
+
def ao_map(self): return self._ao_map
|
|
125
|
+
@property
|
|
112
126
|
def roughness(self): return self._roughness
|
|
113
127
|
@property
|
|
114
128
|
def subsurface(self): return self._subsurface
|
|
@@ -145,6 +159,16 @@ class Material():
|
|
|
145
159
|
self._normal = validate_image("Material", "normal map", value)
|
|
146
160
|
if self.material_handler: self.material_handler.write(regenerate=True)
|
|
147
161
|
|
|
162
|
+
@roughness_map.setter
|
|
163
|
+
def roughness_map(self, value: Image | None):
|
|
164
|
+
self._roughness_map = validate_image("Material", "roughness_map", value)
|
|
165
|
+
if self.material_handler: self.material_handler.write(regenerate=True)
|
|
166
|
+
|
|
167
|
+
@ao_map.setter
|
|
168
|
+
def ao_map(self, value: Image | None):
|
|
169
|
+
self._ao_map = validate_image("Material", "ao_map map", value)
|
|
170
|
+
if self.material_handler: self.material_handler.write(regenerate=True)
|
|
171
|
+
|
|
148
172
|
@roughness.setter
|
|
149
173
|
def roughness(self, value: float | int | glm.float32):
|
|
150
174
|
self._roughness = validate_float("Material", "roughness", value)
|
|
@@ -39,18 +39,27 @@ class MaterialHandler():
|
|
|
39
39
|
Adds the given material to the handler if it is not already present
|
|
40
40
|
"""
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
42
|
+
write = False
|
|
43
|
+
|
|
44
|
+
if isinstance(material, Material): material = [material]
|
|
45
|
+
|
|
46
|
+
for mtl in material:
|
|
47
|
+
# Check that the material is not already in the scene
|
|
48
|
+
if mtl in self.materials: continue
|
|
49
|
+
# Update the material's handler
|
|
50
|
+
mtl.material_handler = self
|
|
51
|
+
# Add images
|
|
52
|
+
if mtl.texture: self.image_handler.add(mtl.texture)
|
|
53
|
+
if mtl.normal: self.image_handler.add(mtl.normal)
|
|
54
|
+
|
|
55
|
+
# Add the material
|
|
56
|
+
self.materials.append(mtl)
|
|
57
|
+
|
|
58
|
+
write = True
|
|
59
|
+
|
|
60
|
+
|
|
52
61
|
# Write materials
|
|
53
|
-
self.write(regenerate=True)
|
|
62
|
+
if write: self.write(regenerate=True)
|
|
54
63
|
|
|
55
64
|
def generate_material_texture(self) -> None:
|
|
56
65
|
"""
|
|
@@ -64,7 +73,7 @@ class MaterialHandler():
|
|
|
64
73
|
if self.data_texture: self.data_texture.release()
|
|
65
74
|
|
|
66
75
|
# Create empty texture data
|
|
67
|
-
material_data = np.zeros(shape=(len(self.materials),
|
|
76
|
+
material_data = np.zeros(shape=(len(self.materials), 25), dtype="f4")
|
|
68
77
|
|
|
69
78
|
# Get data from the materials
|
|
70
79
|
for i, mtl in enumerate(self.materials):
|
|
@@ -84,7 +93,7 @@ class MaterialHandler():
|
|
|
84
93
|
|
|
85
94
|
if not self.data_texture: return
|
|
86
95
|
|
|
87
|
-
for shader in self.engine.scene.shader_handler.shaders
|
|
96
|
+
for shader in self.engine.scene.shader_handler.shaders:
|
|
88
97
|
if 'materialsTexture' not in shader.uniforms: continue
|
|
89
98
|
|
|
90
99
|
shader.program['materialsTexture'] = 9
|
basilisk/render/shader.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import moderngl as mgl
|
|
2
|
-
|
|
2
|
+
import random
|
|
3
3
|
|
|
4
4
|
attribute_mappings = {
|
|
5
5
|
'in_position' : [0, 1, 2],
|
|
@@ -60,7 +60,10 @@ class Shader:
|
|
|
60
60
|
self.fragment_shader = file.read()
|
|
61
61
|
|
|
62
62
|
# Hash value for references
|
|
63
|
-
|
|
63
|
+
if vert == None and frag == None:
|
|
64
|
+
self.hash = hash((self.vertex_shader, self.fragment_shader, 'default'))
|
|
65
|
+
else:
|
|
66
|
+
self.hash = hash((self.vertex_shader, self.fragment_shader))
|
|
64
67
|
|
|
65
68
|
# Create a string of all lines in both shaders
|
|
66
69
|
lines = f'{self.vertex_shader}\n{self.fragment_shader}'.split('\n')
|
|
@@ -85,15 +88,12 @@ class Shader:
|
|
|
85
88
|
# Create a program with shaders
|
|
86
89
|
self.program = self.ctx.program(vertex_shader=self.vertex_shader, fragment_shader=self.fragment_shader)
|
|
87
90
|
|
|
88
|
-
def
|
|
91
|
+
def set_main(self):
|
|
89
92
|
"""
|
|
90
93
|
Selects a shader for use
|
|
91
94
|
"""
|
|
92
95
|
|
|
93
|
-
self.engine.scene.shader_handler.add(
|
|
94
|
-
self.engine.scene.light_handler.write()
|
|
95
|
-
self.engine.scene.material_handler.write()
|
|
96
|
-
self.engine.scene.sky.write()
|
|
96
|
+
self.engine.scene.shader_handler.add(self)
|
|
97
97
|
self.engine.scene.node_handler.chunk_handler.update_all()
|
|
98
98
|
|
|
99
99
|
def write(self, name: str, value) -> None:
|
|
@@ -10,7 +10,7 @@ class ShaderHandler:
|
|
|
10
10
|
"""Back reference to the parent scene"""
|
|
11
11
|
ctx: mgl.Context
|
|
12
12
|
"""Back reference to the parent context"""
|
|
13
|
-
shaders:
|
|
13
|
+
shaders: set
|
|
14
14
|
"""Dictionary containing all the shaders"""
|
|
15
15
|
uniform_values: dict = {}
|
|
16
16
|
"""Dictionary containing uniform values"""
|
|
@@ -26,27 +26,28 @@ class ShaderHandler:
|
|
|
26
26
|
self.ctx = scene.engine.ctx
|
|
27
27
|
|
|
28
28
|
# Initalize dictionaries
|
|
29
|
-
self.shaders =
|
|
29
|
+
self.shaders = set()
|
|
30
|
+
self.add(self.engine.shader)
|
|
30
31
|
|
|
31
|
-
|
|
32
|
-
self.add('default', self.engine.shader)
|
|
33
|
-
self.add('draw', Shader(self.engine, root + '/shaders/draw.vert' , root + '/shaders/draw.frag' ))
|
|
34
|
-
self.add('sky', Shader(self.engine, root + '/shaders/sky.vert' , root + '/shaders/sky.frag' ))
|
|
35
|
-
|
|
36
|
-
def add(self, name: str, shader: Shader) -> None:
|
|
32
|
+
def add(self, shader: Shader) -> None:
|
|
37
33
|
"""
|
|
38
34
|
Creates a shader program from a file name.
|
|
39
35
|
Parses through shaders to identify uniforms and save for writting
|
|
40
36
|
"""
|
|
41
37
|
|
|
42
|
-
if shader in self.shaders.values(): return
|
|
43
38
|
|
|
44
|
-
|
|
39
|
+
if not shader: return None
|
|
40
|
+
if shader in self.shaders: return shader
|
|
41
|
+
|
|
42
|
+
self.shaders.add(shader)
|
|
45
43
|
|
|
46
44
|
if self.scene.material_handler:
|
|
45
|
+
self.scene.light_handler.write()
|
|
47
46
|
self.scene.material_handler.write()
|
|
48
47
|
self.scene.material_handler.image_handler.write()
|
|
49
48
|
|
|
49
|
+
return shader
|
|
50
|
+
|
|
50
51
|
def get_uniforms_values(self) -> None:
|
|
51
52
|
"""
|
|
52
53
|
Gets uniforms from various parts of the scene.
|
|
@@ -67,7 +68,7 @@ class ShaderHandler:
|
|
|
67
68
|
|
|
68
69
|
self.get_uniforms_values()
|
|
69
70
|
for uniform in self.uniform_values:
|
|
70
|
-
for shader in self.shaders
|
|
71
|
+
for shader in self.shaders:
|
|
71
72
|
if not uniform in shader.uniforms: continue # Does not write uniforms not in the shader
|
|
72
73
|
shader.write(uniform, self.uniform_values[uniform])
|
|
73
74
|
|
|
@@ -76,4 +77,4 @@ class ShaderHandler:
|
|
|
76
77
|
Releases all shader programs in handler
|
|
77
78
|
"""
|
|
78
79
|
|
|
79
|
-
[shader.__del__() for shader in self.shaders
|
|
80
|
+
[shader.__del__() for shader in self.shaders]
|
basilisk/render/sky.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
from PIL import Image as PIL_Image
|
|
3
|
+
from .shader import Shader
|
|
3
4
|
|
|
4
5
|
class Sky:
|
|
5
6
|
texture_cube=None
|
|
@@ -26,7 +27,7 @@ class Sky:
|
|
|
26
27
|
|
|
27
28
|
def write(self):
|
|
28
29
|
# Write the texture cube to the sky shader
|
|
29
|
-
self.program['skyboxTexture'] = 8
|
|
30
|
+
self.shader.program['skyboxTexture'] = 8
|
|
30
31
|
self.texture_cube.use(location = 8)
|
|
31
32
|
|
|
32
33
|
shader = self.scene.engine.shader
|
|
@@ -106,8 +107,9 @@ class Sky:
|
|
|
106
107
|
|
|
107
108
|
# Create a renderable vao
|
|
108
109
|
self.vbo = self.ctx.buffer(vertex_data)
|
|
109
|
-
|
|
110
|
-
self.
|
|
110
|
+
root = self.scene.engine.root
|
|
111
|
+
self.shader = self.scene.shader_handler.add(Shader(self.scene.engine, root + '/shaders/sky.vert', root + '/shaders/sky.frag'))
|
|
112
|
+
self.vao = self.ctx.vertex_array(self.shader.program, [(self.vbo, '3f', 'in_position')], skip_errors=True)
|
|
111
113
|
|
|
112
114
|
def __del__(self):
|
|
113
115
|
"""
|