Skip to content

Commit

Permalink
init wiggle
Browse files Browse the repository at this point in the history
  • Loading branch information
damienmontastier committed Feb 8, 2025
1 parent 8b538b5 commit c41c295
Show file tree
Hide file tree
Showing 12 changed files with 307 additions and 1 deletion.
1 change: 1 addition & 0 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export default defineConfig({
{ text: 'useFBO', link: '/guide/abstractions/use-fbo' },
{ text: 'useSurfaceSampler', link: '/guide/abstractions/use-surface-sampler' },
{ text: 'Sampler', link: '/guide/abstractions/sampler' },
{ text: 'Wiggle', link: '/guide/abstractions/wiggle' },
{ text: 'Edges', link: '/guide/abstractions/edges' },
{ text: 'PositionalAudio', link: '/guide/abstractions/positional-audio' },
{ text: 'AnimatedSprite', link: '/guide/abstractions/animated-sprite' },
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@
"stats-gl": "^2.0.1",
"stats.js": "^0.17.0",
"three-custom-shader-material": "^5.4.0",
"three-stdlib": "^2.34.0"
"three-stdlib": "^2.34.0",
"wiggle": "^0.0.17"
},
"devDependencies": {
"@release-it/conventional-changelog": "^10.0.0",
Expand Down
Binary file added playground/vue/public/wiggle/balloon.glb
Binary file not shown.
Binary file added playground/vue/public/wiggle/banana.glb
Binary file not shown.
Binary file added playground/vue/public/wiggle/demo.glb
Binary file not shown.
Binary file added playground/vue/public/wiggle/flower_draco.glb
Binary file not shown.
116 changes: 116 additions & 0 deletions playground/vue/src/pages/abstractions/WiggleDemo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<script setup lang="ts">
import { gsap } from 'gsap'

Check failure on line 2 in playground/vue/src/pages/abstractions/WiggleDemo.vue

View workflow job for this annotation

GitHub Actions / Lint (20)

'gsap' is defined but never used
import { TresCanvas, useRenderLoop } from '@tresjs/core'
import { Box, Environment, OrbitControls, TransformControls, useGLTF, Wiggle } from '@tresjs/cientos'

Check failure on line 4 in playground/vue/src/pages/abstractions/WiggleDemo.vue

View workflow job for this annotation

GitHub Actions / Lint (20)

'Box' is defined but never used
import { TresLeches, useControls } from '@tresjs/leches'
import '@tresjs/leches/styles'
const gl = {
powerPreference: 'high-performance',
precision: 'highp',
clearColor: '#F6B03B',
}
const model = await useGLTF(
'/wiggle/banana.glb',
{ draco: true },
)
const modelFlower = await useGLTF(
'/wiggle/banana.glb',
{ draco: true },
)
console.log('demo — useGLTF', model)

Check failure on line 24 in playground/vue/src/pages/abstractions/WiggleDemo.vue

View workflow job for this annotation

GitHub Actions / Lint (20)

Unexpected console statement
const modelRef = ref<TresObject | null>(null)
const modelRefBis = ref<TresObject | null>(null)
const testRef = ref(null)
const testRefBis = ref(null)
const { debug, velocity, stiffness, damping } = useControls({

Check failure on line 31 in playground/vue/src/pages/abstractions/WiggleDemo.vue

View workflow job for this annotation

GitHub Actions / Lint (20)

'debug' is assigned a value but never used. Allowed unused vars must match /^_/u
debug: { value: false, type: 'boolean', label: 'Debug' },
velocity: {
label: 'Velocity',
value: 0.1,
min: 0.01,
max: 1,
step: 0.01,
},
stiffness: {
label: 'Stiffness',
value: 500,
min: 100,
max: 1000,
step: 10,
},
damping: {
label: 'Damping',
value: 17,
min: 1,
max: 30,
step: 1,
},
})
// watch(testRef, () => {
// if (!testRef.value) { return }
// // gsap.to(testRef.value.root.position, {
// // z: 5,
// // repeat: -1,
// // ease: 'elastic.out(1,0.3)',
// // duration: 2,
// // })
// console.log(testRef.value.root)
// })
const { onLoop } = useRenderLoop()
onLoop(({ delta, elapsed, clock }) => {

Check failure on line 70 in playground/vue/src/pages/abstractions/WiggleDemo.vue

View workflow job for this annotation

GitHub Actions / Lint (20)

'delta' is defined but never used. Allowed unused args must match /^_/u

Check failure on line 70 in playground/vue/src/pages/abstractions/WiggleDemo.vue

View workflow job for this annotation

GitHub Actions / Lint (20)

'elapsed' is defined but never used. Allowed unused args must match /^_/u

Check failure on line 70 in playground/vue/src/pages/abstractions/WiggleDemo.vue

View workflow job for this annotation

GitHub Actions / Lint (20)

'clock' is defined but never used. Allowed unused args must match /^_/u
// testRef.value.root.position.x = 0.35 * Math.sin(3 * elapsed)
// rootBone.position.y = 1 * Math.sin(3 * elapsed)
})
</script>

<template>
<TresLeches />

<TresCanvas
v-bind="gl"
>
<TresPerspectiveCamera
:position="[5, 2.5, 5]"
/>

<OrbitControls
make-default
:target="[0, 0, 0]"
/>

<TresGridHelper
:args="[10, 10]"
:position-y="0.25"
/>

<Suspense>
<Environment
preset="shangai"
/>
</Suspense>

<Suspense>
<Wiggle ref="testRef" :scale="15" :debug="true" :basic="{ velocity: velocity.value }">
<primitive ref="modelRef" :object="model.scene" />
</Wiggle>
</Suspense>

<Suspense>
<Wiggle ref="testRefBis" :position-z="-2" :scale="15" :debug="true" :spring="{ stiffness: stiffness.value, damping: damping.value }">
<primitive ref="modelRefBis" :object="modelFlower.scene" />
</Wiggle>
</Suspense>

<TransformControls :object="modelRefBis" />
</TresCanvas>
</template>
5 changes: 5 additions & 0 deletions playground/vue/src/router/routes/abstractions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ export const abstractionsRoutes = [
name: 'Edges',
component: () => import('../../pages/abstractions/EdgesDemo.vue'),
},
{
path: '/abstractions/wiggle',
name: 'Wiggle',
component: () => import('../../pages/abstractions/WiggleDemo.vue'),
},
{
path: '/abstractions/positional-audio',
name: 'PositionalAudio',
Expand Down
12 changes: 12 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 34 additions & 0 deletions src/core/abstractions/Wiggle/component.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<script setup lang="ts">
import { shallowRef, toRefs, useSlots, watch } from 'vue'

Check failure on line 2 in src/core/abstractions/Wiggle/component.vue

View workflow job for this annotation

GitHub Actions / Lint (20)

'watch' is defined but never used
import type { TresGroup } from '@tresjs/core'
import { useWiggle } from '.'
export interface WiggleProps {
debug: boolean
basic?: boolean | { velocity?: number }
spring?: boolean | { stiffness?: number, damping?: number }
}
const props = withDefaults(defineProps<WiggleProps>(), {
debug: false,
})
const { debug, basic, spring } = toRefs(props)
const mainRef = shallowRef<TresGroup>()
const slots = useSlots()
const model = slots.default?.({})[0].props.object
useWiggle(model, { debug: debug.value, ...(basic.value ? { basic } : { spring }) })
defineExpose({
root: mainRef,
})
</script>

<template>
<TresGroup ref="mainRef">
<slot></slot>
</TresGroup>
</template>
135 changes: 135 additions & 0 deletions src/core/abstractions/Wiggle/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import { WiggleBone as WiggleSpringBone } from 'wiggle/spring'
import { WiggleBone } from 'wiggle'
import type { Bone, Object3D, SkinnedMesh } from 'three'
import { WiggleRigHelper } from 'wiggle/helper'
import { useRenderLoop, useTresContext } from '@tresjs/core'
import { isRef, ref, watch } from 'vue'

/**
* Hook useWiggle : applique l'effet wiggle aux bones du modèle.
*
* @param {Object3D} model - Le modèle 3D auquel appliquer l'effet wiggle.
* @param {object} options - Les options pour useWiggle.
* @param {boolean} [options.debug] - Activer ou désactiver le mode debug.
* @param {boolean|object} [options.basic] - Activer ou désactiver le mode basic avec options.
*
*/

interface UseWiggleProps {
debug?: boolean
basic?: boolean | { velocity?: number }
spring?: boolean | { stiffness?: number, damping?: number }
helper?: object
}

export function useWiggle(model: Object3D, { debug = false, basic = true, spring = false, helper }: UseWiggleProps) {
if (!model) {
console.error('No model provided')
return
}

console.log('ehlper', helper)

Check failure on line 31 in src/core/abstractions/Wiggle/index.ts

View workflow job for this annotation

GitHub Actions / Lint (20)

Unexpected console statement

const { scene } = useTresContext()
const { onLoop } = useRenderLoop()

const skinnedMesh = model.getObjectByProperty('type', 'SkinnedMesh') as SkinnedMesh

if (!skinnedMesh) { return }

const skeleton = skinnedMesh.skeleton

if (!skeleton) { return }

const wiggleBones: WiggleBone[] = []

const wiggleHelper = new WiggleRigHelper({
skeleton,
...helper,
})

if (debug) {
// Prevent dispose issue on Unmount caused by the memory clean up
// of tresjs (WiggleRighelper is not a Tresjs object)
delete Object.getPrototypeOf(wiggleHelper).dispose

scene.value.add(wiggleHelper)
}

const basicRef = isRef(basic) ? basic : ref(basic)
const springRef = isRef(spring) ? spring : ref(spring)

if (springRef.value) {
basicRef.value = !basicRef.value
}

const isBasicMode = basicRef.value && (typeof basicRef.value === 'boolean' || typeof basicRef.value === 'object')
const isSpringMode = springRef.value && (typeof springRef.value === 'boolean' || typeof springRef.value === 'object')

let rootBone: Bone | undefined

skeleton.bones.forEach((bone: Bone) => {
if (!bone.parent || bone.parent.type !== 'Bone') {
rootBone = bone
}
else {
if (isBasicMode) {
if (typeof basicRef.value === 'boolean') {
const wiggleBone = new WiggleBone(bone)
wiggleBones.push(wiggleBone)
}
else if (typeof basicRef.value === 'object') {
const wiggleBone = new WiggleBone(bone, basicRef.value)
wiggleBones.push(wiggleBone)
}
}

if (isSpringMode) {
if (typeof springRef.value === 'boolean') {
const wiggleBone = new WiggleSpringBone(bone)
wiggleBones.push(wiggleBone)
}
else if (typeof springRef.value === 'object') {
const wiggleBone = new WiggleSpringBone(bone, springRef.value)
wiggleBones.push(wiggleBone)
}
}
}
})

onLoop(({ elapsed }) => {
if (!wiggleBones.length || !rootBone) { return }

rootBone.position.x = 2 * Math.sin(3 * elapsed)
rootBone.position.y = 1 * Math.sin(3 * elapsed)

wiggleBones.forEach(wb => wb.update())
})

if (isBasicMode) {
watch(basicRef, () => {
if (!basicRef) { return }

wiggleBones.forEach((wb) => {
wb.options = basicRef.value
})
})
}

if (isSpringMode && typeof springRef.value === 'object') {
watch(springRef, () => {
wiggleBones.forEach((wb) => {
// Ensure the new values are applied to the springs
wb.springX.updateConfig(springRef.value)
wb.springY.updateConfig(springRef.value)
wb.springZ.updateConfig(springRef.value)
})
})
}

return {
// wiggleHelper,
wiggleBones,
rootBone,
}
}
2 changes: 2 additions & 0 deletions src/core/abstractions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import Fbo from './useFBO/component.vue'
import Sampler from './useSurfaceSampler/component.vue'
import ScreenSizer from './ScreenSizer.vue'
import Edges from './Edges.vue'
import Wiggle from './Wiggle/component.vue'

export * from '../staging/useEnvironment'
export * from './useFBO/'
Expand All @@ -45,4 +46,5 @@ export {
Text3D,
useAnimations,
useMask,
Wiggle,
}

0 comments on commit c41c295

Please sign in to comment.