Skip to content
This repository has been archived by the owner on Aug 21, 2024. It is now read-only.

Commit

Permalink
wip: init UniformUVOL
Browse files Browse the repository at this point in the history
  • Loading branch information
CITIZENDOT committed Sep 22, 2023
1 parent 1bfb929 commit 98e14a6
Show file tree
Hide file tree
Showing 7 changed files with 910 additions and 179 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import { VolumetricComponent } from '@etherealengine/engine/src/scene/components
import { PlayMode } from '@etherealengine/engine/src/scene/constants/PlayMode'

import VideocamIcon from '@mui/icons-material/Videocam'

import { ItemTypes } from '../../constants/AssetTypes'
import ArrayInputGroup from '../inputs/ArrayInputGroup'
import { Button } from '../inputs/Button'
Expand Down Expand Up @@ -119,7 +118,7 @@ export const VolumetricNodeEditor: EditorComponentType = (props) => {
/>
{volumetricComponent.paths && volumetricComponent.paths.length > 0 && volumetricComponent.paths[0] && (
<Button style={{ marginLeft: '5px', width: '60px' }} type="submit" onClick={toggle}>
{volumetricComponent.paused
{volumetricComponent.paused.value
? t('editor:properties.media.playtitle')
: t('editor:properties.media.pausetitle')}
</Button>
Expand Down
3 changes: 3 additions & 0 deletions packages/engine/src/assets/functions/createGLTFLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ export const createGLTFLoader = (keepMaterials = false) => {
loader.register((parser) => new HubsComponentsExtension(parser))
loader.register((parser) => new VRMLoaderPlugin(parser, { helperRoot: new Group(), autoUpdateHumanBones: true }))
loader.register((parser) => new CachedImageLoadExtension(parser))
if (MeshoptDecoder.useWorkers) {
MeshoptDecoder.useWorkers(2)
}
loader.setMeshoptDecoder(MeshoptDecoder)

if (isClient) {
Expand Down
302 changes: 177 additions & 125 deletions packages/engine/src/assets/loaders/gltf/meshopt_decoder.module.js

Large diffs are not rendered by default.

49 changes: 27 additions & 22 deletions packages/engine/src/scene/components/UVOL1Component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { getState } from '@etherealengine/hyperflux'
import { useEffect, useMemo, useRef } from 'react'
import { BufferGeometry, LinearFilter, Mesh, MeshBasicMaterial, PlaneGeometry, Texture } from 'three'
import { CORTOLoader } from '../../assets/loaders/corto/CORTOLoader'
import { AudioState } from '../../audio/AudioState'
import { iOS } from '../../common/functions/isMobile'
import { Engine } from '../../ecs/classes/Engine'
import { EngineState } from '../../ecs/classes/EngineState'
Expand All @@ -38,7 +39,7 @@ import { useExecute } from '../../ecs/functions/SystemFunctions'
import { EngineRenderer } from '../../renderer/WebGLRendererSystem'
import { addObjectToGroup, removeObjectFromGroup } from './GroupComponent'
import { MediaElementComponent } from './MediaComponent'
import { VolumetricComponent } from './VolumetricComponent'
import { VolumetricComponent, handleAutoplay } from './VolumetricComponent'

const decodeCorto = (url: string, start: number, end: number) => {
return new Promise((res, rej) => {
Expand Down Expand Up @@ -69,10 +70,8 @@ export const UVOL1Component = defineComponent({

onInit: (entity) => {
return {
track: {
manifestPath: '',
data: {} as ManifestSchema
}
manifestPath: '',
data: {} as ManifestSchema
}
},

Expand All @@ -84,10 +83,11 @@ function UVOL1Reactor() {
const volumetric = useComponent(entity, VolumetricComponent)
const component = useComponent(entity, UVOL1Component)
const videoElement = getMutableComponent(entity, MediaElementComponent).value
const audioContext = getState(AudioState).audioContext
const video = videoElement.element as HTMLVideoElement

const meshBuffer = useMemo(() => new Map<number, BufferGeometry>(), [])
const targetFramesToRequest = useMemo(() => (iOS ? 10 : 90), [])
const targetFramesToRequest = iOS ? 10 : 90

const videoTexture = useMemo(() => {
const element = videoElement.element as HTMLVideoElement
Expand Down Expand Up @@ -121,27 +121,32 @@ function UVOL1Reactor() {
Engine.instance.cortoLoader = loader
}
addObjectToGroup(entity, mesh)
pendingRequests.current = 0
nextFrameToRequest.current = 0
video.src = component.track.manifestPath.value.replace('.manifest', '.mp4')
video.src = component.manifestPath.value.replace('.manifest', '.mp4')

return () => {
removeObjectFromGroup(entity, mesh)
videoTexture.dispose()
const numberOfFrames = component.track.data.value.frameData.length
const numberOfFrames = component.data.value.frameData.length
removePlayedBuffer(numberOfFrames)
meshBuffer.clear()
video.src = ''
}
}, [])

useEffect(() => {
if (volumetric.paused.value) {
if (volumetric.paused.value || !volumetric.initialBuffersLoaded.value) {
video.pause()
} else {
video.play()
return
}
}, [volumetric.paused])

video.play().catch((e) => {
if (e.name === 'NotAllowedError') {
handleAutoplay(audioContext, video)
} else {
console.error(e)
}
})
}, [volumetric.paused, volumetric.initialBuffersLoaded])

/**
* sync mesh frame to video texture frame
Expand All @@ -159,29 +164,29 @@ function UVOL1Reactor() {
}

const handleVideoFrame = (now: DOMHighResTimeStamp, metadata: VideoFrameCallbackMetadata) => {
const frameToPlay = Math.round(metadata.mediaTime * component.track.data.value.frameRate)
const frameToPlay = Math.round(metadata.mediaTime * component.data.value.frameRate)
processFrame(frameToPlay)
}

useVideoFrameCallback(video, handleVideoFrame)

const bufferLoop = () => {
const numberOfFrames = component.track.data.value.frameData.length
const numberOfFrames = component.data.value.frameData.length
if (nextFrameToRequest.current === numberOfFrames - 1) {
// Fetched all frames
return
}

const minimumBufferLength = targetFramesToRequest * 2
const meshBufferHasEnoughToPlay = meshBuffer.size >= minimumBufferLength * 3
const meshBufferHasEnoughToPlay = meshBuffer.size >= 60 // 2 seconds
const meshBufferHasEnough = meshBuffer.size >= minimumBufferLength * 5

if (pendingRequests.current == 0 && !meshBufferHasEnough) {
const newLastFrame = Math.min(nextFrameToRequest.current + targetFramesToRequest - 1, numberOfFrames - 1)
for (let i = nextFrameToRequest.current; i <= newLastFrame; i++) {
const meshFilePath = component.track.manifestPath.value.replace('.manifest', '.drcs')
const byteStart = component.track.data.value.frameData[i].startBytePosition
const byteEnd = byteStart + component.track.data.value.frameData[i].meshLength
const meshFilePath = component.manifestPath.value.replace('.manifest', '.drcs')
const byteStart = component.data.value.frameData[i].startBytePosition
const byteEnd = byteStart + component.data.value.frameData[i].meshLength
pendingRequests.current += 1
decodeCorto(meshFilePath, byteStart, byteEnd).then((geometry: BufferGeometry) => {
meshBuffer.set(i, geometry)
Expand All @@ -191,8 +196,8 @@ function UVOL1Reactor() {
nextFrameToRequest.current = newLastFrame
}

if (meshBufferHasEnoughToPlay && volumetric.paused.value) {
volumetric.paused.set(false)
if (meshBufferHasEnoughToPlay && !volumetric.initialBuffersLoaded.value) {
volumetric.initialBuffersLoaded.set(true)
}
}
}
Expand Down
Loading

0 comments on commit 98e14a6

Please sign in to comment.