Skip to content

Commit 9e74ef6

Browse files
committed
Add scaleOverride property (Fixes #367)
1 parent 7f5c5ef commit 9e74ef6

File tree

3 files changed

+31
-17
lines changed

3 files changed

+31
-17
lines changed

packages/react-three-cannon/src/hooks.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ export type WorkerApi = {
7575
applyTorque: (torque: Triplet) => void
7676
quaternion: QuaternionApi
7777
rotation: VectorApi
78+
scaleOverride: (scale: Triplet) => void
7879
sleep: () => void
7980
wakeUp: () => void
8081
}
@@ -130,10 +131,10 @@ function subscribe<T extends SubscriptionName>(
130131
}
131132
}
132133

133-
function prepare(object: Object3D, props: BodyProps) {
134-
object.userData = props.userData || {}
135-
object.position.set(...(props.position || [0, 0, 0]))
136-
object.rotation.set(...(props.rotation || [0, 0, 0]))
134+
function prepare(object: Object3D, { position = [0, 0, 0], rotation = [0, 0, 0], userData = {} }: BodyProps) {
135+
object.userData = userData
136+
object.position.set(...position)
137+
object.rotation.set(...rotation)
137138
object.updateMatrix()
138139
}
139140

@@ -161,7 +162,7 @@ function useBody<B extends BodyProps<unknown[]>>(
161162
): Api {
162163
const ref = useForwardedRef(fwdRef)
163164

164-
const { events, refs, subscriptions, worker } = usePhysicsContext()
165+
const { events, refs, scaleOverrides, subscriptions, worker } = usePhysicsContext()
165166
const debugApi = useDebugContext()
166167

167168
useLayoutEffect(() => {
@@ -332,6 +333,10 @@ function useBody<B extends BodyProps<unknown[]>>(
332333
position: makeVec('position', index),
333334
quaternion: makeQuaternion(index),
334335
rotation: makeRotation(index),
336+
scaleOverride(scale) {
337+
const uuid = getUUID(ref, index)
338+
if (uuid) scaleOverrides[uuid] = new Vector3(...scale)
339+
},
335340
sleep() {
336341
const uuid = getUUID(ref, index)
337342
uuid && worker.sleep({ uuid })

packages/react-three-cannon/src/physics-context.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import type {
88
Subscriptions,
99
} from '@pmndrs/cannon-worker-api'
1010
import { createContext, useContext } from 'react'
11+
import type { Vector3 } from 'three'
1112

1213
type CannonEvent = CollideBeginEvent | CollideEndEvent | CollideEvent | RayhitEvent
1314
type CallbackByType<T extends { type: string }> = {
@@ -16,10 +17,13 @@ type CallbackByType<T extends { type: string }> = {
1617

1718
export type CannonEvents = { [uuid: string]: Partial<CallbackByType<CannonEvent>> }
1819

20+
export type ScaleOverrides = { [uuid: string]: Vector3 }
21+
1922
export type PhysicsContext = {
2023
bodies: { [uuid: string]: number }
2124
events: CannonEvents
2225
refs: Refs
26+
scaleOverrides: ScaleOverrides
2327
subscriptions: Subscriptions
2428
worker: CannonWorkerAPI
2529
}

packages/react-three-cannon/src/physics-provider.tsx

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,15 @@ const s = new Vector3(1, 1, 1)
3131
const q = new Quaternion()
3232
const m = new Matrix4()
3333

34-
function apply(index: number, positions: Float32Array, quaternions: Float32Array, object?: Object3D) {
34+
function apply(
35+
index: number,
36+
positions: Float32Array,
37+
quaternions: Float32Array,
38+
scale = s,
39+
object?: Object3D,
40+
) {
3541
if (index !== undefined) {
36-
m.compose(
37-
v.fromArray(positions, index * 3),
38-
q.fromArray(quaternions, index * 4),
39-
object ? object.scale : s,
40-
)
42+
m.compose(v.fromArray(positions, index * 3), q.fromArray(quaternions, index * 4), scale)
4143
if (object) {
4244
object.matrixAutoUpdate = false
4345
object.matrix.copy(m)
@@ -67,10 +69,11 @@ export const PhysicsProvider: FC<PhysicsProviderProps> = ({
6769
}) => {
6870
const { invalidate } = useThree()
6971

70-
const [{ bodies, events, refs, subscriptions, worker }] = useState<PhysicsContext>(() => ({
72+
const [{ bodies, events, refs, scaleOverrides, subscriptions, worker }] = useState<PhysicsContext>(() => ({
7173
bodies: {},
7274
events: {},
7375
refs: {},
76+
scaleOverrides: {},
7477
subscriptions: {},
7578
worker: new CannonWorkerAPI({
7679
allowSleep,
@@ -178,14 +181,16 @@ export const PhysicsProvider: FC<PhysicsProviderProps> = ({
178181
for (const ref of Object.values(refs)) {
179182
if (ref instanceof InstancedMesh) {
180183
for (let i = 0; i < ref.count; i++) {
181-
const index = bodies[`${ref.uuid}/${i}`]
184+
const uuid = `${ref.uuid}/${i}`
185+
const index = bodies[uuid]
182186
if (index !== undefined) {
183-
ref.setMatrixAt(i, apply(index, positions, quaternions))
187+
ref.setMatrixAt(i, apply(index, positions, quaternions, scaleOverrides[uuid]))
188+
ref.instanceMatrix.needsUpdate = true
184189
}
185-
ref.instanceMatrix.needsUpdate = true
186190
}
187191
} else {
188-
apply(bodies[ref.uuid], positions, quaternions, ref)
192+
const scale = scaleOverrides[ref.uuid] || ref.scale
193+
apply(bodies[ref.uuid], positions, quaternions, scale, ref)
189194
}
190195
}
191196
if (shouldInvalidate) {
@@ -241,7 +246,7 @@ export const PhysicsProvider: FC<PhysicsProviderProps> = ({
241246
}, [tolerance])
242247

243248
const value = useMemo<PhysicsContext>(
244-
() => ({ bodies, events, refs, subscriptions, worker }),
249+
() => ({ bodies, events, refs, scaleOverrides, subscriptions, worker }),
245250
[bodies, events, refs, subscriptions, worker],
246251
)
247252

0 commit comments

Comments
 (0)