Skip to content

Commit

Permalink
feat(app): 119 Props for colliders
Browse files Browse the repository at this point in the history
  • Loading branch information
JaimeTorrealba committed Sep 26, 2024
1 parent e3ec76f commit 32dbccd
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 25 deletions.
27 changes: 27 additions & 0 deletions docs/components/collider.md
Original file line number Diff line number Diff line change
@@ -1 +1,28 @@
# Collider

## Props

| Prop | Description | Default |
| :-------------- | :------------------------------------------------------------------------------------------------------------ | --------- |
| **shape** | shape of the collider | `cuboid` |
| **args** | The half-sizes of the collider shapes | `[1,1,1]` |
| **object** | Required for certain shapes like `trimesh`, `hull`, `heightfield`. | |
| **friction** | The friction coefficient of this collider. (automatic-collider) | `0.5` |
| **mass** | Mass of the collider. (automatic-collider) | `1` |
| **density** | Restitution controls how elastic (aka. bouncy) a contact is. (automatic-collider) | `0` |
| **restitution** | The collider density. If non-zero the collider's mass and angular inertia will be added. (automatic-collider) | `1` |

:::info The `colliders` instance has many other methods, please check the
[official docs](https://rapier.rs/docs/api/javascript/JavaScript3D/) for a
complete list, if you need them, you can
use[Template ref](https://vuejs.org/guide/essentials/template-refs.html#template-refs).
:::

## Expose object

```
{
instance,
colliderDesc,
}
```
34 changes: 19 additions & 15 deletions docs/components/rigid-body.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,21 +133,25 @@ SOON

## Props

| Prop | Description | Default |
| :---------------------- | :----------------------------------- | ------------------------------ |
| **type** | `rigidBody` type | `dynamic` |
| **collider** | `automatic collider | `cuboid` |
| **gravityScale** | gravity for the `rigidBody` | `1` |
| **additionalMass** | add extra mass to the `rigidBody` | `0` |
| **linearDamping** | set the linear damping | `0` |
| **angularDamping** | set the angular damping | `0` |
| **dominanceGroup** | set the dominance group | `0` |
| **linvel** | linear velocity | `x: 0, y: 0, z: 0` |
| **angvel** | angular velocity | `x: 0, y: 0, z: 0` |
| **enabledRotations** | enable rotations in specific axis | `{x: true, y: true, z: true }` |
| **enabledTranslations** | enable translations in specific axis | `{x: true, y: true, z: true }` |
| **lockTranslations** | Lock all translations | `false` |
| **lockRotations** | Lock all rotations | `false` |
| Prop | Description | Default |
| :---------------------- | :------------------------------------------------------------------------------------------------------------ | ------------------------------ |
| **type** | `rigidBody` type | `dynamic` |
| **collider** | automatic collider | `cuboid` |
| **gravityScale** | gravity for the `rigidBody` | `1` |
| **additionalMass** | add extra mass to the `rigidBody` | `0` |
| **linearDamping** | set the linear damping | `0` |
| **angularDamping** | set the angular damping | `0` |
| **dominanceGroup** | set the dominance group | `0` |
| **linvel** | linear velocity | `x: 0, y: 0, z: 0` |
| **angvel** | angular velocity | `x: 0, y: 0, z: 0` |
| **enabledRotations** | enable rotations in specific axis | `{x: true, y: true, z: true }` |
| **enabledTranslations** | enable translations in specific axis | `{x: true, y: true, z: true }` |
| **lockTranslations** | Lock all translations | `false` |
| **lockRotations** | Lock all rotations | `false` |
| **friction** | The friction coefficient of this collider. (automatic-collider) | `0.5` |
| **mass** | Mass of the collider. (automatic-collider) | `1` |
| **density** | Restitution controls how elastic (aka. bouncy) a contact is. (automatic-collider) | `0` |
| **restitution** | The collider density. If non-zero the collider's mass and angular inertia will be added. (automatic-collider) | `1` |

:::info The `rigidBody` instance has many other functions, please check the
[official docs](https://rapier.rs/docs/api/javascript/JavaScript3D/) for a
Expand Down
23 changes: 14 additions & 9 deletions playground/src/pages/basics/RigidBodyProps.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { OrbitControls } from '@tresjs/cientos'
import { TresCanvas } from '@tresjs/core'
import { TresLeches, useControls } from '@tresjs/leches'
import { type ExposedRigidBody, Physics, RigidBody } from '@tresjs/rapier'
import { BallCollider, type ExposedRigidBody, Physics, RigidBody } from '@tresjs/rapier'
import { ACESFilmicToneMapping, SRGBColorSpace } from 'three'
import { shallowRef } from 'vue'
import '@tresjs/leches/styles'
Expand All @@ -28,15 +28,18 @@ const rotate = () => {
rigidBoxRef.value.instance.applyTorqueImpulse({ x: 3, y: 5, z: 0 }, true)
}
const { gravityScale, linearDamping, angularDamping, lockT, linvelX } = useControls({
const { gravityScale, linearDamping, angularDamping, lockT, linvelX, friction, mass, density, restitution } = useControls({
gravityScale: { value: 2.5, min: -10, max: 10, step: 1 },
linearDamping: { value: 0, min: -10, max: 10, step: 1 },
angularDamping: { value: 0, min: -10, max: 10, step: 1 },
linvelX: { value: 0, min: -10, max: 10, step: 1 },
lockT: true,
lockT: false,
// colliders
friction: { value: 0, min: 0, max: 10, step: 1 },
mass: { value: 1, min: 0, max: 10, step: 1 },
density: { value: 1, min: 0, max: 10, step: 1 },
restitution: { value: 1, min: 0, max: 10, step: 1 },
})
// TODO test locks and enabledTranslations, check docs
</script>

<template>
Expand All @@ -55,6 +58,11 @@ const { gravityScale, linearDamping, angularDamping, lockT, linvelX } = useContr
:angularDamping="angularDamping.value"
:enabledTranslations="{ x: true, y: true, z: true }"
:lockTranslations="lockT.value"
:linvelX="linvelX.value"
:friction="friction.value"
:mass="mass.value"
:density="density.value"
:restitution="restitution.value"
>
<TresMesh :position="[4, 8, 0]" @click="jump">
<TresTorusGeometry />
Expand All @@ -63,10 +71,7 @@ const { gravityScale, linearDamping, angularDamping, lockT, linvelX } = useContr
</RigidBody>

<RigidBody>
<TresMesh :position="[0, 8, 0]">
<TresTorusGeometry />
<TresMeshNormalMaterial />
</TresMesh>
<BallCollider :restitution="2" :args="[1, 1, 1]" :position="[2, 10, 2]" />
</RigidBody>

<!-- BOX -->
Expand Down
10 changes: 10 additions & 0 deletions src/components/RigidBody.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ const props = withDefaults(defineProps<Partial<RigidBodyProps>>(), {
enabledTranslations: () => ({ x: true, y: true, z: true }),
lockTranslations: false,
lockRotations: false,
// Automatic collider props
friction: 0.5,
mass: 1,
restitution: 0,
density: 1,
})
const { onBeforeRender } = useLoop()
const { world } = useRapierContext()
Expand Down Expand Up @@ -132,6 +138,10 @@ onUnmounted(() => {
:shape="_props.shape"
:args="_props.args"
:object="_props.object"
:friction="props.friction"
:mass="props.mass"
:restitution="props.restitution"
:density="props.density"
/>
<slot v-once></slot>
</TresGroup>
Expand Down
7 changes: 7 additions & 0 deletions src/components/colliders/BaseCollider.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@ import { inject, nextTick, onUnmounted, type ShallowRef, shallowRef, watch } fro
import { useRapierContext } from '../../composables'
import { createCollider } from '../../core/collider'
import { makePropsWatcherCL } from '../../utils/props'
import type { ColliderProps, CreateColliderReturnType, ExposedCollider, RigidBodyContext } from '../../types'
const props = withDefaults(defineProps<Partial<ColliderProps>>(), {
shape: 'cuboid',
args: () => [1, 1, 1],
friction: 0.5,
mass: 1,
restitution: 0,
density: 1,
})
const { world } = useRapierContext()
Expand Down Expand Up @@ -49,6 +54,8 @@ watch(bodyContext, async (state) => {
state.colliders.push(infos)
}, { immediate: true })
makePropsWatcherCL(props, ['friction', 'restitution', 'density', 'mass'], colliderInfos)
onUnmounted(() => {
if (!bodyContext.value || !colliderInfos.value?.collider) { return }
Expand Down
20 changes: 20 additions & 0 deletions src/types/collider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,26 @@ export interface ColliderProps {

/** @description {@link Collider} scale */
scale?: [x: number, y: number, z: number] | [radiusScale: number]
/**
* @description The friction coefficient of this collider.
* @default 0.5
*/
friction?: number
/**
* @description Mass of the collider.
* @default 1
*/
mass?: number
/**
* @description Restitution controls how elastic (aka. bouncy) a contact is.
* @default 0
*/
restitution?: number
/**
* @description The collider density. If non-zero the collider's mass and angular inertia will be added.
* @default 1.0
*/
density?: number
}

export interface ExposedCollider {
Expand Down
23 changes: 23 additions & 0 deletions src/types/rigid-body.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,29 @@ export interface RigidBodyProps {
* @default false
*/
lockRotations?: boolean

// AUTOMATIC COLLIDERS

/**
* @description The friction coefficient of this collider.
* @default 0.5
*/
friction?: number
/**
* @description mass.
* @default 1
*/
mass?: number
/**
* @description Restitution controls how elastic (aka. bouncy) a contact is.
* @default 0
*/
restitution?: number
/**
* @description The collider density. If non-zero the collider's mass and angular inertia will be added.
* @default 1.0
*/
density?: number
}

export interface ExposedRigidBody {
Expand Down
28 changes: 27 additions & 1 deletion src/utils/props.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { watch } from 'vue'
import type { RigidBody } from '@dimforge/rapier3d-compat'
import type { ShallowRef } from 'vue'
import type { CallableProps, Methods, RigidBodyContext, RigidBodyProps } from '../types'
import type { CallableProps, ColliderProps, CreateColliderReturnType, Methods, RigidBodyContext, RigidBodyProps } from '../types'

export const makePropWatcherRB = <
K extends keyof RigidBodyProps,
Expand All @@ -28,3 +28,29 @@ export const makePropsWatcherRB = <
+ watcher.slice(1) as Capitalize<keyof RigidBodyProps>
makePropWatcherRB(props, watcher as keyof RigidBodyProps, instance, `set${watcherName}`)
})

export const makePropWatcherCL = <
K extends keyof ColliderProps,
>(
props: ColliderProps,
toWatch: K,
instance: ShallowRef<CreateColliderReturnType | undefined>,
onSet: `set${Capitalize<keyof ColliderProps>}`,
) => watch([() => props[toWatch], instance], ([newValue, _]) => {
if (!instance.value) { return }
(instance.value.collider[onSet as keyof typeof instance.value.collider] as CallableProps<ColliderProps>[keyof CallableProps<ColliderProps>])?.(newValue, true)
})

export const makePropsWatcherCL = <
K extends keyof ColliderProps,
>(
props: ColliderProps,
watchers: K[],
instance: ShallowRef<CreateColliderReturnType | undefined>,
) => watchers.forEach((_) => {
const watcher = _ as string
// Uppercase only for the first letter in the watcher
const watcherName = watcher.charAt(0).toUpperCase()
+ watcher.slice(1) as Capitalize<keyof ColliderProps>
makePropWatcherCL(props, watcher as keyof ColliderProps, instance, `set${watcherName}`)
})

0 comments on commit 32dbccd

Please sign in to comment.