mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-05-23 06:10:32 +00:00
chore: upgrade sparkjs to 2.x and three to 0.184 (#12396)
## Summary - Spark 2.x requires SparkRenderer in scene tree; add it in SceneManager and protect it in clearModel so model reloads don't dispose the splat renderer. - three 0.184 OrbitControls listens on ownerDocument; drop redundant pointermove/up .stop in Load3D containers so the document listener can receive events. - Narrow Texture.image type for 0.184 strict typing.
This commit is contained in:
@@ -113,7 +113,7 @@
|
||||
"primevue": "catalog:",
|
||||
"reka-ui": "catalog:",
|
||||
"semver": "^7.7.2",
|
||||
"three": "^0.170.0",
|
||||
"three": "catalog:",
|
||||
"tiptap-markdown": "^0.8.10",
|
||||
"typegpu": "catalog:",
|
||||
"vee-validate": "catalog:",
|
||||
|
||||
78
pnpm-lock.yaml
generated
78
pnpm-lock.yaml
generated
@@ -91,8 +91,8 @@ catalogs:
|
||||
specifier: ^10.32.1
|
||||
version: 10.32.1
|
||||
'@sparkjsdev/spark':
|
||||
specifier: ^0.1.10
|
||||
version: 0.1.10
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
'@storybook/addon-docs':
|
||||
specifier: ^10.2.10
|
||||
version: 10.2.10
|
||||
@@ -157,8 +157,8 @@ catalogs:
|
||||
specifier: ^7.7.0
|
||||
version: 7.7.0
|
||||
'@types/three':
|
||||
specifier: ^0.170.0
|
||||
version: 0.170.0
|
||||
specifier: ^0.184.1
|
||||
version: 0.184.1
|
||||
'@vee-validate/zod':
|
||||
specifier: ^4.15.1
|
||||
version: 4.15.1
|
||||
@@ -337,8 +337,8 @@ catalogs:
|
||||
specifier: ^0.6.1
|
||||
version: 0.6.1
|
||||
three:
|
||||
specifier: ^0.170.0
|
||||
version: 0.170.0
|
||||
specifier: ^0.184.0
|
||||
version: 0.184.0
|
||||
tsx:
|
||||
specifier: ^4.15.6
|
||||
version: 4.19.4
|
||||
@@ -438,7 +438,7 @@ importers:
|
||||
version: link:packages/design-system
|
||||
'@comfyorg/fbx-exporter-three':
|
||||
specifier: ^1.0.1
|
||||
version: 1.0.1(@types/three@0.170.0)(three@0.170.0)
|
||||
version: 1.0.1(@types/three@0.184.1)(three@0.184.0)
|
||||
'@comfyorg/object-info-parser':
|
||||
specifier: workspace:*
|
||||
version: link:packages/object-info-parser
|
||||
@@ -483,7 +483,7 @@ importers:
|
||||
version: 10.32.1(pinia@3.0.4(typescript@5.9.3)(vue@3.5.13(typescript@5.9.3)))(vue@3.5.13(typescript@5.9.3))
|
||||
'@sparkjsdev/spark':
|
||||
specifier: 'catalog:'
|
||||
version: 0.1.10
|
||||
version: 2.1.0(three@0.184.0)
|
||||
'@tanstack/vue-virtual':
|
||||
specifier: 'catalog:'
|
||||
version: 3.13.12(vue@3.5.13(typescript@5.9.3))
|
||||
@@ -596,8 +596,8 @@ importers:
|
||||
specifier: ^7.7.2
|
||||
version: 7.7.4
|
||||
three:
|
||||
specifier: ^0.170.0
|
||||
version: 0.170.0
|
||||
specifier: 'catalog:'
|
||||
version: 0.184.0
|
||||
tiptap-markdown:
|
||||
specifier: ^0.8.10
|
||||
version: 0.8.10(@tiptap/core@2.27.2(@tiptap/pm@2.27.2))
|
||||
@@ -621,7 +621,7 @@ importers:
|
||||
version: 3.2.1(consola@3.4.2)(firebase@11.6.0)(vue@3.5.13(typescript@5.9.3))
|
||||
wwobjloader2:
|
||||
specifier: 'catalog:'
|
||||
version: 6.2.1(three@0.170.0)
|
||||
version: 6.2.1(three@0.184.0)
|
||||
yjs:
|
||||
specifier: 'catalog:'
|
||||
version: 13.6.27
|
||||
@@ -706,7 +706,7 @@ importers:
|
||||
version: 7.7.0
|
||||
'@types/three':
|
||||
specifier: 'catalog:'
|
||||
version: 0.170.0
|
||||
version: 0.184.1
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: 'catalog:'
|
||||
version: 6.0.3(vite@8.0.0(@types/node@24.10.4)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.39.2)(tsx@4.19.4)(yaml@2.9.0))(vue@3.5.13(typescript@5.9.3))
|
||||
@@ -980,7 +980,7 @@ importers:
|
||||
version: 1.358.1
|
||||
three:
|
||||
specifier: 'catalog:'
|
||||
version: 0.170.0
|
||||
version: 0.184.0
|
||||
vue:
|
||||
specifier: 'catalog:'
|
||||
version: 3.5.13(typescript@5.9.3)
|
||||
@@ -1850,6 +1850,9 @@ packages:
|
||||
'@cyberalien/svg-utils@1.1.1':
|
||||
resolution: {integrity: sha512-i05Cnpzeezf3eJAXLx7aFirTYYoq5D1XUItp1XsjqkerNJh//6BG9sOYHbiO7v0KYMvJAx3kosrZaRcNlQPdsA==}
|
||||
|
||||
'@dimforge/rapier3d-compat@0.12.0':
|
||||
resolution: {integrity: sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow==}
|
||||
|
||||
'@dual-bundle/import-meta-resolve@4.2.1':
|
||||
resolution: {integrity: sha512-id+7YRUgoUX6CgV0DtuhirQWodeeA7Lf4i2x71JS/vtA5pRb/hIGWlw+G6MeXvsM+MXrz0VAydTGElX1rAfgPg==}
|
||||
|
||||
@@ -3948,8 +3951,10 @@ packages:
|
||||
resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@sparkjsdev/spark@0.1.10':
|
||||
resolution: {integrity: sha512-CiijdZQuj7KPDUqIZPiEqyUkJCYo1JqR05vq/V+ElxMwqR7L70ZuZDyIKcasjZHSiPB8pGRMH8HZGqUKO9aRPQ==}
|
||||
'@sparkjsdev/spark@2.1.0':
|
||||
resolution: {integrity: sha512-BRw+MuMzx0B3K8fDLQygt2OHEhYUV+41RX7btq9pZ3rCVrq42o57jW34VAIvC7JO/84DJh/1AutACV9ym6BfVg==}
|
||||
peerDependencies:
|
||||
three: '>=0.180.0'
|
||||
|
||||
'@standard-schema/spec@1.1.0':
|
||||
resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
|
||||
@@ -4424,8 +4429,8 @@ packages:
|
||||
'@types/stats.js@0.17.3':
|
||||
resolution: {integrity: sha512-pXNfAD3KHOdif9EQXZ9deK82HVNaXP5ZIF5RP2QG6OQFNTaY2YIetfrE9t528vEreGQvEPRDDc8muaoYeK0SxQ==}
|
||||
|
||||
'@types/three@0.170.0':
|
||||
resolution: {integrity: sha512-CUm2uckq+zkCY7ZbFpviRttY+6f9fvwm6YqSqPfA5K22s9w7R4VnA3rzJse8kHVvuzLcTx+CjNCs2NYe0QFAyg==}
|
||||
'@types/three@0.184.1':
|
||||
resolution: {integrity: sha512-6q4VdiqVsrTRqmk62/BnlcAvIrnDM0zf2ZDVKI5kZiniWrSaOHaQzmbp+BNzoggc/8tgW412pL//wZIxu2PPTA==}
|
||||
|
||||
'@types/tough-cookie@4.0.5':
|
||||
resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==}
|
||||
@@ -7441,8 +7446,8 @@ packages:
|
||||
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
meshoptimizer@0.18.1:
|
||||
resolution: {integrity: sha512-ZhoIoL7TNV4s5B6+rx5mC//fw8/POGyNxS/DZyCJeiZ12ScLfVwRE/GfsxwiTkMYYD5DmK2/JXnEVXqL4rF+Sw==}
|
||||
meshoptimizer@1.1.1:
|
||||
resolution: {integrity: sha512-oRFNWJRDA/WTrVj7NWvqa5HqE1t9MYDj2VaWirQCzCCrAd2GHrqR/sQezCxiWATPNlKTcRaPRHPJwIRoPBAp5g==}
|
||||
|
||||
micromark-core-commonmark@2.0.3:
|
||||
resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==}
|
||||
@@ -8823,8 +8828,8 @@ packages:
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
|
||||
three@0.170.0:
|
||||
resolution: {integrity: sha512-FQK+LEpYc0fBD+J8g6oSEyyNzjp+Q7Ks1C568WWaoMRLW+TkNNWmenWeGgJjV105Gd+p/2ql1ZcjYvNiPZBhuQ==}
|
||||
three@0.184.0:
|
||||
resolution: {integrity: sha512-wtTRjG92pM5eUg/KuUnHsqSAlPM296brTOcLgMRqEeylYTh/CdtvKUvCyyCQTzFuStieWxvZb8mVTMvdPyUpxg==}
|
||||
|
||||
tiny-inflate@1.0.3:
|
||||
resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==}
|
||||
@@ -10875,12 +10880,12 @@ snapshots:
|
||||
|
||||
'@comfyorg/comfyui-electron-types@0.6.2': {}
|
||||
|
||||
'@comfyorg/fbx-exporter-three@1.0.1(@types/three@0.170.0)(three@0.170.0)':
|
||||
'@comfyorg/fbx-exporter-three@1.0.1(@types/three@0.184.1)(three@0.184.0)':
|
||||
dependencies:
|
||||
fflate: 0.8.2
|
||||
three: 0.170.0
|
||||
three: 0.184.0
|
||||
optionalDependencies:
|
||||
'@types/three': 0.170.0
|
||||
'@types/three': 0.184.1
|
||||
|
||||
'@csstools/color-helpers@5.1.0': {}
|
||||
|
||||
@@ -10917,6 +10922,8 @@ snapshots:
|
||||
dependencies:
|
||||
'@iconify/types': 2.0.0
|
||||
|
||||
'@dimforge/rapier3d-compat@0.12.0': {}
|
||||
|
||||
'@dual-bundle/import-meta-resolve@4.2.1': {}
|
||||
|
||||
'@emmetio/abbreviation@2.3.3':
|
||||
@@ -12880,9 +12887,10 @@ snapshots:
|
||||
|
||||
'@sindresorhus/merge-streams@4.0.0': {}
|
||||
|
||||
'@sparkjsdev/spark@0.1.10':
|
||||
'@sparkjsdev/spark@2.1.0(three@0.184.0)':
|
||||
dependencies:
|
||||
fflate: 0.8.2
|
||||
three: 0.184.0
|
||||
|
||||
'@standard-schema/spec@1.1.0': {}
|
||||
|
||||
@@ -13405,14 +13413,14 @@ snapshots:
|
||||
|
||||
'@types/stats.js@0.17.3': {}
|
||||
|
||||
'@types/three@0.170.0':
|
||||
'@types/three@0.184.1':
|
||||
dependencies:
|
||||
'@dimforge/rapier3d-compat': 0.12.0
|
||||
'@tweenjs/tween.js': 23.1.3
|
||||
'@types/stats.js': 0.17.3
|
||||
'@types/webxr': 0.5.20
|
||||
'@webgpu/types': 0.1.66
|
||||
fflate: 0.8.2
|
||||
meshoptimizer: 0.18.1
|
||||
meshoptimizer: 1.1.1
|
||||
|
||||
'@types/tough-cookie@4.0.5': {}
|
||||
|
||||
@@ -16910,7 +16918,7 @@ snapshots:
|
||||
|
||||
merge2@1.4.1: {}
|
||||
|
||||
meshoptimizer@0.18.1: {}
|
||||
meshoptimizer@1.1.1: {}
|
||||
|
||||
micromark-core-commonmark@2.0.3:
|
||||
dependencies:
|
||||
@@ -18772,7 +18780,7 @@ snapshots:
|
||||
commander: 2.20.3
|
||||
source-map-support: 0.5.21
|
||||
|
||||
three@0.170.0: {}
|
||||
three@0.184.0: {}
|
||||
|
||||
tiny-inflate@1.0.3: {}
|
||||
|
||||
@@ -19831,16 +19839,16 @@ snapshots:
|
||||
|
||||
wtd-core@3.0.0: {}
|
||||
|
||||
wtd-three-ext@3.0.0(three@0.170.0):
|
||||
wtd-three-ext@3.0.0(three@0.184.0):
|
||||
dependencies:
|
||||
three: 0.170.0
|
||||
three: 0.184.0
|
||||
wtd-core: 3.0.0
|
||||
|
||||
wwobjloader2@6.2.1(three@0.170.0):
|
||||
wwobjloader2@6.2.1(three@0.184.0):
|
||||
dependencies:
|
||||
three: 0.170.0
|
||||
three: 0.184.0
|
||||
wtd-core: 3.0.0
|
||||
wtd-three-ext: 3.0.0(three@0.170.0)
|
||||
wtd-three-ext: 3.0.0(three@0.184.0)
|
||||
|
||||
xdg-basedir@5.1.0: {}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ catalog:
|
||||
'@primevue/themes': ^4.2.5
|
||||
'@sentry/vite-plugin': ^4.6.0
|
||||
'@sentry/vue': ^10.32.1
|
||||
'@sparkjsdev/spark': ^0.1.10
|
||||
'@sparkjsdev/spark': ^2.1.0
|
||||
'@storybook/addon-docs': ^10.2.10
|
||||
'@storybook/addon-mcp': 0.1.6
|
||||
'@storybook/vue3': ^10.2.10
|
||||
@@ -59,7 +59,7 @@ catalog:
|
||||
'@types/jsdom': ^21.1.7
|
||||
'@types/node': ^24.1.0
|
||||
'@types/semver': ^7.7.0
|
||||
'@types/three': ^0.170.0
|
||||
'@types/three': ^0.184.1
|
||||
'@vee-validate/zod': ^4.15.1
|
||||
'@vercel/analytics': ^2.0.1
|
||||
'@vitejs/plugin-vue': ^6.0.0
|
||||
@@ -118,7 +118,7 @@ catalog:
|
||||
storybook: ^10.2.10
|
||||
stylelint: ^16.26.1
|
||||
tailwindcss: ^4.3.0
|
||||
three: ^0.170.0
|
||||
three: ^0.184.0
|
||||
tailwindcss-primeui: ^0.6.1
|
||||
tsx: ^4.15.6
|
||||
tw-animate-css: ^1.3.8
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
@mouseenter="handleMouseEnter"
|
||||
@mouseleave="handleMouseLeave"
|
||||
@pointerdown.stop
|
||||
@pointermove.stop
|
||||
@pointerup.stop
|
||||
>
|
||||
<Load3DScene
|
||||
v-if="node"
|
||||
|
||||
@@ -5,11 +5,7 @@
|
||||
data-capture-wheel="true"
|
||||
tabindex="-1"
|
||||
@pointerdown.stop="focusContainer"
|
||||
@pointermove.stop
|
||||
@pointerup.stop
|
||||
@mousedown.stop
|
||||
@mousemove.stop
|
||||
@mouseup.stop
|
||||
@contextmenu.stop.prevent
|
||||
@dragover.prevent.stop="handleDragOver"
|
||||
@dragleave.stop="handleDragLeave"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { SparkRenderer } from '@sparkjsdev/spark'
|
||||
import * as THREE from 'three'
|
||||
import type { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
@@ -137,6 +138,13 @@ describe('SceneManager', () => {
|
||||
expect(manager.scene.children).toContain(manager.gridHelper)
|
||||
})
|
||||
|
||||
it('adds a SparkRenderer to the scene so SplatMesh instances render', () => {
|
||||
const sparkRenderers = manager.scene.children.filter(
|
||||
(child) => child instanceof SparkRenderer
|
||||
)
|
||||
expect(sparkRenderers).toHaveLength(1)
|
||||
})
|
||||
|
||||
it('builds a separate background scene with a tiled mesh', () => {
|
||||
expect(manager.backgroundScene).toBeInstanceOf(THREE.Scene)
|
||||
expect(manager.backgroundMesh).toBeInstanceOf(THREE.Mesh)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { SparkRenderer } from '@sparkjsdev/spark'
|
||||
import * as THREE from 'three'
|
||||
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
|
||||
|
||||
@@ -11,6 +12,7 @@ import {
|
||||
export class SceneManager implements SceneManagerInterface {
|
||||
scene!: THREE.Scene
|
||||
gridHelper: THREE.GridHelper
|
||||
private sparkRenderer: SparkRenderer
|
||||
|
||||
backgroundScene!: THREE.Scene
|
||||
backgroundCamera: THREE.OrthographicCamera
|
||||
@@ -42,6 +44,12 @@ export class SceneManager implements SceneManagerInterface {
|
||||
|
||||
this.getActiveCamera = getActiveCamera
|
||||
|
||||
// Spark 2.x requires a SparkRenderer in the scene tree to render SplatMesh
|
||||
// (Gaussian splat) instances; without it splats are silent no-ops. Kept
|
||||
// alive across model reloads by SceneModelManager.clearModel.
|
||||
this.sparkRenderer = new SparkRenderer({ renderer })
|
||||
this.scene.add(this.sparkRenderer)
|
||||
|
||||
this.gridHelper = new THREE.GridHelper(20, 20)
|
||||
this.gridHelper.position.set(0, 0, 0)
|
||||
this.scene.add(this.gridHelper)
|
||||
@@ -277,8 +285,8 @@ export class SceneManager implements SceneManagerInterface {
|
||||
|
||||
if (!material.map) return
|
||||
|
||||
const imageAspect =
|
||||
backgroundTexture.image.width / backgroundTexture.image.height
|
||||
const image = backgroundTexture.image as { width: number; height: number }
|
||||
const imageAspect = image.width / image.height
|
||||
const targetAspect = targetWidth / targetHeight
|
||||
|
||||
if (imageAspect > targetAspect) {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { SparkRenderer } from '@sparkjsdev/spark'
|
||||
import * as THREE from 'three'
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
|
||||
@@ -355,6 +356,20 @@ describe('SceneModelManager', () => {
|
||||
expect(geoDispose).toHaveBeenCalled()
|
||||
expect(matDispose).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('preserves SparkRenderer across model reloads', async () => {
|
||||
const { manager, scene } = createManager()
|
||||
const sparkRenderer = new SparkRenderer({
|
||||
renderer: {} as THREE.WebGLRenderer
|
||||
})
|
||||
scene.add(sparkRenderer)
|
||||
|
||||
const model = createMeshModel()
|
||||
await manager.setupModel(model)
|
||||
manager.clearModel()
|
||||
|
||||
expect(scene.children).toContain(sparkRenderer)
|
||||
})
|
||||
})
|
||||
|
||||
describe('reset', () => {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { SparkRenderer } from '@sparkjsdev/spark'
|
||||
import * as THREE from 'three'
|
||||
import type { GLTF } from 'three/examples/jsm/loaders/GLTFLoader'
|
||||
|
||||
@@ -317,6 +318,7 @@ export class SceneModelManager implements ModelManagerInterface {
|
||||
object instanceof THREE.GridHelper ||
|
||||
object instanceof THREE.Light ||
|
||||
object instanceof THREE.Camera ||
|
||||
object instanceof SparkRenderer ||
|
||||
object.name === 'GizmoTransformControls'
|
||||
|
||||
if (!isEnvironmentObject) {
|
||||
|
||||
@@ -3,11 +3,19 @@ import { vi } from 'vitest'
|
||||
import 'vue'
|
||||
|
||||
// Mock @sparkjsdev/spark which uses WASM that doesn't work in Node.js
|
||||
vi.mock('@sparkjsdev/spark', () => ({
|
||||
SplatMesh: class SplatMesh {
|
||||
constructor() {}
|
||||
vi.mock('@sparkjsdev/spark', async () => {
|
||||
const three = await import('three')
|
||||
return {
|
||||
SplatMesh: class SplatMesh {
|
||||
constructor() {}
|
||||
},
|
||||
SparkRenderer: class SparkRenderer extends three.Object3D {
|
||||
constructor() {
|
||||
super()
|
||||
}
|
||||
}
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
// Augment Window interface for tests
|
||||
declare global {
|
||||
|
||||
Reference in New Issue
Block a user