-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(app): 110 Applying methods to RigidBodies (#112)
* feat(app): 110 Applying methods to RigidBodies * docs: update rigidBody docs
- Loading branch information
1 parent
7deb26f
commit 2f95276
Showing
7 changed files
with
290 additions
and
115 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
<script setup lang="ts"> | ||
import { OrbitControls } from '@tresjs/cientos' | ||
import { TresCanvas } from '@tresjs/core' | ||
import { Physics, RigidBody } from '@tresjs/rapier' | ||
import { ACESFilmicToneMapping, SRGBColorSpace } from 'three' | ||
import { shallowRef } from 'vue' | ||
const gl = { | ||
clearColor: '#82DBC5', | ||
shadows: true, | ||
alpha: false, | ||
outputColorSpace: SRGBColorSpace, | ||
toneMapping: ACESFilmicToneMapping, | ||
} | ||
const rigidCubeRef = shallowRef(null) | ||
const rigidSphereRef = shallowRef(null) | ||
const jumpCube = () => { | ||
if (rigidCubeRef.value) { | ||
rigidCubeRef.value.rigidBodyInfos.rigidBodyDesc.mass = 5 | ||
rigidCubeRef.value.instance.applyImpulse({ x: 0, y: 15, z: 0 }, true) | ||
} | ||
} | ||
const windSphere = () => { | ||
if (rigidSphereRef.value) { | ||
rigidSphereRef.value.rigidBodyInfos.rigidBodyDesc.mass = 5 | ||
rigidSphereRef.value.instance.applyImpulse({ x: 5, y: 0, z: 0 }, true) | ||
} | ||
} | ||
</script> | ||
|
||
<template> | ||
<TresCanvas v-bind="gl" window-size> | ||
<TresPerspectiveCamera :position="[11, 11, 11]" :look-at="[0, 0, 0]" /> | ||
<OrbitControls /> | ||
|
||
<Suspense> | ||
<Physics debug> | ||
<RigidBody ref="rigidCubeRef"> | ||
<TresMesh :position="[0, 5, 0]" @click="jumpCube"> | ||
<TresBoxGeometry /> | ||
<TresMeshNormalMaterial /> | ||
</TresMesh> | ||
</RigidBody> | ||
|
||
<RigidBody ref="rigidSphereRef" collider="ball"> | ||
<TresMesh :position="[Math.random() * 2, Math.random() * 2 + 8, Math.random() * 2]" @click="windSphere"> | ||
<TresSphereGeometry /> | ||
<TresMeshNormalMaterial /> | ||
</TresMesh> | ||
</RigidBody> | ||
|
||
<RigidBody type="fixed"> | ||
<TresMesh :position="[0, 0, 0]"> | ||
<TresPlaneGeometry :args="[20, 20, 20]" :rotate-x="-Math.PI / 2" /> | ||
<TresMeshBasicMaterial color="#f4f4f4" /> | ||
</TresMesh> | ||
</RigidBody> | ||
</Physics> | ||
</Suspense> | ||
</TresCanvas> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
<script setup lang="ts"> | ||
import { type TresObject, useLoop } from '@tresjs/core' | ||
import { InstancedMesh } from 'three' | ||
import { shallowRef, watch } from 'vue' | ||
import { useRapierContext } from '../composables/useRapier' | ||
import { MATRIX_ZERO, QUATERNION_ZERO, VECTOR_ZERO } from '../constants/object' | ||
import { createCollider } from '../utils/collider' | ||
import { createRigidBody } from '../utils/rigid-body' | ||
import type { CreateColliderReturnType } from '../types/collider' | ||
import type { CreateRigidBodyReturnType, RigidBodyProps } from '../types/rigid-body' | ||
const props = withDefaults(defineProps<Partial<RigidBodyProps>>(), { | ||
type: 'dynamic', | ||
collider: 'cuboid', | ||
}) | ||
const parentObject = shallowRef<TresObject>() | ||
const rigidBodyInfos = shallowRef<CreateRigidBodyReturnType[]>() | ||
const colliderInfos = shallowRef<CreateColliderReturnType[]>() | ||
const rigidBodyInstance = shallowRef() | ||
defineExpose({ | ||
instance: rigidBodyInstance, | ||
rigidBodyInfos, | ||
collider: colliderInfos, | ||
group: parentObject, | ||
}) | ||
const { world } = await useRapierContext() | ||
const { onBeforeRender } = useLoop() | ||
watch(parentObject, (object?: TresObject) => { | ||
if (!object) { return } | ||
const child = object?.children[0] | ||
if ( | ||
!(child instanceof InstancedMesh) | ||
|| typeof parentObject.value?.children?.length !== 'number' | ||
|| parentObject.value.children.length > 1 | ||
) { | ||
throw new Error('Incorrect data assignment detected! #RigidBody support only one #InstancedMesh') | ||
} | ||
const instanceArray = child.instanceMatrix.array | ||
const rigidBodies: CreateRigidBodyReturnType[] = [] | ||
const colliders: CreateColliderReturnType[] = [] | ||
for (let i = 0; i < child.count; i++) { | ||
const matrix = MATRIX_ZERO.fromArray(instanceArray, i * 16) | ||
const position = VECTOR_ZERO.clone() | ||
const quaternion = QUATERNION_ZERO.clone() | ||
const scale = VECTOR_ZERO.clone() | ||
matrix.decompose(position, quaternion, scale) | ||
const rigidBodyInfo = createRigidBody({ | ||
object: child, | ||
rigidBodyType: props.type, | ||
world, | ||
}) | ||
rigidBodyInfo.rigidBody.setTranslation(position, true) | ||
rigidBodyInfo.rigidBody.setRotation(quaternion, true) | ||
const colliderInfo = createCollider({ | ||
object: child, | ||
colliderShape: props.collider, | ||
rigidBody: rigidBodyInfo.rigidBody, | ||
world, | ||
}) | ||
rigidBodies.push(rigidBodyInfo) | ||
colliders.push(colliderInfo) | ||
} | ||
rigidBodyInfos.value = rigidBodies | ||
colliderInfos.value = colliders | ||
rigidBodyInstance.value = rigidBodyInfos.value.map(rigidBodyInfo => rigidBodyInfo.rigidBody) | ||
}) | ||
onBeforeRender(() => { | ||
if (!colliderInfos.value || !rigidBodyInfos.value) { return } | ||
const child: InstancedMesh = parentObject.value?.children[0] | ||
const array = child.instanceMatrix.array | ||
for (let i = 0; i < child.count; i++) { | ||
let position = VECTOR_ZERO.clone() | ||
let quaternion = QUATERNION_ZERO.clone() | ||
let scale = VECTOR_ZERO.clone() | ||
child.getMatrixAt(i, MATRIX_ZERO) | ||
MATRIX_ZERO.decompose(position, quaternion, scale) | ||
position = position.copy( | ||
rigidBodyInfos.value[i].rigidBody.translation(), | ||
) | ||
quaternion = quaternion.copy( | ||
rigidBodyInfos.value[i].rigidBody.rotation(), | ||
) | ||
scale = scale.copy(scale) | ||
MATRIX_ZERO | ||
.compose(position, quaternion, scale) | ||
.toArray(array, i * 16) | ||
} | ||
child.instanceMatrix.needsUpdate = true | ||
child.computeBoundingSphere() | ||
}) | ||
</script> | ||
|
||
<template> | ||
<TresGroup ref="parentObject"> | ||
<slot></slot> | ||
</TresGroup> | ||
</template> |
Oops, something went wrong.