diff --git a/package.json b/package.json index cb10d86..feb4620 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,28 @@ "mcmodel-viewer.assetRoots": { "description": "A list of directories that contain minecraft assets", "type": "array", - "default": [] + "default": [], + "uniqueItems": true + }, + "mcmodel-viewer.helpers.showBoundingBox": { + "description": "Show bounding box in model preview", + "type": "boolean", + "default": true + }, + "mcmodel-viewer.helpers.showCardinalDirectionLabeles": { + "title": "Show labels for cardinal directions", + "type": "boolean", + "default": true + }, + "mcmodel-viewer.helpers.show3x3BlocksGrid": { + "title": "Show 3x3 Blocks Grid", + "type": "boolean", + "default": true + }, + "mcmodel-viewer.helpers.showVoxelGrid": { + "then": "Show voxel grid", + "type": "boolean", + "default": true } } } diff --git a/src/MCModelPanel.ts b/src/MCModelPanel.ts index 10c40f0..e3a2d8c 100644 --- a/src/MCModelPanel.ts +++ b/src/MCModelPanel.ts @@ -34,6 +34,10 @@ export class MCModelPanel { return true; }; + public static updateHelpersConfiguration(cfg: any) { + MCModelPanel.postMessage({command: "updateHelpersConfiguration", value: cfg}); + } + static get webview() { return this.currentPanel?._panel.webview; } diff --git a/src/config.ts b/src/config.ts index 370b98a..c2853b4 100644 --- a/src/config.ts +++ b/src/config.ts @@ -10,6 +10,15 @@ export function getAssetRoots(): vscode.Uri[] { return roots.map(r => vscode.Uri.file(r)); } +export function getHelperConfiguration() { + return { + showBoundingBox: vscode.workspace.getConfiguration("mcmodel-viewer.helpers").get("showBoundingBox"), + showCardinalDirectionLabeles: vscode.workspace.getConfiguration("mcmodel-viewer.helpers").get("showCardinalDirectionLabeles"), + show3x3BlocksGrid: vscode.workspace.getConfiguration("mcmodel-viewer.helpers").get("show3x3BlocksGrid"), + showVoxelGrid: vscode.workspace.getConfiguration("mcmodel-viewer.helpers").get("showVoxelGrid") + }; +} + export function createConfigurationListeners() { onAssetRootsChanged(); @@ -18,12 +27,34 @@ export function createConfigurationListeners() { if(e.affectsConfiguration("mcmodel-viewer.assetRoots")) { onAssetRootsChanged(); } + }), + vscode.workspace.onDidChangeConfiguration((e) => { + if(e.affectsConfiguration("mcmodel-viewer.helpers")) { + notifyConfigChanged("mcmodel-viewer.helpers"); + } }) ]; } +let configSubscribers: {[config: string]: Set<() => void>} = {}; + +export function subscribeConfiguration(config: string, onDidChange: () => void) { + if(!(config in configSubscribers)) { + configSubscribers[config] = new Set(); + } + configSubscribers[config].add(onDidChange); + return new vscode.Disposable(() => configSubscribers[config].delete(onDidChange)); +} + +function notifyConfigChanged(config: string) { + configSubscribers[config]?.forEach((cb) => { + cb(); + }); +} + async function onAssetRootsChanged() { assetRoots = (await minecraft.findAssetRootsInWorkspace()).concat(getAssetRoots()); textureAssetsRoots = await minecraft.findTextureAssetsRoots(assetRoots); modelAssetsRoots = await minecraft.findModelAssetsRoots(assetRoots); + notifyConfigChanged("mcmodel-viewer.assetRoots"); } \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts index a9248e3..48a641b 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -10,7 +10,12 @@ export async function activate(context: vscode.ExtensionContext) { ); // Listen to configuration changes - context.subscriptions.push(...config.createConfigurationListeners()); + context.subscriptions.push( + ...config.createConfigurationListeners(), + config.subscribeConfiguration("mcmodel-viewer.helpers", () => { + MCModelPanel.updateHelpersConfiguration(config.getHelperConfiguration()); + }) + ); // Register commands context.subscriptions.push( @@ -20,6 +25,7 @@ export async function activate(context: vscode.ExtensionContext) { MCModelPanel.createOrShow(context.extensionUri); MCModelPanel.loadModel(modelUri); + MCModelPanel.updateHelpersConfiguration(config.getHelperConfiguration()); }), vscode.commands.registerCommand('mcmodel-viewer.refresh', () => { MCModelPanel.kill(); diff --git a/webviews/components/ModelCanvas.svelte b/webviews/components/ModelCanvas.svelte index 9072739..8d9a30a 100644 --- a/webviews/components/ModelCanvas.svelte +++ b/webviews/components/ModelCanvas.svelte @@ -4,6 +4,7 @@ import { MinecraftModelMesh, MinecraftTextureLoader } from '@oran9e/three-mcmodel'; import { Text2D } from '../utils/Text2D' import { modelStore, texturesStore } from '../data/model' + import { helpersCfgStore } from '../data/config' let canvas: HTMLCanvasElement; @@ -19,12 +20,15 @@ // Helpers const voxelGrid = new THREE.GridHelper(48, 48, 0x444444, 0x444444) const blockGrid = new THREE.GridHelper(48, 3) - let cardinalDirectionLabels = [] + let cardinalDirectionLabels: Text2D[] = [] + createCardinalDirectionLabels() const boundingBox = new THREE.LineSegments( new THREE.EdgesGeometry(new THREE.BoxGeometry(48, 48, 48)).translate(0, 8, 0), new THREE.LineBasicMaterial({ color: 0x444444, linewidth: 3 }) ) + init() + modelStore.subscribe(mesh => { if(modelMesh) { scene.remove(modelMesh) @@ -37,6 +41,13 @@ texturesStore.subscribe(t => textures = t) + helpersCfgStore.subscribe(cfg => { + cfg.showBoundingBox ? scene.add(boundingBox) : scene.remove(boundingBox) + cfg.show3x3BlocksGrid ? scene.add(blockGrid) : scene.remove(blockGrid) + cfg.showVoxelGrid ? scene.add(voxelGrid) : scene.remove(voxelGrid) + cfg.showCardinalDirectionLabeles ? scene.add(...cardinalDirectionLabels) : scene.remove(...cardinalDirectionLabels) + }); + $: if(modelMesh != null && textures != null) { const textureLoader = new MinecraftTextureLoader() modelMesh.resolveTextures(p => textureLoader.load(textures![p])) @@ -61,12 +72,6 @@ controls.enableKeys = false controls.screenSpacePanning = true - // Add helpers - scene.add(boundingBox) - scene.add(voxelGrid) - scene.add(blockGrid) - createCardinalDirectionLabels() - animate() } @@ -82,8 +87,6 @@ renderer.render(scene, camera) } - init() - function createCardinalDirectionLabels() { const loader = new THREE.FontLoader(); loader.load(MEDIA_ROOT + '/helvetiker_regular.typeface.json', function ( font ) { @@ -93,10 +96,6 @@ new Text2D("S", font, [-Math.PI / 2, Math.PI, 0], [2, 0, 26]), new Text2D("W", font, [0, Math.PI / 2, Math.PI / 2], [-26, 0, 2]), ] - - for(const label of cardinalDirectionLabels) { - scene.add(label) - } }) } diff --git a/webviews/components/ModelPreviewPanel.svelte b/webviews/components/ModelPreviewPanel.svelte index 126892f..8d106e7 100644 --- a/webviews/components/ModelPreviewPanel.svelte +++ b/webviews/components/ModelPreviewPanel.svelte @@ -2,6 +2,7 @@ import { MinecraftModelLoader, MinecraftModelMesh } from '@oran9e/three-mcmodel'; import ModelCanvas from './ModelCanvas.svelte' import { modelStore, texturesStore } from '../data/model' + import { helpersCfgStore } from '../data/config' let modelCanvas: ModelCanvas @@ -11,9 +12,14 @@ new MinecraftModelLoader().load(e.data.value.model, mesh => { texturesStore.set(e.data.value.textures) modelStore.set(mesh) + console.log("Loaded model"); }) + break; + case "updateHelpersConfiguration": + helpersCfgStore.set(e.data.value) } }); + \ No newline at end of file diff --git a/webviews/data/config.ts b/webviews/data/config.ts new file mode 100644 index 0000000..f87378b --- /dev/null +++ b/webviews/data/config.ts @@ -0,0 +1,12 @@ +import { writable } from 'svelte/store'; + +export class HelperConfiguration { + constructor( + public showBoundingBox = true, + public showCardinalDirectionLabeles = true, + public show3x3BlocksGrid = true, + public showVoxelGrid = true + ) {} +} + +export const helpersCfgStore = writable(new HelperConfiguration()); \ No newline at end of file diff --git a/webviews/tsconfig.json b/webviews/tsconfig.json index a6b3a59..b8972e2 100644 --- a/webviews/tsconfig.json +++ b/webviews/tsconfig.json @@ -1,5 +1,6 @@ { "extends": "@tsconfig/svelte/tsconfig.json", + "target": "es6", "include": ["./**/*", ], "exclude": ["../node_modules/*"], "compilerOptions": {"strict": true, }