diff --git a/src/components/load3d/Load3D.vue b/src/components/load3d/Load3D.vue index ce6f83bc2..75635f1b8 100644 --- a/src/components/load3d/Load3D.vue +++ b/src/components/load3d/Load3D.vue @@ -10,6 +10,8 @@ :cameraType="cameraType" :showPreview="showPreview" :backgroundImage="backgroundImage" + :upDirection="upDirection" + :materialMode="materialMode" @materialModeChange="listenMaterialModeChange" @backgroundColorChange="listenBackgroundColorChange" @lightIntensityChange="listenLightIntensityChange" @@ -18,6 +20,7 @@ @showGridChange="listenShowGridChange" @showPreviewChange="listenShowPreviewChange" @backgroundImageChange="listenBackgroundImageChange" + @upDirectionChange="listenUpDirectionChange" /> @@ -47,6 +54,11 @@ import { computed, ref } from 'vue' import Load3DControls from '@/components/load3d/Load3DControls.vue' import Load3DScene from '@/components/load3d/Load3DScene.vue' import Load3dUtils from '@/extensions/core/load3d/Load3dUtils' +import { + CameraType, + MaterialMode, + UpDirection +} from '@/extensions/core/load3d/interfaces' const props = defineProps<{ node: any @@ -61,9 +73,11 @@ const lightIntensity = ref(5) const showLightIntensityButton = ref(true) const fov = ref(75) const showFOVButton = ref(true) -const cameraType = ref<'perspective' | 'orthographic'>('perspective') +const cameraType = ref('perspective') const hasBackgroundImage = ref(false) const backgroundImage = ref('') +const upDirection = ref('original') +const materialMode = ref('original') const showPreviewButton = computed(() => { return !props.type.includes('Preview') @@ -115,24 +129,34 @@ const handleUpdateFOV = (value: number) => { node.value.properties['FOV'] = fov.value } -const materialMode = ref<'original' | 'normal' | 'wireframe' | 'depth'>( - 'original' -) - const handleBackgroundColorChange = (value: string) => { backgroundColor.value = value node.value.properties['Background Color'] = value } -const listenMaterialModeChange = ( - mode: 'original' | 'normal' | 'wireframe' | 'depth' -) => { +const handleUpdateUpDirection = (value: UpDirection) => { + upDirection.value = value + + node.value.properties['Up Direction'] = value +} + +const handleUpdateMaterialMode = (value: MaterialMode) => { + materialMode.value = value + + node.value.properties['Material Mode'] = value +} + +const listenMaterialModeChange = (mode: MaterialMode) => { materialMode.value = mode showLightIntensityButton.value = mode === 'original' } +const listenUpDirectionChange = (value: UpDirection) => { + upDirection.value = value +} + const listenBackgroundColorChange = (value: string) => { backgroundColor.value = value } @@ -145,7 +169,7 @@ const listenFOVChange = (value: number) => { fov.value = value } -const listenCameraTypeChange = (value: 'perspective' | 'orthographic') => { +const listenCameraTypeChange = (value: CameraType) => { cameraType.value = value showFOVButton.value = cameraType.value === 'perspective' } diff --git a/src/components/load3d/Load3DAnimation.vue b/src/components/load3d/Load3DAnimation.vue index 753226df3..bd3d03af5 100644 --- a/src/components/load3d/Load3DAnimation.vue +++ b/src/components/load3d/Load3DAnimation.vue @@ -9,13 +9,14 @@ :fov="fov" :cameraType="cameraType" :showPreview="showPreview" - :materialMode="materialMode" :showFOVButton="showFOVButton" :showLightIntensityButton="showLightIntensityButton" :playing="playing" :selectedSpeed="selectedSpeed" :selectedAnimation="selectedAnimation" :backgroundImage="backgroundImage" + :upDirection="upDirection" + :materialMode="materialMode" @materialModeChange="listenMaterialModeChange" @backgroundColorChange="listenBackgroundColorChange" @lightIntensityChange="listenLightIntensityChange" @@ -25,6 +26,7 @@ @showPreviewChange="listenShowPreviewChange" @backgroundImageChange="listenBackgroundImageChange" @animationListChange="animationListChange" + @upDirectionChange="listenUpDirectionChange" /> { node.value.properties['FOV'] = fov.value } -const materialMode = ref<'original' | 'normal' | 'wireframe' | 'depth'>( - 'original' -) +const materialMode = ref('original') +const upDirection = ref('original') + +const handleUpdateUpDirection = (value: UpDirection) => { + upDirection.value = value + + node.value.properties['Up Direction'] = value +} + +const handleUpdateMaterialMode = (value: MaterialMode) => { + materialMode.value = value + + node.value.properties['Material Mode'] = value +} const handleBackgroundColorChange = (value: string) => { backgroundColor.value = value @@ -164,14 +186,16 @@ const animationListChange = (value: any) => { animations.value = value } -const listenMaterialModeChange = ( - mode: 'original' | 'normal' | 'wireframe' | 'depth' -) => { +const listenMaterialModeChange = (mode: MaterialMode) => { materialMode.value = mode showLightIntensityButton.value = mode === 'original' } +const listenUpDirectionChange = (value: UpDirection) => { + upDirection.value = value +} + const listenBackgroundColorChange = (value: string) => { backgroundColor.value = value } @@ -184,7 +208,7 @@ const listenFOVChange = (value: number) => { fov.value = value } -const listenCameraTypeChange = (value: 'perspective' | 'orthographic') => { +const listenCameraTypeChange = (value: CameraType) => { cameraType.value = value showFOVButton.value = cameraType.value === 'perspective' diff --git a/src/components/load3d/Load3DAnimationScene.vue b/src/components/load3d/Load3DAnimationScene.vue index 687213d3f..5d85f58b8 100644 --- a/src/components/load3d/Load3DAnimationScene.vue +++ b/src/components/load3d/Load3DAnimationScene.vue @@ -10,6 +10,8 @@ :showPreview="showPreview" :extraListeners="animationListeners" :backgroundImage="backgroundImage" + :upDirection="upDirection" + :materialMode="materialMode" @materialModeChange="listenMaterialModeChange" @backgroundColorChange="listenBackgroundColorChange" @lightIntensityChange="listenLightIntensityChange" @@ -24,6 +26,11 @@ import { ref, watch } from 'vue' import Load3DScene from '@/components/load3d/Load3DScene.vue' +import { + CameraType, + MaterialMode, + UpDirection +} from '@/extensions/core/load3d/interfaces' const props = defineProps<{ node: any @@ -32,9 +39,10 @@ const props = defineProps<{ showGrid: boolean lightIntensity: number fov: number - cameraType: 'perspective' | 'orthographic' + cameraType: CameraType showPreview: boolean - materialMode: 'original' | 'normal' | 'wireframe' | 'depth' + materialMode: MaterialMode + upDirection: UpDirection showFOVButton: boolean showLightIntensityButton: boolean playing: boolean @@ -50,6 +58,7 @@ const fov = ref(props.fov) const lightIntensity = ref(props.lightIntensity) const cameraType = ref(props.cameraType) const showGrid = ref(props.showGrid) +const upDirection = ref(props.upDirection) const materialMode = ref(props.materialMode) const showFOVButton = ref(props.showFOVButton) const showLightIntensityButton = ref(props.showLightIntensityButton) @@ -90,6 +99,20 @@ watch( } ) +watch( + () => props.upDirection, + (newValue) => { + upDirection.value = newValue + } +) + +watch( + () => props.materialMode, + (newValue) => { + materialMode.value = newValue + } +) + watch( () => props.showPreview, (newValue) => { @@ -122,9 +145,7 @@ const emit = defineEmits<{ (e: 'animationListChange', animationList: string): void }>() -const listenMaterialModeChange = ( - mode: 'original' | 'normal' | 'wireframe' | 'depth' -) => { +const listenMaterialModeChange = (mode: MaterialMode) => { materialMode.value = mode showLightIntensityButton.value = mode === 'original' @@ -142,7 +163,7 @@ const listenFOVChange = (value: number) => { fov.value = value } -const listenCameraTypeChange = (value: 'perspective' | 'orthographic') => { +const listenCameraTypeChange = (value: CameraType) => { cameraType.value = value showFOVButton.value = cameraType.value === 'perspective' diff --git a/src/components/load3d/Load3DControls.vue b/src/components/load3d/Load3DControls.vue index c0a59c5ec..ceba5dd92 100644 --- a/src/components/load3d/Load3DControls.vue +++ b/src/components/load3d/Load3DControls.vue @@ -1,132 +1,240 @@ - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - + + + + {{ label }} + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{ formatOption(direction) }} + + + + + + + + + + + + + {{ formatMaterialMode(mode) }} + + + + + + + + + + + + + + + + + + + + + + + + + + + + - () +const isMenuOpen = ref(false) +const activeCategory = ref<'scene' | 'model' | 'camera' | 'light'>('scene') +const categories = { + scene: 'scene', + model: 'model', + camera: 'camera', + light: 'light' +} + +const toggleMenu = () => { + isMenuOpen.value = !isMenuOpen.value +} + +const selectCategory = (category: 'scene' | 'model' | 'camera' | 'light') => { + activeCategory.value = category + isMenuOpen.value = false +} + +const getCategoryIcon = (category: string) => { + const icons = { + scene: 'pi pi-image', + model: 'pi pi-box', + camera: 'pi pi-camera', + light: 'pi pi-sun' + } + return `${icons[category]} text-white text-lg` +} + const emit = defineEmits<{ (e: 'switchCamera'): void (e: 'toggleGrid', value: boolean): void @@ -173,6 +316,8 @@ const emit = defineEmits<{ (e: 'updateFOV', value: number): void (e: 'togglePreview', value: boolean): void (e: 'updateBackgroundImage', file: File | null): void + (e: 'updateUpDirection', direction: UpDirection): void + (e: 'updateMaterialMode', mode: MaterialMode): void }>() const backgroundColor = ref(props.backgroundColor) @@ -180,6 +325,8 @@ const showGrid = ref(props.showGrid) const showPreview = ref(props.showPreview) const colorPickerRef = ref(null) const lightIntensity = ref(props.lightIntensity) +const upDirection = ref(props.upDirection || 'original') +const materialMode = ref(props.materialMode || 'original') const showLightIntensity = ref(false) const showLightIntensityButton = ref(props.showLightIntensityButton) const fov = ref(props.fov) @@ -188,6 +335,23 @@ const showFOVButton = ref(props.showFOVButton) const showPreviewButton = ref(props.showPreviewButton) const hasBackgroundImage = ref(props.hasBackgroundImage) const imagePickerRef = ref(null) +const showUpDirection = ref(false) +const upDirections: UpDirection[] = [ + 'original', + '-x', + '+x', + '-y', + '+y', + '-z', + '+z' +] +const showMaterialMode = ref(false) +const materialModes: MaterialMode[] = [ + 'original', + 'normal', + 'wireframe', + 'depth' +] const switchCamera = () => { emit('switchCamera') @@ -227,9 +391,40 @@ const updateFOV = () => { emit('updateFOV', fov.value) } +const toggleUpDirection = () => { + showUpDirection.value = !showUpDirection.value +} + +const selectUpDirection = (direction: UpDirection) => { + upDirection.value = direction + emit('updateUpDirection', direction) +} + +const formatOption = (option: string) => { + if (option === 'original') return 'Original' + return option.toUpperCase() +} + +const toggleMaterialMode = () => { + showMaterialMode.value = !showMaterialMode.value +} + +const selectMaterialMode = (mode: MaterialMode) => { + materialMode.value = mode + emit('updateMaterialMode', mode) +} + +const formatMaterialMode = (mode: MaterialMode) => { + return mode.charAt(0).toUpperCase() + mode.slice(1) +} + const closeSlider = (e: MouseEvent) => { const target = e.target as HTMLElement + if (!target.closest('.show-menu')) { + isMenuOpen.value = false + } + if (!target.closest('.show-fov')) { showFOV.value = false } @@ -237,12 +432,29 @@ const closeSlider = (e: MouseEvent) => { if (!target.closest('.show-light-intensity')) { showLightIntensity.value = false } + + if (!target.closest('.show-up-direction')) { + showUpDirection.value = false + } + + if (!target.closest('.show-material-mode')) { + showMaterialMode.value = false + } } const openImagePicker = () => { imagePickerRef.value?.click() } +watch( + () => props.upDirection, + (newValue) => { + if (newValue) { + upDirection.value = newValue + } + } +) + const uploadBackgroundImage = (event: Event) => { const input = event.target as HTMLInputElement @@ -294,6 +506,20 @@ watch( } ) +watch( + () => props.upDirection, + (newValue) => { + upDirection.value = newValue + } +) + +watch( + () => props.materialMode, + (newValue) => { + materialMode.value = newValue + } +) + watch( () => props.showPreviewButton, (newValue) => { @@ -315,6 +541,15 @@ watch( } ) +watch( + () => props.materialMode, + (newValue) => { + if (newValue) { + materialMode.value = newValue + } + } +) + onMounted(() => { document.addEventListener('click', closeSlider) }) diff --git a/src/components/load3d/Load3DScene.vue b/src/components/load3d/Load3DScene.vue index 589494b4e..47ec55b2e 100644 --- a/src/components/load3d/Load3DScene.vue +++ b/src/components/load3d/Load3DScene.vue @@ -11,6 +11,11 @@ import { onMounted, onUnmounted, ref, toRaw, watchEffect } from 'vue' import LoadingOverlay from '@/components/load3d/LoadingOverlay.vue' import Load3d from '@/extensions/core/load3d/Load3d' import Load3dAnimation from '@/extensions/core/load3d/Load3dAnimation' +import { + CameraType, + MaterialMode, + UpDirection +} from '@/extensions/core/load3d/interfaces' import { useLoad3dService } from '@/services/load3dService' const props = defineProps<{ @@ -20,9 +25,11 @@ const props = defineProps<{ showGrid: boolean lightIntensity: number fov: number - cameraType: 'perspective' | 'orthographic' + cameraType: CameraType showPreview: boolean backgroundImage: string + upDirection: UpDirection + materialMode: MaterialMode extraListeners?: Record void> }>() @@ -42,6 +49,7 @@ const eventConfig = { showPreviewChange: (value: boolean) => emit('showPreviewChange', value), backgroundImageChange: (value: string) => emit('backgroundImageChange', value), + upDirectionChange: (value: string) => emit('upDirectionChange', value), modelLoadingStart: () => loadingOverlayRef.value?.startLoading(), modelLoadingEnd: () => loadingOverlayRef.value?.endLoading() } as const @@ -57,6 +65,8 @@ watchEffect(() => { rawLoad3d.toggleCamera(props.cameraType) rawLoad3d.togglePreview(props.showPreview) rawLoad3d.setBackgroundImage(props.backgroundImage) + rawLoad3d.setUpDirection(props.upDirection) + rawLoad3d.setMaterialMode(props.materialMode) } }) @@ -69,6 +79,7 @@ const emit = defineEmits<{ (e: 'showGridChange', showGrid: boolean): void (e: 'showPreviewChange', showPreview: boolean): void (e: 'backgroundImageChange', backgroundImage: string): void + (e: 'upDirectionChange', upDirection: string): void }>() const handleEvents = (action: 'add' | 'remove') => { diff --git a/src/extensions/core/load3d.ts b/src/extensions/core/load3d.ts index 25895ff6f..d41c9c872 100644 --- a/src/extensions/core/load3d.ts +++ b/src/extensions/core/load3d.ts @@ -138,12 +138,6 @@ app.registerExtension({ (w: IWidget) => w.name === 'model_file' ) - const material = node.widgets.find((w: IWidget) => w.name === 'material') - - const upDirection = node.widgets.find( - (w: IWidget) => w.name === 'up_direction' - ) - let cameraState = node.properties['Camera Info'] const config = new Load3DConfiguration(load3d) @@ -151,15 +145,7 @@ app.registerExtension({ const width = node.widgets.find((w: IWidget) => w.name === 'width') const height = node.widgets.find((w: IWidget) => w.name === 'height') - config.configure( - 'input', - modelWidget, - material, - upDirection, - cameraState, - width, - height - ) + config.configure('input', modelWidget, cameraState, width, height) sceneWidget.serializeValue = async () => { node.properties['Camera Info'] = load3d.getCameraState() @@ -309,12 +295,6 @@ app.registerExtension({ (w: IWidget) => w.name === 'model_file' ) - const material = node.widgets.find((w: IWidget) => w.name === 'material') - - const upDirection = node.widgets.find( - (w: IWidget) => w.name === 'up_direction' - ) - let cameraState = node.properties['Camera Info'] const config = new Load3DConfiguration(load3d) @@ -322,15 +302,7 @@ app.registerExtension({ const width = node.widgets.find((w: IWidget) => w.name === 'width') const height = node.widgets.find((w: IWidget) => w.name === 'height') - config.configure( - 'input', - modelWidget, - material, - upDirection, - cameraState, - width, - height - ) + config.configure('input', modelWidget, cameraState, width, height) sceneWidget.serializeValue = async () => { node.properties['Camera Info'] = load3d.getCameraState() @@ -435,12 +407,6 @@ app.registerExtension({ (w: IWidget) => w.name === 'model_file' ) - const material = node.widgets.find((w: IWidget) => w.name === 'material') - - const upDirection = node.widgets.find( - (w: IWidget) => w.name === 'up_direction' - ) - const onExecuted = node.onExecuted node.onExecuted = function (message: any) { @@ -460,7 +426,7 @@ app.registerExtension({ const config = new Load3DConfiguration(load3d) - config.configure('output', modelWidget, material, upDirection) + config.configure('output', modelWidget) } } }) @@ -536,12 +502,6 @@ app.registerExtension({ (w: IWidget) => w.name === 'model_file' ) - const material = node.widgets.find((w: IWidget) => w.name === 'material') - - const upDirection = node.widgets.find( - (w: IWidget) => w.name === 'up_direction' - ) - const onExecuted = node.onExecuted node.onExecuted = function (message: any) { @@ -561,7 +521,7 @@ app.registerExtension({ const config = new Load3DConfiguration(load3d) - config.configure('output', modelWidget, material, upDirection) + config.configure('output', modelWidget) } } }) diff --git a/src/extensions/core/load3d/Load3DConfiguration.ts b/src/extensions/core/load3d/Load3DConfiguration.ts index 5c2134ed7..29375da45 100644 --- a/src/extensions/core/load3d/Load3DConfiguration.ts +++ b/src/extensions/core/load3d/Load3DConfiguration.ts @@ -2,6 +2,7 @@ import type { IWidget } from '@comfyorg/litegraph' import Load3d from '@/extensions/core/load3d/Load3d' import Load3dUtils from '@/extensions/core/load3d/Load3dUtils' +import { MaterialMode } from '@/extensions/core/load3d/interfaces' import { api } from '@/scripts/api' class Load3DConfiguration { @@ -10,21 +11,11 @@ class Load3DConfiguration { configure( loadFolder: 'input' | 'output', modelWidget: IWidget, - material: IWidget, - upDirection: IWidget, cameraState?: any, width: IWidget | null = null, - height: IWidget | null = null, - postModelUpdateFunc?: (load3d: Load3d) => void + height: IWidget | null = null ) { - this.setupModelHandling( - modelWidget, - loadFolder, - cameraState, - postModelUpdateFunc - ) - this.setupMaterial(material) - this.setupDirection(upDirection) + this.setupModelHandling(modelWidget, loadFolder, cameraState) this.setupTargetSize(width, height) this.setupDefaultProperties() } @@ -46,13 +37,11 @@ class Load3DConfiguration { private setupModelHandling( modelWidget: IWidget, loadFolder: 'input' | 'output', - cameraState?: any, - postModelUpdateFunc?: (load3d: Load3d) => void + cameraState?: any ) { const onModelWidgetUpdate = this.createModelUpdateHandler( loadFolder, - cameraState, - postModelUpdateFunc + cameraState ) if (modelWidget.value) { onModelWidgetUpdate(modelWidget.value) @@ -60,26 +49,6 @@ class Load3DConfiguration { modelWidget.callback = onModelWidgetUpdate } - private setupMaterial(material: IWidget) { - material.callback = (value: 'original' | 'normal' | 'wireframe') => { - this.load3d.setMaterialMode(value) - } - this.load3d.setMaterialMode( - material.value as 'original' | 'normal' | 'wireframe' - ) - } - - private setupDirection(upDirection: IWidget) { - upDirection.callback = ( - value: 'original' | '-x' | '+x' | '-y' | '+y' | '-z' | '+z' - ) => { - this.load3d.setUpDirection(value) - } - this.load3d.setUpDirection( - upDirection.value as 'original' | '-x' | '+x' | '-y' | '+y' | '-z' | '+z' - ) - } - private setupDefaultProperties() { const cameraType = this.load3d.loadNodeProperty( 'Camera Type', @@ -114,8 +83,7 @@ class Load3DConfiguration { private createModelUpdateHandler( loadFolder: 'input' | 'output', - cameraState?: any, - postModelUpdateFunc?: (load3d: Load3d) => void + cameraState?: any ) { let isFirstLoad = true return async (value: string | number | boolean | object) => { @@ -131,9 +99,19 @@ class Load3DConfiguration { await this.load3d.loadModel(modelUrl, filename) - if (postModelUpdateFunc) { - postModelUpdateFunc(this.load3d) - } + const upDirection = this.load3d.loadNodeProperty( + 'Up Direction', + 'original' + ) + + this.load3d.setUpDirection(upDirection) + + const materialMode = this.load3d.loadNodeProperty( + 'Material Mode', + 'original' + ) + + this.load3d.setMaterialMode(materialMode) if (isFirstLoad && cameraState && typeof cameraState === 'object') { try { diff --git a/src/extensions/core/load3d/Load3d.ts b/src/extensions/core/load3d/Load3d.ts index 112479e7c..8425bac17 100644 --- a/src/extensions/core/load3d/Load3d.ts +++ b/src/extensions/core/load3d/Load3d.ts @@ -254,6 +254,7 @@ class Load3d { setUpDirection(direction: UpDirection): void { this.modelManager.setUpDirection(direction) + this.renderer.render( this.sceneManager.scene, this.cameraManager.activeCamera diff --git a/src/locales/en/main.json b/src/locales/en/main.json index da9579d12..59b775489 100644 --- a/src/locales/en/main.json +++ b/src/locales/en/main.json @@ -850,6 +850,8 @@ "previewOutput": "Preview Output", "uploadBackgroundImage": "Upload Background Image", "removeBackgroundImage": "Remove Background Image", - "loadingModel": "Loading 3D Model..." + "loadingModel": "Loading 3D Model...", + "upDirection": "Up Direction", + "materialMode": "Material Mode" } } \ No newline at end of file diff --git a/src/locales/fr/main.json b/src/locales/fr/main.json index 559f8109b..0455c93bc 100644 --- a/src/locales/fr/main.json +++ b/src/locales/fr/main.json @@ -324,10 +324,12 @@ "fov": "FOV", "lightIntensity": "Intensité de la lumière", "loadingModel": "Chargement du modèle 3D...", + "materialMode": "Mode Matériel", "previewOutput": "Aperçu de la sortie", "removeBackgroundImage": "Supprimer l'image de fond", "showGrid": "Afficher la grille", "switchCamera": "Changer de caméra", + "upDirection": "Direction Haut", "uploadBackgroundImage": "Télécharger l'image de fond" }, "maintenance": { diff --git a/src/locales/ja/main.json b/src/locales/ja/main.json index 5ba639ea2..9a9ab5d0d 100644 --- a/src/locales/ja/main.json +++ b/src/locales/ja/main.json @@ -324,10 +324,12 @@ "fov": "FOV", "lightIntensity": "光の強度", "loadingModel": "3Dモデルを読み込んでいます...", + "materialMode": "マテリアルモード", "previewOutput": "出力のプレビュー", "removeBackgroundImage": "背景画像を削除", "showGrid": "グリッドを表示", "switchCamera": "カメラを切り替える", + "upDirection": "上方向", "uploadBackgroundImage": "背景画像をアップロード" }, "maintenance": { diff --git a/src/locales/ko/main.json b/src/locales/ko/main.json index 26bb7dabc..7fe9a4621 100644 --- a/src/locales/ko/main.json +++ b/src/locales/ko/main.json @@ -324,10 +324,12 @@ "fov": "FOV", "lightIntensity": "조명 강도", "loadingModel": "3D 모델 로딩 중...", + "materialMode": "재질 모드", "previewOutput": "출력 미리보기", "removeBackgroundImage": "배경 이미지 제거", "showGrid": "그리드 표시", "switchCamera": "카메라 전환", + "upDirection": "위 방향", "uploadBackgroundImage": "배경 이미지 업로드" }, "maintenance": { diff --git a/src/locales/ru/main.json b/src/locales/ru/main.json index e04a8cd7f..60dcff386 100644 --- a/src/locales/ru/main.json +++ b/src/locales/ru/main.json @@ -324,10 +324,12 @@ "fov": "Угол обзора", "lightIntensity": "Интенсивность света", "loadingModel": "Загрузка 3D модели...", + "materialMode": "Режим Материала", "previewOutput": "Предварительный просмотр", "removeBackgroundImage": "Удалить фоновое изображение", "showGrid": "Показать сетку", "switchCamera": "Переключить камеру", + "upDirection": "Направление Вверх", "uploadBackgroundImage": "Загрузить фоновое изображение" }, "maintenance": { diff --git a/src/locales/zh/main.json b/src/locales/zh/main.json index 5ff882ff9..86d8db2c5 100644 --- a/src/locales/zh/main.json +++ b/src/locales/zh/main.json @@ -324,10 +324,12 @@ "fov": "视场", "lightIntensity": "光照强度", "loadingModel": "正在加载3D模型...", + "materialMode": "材料模式", "previewOutput": "预览输出", "removeBackgroundImage": "移除背景图片", "showGrid": "显示网格", "switchCamera": "切换摄像头", + "upDirection": "向上方向", "uploadBackgroundImage": "上传背景图片" }, "maintenance": {