basilisk-engine 0.1.35__py3-none-any.whl → 0.1.37__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 -225
- 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 +178 -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 +93 -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 +109 -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 +291 -290
- 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 +10 -8
- basilisk/shaders/geometry.vert +41 -41
- basilisk/shaders/normal.frag +62 -59
- basilisk/shaders/normal.vert +96 -96
- basilisk/shaders/particle.frag +76 -71
- basilisk/shaders/particle.vert +86 -84
- basilisk/shaders/sky.frag +23 -9
- basilisk/shaders/sky.vert +13 -13
- basilisk_engine-0.1.37.dist-info/METADATA +89 -0
- basilisk_engine-0.1.37.dist-info/RECORD +110 -0
- {basilisk_engine-0.1.35.dist-info → basilisk_engine-0.1.37.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.35.dist-info/METADATA +0 -45
- basilisk_engine-0.1.35.dist-info/RECORD +0 -109
- {basilisk_engine-0.1.35.dist-info → basilisk_engine-0.1.37.dist-info}/top_level.txt +0 -0
basilisk/mesh/narrow_aabb.py
CHANGED
|
@@ -1,90 +1,90 @@
|
|
|
1
|
-
import glm
|
|
2
|
-
|
|
3
|
-
from basilisk.generic.collisions import collide_aabb_line
|
|
4
|
-
from .narrow_primative import NarrowPrimative
|
|
5
|
-
from ..generic.abstract_bvh import AbstractAABB as AABB
|
|
6
|
-
from ..generic.meshes import get_aabb_line_collision
|
|
7
|
-
|
|
8
|
-
class NarrowAABB(AABB):
|
|
9
|
-
top_right: glm.vec3
|
|
10
|
-
"""The furthest positive corner of the AABB"""
|
|
11
|
-
bottom_left: glm.vec3
|
|
12
|
-
"""The furthest negative corner of the AABB"""
|
|
13
|
-
geometric_center: glm.vec3
|
|
14
|
-
"""The center of the object calculated from its extreme points"""
|
|
15
|
-
a: AABB | NarrowPrimative
|
|
16
|
-
"""Child AABB or Collider 1"""
|
|
17
|
-
b: AABB | NarrowPrimative
|
|
18
|
-
"""Child AABB or Collider 2"""
|
|
19
|
-
|
|
20
|
-
def __init__(self, top_right:glm.vec3, bottom_left:glm.vec3, a: AABB, b: AABB) -> None:
|
|
21
|
-
self.top_right = top_right
|
|
22
|
-
self.bottom_left = bottom_left
|
|
23
|
-
self.geometric_center = (top_right + bottom_left) / 2
|
|
24
|
-
self.a = a
|
|
25
|
-
self.b = b
|
|
26
|
-
|
|
27
|
-
def get_possible_triangles(self, point: glm.vec3, vec: glm.vec3) -> list[int]:
|
|
28
|
-
"""
|
|
29
|
-
Determines the closest intersecting on the bvh
|
|
30
|
-
"""
|
|
31
|
-
indices = []
|
|
32
|
-
if not get_aabb_line_collision(self.top_right, self.bottom_left, point, vec): return indices
|
|
33
|
-
|
|
34
|
-
for child in (self.a, self.b):
|
|
35
|
-
|
|
36
|
-
# if child is another AABB
|
|
37
|
-
if isinstance(child, NarrowAABB):
|
|
38
|
-
indices += child.get_possible_triangles(point, vec)
|
|
39
|
-
continue
|
|
40
|
-
|
|
41
|
-
# if child is a primative
|
|
42
|
-
index = child.is_possible_triangle(point, vec)
|
|
43
|
-
if index == -1: continue
|
|
44
|
-
indices.append(index)
|
|
45
|
-
|
|
46
|
-
return indices
|
|
47
|
-
|
|
48
|
-
def get_best_dot(self, vec: glm.vec3) -> int:
|
|
49
|
-
"""
|
|
50
|
-
Returns the best triangle with the highest dot product with the vector from the geometric center to its AABB
|
|
51
|
-
"""
|
|
52
|
-
c = max(self.a, self.b, key=lambda x: glm.dot(x.geometric_center, vec))
|
|
53
|
-
if isinstance(c, NarrowAABB): return c.get_best_dot(vec)
|
|
54
|
-
return c.index
|
|
55
|
-
|
|
56
|
-
def get_all_aabbs(self, layer: int) -> list[tuple[glm.vec3, glm.vec3, int]]:
|
|
57
|
-
"""
|
|
58
|
-
Returns all AABBs, their extreme points, and their layer
|
|
59
|
-
"""
|
|
60
|
-
aabbs = [(self.top_right, self.bottom_left, layer)]
|
|
61
|
-
if isinstance(self.a, NarrowAABB): aabbs += self.a.get_all_aabbs(layer + 1)
|
|
62
|
-
else: aabbs.append((self.a.top_right, self.a.bottom_left, layer + 1))
|
|
63
|
-
if isinstance(self.b, NarrowAABB): aabbs += self.b.get_all_aabbs(layer + 1)
|
|
64
|
-
else: aabbs.append((self.b.top_right, self.b.bottom_left, layer + 1))
|
|
65
|
-
return aabbs
|
|
66
|
-
|
|
67
|
-
def get_tested_aabbs(self, point: glm.vec3, vec: glm.vec3, layer: int) -> list[tuple[glm.vec3, glm.vec3, int]]:
|
|
68
|
-
"""
|
|
69
|
-
Returns all AABBs, their extreme points, and their layer
|
|
70
|
-
"""
|
|
71
|
-
aabbs = [(self.top_right, self.bottom_left, layer)]
|
|
72
|
-
|
|
73
|
-
if isinstance(self.a, NarrowAABB):
|
|
74
|
-
|
|
75
|
-
aabbs += self.a.get_all_aabbs(layer + 1)
|
|
76
|
-
else: aabbs.append((self.a.top_right, self.a.bottom_left, layer + 1))
|
|
77
|
-
|
|
78
|
-
if isinstance(self.b, NarrowAABB):
|
|
79
|
-
|
|
80
|
-
aabbs += self.b.get_all_aabbs(layer + 1)
|
|
81
|
-
else: aabbs.append((self.b.top_right, self.b.bottom_left, layer + 1))
|
|
82
|
-
|
|
83
|
-
return aabbs
|
|
84
|
-
|
|
85
|
-
def get_line_collided(self, position: glm.vec3, forward: glm.vec3) -> list[int]:
|
|
86
|
-
"""
|
|
87
|
-
Returns the colliders that may intersect with the given line
|
|
88
|
-
"""
|
|
89
|
-
if not collide_aabb_line(self.top_right, self.bottom_left, position, forward): return []
|
|
1
|
+
import glm
|
|
2
|
+
|
|
3
|
+
from basilisk.generic.collisions import collide_aabb_line
|
|
4
|
+
from .narrow_primative import NarrowPrimative
|
|
5
|
+
from ..generic.abstract_bvh import AbstractAABB as AABB
|
|
6
|
+
from ..generic.meshes import get_aabb_line_collision
|
|
7
|
+
|
|
8
|
+
class NarrowAABB(AABB):
|
|
9
|
+
top_right: glm.vec3
|
|
10
|
+
"""The furthest positive corner of the AABB"""
|
|
11
|
+
bottom_left: glm.vec3
|
|
12
|
+
"""The furthest negative corner of the AABB"""
|
|
13
|
+
geometric_center: glm.vec3
|
|
14
|
+
"""The center of the object calculated from its extreme points"""
|
|
15
|
+
a: AABB | NarrowPrimative
|
|
16
|
+
"""Child AABB or Collider 1"""
|
|
17
|
+
b: AABB | NarrowPrimative
|
|
18
|
+
"""Child AABB or Collider 2"""
|
|
19
|
+
|
|
20
|
+
def __init__(self, top_right:glm.vec3, bottom_left:glm.vec3, a: AABB, b: AABB) -> None:
|
|
21
|
+
self.top_right = top_right
|
|
22
|
+
self.bottom_left = bottom_left
|
|
23
|
+
self.geometric_center = (top_right + bottom_left) / 2
|
|
24
|
+
self.a = a
|
|
25
|
+
self.b = b
|
|
26
|
+
|
|
27
|
+
def get_possible_triangles(self, point: glm.vec3, vec: glm.vec3) -> list[int]:
|
|
28
|
+
"""
|
|
29
|
+
Determines the closest intersecting on the bvh
|
|
30
|
+
"""
|
|
31
|
+
indices = []
|
|
32
|
+
if not get_aabb_line_collision(self.top_right, self.bottom_left, point, vec): return indices
|
|
33
|
+
|
|
34
|
+
for child in (self.a, self.b):
|
|
35
|
+
|
|
36
|
+
# if child is another AABB
|
|
37
|
+
if isinstance(child, NarrowAABB):
|
|
38
|
+
indices += child.get_possible_triangles(point, vec)
|
|
39
|
+
continue
|
|
40
|
+
|
|
41
|
+
# if child is a primative
|
|
42
|
+
index = child.is_possible_triangle(point, vec)
|
|
43
|
+
if index == -1: continue
|
|
44
|
+
indices.append(index)
|
|
45
|
+
|
|
46
|
+
return indices
|
|
47
|
+
|
|
48
|
+
def get_best_dot(self, vec: glm.vec3) -> int:
|
|
49
|
+
"""
|
|
50
|
+
Returns the best triangle with the highest dot product with the vector from the geometric center to its AABB
|
|
51
|
+
"""
|
|
52
|
+
c = max(self.a, self.b, key=lambda x: glm.dot(x.geometric_center, vec))
|
|
53
|
+
if isinstance(c, NarrowAABB): return c.get_best_dot(vec)
|
|
54
|
+
return c.index
|
|
55
|
+
|
|
56
|
+
def get_all_aabbs(self, layer: int) -> list[tuple[glm.vec3, glm.vec3, int]]:
|
|
57
|
+
"""
|
|
58
|
+
Returns all AABBs, their extreme points, and their layer
|
|
59
|
+
"""
|
|
60
|
+
aabbs = [(self.top_right, self.bottom_left, layer)]
|
|
61
|
+
if isinstance(self.a, NarrowAABB): aabbs += self.a.get_all_aabbs(layer + 1)
|
|
62
|
+
else: aabbs.append((self.a.top_right, self.a.bottom_left, layer + 1))
|
|
63
|
+
if isinstance(self.b, NarrowAABB): aabbs += self.b.get_all_aabbs(layer + 1)
|
|
64
|
+
else: aabbs.append((self.b.top_right, self.b.bottom_left, layer + 1))
|
|
65
|
+
return aabbs
|
|
66
|
+
|
|
67
|
+
def get_tested_aabbs(self, point: glm.vec3, vec: glm.vec3, layer: int) -> list[tuple[glm.vec3, glm.vec3, int]]:
|
|
68
|
+
"""
|
|
69
|
+
Returns all AABBs, their extreme points, and their layer
|
|
70
|
+
"""
|
|
71
|
+
aabbs = [(self.top_right, self.bottom_left, layer)]
|
|
72
|
+
|
|
73
|
+
if isinstance(self.a, NarrowAABB):
|
|
74
|
+
|
|
75
|
+
aabbs += self.a.get_all_aabbs(layer + 1)
|
|
76
|
+
else: aabbs.append((self.a.top_right, self.a.bottom_left, layer + 1))
|
|
77
|
+
|
|
78
|
+
if isinstance(self.b, NarrowAABB):
|
|
79
|
+
|
|
80
|
+
aabbs += self.b.get_all_aabbs(layer + 1)
|
|
81
|
+
else: aabbs.append((self.b.top_right, self.b.bottom_left, layer + 1))
|
|
82
|
+
|
|
83
|
+
return aabbs
|
|
84
|
+
|
|
85
|
+
def get_line_collided(self, position: glm.vec3, forward: glm.vec3) -> list[int]:
|
|
86
|
+
"""
|
|
87
|
+
Returns the colliders that may intersect with the given line
|
|
88
|
+
"""
|
|
89
|
+
if not collide_aabb_line(self.top_right, self.bottom_left, position, forward): return []
|
|
90
90
|
return (self.a.get_line_collided(position, forward) if isinstance(self.a, NarrowAABB) else [self.a.index]) + (self.b.get_line_collided(position, forward) if isinstance(self.b, NarrowAABB) else [self.b.index])
|
basilisk/mesh/narrow_bvh.py
CHANGED
|
@@ -1,92 +1,92 @@
|
|
|
1
|
-
import glm
|
|
2
|
-
from .narrow_aabb import NarrowAABB
|
|
3
|
-
from .narrow_primative import NarrowPrimative
|
|
4
|
-
from ..generic.abstract_bvh import AbstractAABB as BVH
|
|
5
|
-
from ..generic.meshes import get_extreme_points_np, get_aabb_surface_area
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class NarrowBVH(BVH):
|
|
9
|
-
root: NarrowAABB | NarrowPrimative
|
|
10
|
-
"""Root aabb used for the start of all collisions"""
|
|
11
|
-
primatives: list[NarrowPrimative]
|
|
12
|
-
"""All of the primatives in the BVH associated with triangles in the mesh"""
|
|
13
|
-
mesh: ...
|
|
14
|
-
"""Back reference to the parent mesh"""
|
|
15
|
-
|
|
16
|
-
def __init__(self, mesh) -> None:
|
|
17
|
-
self.mesh = mesh
|
|
18
|
-
self.primatives = []
|
|
19
|
-
for index, triangle in enumerate(self.mesh.indices):
|
|
20
|
-
points = [self.mesh.points[t] for t in triangle] # TODO check np array accessing
|
|
21
|
-
top_right, bottom_left = get_extreme_points_np(points)
|
|
22
|
-
self.primatives.append(NarrowPrimative(top_right, bottom_left, index))
|
|
23
|
-
|
|
24
|
-
top_right = mesh.geometric_center + mesh.half_dimensions
|
|
25
|
-
bottom_left = mesh.geometric_center - mesh.half_dimensions
|
|
26
|
-
self.root = self.build_bvh(self.primatives, top_right, bottom_left)
|
|
27
|
-
|
|
28
|
-
def build_bvh(self, primatives: list[NarrowPrimative], top_right: glm.vec3, bottom_left: glm.vec3) -> NarrowAABB | NarrowPrimative:
|
|
29
|
-
"""
|
|
30
|
-
Creates a root node for the BVH with the given primatives and bounds
|
|
31
|
-
"""
|
|
32
|
-
best_cost = -1
|
|
33
|
-
best_split = primatives
|
|
34
|
-
best_aabb = []
|
|
35
|
-
count = len(primatives) // 2
|
|
36
|
-
|
|
37
|
-
# return primative if it is a leaf
|
|
38
|
-
if not count: return primatives[0]
|
|
39
|
-
|
|
40
|
-
for axis in range(3):
|
|
41
|
-
# sort primatives along axis and determine if it is lowest cost
|
|
42
|
-
primatives.sort(key=lambda p: p.geometric_center[axis])
|
|
43
|
-
aabb = self.calculate_primative_aabb(primatives[:count]) + self.calculate_primative_aabb(primatives[count:])
|
|
44
|
-
cost = get_aabb_surface_area(aabb[0], aabb[1]) + get_aabb_surface_area(aabb[2], aabb[3])
|
|
45
|
-
|
|
46
|
-
if best_cost < 0 or cost < best_cost:
|
|
47
|
-
best_cost = cost
|
|
48
|
-
best_split = list(primatives) # TODO ensure that this is a shallow copy
|
|
49
|
-
best_aabb = aabb
|
|
50
|
-
|
|
51
|
-
a = self.build_bvh(best_split[:count], best_aabb[0], best_aabb[1])
|
|
52
|
-
b = self.build_bvh(best_split[count:], best_aabb[2], best_aabb[3])
|
|
53
|
-
return NarrowAABB(top_right, bottom_left, a, b)
|
|
54
|
-
|
|
55
|
-
def calculate_primative_aabb(self, primatives: list[NarrowPrimative]) -> float:
|
|
56
|
-
"""
|
|
57
|
-
Computes the aabb surface area of the primatives
|
|
58
|
-
"""
|
|
59
|
-
points = set()
|
|
60
|
-
for primative in primatives:
|
|
61
|
-
points.update([tuple(self.mesh.points[t]) for t in self.mesh.indices[primative.index]])
|
|
62
|
-
return list(get_extreme_points_np(list(points)))
|
|
63
|
-
|
|
64
|
-
def get_possible_triangles(self, point: glm.vec3, vec: glm.vec3) -> list[int]:
|
|
65
|
-
"""
|
|
66
|
-
Determines the closest intersecting on the bvh
|
|
67
|
-
"""
|
|
68
|
-
if isinstance(self.root, NarrowAABB): return self.root.get_possible_triangles(point, vec)
|
|
69
|
-
index = self.root.is_possible_triangle(point, vec)
|
|
70
|
-
return [index] if index != -1 else []
|
|
71
|
-
|
|
72
|
-
def get_best_dot(self, vec: glm.vec3) -> int:
|
|
73
|
-
"""
|
|
74
|
-
Returns the best triangle with the highest dot product with the vector from the geometric center to its AABB
|
|
75
|
-
"""
|
|
76
|
-
if isinstance(self.root, NarrowAABB): return self.root.get_best_dot(vec)
|
|
77
|
-
return self.root.index
|
|
78
|
-
|
|
79
|
-
def get_all_aabbs(self) -> list[tuple[glm.vec3, glm.vec3, int]]:
|
|
80
|
-
"""
|
|
81
|
-
Returns all AABBs, their extreme points, and their layer
|
|
82
|
-
"""
|
|
83
|
-
if isinstance(self.root, NarrowAABB): return self.root.get_all_aabbs(0)
|
|
84
|
-
return [(self.root.top_right, self.root.bottom_left, 0)]
|
|
85
|
-
|
|
86
|
-
def get_line_collided(self, position: glm.vec3, forward: glm.vec3) -> list[tuple[int, int, int]]:
|
|
87
|
-
"""
|
|
88
|
-
Determines which triangles are intersecting with the given line segment. Returns the indices of the triangle contained in the mesh points list
|
|
89
|
-
"""
|
|
90
|
-
if isinstance(self.root, NarrowAABB): return self.root.get_line_collided(position, forward)
|
|
91
|
-
return self.root.index
|
|
1
|
+
import glm
|
|
2
|
+
from .narrow_aabb import NarrowAABB
|
|
3
|
+
from .narrow_primative import NarrowPrimative
|
|
4
|
+
from ..generic.abstract_bvh import AbstractAABB as BVH
|
|
5
|
+
from ..generic.meshes import get_extreme_points_np, get_aabb_surface_area
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class NarrowBVH(BVH):
|
|
9
|
+
root: NarrowAABB | NarrowPrimative
|
|
10
|
+
"""Root aabb used for the start of all collisions"""
|
|
11
|
+
primatives: list[NarrowPrimative]
|
|
12
|
+
"""All of the primatives in the BVH associated with triangles in the mesh"""
|
|
13
|
+
mesh: ...
|
|
14
|
+
"""Back reference to the parent mesh"""
|
|
15
|
+
|
|
16
|
+
def __init__(self, mesh) -> None:
|
|
17
|
+
self.mesh = mesh
|
|
18
|
+
self.primatives = []
|
|
19
|
+
for index, triangle in enumerate(self.mesh.indices):
|
|
20
|
+
points = [self.mesh.points[t] for t in triangle] # TODO check np array accessing
|
|
21
|
+
top_right, bottom_left = get_extreme_points_np(points)
|
|
22
|
+
self.primatives.append(NarrowPrimative(top_right, bottom_left, index))
|
|
23
|
+
|
|
24
|
+
top_right = mesh.geometric_center + mesh.half_dimensions
|
|
25
|
+
bottom_left = mesh.geometric_center - mesh.half_dimensions
|
|
26
|
+
self.root = self.build_bvh(self.primatives, top_right, bottom_left)
|
|
27
|
+
|
|
28
|
+
def build_bvh(self, primatives: list[NarrowPrimative], top_right: glm.vec3, bottom_left: glm.vec3) -> NarrowAABB | NarrowPrimative:
|
|
29
|
+
"""
|
|
30
|
+
Creates a root node for the BVH with the given primatives and bounds
|
|
31
|
+
"""
|
|
32
|
+
best_cost = -1
|
|
33
|
+
best_split = primatives
|
|
34
|
+
best_aabb = []
|
|
35
|
+
count = len(primatives) // 2
|
|
36
|
+
|
|
37
|
+
# return primative if it is a leaf
|
|
38
|
+
if not count: return primatives[0]
|
|
39
|
+
|
|
40
|
+
for axis in range(3):
|
|
41
|
+
# sort primatives along axis and determine if it is lowest cost
|
|
42
|
+
primatives.sort(key=lambda p: p.geometric_center[axis])
|
|
43
|
+
aabb = self.calculate_primative_aabb(primatives[:count]) + self.calculate_primative_aabb(primatives[count:])
|
|
44
|
+
cost = get_aabb_surface_area(aabb[0], aabb[1]) + get_aabb_surface_area(aabb[2], aabb[3])
|
|
45
|
+
|
|
46
|
+
if best_cost < 0 or cost < best_cost:
|
|
47
|
+
best_cost = cost
|
|
48
|
+
best_split = list(primatives) # TODO ensure that this is a shallow copy
|
|
49
|
+
best_aabb = aabb
|
|
50
|
+
|
|
51
|
+
a = self.build_bvh(best_split[:count], best_aabb[0], best_aabb[1])
|
|
52
|
+
b = self.build_bvh(best_split[count:], best_aabb[2], best_aabb[3])
|
|
53
|
+
return NarrowAABB(top_right, bottom_left, a, b)
|
|
54
|
+
|
|
55
|
+
def calculate_primative_aabb(self, primatives: list[NarrowPrimative]) -> float:
|
|
56
|
+
"""
|
|
57
|
+
Computes the aabb surface area of the primatives
|
|
58
|
+
"""
|
|
59
|
+
points = set()
|
|
60
|
+
for primative in primatives:
|
|
61
|
+
points.update([tuple(self.mesh.points[t]) for t in self.mesh.indices[primative.index]])
|
|
62
|
+
return list(get_extreme_points_np(list(points)))
|
|
63
|
+
|
|
64
|
+
def get_possible_triangles(self, point: glm.vec3, vec: glm.vec3) -> list[int]:
|
|
65
|
+
"""
|
|
66
|
+
Determines the closest intersecting on the bvh
|
|
67
|
+
"""
|
|
68
|
+
if isinstance(self.root, NarrowAABB): return self.root.get_possible_triangles(point, vec)
|
|
69
|
+
index = self.root.is_possible_triangle(point, vec)
|
|
70
|
+
return [index] if index != -1 else []
|
|
71
|
+
|
|
72
|
+
def get_best_dot(self, vec: glm.vec3) -> int:
|
|
73
|
+
"""
|
|
74
|
+
Returns the best triangle with the highest dot product with the vector from the geometric center to its AABB
|
|
75
|
+
"""
|
|
76
|
+
if isinstance(self.root, NarrowAABB): return self.root.get_best_dot(vec)
|
|
77
|
+
return self.root.index
|
|
78
|
+
|
|
79
|
+
def get_all_aabbs(self) -> list[tuple[glm.vec3, glm.vec3, int]]:
|
|
80
|
+
"""
|
|
81
|
+
Returns all AABBs, their extreme points, and their layer
|
|
82
|
+
"""
|
|
83
|
+
if isinstance(self.root, NarrowAABB): return self.root.get_all_aabbs(0)
|
|
84
|
+
return [(self.root.top_right, self.root.bottom_left, 0)]
|
|
85
|
+
|
|
86
|
+
def get_line_collided(self, position: glm.vec3, forward: glm.vec3) -> list[tuple[int, int, int]]:
|
|
87
|
+
"""
|
|
88
|
+
Determines which triangles are intersecting with the given line segment. Returns the indices of the triangle contained in the mesh points list
|
|
89
|
+
"""
|
|
90
|
+
if isinstance(self.root, NarrowAABB): return self.root.get_line_collided(position, forward)
|
|
91
|
+
return self.root.index
|
|
92
92
|
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import glm
|
|
2
|
-
from ..generic.meshes import get_aabb_line_collision
|
|
3
|
-
|
|
4
|
-
class NarrowPrimative():
|
|
5
|
-
top_right: glm.vec3
|
|
6
|
-
"""The furthest positive corner of the AABB"""
|
|
7
|
-
bottom_left: glm.vec3
|
|
8
|
-
"""The furthest negative corner of the AABB"""
|
|
9
|
-
geometric_center: glm.vec3
|
|
10
|
-
"""The centroid of the primative"""
|
|
11
|
-
index: int
|
|
12
|
-
"""the index of the triangle in the mesh"""
|
|
13
|
-
|
|
14
|
-
def __init__(self, top_right:glm.vec3, bottom_left:glm.vec3, index: int) -> None:
|
|
15
|
-
self.top_right = top_right
|
|
16
|
-
self.bottom_left = bottom_left
|
|
17
|
-
self.geometric_center = (self.top_right + self.bottom_left) / 2
|
|
18
|
-
self.index = index
|
|
19
|
-
|
|
20
|
-
def is_possible_triangle(self, point: glm.vec3, vec: glm.vec3) -> int:
|
|
21
|
-
"""
|
|
22
|
-
Determines if this triangle's AABB intersects with the line
|
|
23
|
-
"""
|
|
1
|
+
import glm
|
|
2
|
+
from ..generic.meshes import get_aabb_line_collision
|
|
3
|
+
|
|
4
|
+
class NarrowPrimative():
|
|
5
|
+
top_right: glm.vec3
|
|
6
|
+
"""The furthest positive corner of the AABB"""
|
|
7
|
+
bottom_left: glm.vec3
|
|
8
|
+
"""The furthest negative corner of the AABB"""
|
|
9
|
+
geometric_center: glm.vec3
|
|
10
|
+
"""The centroid of the primative"""
|
|
11
|
+
index: int
|
|
12
|
+
"""the index of the triangle in the mesh"""
|
|
13
|
+
|
|
14
|
+
def __init__(self, top_right:glm.vec3, bottom_left:glm.vec3, index: int) -> None:
|
|
15
|
+
self.top_right = top_right
|
|
16
|
+
self.bottom_left = bottom_left
|
|
17
|
+
self.geometric_center = (self.top_right + self.bottom_left) / 2
|
|
18
|
+
self.index = index
|
|
19
|
+
|
|
20
|
+
def is_possible_triangle(self, point: glm.vec3, vec: glm.vec3) -> int:
|
|
21
|
+
"""
|
|
22
|
+
Determines if this triangle's AABB intersects with the line
|
|
23
|
+
"""
|
|
24
24
|
return self.index if get_aabb_line_collision(self.top_right, self.bottom_left, point, vec) else -1
|
basilisk/nodes/helper.py
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
import glm
|
|
2
|
-
# from .node import Node
|
|
3
|
-
from ..mesh.mesh import Mesh
|
|
4
|
-
from ..render.material import Material
|
|
5
|
-
|
|
6
|
-
def node_is(node, position: glm.vec3=None, scale: glm.vec3=None, rotation: glm.quat=None, forward: glm.vec3=None, mesh: Mesh=None, material: Material=None, velocity: glm.vec3=None, rotational_velocity: glm.quat=None, physics: bool=None, mass: float=None, collisions: bool=None, static_friction: float=None, kinetic_friction: float=None, elasticity: float=None, collision_group: float=None, name: str=None, tags: list[str]=None,static: bool=None) -> bool:
|
|
7
|
-
"""
|
|
8
|
-
Determine if a node meets the requirements given by the parameters. If a parameter is None, then the filter is not applied.
|
|
9
|
-
"""
|
|
10
|
-
return all([
|
|
11
|
-
position is None or position == node.position,
|
|
12
|
-
scale is None or scale == node.scale,
|
|
13
|
-
rotation is None or rotation == node.rotation,
|
|
14
|
-
forward is None or forward == node.forward,
|
|
15
|
-
mesh is None or mesh == node.mesh,
|
|
16
|
-
material is None or material == node.material,
|
|
17
|
-
velocity is None or velocity == node.velocity,
|
|
18
|
-
rotational_velocity is None or rotational_velocity == node.rotational_velocity,
|
|
19
|
-
physics is None or bool(node.physics_body) == physics,
|
|
20
|
-
mass is None or (node.physics_body and mass == node.physics_body.mass),
|
|
21
|
-
collisions is None or bool(node.collider) == collisions,
|
|
22
|
-
static_friction is None or (node.collider and node.collider.static_friction == static_friction),
|
|
23
|
-
kinetic_friction is None or (node.collider and node.collider.kinetic_friction == kinetic_friction),
|
|
24
|
-
elasticity is None or (node.collider and node.collider.elasticity == elasticity),
|
|
25
|
-
collision_group is None or (node.collider and node.collider.collision_group == collision_group),
|
|
26
|
-
name is None or node.name == name,
|
|
27
|
-
tags is None or all([tag in node.tags for tag in tags]),
|
|
28
|
-
static is None or node.static == static
|
|
1
|
+
import glm
|
|
2
|
+
# from .node import Node
|
|
3
|
+
from ..mesh.mesh import Mesh
|
|
4
|
+
from ..render.material import Material
|
|
5
|
+
|
|
6
|
+
def node_is(node, position: glm.vec3=None, scale: glm.vec3=None, rotation: glm.quat=None, forward: glm.vec3=None, mesh: Mesh=None, material: Material=None, velocity: glm.vec3=None, rotational_velocity: glm.quat=None, physics: bool=None, mass: float=None, collisions: bool=None, static_friction: float=None, kinetic_friction: float=None, elasticity: float=None, collision_group: float=None, name: str=None, tags: list[str]=None,static: bool=None) -> bool:
|
|
7
|
+
"""
|
|
8
|
+
Determine if a node meets the requirements given by the parameters. If a parameter is None, then the filter is not applied.
|
|
9
|
+
"""
|
|
10
|
+
return all([
|
|
11
|
+
position is None or position == node.position,
|
|
12
|
+
scale is None or scale == node.scale,
|
|
13
|
+
rotation is None or rotation == node.rotation,
|
|
14
|
+
forward is None or forward == node.forward,
|
|
15
|
+
mesh is None or mesh == node.mesh,
|
|
16
|
+
material is None or material == node.material,
|
|
17
|
+
velocity is None or velocity == node.velocity,
|
|
18
|
+
rotational_velocity is None or rotational_velocity == node.rotational_velocity,
|
|
19
|
+
physics is None or bool(node.physics_body) == physics,
|
|
20
|
+
mass is None or (node.physics_body and mass == node.physics_body.mass),
|
|
21
|
+
collisions is None or bool(node.collider) == collisions,
|
|
22
|
+
static_friction is None or (node.collider and node.collider.static_friction == static_friction),
|
|
23
|
+
kinetic_friction is None or (node.collider and node.collider.kinetic_friction == kinetic_friction),
|
|
24
|
+
elasticity is None or (node.collider and node.collider.elasticity == elasticity),
|
|
25
|
+
collision_group is None or (node.collider and node.collider.collision_group == collision_group),
|
|
26
|
+
name is None or node.name == name,
|
|
27
|
+
tags is None or all([tag in node.tags for tag in tags]),
|
|
28
|
+
static is None or node.static == static
|
|
29
29
|
])
|