Skip to content

Commit

Permalink
refactor(architecture): better structure separation
Browse files Browse the repository at this point in the history
### Description

- Move `vue` components at `./src/components/`
- Move all types/interfaces at `./src/types`
  - Add `RigidBodyType` type (containing the supported rigidBodyDesc types)
  - Add `RigidBodyProps` interface
  - Add `InjectableRapierContext` interface
  - Add `PhysicsProps` interface
  - Add `ColliderShape` type
- Move helper/utils at `./src/utils/`
  - Rename `createColliderDesc` to `createColliderDesc`, and return a `ColliderDesc`
  - Rename `createRigidBody` to `createRigidBodyDesc` and return a `RigidBodyDesc`
- Add a `./src/constants/` sub folder

Co-Authored-By: Alvaro Saburido <alvaro.saburido@gmail.com>
  • Loading branch information
Neosoulink and alvarosabu committed Jun 17, 2024
1 parent 6cca9d3 commit 9441602
Show file tree
Hide file tree
Showing 15 changed files with 241 additions and 175 deletions.
15 changes: 6 additions & 9 deletions src/core/Debug.vue → src/components/Debug.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<script setup lang="ts">
import { useLoop } from '@tresjs/core'
import type { LineSegments } from 'three'
import { BufferAttribute } from 'three'
import { ref } from 'vue'
import { BufferAttribute, type LineSegments } from 'three'
import { useLoop } from '@tresjs/core'
import { useRapierContext } from '../composables/useRapier'
const { world } = await useRapierContext()
const lineSegmentsRef = ref<LineSegments | null>(null)
const { onBeforeRender } = useLoop()
const lineSegmentsRef = ref<LineSegments | null>(null)
onBeforeRender(() => {
if (!world || !lineSegmentsRef.value) { return }
world.step()
Expand All @@ -27,10 +27,7 @@ onBeforeRender(() => {
<template>
<TresGroup>
<TresLineSegments ref="lineSegmentsRef">
<TresLineBasicMaterial
color="#ff0000"
vertex-colors
/>
<TresLineBasicMaterial color="#ff0000" vertex-colors />
<TresBufferGeometry />
</TresLineSegments>
</TresGroup>
Expand Down
5 changes: 3 additions & 2 deletions src/core/Physics.vue → src/components/Physics.vue
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
<script setup lang="ts">
import { useLoop } from '@tresjs/core'
import { useRapierContextProvider } from '../composables/useRapier'
import type { PhysicsProps } from '../types/physics.type'
import Debug from './Debug.vue'
withDefaults(
defineProps<{ debug: boolean }>(),
defineProps<Partial<PhysicsProps>>(),
{
debug: false,
},
)
const { world } = await useRapierContextProvider()
const { onBeforeRender } = useLoop()
onBeforeRender(() => {
Expand Down
52 changes: 52 additions & 0 deletions src/components/RigidBody.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<script setup lang="ts">
import { shallowRef, watch } from 'vue'
import type { Collider, RigidBody } from '@dimforge/rapier3d-compat'
import { type TresObject, useLoop } from '@tresjs/core'
import { useRapierContext } from '../composables/useRapier'
import { createRigidBodyDesc } from '../utils/rigid-body.util'
import { createColliderDesc } from '../utils/collider.util'
import type { RigidBodyProps } from '../types/rigid-body.type'
const props = withDefaults(defineProps<Partial<RigidBodyProps>>(), {
type: 'dynamic',
collider: 'cuboid',
})
const { world } = await useRapierContext()
const { onBeforeRender } = useLoop()
const rigidRef = shallowRef<TresObject>()
const rigidBody = shallowRef<RigidBody>()
const collider = shallowRef<Collider>()
watch(rigidRef, (value) => {
if (!value) { return }
const rigidBodyDesc = createRigidBodyDesc(value.children[0], props.type)
const colliderDesc = createColliderDesc(value.children[0], props.collider)
if (!rigidBodyDesc || !colliderDesc) {
throw new Error('Invalid #RigidBody properties detected. Unable to construct the physics body')
}
rigidBody.value = world.createRigidBody(rigidBodyDesc)
collider.value = world.createCollider(colliderDesc, rigidBody.value)
})
onBeforeRender(() => {
if (!rigidBody.value) { return }
const position = rigidBody.value.translation()
rigidRef.value?.children[0].position.set(position.x, position.y, position.z)
const rotation = rigidBody.value.rotation()
rigidRef.value?.children[0].quaternion.set(rotation.x, rotation.y, rotation.z, rotation.w)
})
</script>

<template>
<TresGroup ref="rigidRef">
<slot></slot>
</TresGroup>
</template>
48 changes: 5 additions & 43 deletions src/composables/useRapier.ts
Original file line number Diff line number Diff line change
@@ -1,48 +1,10 @@
import type { World } from '@dimforge/rapier3d-compat'
import type Rapier from '@dimforge/rapier3d-compat'
import { inject, provide } from 'vue'

const GRAVITY = { x: 0, y: -9.81, z: 0 }
export interface RapierContext {
/**
* @description Rapier instance.
*
* @docs https://rapier.rs/docs/api/javascript/JavaScript3D/
*/
rapier: typeof Rapier
/**
* @description Rapier physics world
*/
world: World
/**
* @description If the physics simulation is paused.
*/
isPaused: boolean
/**
* @description If the debugging mode enabled.
*/
isDebug: boolean
/**
* @description Set the physics world.
*
* @param world New physics world.
*/
setWorld: (world: World) => void
/**
* @description Step the physics world.
*
* @param timestep The timestep length, in seconds.
*
* @example
* ```ts
* step(1/60)
* ```
*/
step: (timestep?: number) => void
}
import { GRAVITY } from '../constants/physics.constant'
import type { RapierContext } from '../types/rapier.type'

/**
* @description to retrieve the `RapierContext` provider.
* @description Provides the `RapierContext` provider.
*/
export async function useRapierContextProvider() {
const toProvide: Partial<RapierContext> = {
Expand Down Expand Up @@ -73,7 +35,7 @@ export async function useRapierContextProvider() {
}

/**
* @description To retrieve the `RapierContext`
* @description Provides the `RapierContext`
*
* @internal
*/
Expand All @@ -90,6 +52,6 @@ export function useRapierContext(): RapierContext {
}

/**
* @description Retrieve the `RapierContext`
* @description Provides the `RapierContext`
*/
export const useRapier = useRapierContext
3 changes: 3 additions & 0 deletions src/constants/object.constant.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { Vector3 } from 'three'

export const VECTOR_ZERO = new Vector3()
1 change: 1 addition & 0 deletions src/constants/physics.constant.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const GRAVITY = { x: 0, y: -9.81, z: 0 }
117 changes: 0 additions & 117 deletions src/core/RigidBody.vue

This file was deleted.

4 changes: 2 additions & 2 deletions src/core/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Physics from './Physics.vue'
import RigidBody from './RigidBody.vue'
import Physics from '../components/Physics.vue'
import RigidBody from '../components/RigidBody.vue'
import { useRapier } from './../composables/useRapier'

export { Physics, RigidBody, useRapier }
4 changes: 2 additions & 2 deletions src/core/injectionKeys.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { InjectionKey, ShallowRef } from 'vue'

export interface RapierContext {}
import type { InjectableRapierContext } from '../types/rapier.type'

export const rapierInjectionKey: InjectionKey<
ShallowRef<RapierContext | null>
ShallowRef<InjectableRapierContext | null>
> = Symbol('tresrapier')
8 changes: 8 additions & 0 deletions src/types/collider.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export type ColliderShape =
| 'cuboid'
| 'ball'
| 'capsule'
| 'cone'
| 'cylinder'
| 'trimesh'
| 'heightfield'
1 change: 1 addition & 0 deletions src/types/physics.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export interface PhysicsProps { debug: boolean }
42 changes: 42 additions & 0 deletions src/types/rapier.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import type Rapier from '@dimforge/rapier3d-compat'
import type { World } from '@dimforge/rapier3d-compat'

export interface RapierContext {
/**
* @description Rapier instance.
*
* @docs https://rapier.rs/docs/api/javascript/JavaScript3D/
*/
rapier: typeof Rapier
/**
* @description Rapier physics world
*/
world: World
/**
* @description If the physics simulation is paused.
*/
isPaused: boolean
/**
* @description If the debugging mode enabled.
*/
isDebug: boolean
/**
* @description Set the physics world.
*
* @param world New physics world.
*/
setWorld: (world: World) => void
/**
* @description Step the physics world.
*
* @param timestep The timestep length, in seconds.
*
* @example
* ```ts
* step(1/60)
* ```
*/
step: (timestep?: number) => void
}

export interface InjectableRapierContext {}
12 changes: 12 additions & 0 deletions src/types/rigid-body.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { ColliderShape } from './collider.type'

export type RigidBodyType =
| 'dynamic'
| 'kinematic'
| 'kinematicVelocity'
| 'fixed'

export interface RigidBodyProps {
type: RigidBodyType
collider: ColliderShape
}
Loading

0 comments on commit 9441602

Please sign in to comment.