basilisk-engine 0.1.51__py3-none-any.whl → 0.1.53__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 +27 -27
- basilisk/audio/sound.py +40 -40
- 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 +53 -53
- basilisk/draw/draw.py +100 -100
- basilisk/draw/draw_handler.py +181 -181
- basilisk/draw/font_renderer.py +28 -28
- basilisk/engine.py +168 -168
- 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 -82
- basilisk/generic/math.py +17 -17
- 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 -90
- 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 +709 -709
- basilisk/nodes/node_handler.py +107 -98
- basilisk/particles/particle_handler.py +69 -65
- basilisk/particles/particle_renderer.py +92 -93
- 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 +117 -117
- basilisk/render/camera.py +260 -260
- basilisk/render/chunk.py +113 -113
- basilisk/render/chunk_handler.py +167 -167
- basilisk/render/frame.py +130 -130
- basilisk/render/framebuffer.py +192 -192
- basilisk/render/image.py +128 -128
- 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 -232
- basilisk/render/material_handler.py +133 -133
- basilisk/render/post_process.py +180 -180
- basilisk/render/shader.py +135 -135
- basilisk/render/shader_handler.py +109 -109
- basilisk/render/sky.py +119 -119
- basilisk/scene.py +295 -291
- basilisk/shaders/batch.frag +291 -291
- basilisk/shaders/batch.vert +117 -117
- basilisk/shaders/bloom_downsample.frag +23 -23
- basilisk/shaders/bloom_upsample.frag +33 -33
- basilisk/shaders/crt.frag +34 -34
- basilisk/shaders/draw.frag +27 -27
- basilisk/shaders/draw.vert +25 -25
- basilisk/shaders/filter.frag +22 -22
- basilisk/shaders/frame.frag +13 -13
- basilisk/shaders/frame.vert +13 -13
- basilisk/shaders/frame_hdr.frag +27 -27
- basilisk/shaders/geometry.frag +10 -10
- basilisk/shaders/geometry.vert +41 -41
- basilisk/shaders/normal.frag +62 -62
- basilisk/shaders/normal.vert +96 -96
- basilisk/shaders/particle.frag +81 -81
- basilisk/shaders/particle.vert +86 -86
- basilisk/shaders/sky.frag +23 -23
- basilisk/shaders/sky.vert +13 -13
- {basilisk_engine-0.1.51.dist-info → basilisk_engine-0.1.53.dist-info}/METADATA +82 -89
- basilisk_engine-0.1.53.dist-info/RECORD +110 -0
- {basilisk_engine-0.1.51.dist-info → basilisk_engine-0.1.53.dist-info}/WHEEL +1 -1
- basilisk_engine-0.1.51.dist-info/RECORD +0 -110
- {basilisk_engine-0.1.51.dist-info → basilisk_engine-0.1.53.dist-info}/top_level.txt +0 -0
|
@@ -1,138 +1,138 @@
|
|
|
1
|
-
import glm
|
|
2
|
-
from .broad_aabb import BroadAABB
|
|
3
|
-
from ..collider import Collider
|
|
4
|
-
from ...generic.abstract_bvh import AbstractBVH as BVH
|
|
5
|
-
from ...generic.meshes import get_aabb_surface_area
|
|
6
|
-
|
|
7
|
-
class BroadBVH(BVH):
|
|
8
|
-
root: BroadAABB
|
|
9
|
-
"""The root node of the BVH"""
|
|
10
|
-
collider_handler: ...
|
|
11
|
-
"""Back reference to the collider ahndler for accessing colliders"""
|
|
12
|
-
|
|
13
|
-
def __init__(self, collider_handler) -> None:
|
|
14
|
-
self.collider_handler = collider_handler
|
|
15
|
-
self.root = None
|
|
16
|
-
|
|
17
|
-
def add(self, collider: Collider) -> None:
|
|
18
|
-
"""
|
|
19
|
-
Adds a single collider to the bvh tree
|
|
20
|
-
"""
|
|
21
|
-
# test if tree needs to be initiated
|
|
22
|
-
if not self.root:
|
|
23
|
-
self.root = collider # TODO ensure that this is final format for primative
|
|
24
|
-
return
|
|
25
|
-
|
|
26
|
-
# check if root is primative
|
|
27
|
-
if isinstance(self.root, Collider):
|
|
28
|
-
sibling = self.root
|
|
29
|
-
self.root = BroadAABB(sibling, collider, None)
|
|
30
|
-
sibling.parent = collider.parent = self.root
|
|
31
|
-
return
|
|
32
|
-
|
|
33
|
-
# find the best sibling (c_best only used during the recursion)
|
|
34
|
-
c_best, sibling = self.root.find_sibling(collider, 0)
|
|
35
|
-
old_parent = sibling.parent
|
|
36
|
-
new_parent = BroadAABB(sibling, collider, old_parent)
|
|
37
|
-
|
|
38
|
-
# if the sibling was not the root
|
|
39
|
-
if old_parent:
|
|
40
|
-
if old_parent.a == sibling: old_parent.a = new_parent
|
|
41
|
-
else: old_parent.b = new_parent
|
|
42
|
-
else: self.root = new_parent
|
|
43
|
-
|
|
44
|
-
sibling.parent = new_parent
|
|
45
|
-
collider.parent = new_parent
|
|
46
|
-
|
|
47
|
-
# walk back up tree and refit TODO add tree rotations
|
|
48
|
-
aabb = new_parent
|
|
49
|
-
while aabb:
|
|
50
|
-
aabb.update_points()
|
|
51
|
-
self.rotate(aabb)
|
|
52
|
-
aabb = aabb.parent
|
|
53
|
-
|
|
54
|
-
def get_all_aabbs(self) -> list[tuple[glm.vec3, glm.vec3, int]]: # TODO test function
|
|
55
|
-
"""
|
|
56
|
-
Returns all AABBs, their extreme points, and their layer
|
|
57
|
-
"""
|
|
58
|
-
if isinstance(self.root, BroadAABB): return self.root.get_all_aabbs(0)
|
|
59
|
-
return [(self.root.top_right, self.root.bottom_left, 0)]
|
|
60
|
-
|
|
61
|
-
def remove(self, collider: Collider) -> None:
|
|
62
|
-
"""
|
|
63
|
-
Removes a collider from the BVH, refitting the tree and adjusting relations
|
|
64
|
-
"""
|
|
65
|
-
parent: BroadAABB | None = collider.parent
|
|
66
|
-
|
|
67
|
-
# if collider is the root, remove the root
|
|
68
|
-
if not parent:
|
|
69
|
-
self.root = None
|
|
70
|
-
return
|
|
71
|
-
|
|
72
|
-
# if collider has no grandparent, remove parent and set sibling as root
|
|
73
|
-
grand = parent.parent
|
|
74
|
-
sibling = parent.b if collider == parent.a else parent.a
|
|
75
|
-
if not grand:
|
|
76
|
-
self.root = sibling
|
|
77
|
-
sibling.parent = None
|
|
78
|
-
return
|
|
79
|
-
|
|
80
|
-
# if grandparent exists
|
|
81
|
-
if parent == grand.a: grand.a = sibling
|
|
82
|
-
else: grand.b = sibling
|
|
83
|
-
sibling.parent = grand
|
|
84
|
-
|
|
85
|
-
# move up and refit tree
|
|
86
|
-
aabb = grand
|
|
87
|
-
while aabb:
|
|
88
|
-
aabb.update_points()
|
|
89
|
-
aabb = aabb.parent
|
|
90
|
-
|
|
91
|
-
def rotate(self, aabb: BroadAABB) -> None:
|
|
92
|
-
"""
|
|
93
|
-
Rotates the BVH tree to reduce surface area of internal AABBs
|
|
94
|
-
"""
|
|
95
|
-
# determine if rotation is possible
|
|
96
|
-
parent: BroadAABB | None = aabb.parent
|
|
97
|
-
if not parent: return
|
|
98
|
-
|
|
99
|
-
grand = parent.parent
|
|
100
|
-
if not grand: return
|
|
101
|
-
|
|
102
|
-
# determine if swapping
|
|
103
|
-
aunt = grand.b if grand.a == parent else grand.a
|
|
104
|
-
sibling = parent.b if parent.a == aabb else parent.a
|
|
105
|
-
|
|
106
|
-
top_right = glm.max(aunt.top_right, sibling.top_right)
|
|
107
|
-
bottom_left = glm.min(aunt.bottom_left, sibling.bottom_left)
|
|
108
|
-
aunt_sibling_area = get_aabb_surface_area(top_right, bottom_left)
|
|
109
|
-
|
|
110
|
-
if aunt_sibling_area > parent.surface_area: return
|
|
111
|
-
|
|
112
|
-
# rotate tree if necessary
|
|
113
|
-
if grand.a == aunt: grand.a = aabb
|
|
114
|
-
else: grand.b = aabb
|
|
115
|
-
|
|
116
|
-
if parent.a == aabb: parent.a = aunt
|
|
117
|
-
else: parent.b = aunt
|
|
118
|
-
|
|
119
|
-
# reset parents and update points to resize AABBs
|
|
120
|
-
aunt.parent = parent
|
|
121
|
-
aabb.parent = grand
|
|
122
|
-
|
|
123
|
-
parent.update_points()
|
|
124
|
-
grand.update_points()
|
|
125
|
-
|
|
126
|
-
def get_collided(self, collider: Collider) -> list[Collider]:
|
|
127
|
-
"""
|
|
128
|
-
Returns which objects may be colliding from the BVH
|
|
129
|
-
"""
|
|
130
|
-
if isinstance(self.root, BroadAABB): return self.root.get_collided(collider)
|
|
131
|
-
else: return [] # if there is only one collider in the scene then there is nothing to collide with
|
|
132
|
-
|
|
133
|
-
def get_line_collided(self, position: glm.vec3, forward: glm.vec3) -> list[Collider]:
|
|
134
|
-
"""
|
|
135
|
-
Returns the colliders that may intersect with the given line
|
|
136
|
-
"""
|
|
137
|
-
if isinstance(self.root, BroadAABB): return self.root.get_line_collided(position, forward)
|
|
1
|
+
import glm
|
|
2
|
+
from .broad_aabb import BroadAABB
|
|
3
|
+
from ..collider import Collider
|
|
4
|
+
from ...generic.abstract_bvh import AbstractBVH as BVH
|
|
5
|
+
from ...generic.meshes import get_aabb_surface_area
|
|
6
|
+
|
|
7
|
+
class BroadBVH(BVH):
|
|
8
|
+
root: BroadAABB
|
|
9
|
+
"""The root node of the BVH"""
|
|
10
|
+
collider_handler: ...
|
|
11
|
+
"""Back reference to the collider ahndler for accessing colliders"""
|
|
12
|
+
|
|
13
|
+
def __init__(self, collider_handler) -> None:
|
|
14
|
+
self.collider_handler = collider_handler
|
|
15
|
+
self.root = None
|
|
16
|
+
|
|
17
|
+
def add(self, collider: Collider) -> None:
|
|
18
|
+
"""
|
|
19
|
+
Adds a single collider to the bvh tree
|
|
20
|
+
"""
|
|
21
|
+
# test if tree needs to be initiated
|
|
22
|
+
if not self.root:
|
|
23
|
+
self.root = collider # TODO ensure that this is final format for primative
|
|
24
|
+
return
|
|
25
|
+
|
|
26
|
+
# check if root is primative
|
|
27
|
+
if isinstance(self.root, Collider):
|
|
28
|
+
sibling = self.root
|
|
29
|
+
self.root = BroadAABB(sibling, collider, None)
|
|
30
|
+
sibling.parent = collider.parent = self.root
|
|
31
|
+
return
|
|
32
|
+
|
|
33
|
+
# find the best sibling (c_best only used during the recursion)
|
|
34
|
+
c_best, sibling = self.root.find_sibling(collider, 0)
|
|
35
|
+
old_parent = sibling.parent
|
|
36
|
+
new_parent = BroadAABB(sibling, collider, old_parent)
|
|
37
|
+
|
|
38
|
+
# if the sibling was not the root
|
|
39
|
+
if old_parent:
|
|
40
|
+
if old_parent.a == sibling: old_parent.a = new_parent
|
|
41
|
+
else: old_parent.b = new_parent
|
|
42
|
+
else: self.root = new_parent
|
|
43
|
+
|
|
44
|
+
sibling.parent = new_parent
|
|
45
|
+
collider.parent = new_parent
|
|
46
|
+
|
|
47
|
+
# walk back up tree and refit TODO add tree rotations
|
|
48
|
+
aabb = new_parent
|
|
49
|
+
while aabb:
|
|
50
|
+
aabb.update_points()
|
|
51
|
+
self.rotate(aabb)
|
|
52
|
+
aabb = aabb.parent
|
|
53
|
+
|
|
54
|
+
def get_all_aabbs(self) -> list[tuple[glm.vec3, glm.vec3, int]]: # TODO test function
|
|
55
|
+
"""
|
|
56
|
+
Returns all AABBs, their extreme points, and their layer
|
|
57
|
+
"""
|
|
58
|
+
if isinstance(self.root, BroadAABB): return self.root.get_all_aabbs(0)
|
|
59
|
+
return [(self.root.top_right, self.root.bottom_left, 0)]
|
|
60
|
+
|
|
61
|
+
def remove(self, collider: Collider) -> None:
|
|
62
|
+
"""
|
|
63
|
+
Removes a collider from the BVH, refitting the tree and adjusting relations
|
|
64
|
+
"""
|
|
65
|
+
parent: BroadAABB | None = collider.parent
|
|
66
|
+
|
|
67
|
+
# if collider is the root, remove the root
|
|
68
|
+
if not parent:
|
|
69
|
+
self.root = None
|
|
70
|
+
return
|
|
71
|
+
|
|
72
|
+
# if collider has no grandparent, remove parent and set sibling as root
|
|
73
|
+
grand = parent.parent
|
|
74
|
+
sibling = parent.b if collider == parent.a else parent.a
|
|
75
|
+
if not grand:
|
|
76
|
+
self.root = sibling
|
|
77
|
+
sibling.parent = None
|
|
78
|
+
return
|
|
79
|
+
|
|
80
|
+
# if grandparent exists
|
|
81
|
+
if parent == grand.a: grand.a = sibling
|
|
82
|
+
else: grand.b = sibling
|
|
83
|
+
sibling.parent = grand
|
|
84
|
+
|
|
85
|
+
# move up and refit tree
|
|
86
|
+
aabb = grand
|
|
87
|
+
while aabb:
|
|
88
|
+
aabb.update_points()
|
|
89
|
+
aabb = aabb.parent
|
|
90
|
+
|
|
91
|
+
def rotate(self, aabb: BroadAABB) -> None:
|
|
92
|
+
"""
|
|
93
|
+
Rotates the BVH tree to reduce surface area of internal AABBs
|
|
94
|
+
"""
|
|
95
|
+
# determine if rotation is possible
|
|
96
|
+
parent: BroadAABB | None = aabb.parent
|
|
97
|
+
if not parent: return
|
|
98
|
+
|
|
99
|
+
grand = parent.parent
|
|
100
|
+
if not grand: return
|
|
101
|
+
|
|
102
|
+
# determine if swapping
|
|
103
|
+
aunt = grand.b if grand.a == parent else grand.a
|
|
104
|
+
sibling = parent.b if parent.a == aabb else parent.a
|
|
105
|
+
|
|
106
|
+
top_right = glm.max(aunt.top_right, sibling.top_right)
|
|
107
|
+
bottom_left = glm.min(aunt.bottom_left, sibling.bottom_left)
|
|
108
|
+
aunt_sibling_area = get_aabb_surface_area(top_right, bottom_left)
|
|
109
|
+
|
|
110
|
+
if aunt_sibling_area > parent.surface_area: return
|
|
111
|
+
|
|
112
|
+
# rotate tree if necessary
|
|
113
|
+
if grand.a == aunt: grand.a = aabb
|
|
114
|
+
else: grand.b = aabb
|
|
115
|
+
|
|
116
|
+
if parent.a == aabb: parent.a = aunt
|
|
117
|
+
else: parent.b = aunt
|
|
118
|
+
|
|
119
|
+
# reset parents and update points to resize AABBs
|
|
120
|
+
aunt.parent = parent
|
|
121
|
+
aabb.parent = grand
|
|
122
|
+
|
|
123
|
+
parent.update_points()
|
|
124
|
+
grand.update_points()
|
|
125
|
+
|
|
126
|
+
def get_collided(self, collider: Collider) -> list[Collider]:
|
|
127
|
+
"""
|
|
128
|
+
Returns which objects may be colliding from the BVH
|
|
129
|
+
"""
|
|
130
|
+
if isinstance(self.root, BroadAABB): return self.root.get_collided(collider)
|
|
131
|
+
else: return [] # if there is only one collider in the scene then there is nothing to collide with
|
|
132
|
+
|
|
133
|
+
def get_line_collided(self, position: glm.vec3, forward: glm.vec3) -> list[Collider]:
|
|
134
|
+
"""
|
|
135
|
+
Returns the colliders that may intersect with the given line
|
|
136
|
+
"""
|
|
137
|
+
if isinstance(self.root, BroadAABB): return self.root.get_line_collided(position, forward)
|
|
138
138
|
return [self.root]
|
basilisk/collisions/collider.py
CHANGED
|
@@ -1,96 +1,96 @@
|
|
|
1
|
-
import glm
|
|
2
|
-
from ..generic.abstract_bvh import AbstractAABB as AABB
|
|
3
|
-
from ..generic.meshes import transform_points, get_aabb_surface_area
|
|
4
|
-
from ..mesh.mesh import Mesh
|
|
5
|
-
from .narrow.dataclasses import Collision
|
|
6
|
-
|
|
7
|
-
class Collider():
|
|
8
|
-
node: ...
|
|
9
|
-
"""Back reference to the node"""
|
|
10
|
-
collider_handler: ...
|
|
11
|
-
"""Back reference to the collider handler"""
|
|
12
|
-
half_dimensions: glm.vec3
|
|
13
|
-
"""The axis aligned dimensions of the transformed mesh"""
|
|
14
|
-
static_friction: float = 0.8 # input from node constructor
|
|
15
|
-
"""Determines the friction of the node when still: recommended 0 - 1"""
|
|
16
|
-
kinetic_friction: float = 0.3 # input from node constructor
|
|
17
|
-
"""Determines the friction of the node when moving: recommended 0 - 1"""
|
|
18
|
-
elasticity: float = 0.1 # input from node constructor
|
|
19
|
-
"""Determines how bouncy an object is: recommended 0 - 1"""
|
|
20
|
-
collision_group: str # input from node constructor
|
|
21
|
-
"""Nodes of the same collision group do not collide with each other"""
|
|
22
|
-
has_collided: bool
|
|
23
|
-
"""Stores whether or not the collider has been collided with in the last frame"""
|
|
24
|
-
collision_velocity: float
|
|
25
|
-
"""Stores the highest velocity from a collision on this collider from the last frame"""
|
|
26
|
-
collisions: dict # {node : (normal, velocity, depth)} TODO determine which variables need to be stored
|
|
27
|
-
"""Stores data from collisions in the previous frame"""
|
|
28
|
-
top_right: glm.vec3
|
|
29
|
-
"""AABB most positive corner"""
|
|
30
|
-
bottom_left: glm.vec3
|
|
31
|
-
"""AABB most negative corner"""
|
|
32
|
-
aabb_surface_area: float
|
|
33
|
-
"""The surface area of the collider's AABB"""
|
|
34
|
-
parent: AABB
|
|
35
|
-
"""Reference to the parent AABB in the broad BVH"""
|
|
36
|
-
mesh: Mesh
|
|
37
|
-
"""Reference to the colliding mesh"""
|
|
38
|
-
|
|
39
|
-
def __init__(self, node, collider_mesh: str|Mesh=None, static_friction: glm.vec3=0.7, kinetic_friction: glm.vec3=0.3, elasticity: glm.vec3=0.2, collision_group: str=None):
|
|
40
|
-
self.collider_handler = None
|
|
41
|
-
self.node = node
|
|
42
|
-
self.static_friction = static_friction if static_friction else 0.8 # added checks to prevent floats being set to None. Also done for kinetic and elasticity
|
|
43
|
-
self.mesh = collider_mesh
|
|
44
|
-
self.kinetic_friction = kinetic_friction if kinetic_friction else 0.4
|
|
45
|
-
self.elasticity = elasticity if elasticity else 0.1
|
|
46
|
-
self.collision_group = collision_group
|
|
47
|
-
self.collision_velocity = 0
|
|
48
|
-
self.collisions: list[Collision] = []
|
|
49
|
-
self.parent = None
|
|
50
|
-
|
|
51
|
-
# lazy update variables TODO change to distinguish between static and nonstatic objects
|
|
52
|
-
self.needs_obb = True # pos, scale, rot
|
|
53
|
-
self.needs_half_dimensions = True # scale, rot
|
|
54
|
-
self.needs_bvh = True # pos, scale, rot
|
|
55
|
-
|
|
56
|
-
def get_vertex(self, index: int) -> glm.vec3:
|
|
57
|
-
"""
|
|
58
|
-
Gets the world space position of a vertex indicated by the index in the mesh
|
|
59
|
-
"""
|
|
60
|
-
return glm.vec3(self.node.model_matrix * glm.vec4(*self.mesh.points[index], 1))
|
|
61
|
-
|
|
62
|
-
@property
|
|
63
|
-
def collider_handler(self): return self._collider_handler
|
|
64
|
-
@property
|
|
65
|
-
def has_collided(self): return bool(self.collisions)
|
|
66
|
-
@property
|
|
67
|
-
def half_dimensions(self): # TODO look for optimization
|
|
68
|
-
if self.needs_half_dimensions:
|
|
69
|
-
top_right = glm.max(self.obb_points)
|
|
70
|
-
self._half_dimensions = top_right - self.node.geometric_center
|
|
71
|
-
self.needs_half_dimensions = False
|
|
72
|
-
return self._half_dimensions
|
|
73
|
-
@property
|
|
74
|
-
def bottom_left(self): return self.node.geometric_center - self.half_dimensions
|
|
75
|
-
@property
|
|
76
|
-
def top_right(self): return self.node.geometric_center + self.half_dimensions
|
|
77
|
-
@property
|
|
78
|
-
def aabb_surface_area(self): return get_aabb_surface_area(self.top_right, self.bottom_left)
|
|
79
|
-
@property
|
|
80
|
-
def obb_points(self):
|
|
81
|
-
if self.needs_obb:
|
|
82
|
-
self._obb_points = transform_points(self.mesh.aabb_points, self.node.model_matrix)
|
|
83
|
-
self.needs_obb = False
|
|
84
|
-
return self._obb_points
|
|
85
|
-
|
|
86
|
-
@collider_handler.setter
|
|
87
|
-
def collider_handler(self, value):
|
|
88
|
-
self._collider_handler = value
|
|
89
|
-
if not value: return
|
|
90
|
-
if self.mesh is None: self.mesh = self.node.mesh
|
|
91
|
-
elif isinstance(self.mesh, Mesh): ...
|
|
92
|
-
elif isinstance(self.mesh, str):
|
|
93
|
-
if self.mesh =='box': self.mesh = value.cube
|
|
94
|
-
else: raise ValueError(f'Incorrect built-in mesh type {self.mesh}')
|
|
95
|
-
else: raise ValueError(f'Unkown type for mesh, got {type(self.mesh)}')
|
|
1
|
+
import glm
|
|
2
|
+
from ..generic.abstract_bvh import AbstractAABB as AABB
|
|
3
|
+
from ..generic.meshes import transform_points, get_aabb_surface_area
|
|
4
|
+
from ..mesh.mesh import Mesh
|
|
5
|
+
from .narrow.dataclasses import Collision
|
|
6
|
+
|
|
7
|
+
class Collider():
|
|
8
|
+
node: ...
|
|
9
|
+
"""Back reference to the node"""
|
|
10
|
+
collider_handler: ...
|
|
11
|
+
"""Back reference to the collider handler"""
|
|
12
|
+
half_dimensions: glm.vec3
|
|
13
|
+
"""The axis aligned dimensions of the transformed mesh"""
|
|
14
|
+
static_friction: float = 0.8 # input from node constructor
|
|
15
|
+
"""Determines the friction of the node when still: recommended 0 - 1"""
|
|
16
|
+
kinetic_friction: float = 0.3 # input from node constructor
|
|
17
|
+
"""Determines the friction of the node when moving: recommended 0 - 1"""
|
|
18
|
+
elasticity: float = 0.1 # input from node constructor
|
|
19
|
+
"""Determines how bouncy an object is: recommended 0 - 1"""
|
|
20
|
+
collision_group: str # input from node constructor
|
|
21
|
+
"""Nodes of the same collision group do not collide with each other"""
|
|
22
|
+
has_collided: bool
|
|
23
|
+
"""Stores whether or not the collider has been collided with in the last frame"""
|
|
24
|
+
collision_velocity: float
|
|
25
|
+
"""Stores the highest velocity from a collision on this collider from the last frame"""
|
|
26
|
+
collisions: dict # {node : (normal, velocity, depth)} TODO determine which variables need to be stored
|
|
27
|
+
"""Stores data from collisions in the previous frame"""
|
|
28
|
+
top_right: glm.vec3
|
|
29
|
+
"""AABB most positive corner"""
|
|
30
|
+
bottom_left: glm.vec3
|
|
31
|
+
"""AABB most negative corner"""
|
|
32
|
+
aabb_surface_area: float
|
|
33
|
+
"""The surface area of the collider's AABB"""
|
|
34
|
+
parent: AABB
|
|
35
|
+
"""Reference to the parent AABB in the broad BVH"""
|
|
36
|
+
mesh: Mesh
|
|
37
|
+
"""Reference to the colliding mesh"""
|
|
38
|
+
|
|
39
|
+
def __init__(self, node, collider_mesh: str|Mesh=None, static_friction: glm.vec3=0.7, kinetic_friction: glm.vec3=0.3, elasticity: glm.vec3=0.2, collision_group: str=None):
|
|
40
|
+
self.collider_handler = None
|
|
41
|
+
self.node = node
|
|
42
|
+
self.static_friction = static_friction if static_friction else 0.8 # added checks to prevent floats being set to None. Also done for kinetic and elasticity
|
|
43
|
+
self.mesh = collider_mesh
|
|
44
|
+
self.kinetic_friction = kinetic_friction if kinetic_friction else 0.4
|
|
45
|
+
self.elasticity = elasticity if elasticity else 0.1
|
|
46
|
+
self.collision_group = collision_group
|
|
47
|
+
self.collision_velocity = 0
|
|
48
|
+
self.collisions: list[Collision] = []
|
|
49
|
+
self.parent = None
|
|
50
|
+
|
|
51
|
+
# lazy update variables TODO change to distinguish between static and nonstatic objects
|
|
52
|
+
self.needs_obb = True # pos, scale, rot
|
|
53
|
+
self.needs_half_dimensions = True # scale, rot
|
|
54
|
+
self.needs_bvh = True # pos, scale, rot
|
|
55
|
+
|
|
56
|
+
def get_vertex(self, index: int) -> glm.vec3:
|
|
57
|
+
"""
|
|
58
|
+
Gets the world space position of a vertex indicated by the index in the mesh
|
|
59
|
+
"""
|
|
60
|
+
return glm.vec3(self.node.model_matrix * glm.vec4(*self.mesh.points[index], 1))
|
|
61
|
+
|
|
62
|
+
@property
|
|
63
|
+
def collider_handler(self): return self._collider_handler
|
|
64
|
+
@property
|
|
65
|
+
def has_collided(self): return bool(self.collisions)
|
|
66
|
+
@property
|
|
67
|
+
def half_dimensions(self): # TODO look for optimization
|
|
68
|
+
if self.needs_half_dimensions:
|
|
69
|
+
top_right = glm.max(self.obb_points)
|
|
70
|
+
self._half_dimensions = top_right - self.node.geometric_center
|
|
71
|
+
self.needs_half_dimensions = False
|
|
72
|
+
return self._half_dimensions
|
|
73
|
+
@property
|
|
74
|
+
def bottom_left(self): return self.node.geometric_center - self.half_dimensions
|
|
75
|
+
@property
|
|
76
|
+
def top_right(self): return self.node.geometric_center + self.half_dimensions
|
|
77
|
+
@property
|
|
78
|
+
def aabb_surface_area(self): return get_aabb_surface_area(self.top_right, self.bottom_left)
|
|
79
|
+
@property
|
|
80
|
+
def obb_points(self):
|
|
81
|
+
if self.needs_obb:
|
|
82
|
+
self._obb_points = transform_points(self.mesh.aabb_points, self.node.model_matrix)
|
|
83
|
+
self.needs_obb = False
|
|
84
|
+
return self._obb_points
|
|
85
|
+
|
|
86
|
+
@collider_handler.setter
|
|
87
|
+
def collider_handler(self, value):
|
|
88
|
+
self._collider_handler = value
|
|
89
|
+
if not value: return
|
|
90
|
+
if self.mesh is None: self.mesh = self.node.mesh
|
|
91
|
+
elif isinstance(self.mesh, Mesh): ...
|
|
92
|
+
elif isinstance(self.mesh, str):
|
|
93
|
+
if self.mesh =='box': self.mesh = value.cube
|
|
94
|
+
else: raise ValueError(f'Incorrect built-in mesh type {self.mesh}')
|
|
95
|
+
else: raise ValueError(f'Unkown type for mesh, got {type(self.mesh)}')
|
|
96
96
|
value.add(self)
|