basilisk-engine 0.1.34__py3-none-any.whl → 0.1.36__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 +26 -26
- 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 +225 -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 +54 -4
- basilisk/draw/draw.py +100 -100
- basilisk/draw/draw_handler.py +175 -175
- basilisk/draw/font_renderer.py +28 -28
- basilisk/engine.py +165 -165
- basilisk/generic/abstract_bvh.py +15 -15
- basilisk/generic/abstract_custom.py +133 -133
- basilisk/generic/collisions.py +70 -70
- basilisk/generic/input_validation.py +82 -74
- 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 +26 -26
- basilisk/generic/vec3.py +143 -143
- basilisk/input_output/IO_handler.py +91 -91
- basilisk/input_output/clock.py +49 -49
- basilisk/input_output/keys.py +43 -43
- basilisk/input_output/mouse.py +90 -89
- basilisk/input_output/path.py +14 -14
- basilisk/mesh/cube.py +33 -33
- basilisk/mesh/mesh.py +233 -233
- basilisk/mesh/mesh_from_data.py +150 -150
- 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 +704 -695
- basilisk/nodes/node_handler.py +97 -97
- basilisk/particles/particle_handler.py +64 -64
- basilisk/particles/particle_renderer.py +92 -92
- basilisk/physics/impulse.py +112 -112
- basilisk/physics/physics_body.py +43 -43
- basilisk/physics/physics_engine.py +35 -35
- basilisk/render/batch.py +103 -103
- basilisk/render/bloom.py +108 -0
- basilisk/render/camera.py +260 -260
- basilisk/render/chunk.py +108 -106
- basilisk/render/chunk_handler.py +167 -165
- basilisk/render/frame.py +107 -95
- basilisk/render/framebuffer.py +203 -192
- basilisk/render/image.py +120 -120
- basilisk/render/image_handler.py +120 -120
- basilisk/render/light.py +96 -96
- basilisk/render/light_handler.py +58 -58
- basilisk/render/material.py +232 -221
- basilisk/render/material_handler.py +133 -133
- basilisk/render/post_process.py +139 -139
- basilisk/render/shader.py +134 -134
- basilisk/render/shader_handler.py +85 -83
- basilisk/render/sky.py +120 -120
- basilisk/scene.py +289 -289
- basilisk/shaders/batch.frag +289 -276
- basilisk/shaders/batch.vert +117 -115
- basilisk/shaders/bloom_downsample.frag +43 -0
- basilisk/shaders/bloom_frame.frag +25 -0
- basilisk/shaders/bloom_upsample.frag +34 -0
- basilisk/shaders/crt.frag +31 -31
- basilisk/shaders/draw.frag +25 -22
- basilisk/shaders/draw.vert +25 -25
- 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 +23 -9
- basilisk/shaders/sky.vert +13 -13
- basilisk_engine-0.1.36.dist-info/METADATA +89 -0
- basilisk_engine-0.1.36.dist-info/RECORD +110 -0
- {basilisk_engine-0.1.34.dist-info → basilisk_engine-0.1.36.dist-info}/WHEEL +1 -1
- basilisk/input/__init__.py +0 -0
- basilisk/input/mouse.py +0 -62
- basilisk/input/path.py +0 -14
- basilisk_engine-0.1.34.dist-info/METADATA +0 -45
- basilisk_engine-0.1.34.dist-info/RECORD +0 -109
- {basilisk_engine-0.1.34.dist-info → basilisk_engine-0.1.36.dist-info}/top_level.txt +0 -0
basilisk/__init__.py
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import pygame as pg
|
|
2
|
-
from .engine import Engine
|
|
3
|
-
from .scene import Scene
|
|
4
|
-
from .nodes.node import Node
|
|
5
|
-
from .mesh.mesh import Mesh
|
|
6
|
-
from .render.image import Image
|
|
7
|
-
from .render.material import Material
|
|
8
|
-
from .render.shader import Shader
|
|
9
|
-
from .render.shader_handler import ShaderHandler
|
|
10
|
-
from .draw import draw
|
|
11
|
-
from .render.camera import FreeCamera, StaticCamera, FollowCamera, OrbitCamera, FixedCamera
|
|
12
|
-
from .render.sky import Sky
|
|
13
|
-
from .render.post_process import PostProcess
|
|
14
|
-
from .particles.particle_handler import ParticleHandler
|
|
15
|
-
from .render.framebuffer import Framebuffer
|
|
16
|
-
from .audio.sound import Sound
|
|
17
|
-
|
|
18
|
-
# expose internal algorithms
|
|
19
|
-
from .collisions.narrow.epa import get_epa_from_gjk
|
|
20
|
-
from .collisions.narrow.gjk import collide_gjk
|
|
21
|
-
from .collisions.narrow.graham_scan import graham_scan
|
|
22
|
-
from .collisions.narrow.helper import get_furthest_point, get_support_point
|
|
23
|
-
from .collisions.narrow.line_intersections import line_line_intersect, line_poly_intersect
|
|
24
|
-
from .collisions.narrow.sutherland_hodgman import sutherland_hodgman
|
|
25
|
-
from .generic.collisions import collide_aabb_aabb, collide_aabb_line
|
|
26
|
-
from .generic.meshes import moller_trumbore
|
|
1
|
+
import pygame as pg
|
|
2
|
+
from .engine import Engine
|
|
3
|
+
from .scene import Scene
|
|
4
|
+
from .nodes.node import Node
|
|
5
|
+
from .mesh.mesh import Mesh
|
|
6
|
+
from .render.image import Image
|
|
7
|
+
from .render.material import Material
|
|
8
|
+
from .render.shader import Shader
|
|
9
|
+
from .render.shader_handler import ShaderHandler
|
|
10
|
+
from .draw import draw
|
|
11
|
+
from .render.camera import FreeCamera, StaticCamera, FollowCamera, OrbitCamera, FixedCamera
|
|
12
|
+
from .render.sky import Sky
|
|
13
|
+
from .render.post_process import PostProcess
|
|
14
|
+
from .particles.particle_handler import ParticleHandler
|
|
15
|
+
from .render.framebuffer import Framebuffer
|
|
16
|
+
from .audio.sound import Sound
|
|
17
|
+
|
|
18
|
+
# expose internal algorithms
|
|
19
|
+
from .collisions.narrow.epa import get_epa_from_gjk
|
|
20
|
+
from .collisions.narrow.gjk import collide_gjk
|
|
21
|
+
from .collisions.narrow.graham_scan import graham_scan
|
|
22
|
+
from .collisions.narrow.helper import get_furthest_point, get_support_point
|
|
23
|
+
from .collisions.narrow.line_intersections import line_line_intersect, line_poly_intersect
|
|
24
|
+
from .collisions.narrow.sutherland_hodgman import sutherland_hodgman
|
|
25
|
+
from .generic.collisions import collide_aabb_aabb, collide_aabb_line
|
|
26
|
+
from .generic.meshes import moller_trumbore
|
basilisk/audio/sound.py
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import pygame as pg
|
|
3
|
-
|
|
4
|
-
class Sound:
|
|
5
|
-
def __init__(self, path: str | os.PathLike):
|
|
6
|
-
"""
|
|
7
|
-
Sound object that can be played
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
if not (isinstance(path, str) or isinstance(path, os.PathLike)):
|
|
11
|
-
raise ValueError(f'bsk.Sound: Invalid source path type {type(path)}. Expected string or os.PathLike')
|
|
12
|
-
|
|
13
|
-
self.source = pg.mixer.Sound(path)
|
|
14
|
-
|
|
15
|
-
def play(self, volume: float=1.0):
|
|
16
|
-
"""
|
|
17
|
-
Play the sound at the given volume level. Full volume if none given
|
|
18
|
-
"""
|
|
19
|
-
|
|
20
|
-
self.source.set_volume(volume)
|
|
21
|
-
self.source.play()
|
|
22
|
-
|
|
23
|
-
def stop(self):
|
|
24
|
-
"""
|
|
25
|
-
Stops the sound
|
|
26
|
-
"""
|
|
27
|
-
|
|
1
|
+
import os
|
|
2
|
+
import pygame as pg
|
|
3
|
+
|
|
4
|
+
class Sound:
|
|
5
|
+
def __init__(self, path: str | os.PathLike):
|
|
6
|
+
"""
|
|
7
|
+
Sound object that can be played
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
if not (isinstance(path, str) or isinstance(path, os.PathLike)):
|
|
11
|
+
raise ValueError(f'bsk.Sound: Invalid source path type {type(path)}. Expected string or os.PathLike')
|
|
12
|
+
|
|
13
|
+
self.source = pg.mixer.Sound(path)
|
|
14
|
+
|
|
15
|
+
def play(self, volume: float=1.0):
|
|
16
|
+
"""
|
|
17
|
+
Play the sound at the given volume level. Full volume if none given
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
self.source.set_volume(volume)
|
|
21
|
+
self.source.play()
|
|
22
|
+
|
|
23
|
+
def stop(self):
|
|
24
|
+
"""
|
|
25
|
+
Stops the sound
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
28
|
self.source.stop()
|
basilisk/bsk_assets/cube.obj
CHANGED
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
# Blender 4.1.0
|
|
2
|
-
# www.blender.org
|
|
3
|
-
mtllib cube.mtl
|
|
4
|
-
o Cube
|
|
5
|
-
v -1.000000 -1.000000 1.000000
|
|
6
|
-
v -1.000000 1.000000 1.000000
|
|
7
|
-
v -1.000000 -1.000000 -1.000000
|
|
8
|
-
v -1.000000 1.000000 -1.000000
|
|
9
|
-
v 1.000000 -1.000000 1.000000
|
|
10
|
-
v 1.000000 1.000000 1.000000
|
|
11
|
-
v 1.000000 -1.000000 -1.000000
|
|
12
|
-
v 1.000000 1.000000 -1.000000
|
|
13
|
-
vn -1.0000 -0.0000 -0.0000
|
|
14
|
-
vn -0.0000 -0.0000 -1.0000
|
|
15
|
-
vn 1.0000 -0.0000 -0.0000
|
|
16
|
-
vn -0.0000 -0.0000 1.0000
|
|
17
|
-
vn -0.0000 -1.0000 -0.0000
|
|
18
|
-
vn -0.0000 1.0000 -0.0000
|
|
19
|
-
vt 0.002191 0.000000
|
|
20
|
-
vt 0.997809 0.002461
|
|
21
|
-
vt 0.996578 0.998078
|
|
22
|
-
vt 0.002191 0.994387
|
|
23
|
-
vt 0.002191 0.005152
|
|
24
|
-
vt 1.000269 0.001461
|
|
25
|
-
vt 0.996578 0.999539
|
|
26
|
-
vt 0.003422 0.998309
|
|
27
|
-
vt 0.000961 0.000461
|
|
28
|
-
vt 0.999039 -0.004461
|
|
29
|
-
vt 0.996578 0.996078
|
|
30
|
-
vt 0.002191 0.993618
|
|
31
|
-
vt 0.003422 -0.001769
|
|
32
|
-
vt 1.001500 0.001922
|
|
33
|
-
vt 0.996578 0.997539
|
|
34
|
-
vt 0.002191 1.001230
|
|
35
|
-
vt 0.005652 0.000461
|
|
36
|
-
vt 0.997578 0.000461
|
|
37
|
-
vt 0.995117 1.001000
|
|
38
|
-
vt 0.000730 0.998539
|
|
39
|
-
vt 0.001191 -0.000769
|
|
40
|
-
vt 1.000000 0.000000
|
|
41
|
-
vt 0.997479 0.997489
|
|
42
|
-
vt 0.006113 0.997309
|
|
43
|
-
s 0
|
|
44
|
-
f 1/1/1 2/2/1 4/3/1 3/4/1
|
|
45
|
-
f 3/5/2 4/6/2 8/7/2 7/8/2
|
|
46
|
-
f 7/9/3 8/10/3 6/11/3 5/12/3
|
|
47
|
-
f 5/13/4 6/14/4 2/15/4 1/16/4
|
|
48
|
-
f 3/17/5 7/18/5 5/19/5 1/20/5
|
|
1
|
+
# Blender 4.1.0
|
|
2
|
+
# www.blender.org
|
|
3
|
+
mtllib cube.mtl
|
|
4
|
+
o Cube
|
|
5
|
+
v -1.000000 -1.000000 1.000000
|
|
6
|
+
v -1.000000 1.000000 1.000000
|
|
7
|
+
v -1.000000 -1.000000 -1.000000
|
|
8
|
+
v -1.000000 1.000000 -1.000000
|
|
9
|
+
v 1.000000 -1.000000 1.000000
|
|
10
|
+
v 1.000000 1.000000 1.000000
|
|
11
|
+
v 1.000000 -1.000000 -1.000000
|
|
12
|
+
v 1.000000 1.000000 -1.000000
|
|
13
|
+
vn -1.0000 -0.0000 -0.0000
|
|
14
|
+
vn -0.0000 -0.0000 -1.0000
|
|
15
|
+
vn 1.0000 -0.0000 -0.0000
|
|
16
|
+
vn -0.0000 -0.0000 1.0000
|
|
17
|
+
vn -0.0000 -1.0000 -0.0000
|
|
18
|
+
vn -0.0000 1.0000 -0.0000
|
|
19
|
+
vt 0.002191 0.000000
|
|
20
|
+
vt 0.997809 0.002461
|
|
21
|
+
vt 0.996578 0.998078
|
|
22
|
+
vt 0.002191 0.994387
|
|
23
|
+
vt 0.002191 0.005152
|
|
24
|
+
vt 1.000269 0.001461
|
|
25
|
+
vt 0.996578 0.999539
|
|
26
|
+
vt 0.003422 0.998309
|
|
27
|
+
vt 0.000961 0.000461
|
|
28
|
+
vt 0.999039 -0.004461
|
|
29
|
+
vt 0.996578 0.996078
|
|
30
|
+
vt 0.002191 0.993618
|
|
31
|
+
vt 0.003422 -0.001769
|
|
32
|
+
vt 1.001500 0.001922
|
|
33
|
+
vt 0.996578 0.997539
|
|
34
|
+
vt 0.002191 1.001230
|
|
35
|
+
vt 0.005652 0.000461
|
|
36
|
+
vt 0.997578 0.000461
|
|
37
|
+
vt 0.995117 1.001000
|
|
38
|
+
vt 0.000730 0.998539
|
|
39
|
+
vt 0.001191 -0.000769
|
|
40
|
+
vt 1.000000 0.000000
|
|
41
|
+
vt 0.997479 0.997489
|
|
42
|
+
vt 0.006113 0.997309
|
|
43
|
+
s 0
|
|
44
|
+
f 1/1/1 2/2/1 4/3/1 3/4/1
|
|
45
|
+
f 3/5/2 4/6/2 8/7/2 7/8/2
|
|
46
|
+
f 7/9/3 8/10/3 6/11/3 5/12/3
|
|
47
|
+
f 5/13/4 6/14/4 2/15/4 1/16/4
|
|
48
|
+
f 3/17/5 7/18/5 5/19/5 1/20/5
|
|
49
49
|
f 8/21/6 4/22/6 2/23/6 6/24/6
|
|
@@ -1,103 +1,103 @@
|
|
|
1
|
-
import glm
|
|
2
|
-
from ...generic.abstract_bvh import AbstractAABB as AABB
|
|
3
|
-
from ...generic.collisions import collide_aabb_aabb, collide_aabb_line
|
|
4
|
-
from ...generic.meshes import get_aabb_surface_area
|
|
5
|
-
from ..collider import Collider
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class BroadAABB(AABB):
|
|
9
|
-
a: AABB | Collider
|
|
10
|
-
"""The first child of the AABB"""
|
|
11
|
-
b: AABB | Collider
|
|
12
|
-
"""The second child of the AABB"""
|
|
13
|
-
top_right: glm.vec3
|
|
14
|
-
"""furthest positive vertex of the AABB"""
|
|
15
|
-
bottom_left: glm.vec3
|
|
16
|
-
"""furthest negative vertex of the AABB"""
|
|
17
|
-
parent: AABB
|
|
18
|
-
"""Back reference to the parent AABB"""
|
|
19
|
-
|
|
20
|
-
def __init__(self, a: AABB | Collider, b: AABB | Collider, parent: AABB) -> None:
|
|
21
|
-
self.a = a
|
|
22
|
-
self.b = b
|
|
23
|
-
self.parent = parent
|
|
24
|
-
|
|
25
|
-
# calculate extreme points
|
|
26
|
-
self.update_points()
|
|
27
|
-
|
|
28
|
-
def update_points(self) -> None:
|
|
29
|
-
"""
|
|
30
|
-
Updates the extreme points of the AABB based on the children
|
|
31
|
-
"""
|
|
32
|
-
self.top_right = glm.max(self.a.top_right, self.b.top_right)
|
|
33
|
-
self.bottom_left = glm.min(self.a.bottom_left, self.b.bottom_left)
|
|
34
|
-
|
|
35
|
-
def find_sibling(self, collider: Collider, inherited: float) -> tuple[float, AABB | Collider]:
|
|
36
|
-
"""
|
|
37
|
-
Determines the best sibling for inserting a collider into the BVH
|
|
38
|
-
"""
|
|
39
|
-
# compute estimate sa
|
|
40
|
-
top_right = glm.max(self.top_right, collider.top_right)
|
|
41
|
-
bottom_left = glm.min(self.bottom_left, collider.bottom_left)
|
|
42
|
-
union_area = get_aabb_surface_area(top_right, bottom_left)
|
|
43
|
-
|
|
44
|
-
# compute lowest cost and determine if children are a viable option
|
|
45
|
-
c_best = union_area + inherited
|
|
46
|
-
|
|
47
|
-
delta_surface_area = union_area - self.surface_area
|
|
48
|
-
|
|
49
|
-
c_low = collider.aabb_surface_area + delta_surface_area + inherited
|
|
50
|
-
|
|
51
|
-
# investigate children
|
|
52
|
-
best_sibling = self
|
|
53
|
-
if c_low >= c_best: return c_best, best_sibling
|
|
54
|
-
|
|
55
|
-
for child in (self.a, self.b):
|
|
56
|
-
if isinstance(child, BroadAABB): child_c, child_aabb = child.find_sibling(collider, inherited + delta_surface_area)
|
|
57
|
-
else:
|
|
58
|
-
# compute cost for child
|
|
59
|
-
top_right = glm.max(self.top_right, child.top_right)
|
|
60
|
-
bottom_left = glm.min(self.bottom_left, child.bottom_left)
|
|
61
|
-
union_area = get_aabb_surface_area(top_right, bottom_left)
|
|
62
|
-
|
|
63
|
-
child_c, child_aabb = union_area + inherited, child
|
|
64
|
-
|
|
65
|
-
if child_c < c_best: c_best, best_sibling = child_c, child_aabb
|
|
66
|
-
|
|
67
|
-
return c_best, best_sibling
|
|
68
|
-
|
|
69
|
-
def get_collided(self, collider: Collider) -> list[Collider]:
|
|
70
|
-
"""
|
|
71
|
-
Returns which objects may be colliding from the BVH
|
|
72
|
-
"""
|
|
73
|
-
if not collide_aabb_aabb(self.top_right, self.bottom_left, collider.top_right, collider.bottom_left): return []
|
|
74
|
-
|
|
75
|
-
# test children
|
|
76
|
-
possible = []
|
|
77
|
-
if isinstance(self.a, BroadAABB): possible.extend(self.a.get_collided(collider))
|
|
78
|
-
elif collide_aabb_aabb(self.a.top_right, self.a.bottom_left, collider.top_right, collider.bottom_left): possible.append(self.a)
|
|
79
|
-
if isinstance(self.b, BroadAABB): possible.extend(self.b.get_collided(collider))
|
|
80
|
-
elif collide_aabb_aabb(self.b.top_right, self.b.bottom_left, collider.top_right, collider.bottom_left): possible.append(self.b)
|
|
81
|
-
return possible
|
|
82
|
-
|
|
83
|
-
def get_line_collided(self, position: glm.vec3, forward: glm.vec3) -> list[Collider]:
|
|
84
|
-
"""
|
|
85
|
-
Returns the colliders that may intersect with the given line
|
|
86
|
-
"""
|
|
87
|
-
if not collide_aabb_line(self.top_right, self.bottom_left, position, forward): return []
|
|
88
|
-
return (self.a.get_line_collided(position, forward) if isinstance(self.a, BroadAABB) else [self.a]) + (self.b.get_line_collided(position, forward) if isinstance(self.b, BroadAABB) else [self.b])
|
|
89
|
-
|
|
90
|
-
def get_all_aabbs(self, layer: int) -> list[tuple[glm.vec3, glm.vec3, int]]: # TODO test function
|
|
91
|
-
"""
|
|
92
|
-
Returns all AABBs, their extreme points, and their layer
|
|
93
|
-
"""
|
|
94
|
-
aabbs = [(self.top_right, self.bottom_left, layer)]
|
|
95
|
-
if isinstance(self.a, BroadAABB): aabbs += self.a.get_all_aabbs(layer + 1)
|
|
96
|
-
else: aabbs.append((self.a.top_right, self.a.bottom_left, layer + 1))
|
|
97
|
-
if isinstance(self.b, BroadAABB): aabbs += self.b.get_all_aabbs(layer + 1)
|
|
98
|
-
else: aabbs.append((self.b.top_right, self.b.bottom_left, layer + 1))
|
|
99
|
-
return aabbs
|
|
100
|
-
|
|
101
|
-
@property
|
|
102
|
-
def surface_area(self): return get_aabb_surface_area(self.top_right, self.bottom_left)
|
|
1
|
+
import glm
|
|
2
|
+
from ...generic.abstract_bvh import AbstractAABB as AABB
|
|
3
|
+
from ...generic.collisions import collide_aabb_aabb, collide_aabb_line
|
|
4
|
+
from ...generic.meshes import get_aabb_surface_area
|
|
5
|
+
from ..collider import Collider
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class BroadAABB(AABB):
|
|
9
|
+
a: AABB | Collider
|
|
10
|
+
"""The first child of the AABB"""
|
|
11
|
+
b: AABB | Collider
|
|
12
|
+
"""The second child of the AABB"""
|
|
13
|
+
top_right: glm.vec3
|
|
14
|
+
"""furthest positive vertex of the AABB"""
|
|
15
|
+
bottom_left: glm.vec3
|
|
16
|
+
"""furthest negative vertex of the AABB"""
|
|
17
|
+
parent: AABB
|
|
18
|
+
"""Back reference to the parent AABB"""
|
|
19
|
+
|
|
20
|
+
def __init__(self, a: AABB | Collider, b: AABB | Collider, parent: AABB) -> None:
|
|
21
|
+
self.a = a
|
|
22
|
+
self.b = b
|
|
23
|
+
self.parent = parent
|
|
24
|
+
|
|
25
|
+
# calculate extreme points
|
|
26
|
+
self.update_points()
|
|
27
|
+
|
|
28
|
+
def update_points(self) -> None:
|
|
29
|
+
"""
|
|
30
|
+
Updates the extreme points of the AABB based on the children
|
|
31
|
+
"""
|
|
32
|
+
self.top_right = glm.max(self.a.top_right, self.b.top_right)
|
|
33
|
+
self.bottom_left = glm.min(self.a.bottom_left, self.b.bottom_left)
|
|
34
|
+
|
|
35
|
+
def find_sibling(self, collider: Collider, inherited: float) -> tuple[float, AABB | Collider]:
|
|
36
|
+
"""
|
|
37
|
+
Determines the best sibling for inserting a collider into the BVH
|
|
38
|
+
"""
|
|
39
|
+
# compute estimate sa
|
|
40
|
+
top_right = glm.max(self.top_right, collider.top_right)
|
|
41
|
+
bottom_left = glm.min(self.bottom_left, collider.bottom_left)
|
|
42
|
+
union_area = get_aabb_surface_area(top_right, bottom_left)
|
|
43
|
+
|
|
44
|
+
# compute lowest cost and determine if children are a viable option
|
|
45
|
+
c_best = union_area + inherited
|
|
46
|
+
|
|
47
|
+
delta_surface_area = union_area - self.surface_area
|
|
48
|
+
|
|
49
|
+
c_low = collider.aabb_surface_area + delta_surface_area + inherited
|
|
50
|
+
|
|
51
|
+
# investigate children
|
|
52
|
+
best_sibling = self
|
|
53
|
+
if c_low >= c_best: return c_best, best_sibling
|
|
54
|
+
|
|
55
|
+
for child in (self.a, self.b):
|
|
56
|
+
if isinstance(child, BroadAABB): child_c, child_aabb = child.find_sibling(collider, inherited + delta_surface_area)
|
|
57
|
+
else:
|
|
58
|
+
# compute cost for child
|
|
59
|
+
top_right = glm.max(self.top_right, child.top_right)
|
|
60
|
+
bottom_left = glm.min(self.bottom_left, child.bottom_left)
|
|
61
|
+
union_area = get_aabb_surface_area(top_right, bottom_left)
|
|
62
|
+
|
|
63
|
+
child_c, child_aabb = union_area + inherited, child
|
|
64
|
+
|
|
65
|
+
if child_c < c_best: c_best, best_sibling = child_c, child_aabb
|
|
66
|
+
|
|
67
|
+
return c_best, best_sibling
|
|
68
|
+
|
|
69
|
+
def get_collided(self, collider: Collider) -> list[Collider]:
|
|
70
|
+
"""
|
|
71
|
+
Returns which objects may be colliding from the BVH
|
|
72
|
+
"""
|
|
73
|
+
if not collide_aabb_aabb(self.top_right, self.bottom_left, collider.top_right, collider.bottom_left): return []
|
|
74
|
+
|
|
75
|
+
# test children
|
|
76
|
+
possible = []
|
|
77
|
+
if isinstance(self.a, BroadAABB): possible.extend(self.a.get_collided(collider))
|
|
78
|
+
elif collide_aabb_aabb(self.a.top_right, self.a.bottom_left, collider.top_right, collider.bottom_left): possible.append(self.a)
|
|
79
|
+
if isinstance(self.b, BroadAABB): possible.extend(self.b.get_collided(collider))
|
|
80
|
+
elif collide_aabb_aabb(self.b.top_right, self.b.bottom_left, collider.top_right, collider.bottom_left): possible.append(self.b)
|
|
81
|
+
return possible
|
|
82
|
+
|
|
83
|
+
def get_line_collided(self, position: glm.vec3, forward: glm.vec3) -> list[Collider]:
|
|
84
|
+
"""
|
|
85
|
+
Returns the colliders that may intersect with the given line
|
|
86
|
+
"""
|
|
87
|
+
if not collide_aabb_line(self.top_right, self.bottom_left, position, forward): return []
|
|
88
|
+
return (self.a.get_line_collided(position, forward) if isinstance(self.a, BroadAABB) else [self.a]) + (self.b.get_line_collided(position, forward) if isinstance(self.b, BroadAABB) else [self.b])
|
|
89
|
+
|
|
90
|
+
def get_all_aabbs(self, layer: int) -> list[tuple[glm.vec3, glm.vec3, int]]: # TODO test function
|
|
91
|
+
"""
|
|
92
|
+
Returns all AABBs, their extreme points, and their layer
|
|
93
|
+
"""
|
|
94
|
+
aabbs = [(self.top_right, self.bottom_left, layer)]
|
|
95
|
+
if isinstance(self.a, BroadAABB): aabbs += self.a.get_all_aabbs(layer + 1)
|
|
96
|
+
else: aabbs.append((self.a.top_right, self.a.bottom_left, layer + 1))
|
|
97
|
+
if isinstance(self.b, BroadAABB): aabbs += self.b.get_all_aabbs(layer + 1)
|
|
98
|
+
else: aabbs.append((self.b.top_right, self.b.bottom_left, layer + 1))
|
|
99
|
+
return aabbs
|
|
100
|
+
|
|
101
|
+
@property
|
|
102
|
+
def surface_area(self): return get_aabb_surface_area(self.top_right, self.bottom_left)
|
|
103
103
|
|