Skip to content

Commit

Permalink
feat: eye blinking
Browse files Browse the repository at this point in the history
  • Loading branch information
nekomeowww committed Dec 6, 2024
1 parent 22395a8 commit 289f822
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 1 deletion.
4 changes: 3 additions & 1 deletion packages/stage/src/components/VRMModel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import type { VRMCore } from '@pixiv/three-vrm-core'
import { useLoop, useTresContext } from '@tresjs/core'
import { AnimationMixer } from 'three'
import { clipFromVRMAnimation, loadVRMAnimation } from '~/composables/vrm/animation'
import { clipFromVRMAnimation, loadVRMAnimation, useBlink } from '~/composables/vrm/animation'
import { loadVrm } from '~/composables/vrm/core'
const props = defineProps<{
Expand All @@ -21,6 +21,7 @@ const vrm = ref<VRMCore>()
const vrmAnimationMixer = ref<AnimationMixer>()
const { scene } = useTresContext()
const { onBeforeRender } = useLoop()
const blink = useBlink()
watch(() => props.position, ([x, y, z]) => {
if (vrm.value) {
Expand Down Expand Up @@ -59,6 +60,7 @@ onMounted(async () => {
onBeforeRender(({ delta }) => {
vrmAnimationMixer.value?.update(delta)
vrm.value?.update(delta)
blink.update(vrm.value, delta)
})
vrm.value = _vrm
Expand Down
48 changes: 48 additions & 0 deletions packages/stage/src/composables/vrm/animation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,51 @@ export async function clipFromVRMAnimation(vrm?: VRMCore, animation?: VRMAnimati
// create animation clip
return createVRMAnimationClip(animation, vrm)
}

export function useBlink() {
/**
* Eye blinking animation
*/
const isBlinking = ref(false)
const blinkProgress = ref(0)
const timeSinceLastBlink = ref(0)
const BLINK_DURATION = 0.2 // Duration of a single blink in seconds
const MIN_BLINK_INTERVAL = 1 // Minimum time between blinks
const MAX_BLINK_INTERVAL = 6 // Maximum time between blinks
const nextBlinkTime = ref(Math.random() * (MAX_BLINK_INTERVAL - MIN_BLINK_INTERVAL) + MIN_BLINK_INTERVAL)

// Function to handle blinking animation
function update(vrm: VRMCore | undefined, delta: number) {
if (!vrm?.expressionManager)
return

timeSinceLastBlink.value += delta

// Check if it's time for next blink
if (!isBlinking.value && timeSinceLastBlink.value >= nextBlinkTime.value) {
isBlinking.value = true
blinkProgress.value = 0
}

// Handle blinking animation
if (isBlinking.value) {
blinkProgress.value += delta / BLINK_DURATION

// Calculate blink value using sine curve for smooth animation
const blinkValue = Math.sin(Math.PI * blinkProgress.value)

// Apply blink expression
vrm.expressionManager.setValue('blink', blinkValue)

// Reset blink when animation is complete
if (blinkProgress.value >= 1) {
isBlinking.value = false
timeSinceLastBlink.value = 0
vrm.expressionManager.setValue('blink', 0) // Reset blink value to 0
nextBlinkTime.value = Math.random() * (MAX_BLINK_INTERVAL - MIN_BLINK_INTERVAL) + MIN_BLINK_INTERVAL
}
}
}

return { update }
}

0 comments on commit 289f822

Please sign in to comment.