Skip to content
This repository was archived by the owner on Aug 21, 2024. It is now read-only.
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 36 additions & 24 deletions packages/engine/src/scene/components/UVOL2Component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -717,17 +717,33 @@ function UVOL2Reactor() {
component.canPlay.set(true)
}, [volumetric.paused])

const getAttribute = (name: string, target: string, index: number) => {
const key = createKey(target, index)
const getFrame = (currentTime: number, frameRate: number, integer = true) => {
const frame = currentTime * frameRate
return integer ? Math.round(frame) : frame
}

const getAttribute = (name: 'keyframeA' | 'keyframeB', currentTime: number) => {
const currentGeometryTarget = component.geometryTarget.value
let index = getFrame(currentTime, manifest.current.geometry.targets[currentGeometryTarget].frameRate, false)
if (name === 'keyframeA') {
index = Math.floor(index)
} else {
index = Math.ceil(index)
}
const key = createKey(currentGeometryTarget, index)
if (!geometryBuffer.has(key)) {
const frameRate = manifest.current.geometry.targets[target].frameRate
const targets = Object.keys(manifest.current.geometry.targets)

for (let i = 0; i < targets.length; i++) {
const _target = targets[i]
const _targetData = manifest.current.geometry.targets[_target]
const _frameRate = _targetData.frameRate
const _index = Math.round((index * _frameRate) / frameRate)
let _index = getFrame(currentTime, _targetData.frameRate, false)
if (name === 'keyframeA') {
_index = Math.floor(_index)
} else {
_index = Math.ceil(_index)
}

if (geometryBuffer.has(createKey(_target, _index))) {
const attribute = geometryBuffer.get(createKey(_target, _index))! as InterleavedBufferAttribute
return attribute
Expand Down Expand Up @@ -842,16 +858,15 @@ function UVOL2Reactor() {
}
}

const setTexture = (target: string, index: number) => {
const setTexture = (target: string, index: number, currentTime: number) => {
const key = createKey(target, index)
if (!textureBuffer.has(key)) {
const targets = Object.keys(manifest.current.texture.baseColor.targets)
const frameRate = manifest.current.texture.baseColor.targets[target].frameRate
for (let i = 0; i < targets.length; i++) {
const _frameRate = manifest.current.texture.baseColor.targets[targets[i]].frameRate
const _index = Math.round((index * _frameRate) / frameRate)
const _index = getFrame(currentTime, _frameRate)
if (textureBuffer.has(createKey(targets[i], _index))) {
setTexture(targets[i], _index)
setTexture(targets[i], _index, currentTime)
return
}
}
Expand Down Expand Up @@ -890,14 +905,8 @@ function UVOL2Reactor() {
}

const updateUniformSolve = (currentTime: number) => {
const geometryTarget = component.geometryTarget.value
const geometryFrame = currentTime * manifest.current.geometry.targets[geometryTarget].frameRate
const keyframeAIndex = Math.floor(geometryFrame)
const keyframeBIndex = Math.ceil(geometryFrame)
let mixRatio = geometryFrame - keyframeAIndex

const keyframeA = getAttribute('position', geometryTarget, keyframeAIndex)
const keyframeB = getAttribute('position', geometryTarget, keyframeBIndex)
const keyframeA = getAttribute('keyframeA', currentTime)
const keyframeB = getAttribute('keyframeB', currentTime)

if (!keyframeA && !keyframeB) {
return
Expand All @@ -910,14 +919,17 @@ function UVOL2Reactor() {
;(mesh.material as ShaderMaterial).uniforms.mixRatio.value = 0
return
} else if (keyframeA && keyframeB) {
const keyframeAIndex = parseInt(keyframeA.name.slice(-KEY_PADDING))
const keyframeATarget = keyframeA.name.slice(0, -KEY_PADDING)
const keyframeATime = keyframeAIndex / manifest.current.geometry.targets[keyframeATarget].frameRate

const keyframeBIndex = parseInt(keyframeB.name.slice(-KEY_PADDING))
const keyframeBTarget = keyframeB.name.slice(0, -KEY_PADDING)
if (keyframeATarget === keyframeBTarget && keyframeATarget !== geometryTarget) {
// If both keyframes are of different target, update the mixRatio
const _geometryFrame = currentTime * manifest.current.geometry.targets[keyframeATarget].frameRate
const _keyframeAIndex = Math.floor(_geometryFrame)
mixRatio = _geometryFrame - _keyframeAIndex
}
const keyframeBTime = keyframeBIndex / manifest.current.geometry.targets[keyframeBTarget].frameRate

const d1 = Math.abs(currentTime - keyframeATime)
const d2 = Math.abs(currentTime - keyframeBTime)
const mixRatio = d1 + d2 > 0 ? d1 / (d1 + d2) : 0.5
setAttribute('keyframeA', keyframeA)
setAttribute('keyframeB', keyframeB)
;(mesh.material as ShaderMaterial).uniforms.mixRatio.value = mixRatio
Expand All @@ -941,7 +953,7 @@ function UVOL2Reactor() {
const updateTexture = (currentTime: number) => {
const textureTarget = component.textureTarget.value
const textureFrame = Math.round(currentTime * manifest.current.texture.baseColor.targets[textureTarget].frameRate)
setTexture(textureTarget, textureFrame)
setTexture(textureTarget, textureFrame, currentTime)
}

const update = () => {
Expand Down