-
-
Notifications
You must be signed in to change notification settings - Fork 115
/
useCollisionGroups.ts
69 lines (61 loc) · 1.85 KB
/
useCollisionGroups.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import type { Collider, ColliderHandle } from '@dimforge/rapier3d-compat'
import { getContext, onDestroy } from 'svelte'
import { get } from 'svelte/store'
import type { CollisionGroupsContext } from '../types/types'
type ColliderMap = Map<
ColliderHandle,
{
collider: Collider
initialCollisionGroup: number
}
>
const applyBitMask = (collidersMap: ColliderMap, bitMask: number) => {
collidersMap.forEach((c) => {
if (c && c.collider && c.collider.isValid()) {
c.collider.setCollisionGroups(bitMask)
}
})
}
export const useCollisionGroups = () => {
const collidersMap: ColliderMap = new Map()
const bitMaskStore = getContext<CollisionGroupsContext>('threlte-rapier-collision-group')
if (!bitMaskStore)
return {
// eslint-disable-next-line @typescript-eslint/no-empty-function
registerColliders: (colliders: Collider[]) => {},
// eslint-disable-next-line @typescript-eslint/no-empty-function
removeColliders: (colliders: Collider[]) => {}
}
let bitMask = get(bitMaskStore)
const unsubscribe = bitMaskStore.subscribe((newBitMask) => {
bitMask = newBitMask
applyBitMask(collidersMap, newBitMask)
})
onDestroy(unsubscribe)
const registerColliders = (colliders: Collider[]) => {
colliders.forEach((c) => {
if (!collidersMap.has(c.handle)) {
collidersMap.set(c.handle, {
collider: c,
initialCollisionGroup: c.collisionGroups()
})
}
})
applyBitMask(collidersMap, bitMask)
}
const removeColliders = (colliders: Collider[]) => {
colliders.forEach((c) => {
const mapItem = collidersMap.get(c.handle)
if (mapItem) {
if (c && c.isValid()) {
c.setCollisionGroups(mapItem.initialCollisionGroup)
}
}
collidersMap.delete(c.handle)
})
}
return {
registerColliders,
removeColliders
}
}