Skip to content

Commit

Permalink
Add experimental 3D clipping view
Browse files Browse the repository at this point in the history
  • Loading branch information
kettek committed Jan 9, 2025
1 parent a21eea0 commit 1091603
Showing 5 changed files with 74 additions and 7 deletions.
9 changes: 9 additions & 0 deletions frontend/src/App.svelte
Original file line number Diff line number Diff line change
@@ -65,6 +65,7 @@
import PalettePopup from './components/PalettePopup.svelte'
import FileUnsaved from './components/FileUnsaved.svelte'
import FilesUnsaved from './components/FilesUnsaved.svelte'
import Clip3D from './sections/Clip3D.svelte'
let is3D: boolean = true
@@ -148,6 +149,8 @@
let savingFileIndex: number = -1
let showUnsavedFilesModal: boolean = false
let show3DClipView: boolean = false
function selectFile(file: LoadedFile, index: number, id: number) {
if (index < 0 || index >= fileStates.length()) return
@@ -643,6 +646,7 @@
<OverflowMenu size="sm">
<div slot="menu">Windows</div>
<OverflowMenuItem text="Preview" on:click={() => (showPreview = true)} />
<OverflowMenuItem text="3D Clip View" on:click={() => (show3DClipView = true)} />
<OverflowMenuItem hasDivider>
<Checkbox on:click={(e) => e.stopPropagation()} bind:checked={$editor2DSettings.minifiedLeftPanel} labelText="Minified Palettes Panel" />
</OverflowMenuItem>
@@ -881,6 +885,11 @@
<StackPreview shronked={previewUseMini} />
</FloatingPanel>
{/if}
{#if show3DClipView}
<FloatingPanel label="3D Clip View" noPadding bind:open={show3DClipView} id="3d-clip-view">
<Clip3D />
</FloatingPanel>
{/if}
{#if is3D && showRotate && $toolSettings.current === toolVoxelBoxSelection}
<FloatingPanel label="3D Resize" noPadding bind:open={showRotate} id="3d-resize">
<Selection3D />
17 changes: 17 additions & 0 deletions frontend/src/components/3d/ClipView.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<script lang="ts">
import { T } from '@threlte/core'
import { BoxGeometry, EdgesGeometry } from 'three'
export let offset: [number, number, number] = [0, 0, 0]
export let x: number = 0
export let y: number = 0
export let z: number = 0
export let w: number = 1
export let h: number = 1
export let d: number = 1
</script>

<T.LineSegments position={[x + offset[0] + (w + 1) / 2, y + offset[1] + (h + 1) / 2, z + offset[2] + (d + 1) / 2]} geometry={new EdgesGeometry(new BoxGeometry(w, h, d))}>
<T.EdgesGeometry args={[new BoxGeometry(w + 1, h + 1, d + 1)]} />
<T.LineBasicMaterial />
</T.LineSegments>
23 changes: 16 additions & 7 deletions frontend/src/components/3d/Scene.svelte
Original file line number Diff line number Diff line change
@@ -24,6 +24,7 @@
import { isKeyActive } from '../Shortcuts.svelte'
import OptimizedRender from './OptimizedRender.svelte'
import Point from './Point.svelte'
import ClipView from './ClipView.svelte'
export let file: LoadedFile
export let palette: Palette | undefined
@@ -426,13 +427,17 @@
{#if $file.frame}
<T.Group>
{#each $file.frame.slices as slice, y}
{#each $file.canvas.getPixels(slice.x, slice.y, $file.frameWidth, $file.frameHeight) as pixel, index}
{#if pixel !== 0}
{@const x = index % $file.frameWidth}
{@const z = Math.floor(index / $file.frameWidth)}
<Voxel hoverScale={$editor3DSettings.hoverScale} hideTransparent={$editor3DSettings.hideTransparent} ignoreAlpha={$editor3DSettings.ignoreAlpha} position={[x, y, z]} offset={[-$file.frameWidth / 2, 0, -$file.frameHeight / 2]} color={$palette ? $palette.swatches[pixel] : $file.canvas.getPaletteColor(pixel)} on:hover={onVoxelHover} on:move={onVoxelMove} on:leave={onVoxelLeave} on:click={onVoxelClick} ignoreEvents={cursorGrabbed} />
{/if}
{/each}
{#if !$editor3DSettings.useClipping || (y >= $editor3DSettings.clipY && y <= $editor3DSettings.clipY + $editor3DSettings.clipH)}
{#each $file.canvas.getPixels(slice.x, slice.y, $file.frameWidth, $file.frameHeight) as pixel, index}
{#if pixel !== 0}
{@const x = index % $file.frameWidth}
{@const z = Math.floor(index / $file.frameWidth)}
{#if !$editor3DSettings.useClipping || (x >= $editor3DSettings.clipX && x <= $editor3DSettings.clipX + $editor3DSettings.clipW && z >= $editor3DSettings.clipZ && z <= $editor3DSettings.clipZ + $editor3DSettings.clipD)}
<Voxel hoverScale={$editor3DSettings.hoverScale} hideTransparent={$editor3DSettings.hideTransparent} ignoreAlpha={$editor3DSettings.ignoreAlpha} position={[x, y, z]} offset={[-$file.frameWidth / 2, 0, -$file.frameHeight / 2]} color={$palette ? $palette.swatches[pixel] : $file.canvas.getPaletteColor(pixel)} on:hover={onVoxelHover} on:move={onVoxelMove} on:leave={onVoxelLeave} on:click={onVoxelClick} ignoreEvents={cursorGrabbed} />
{/if}
{/if}
{/each}
{/if}
{/each}
</T.Group>
{/if}
@@ -468,6 +473,10 @@
<T.MeshBasicMaterial transparent={true} opacity={0.2} color={0xff0000} side={THREE.DoubleSide} />
</T.Mesh>

{#if $editor3DSettings.useClipping}
<ClipView x={$editor3DSettings.clipX} y={$editor3DSettings.clipY} z={$editor3DSettings.clipZ} w={$editor3DSettings.clipW} h={$editor3DSettings.clipH} d={$editor3DSettings.clipD} offset={[-$file.frameWidth / 2, 0, -$file.frameHeight / 2]} />
{/if}

{#if $toolSettings.current === toolVoxelCursor || $toolSettings.current === toolVoxelBoxSelection || pasting.length > 0}
<Cursor position={$file.threeDCursor1} on:move={onCursorChange} on:grab={onCursorGrab} on:release={onCursorRelease} offset={[-$file.frameWidth / 2 + xOffset, 0, -$file.frameHeight / 2 + yOffset]} />
{/if}
16 changes: 16 additions & 0 deletions frontend/src/sections/Clip3D.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<script lang="ts">
import { Checkbox } from 'carbon-components-svelte'
import { editor3DSettings } from '../stores/editor3d'
import Input from '../components/common/Input.svelte'
</script>

<main>
<Checkbox labelText="Clip View" bind:checked={$editor3DSettings.useClipping}></Checkbox>
<Input labelWidth="3" label="X" type="number" size="small" width={4} showSpinner bind:value={$editor3DSettings.clipX} />
<Input labelWidth="3" label="Y" type="number" size="small" width={4} showSpinner bind:value={$editor3DSettings.clipY} />
<Input labelWidth="3" label="Z" type="number" size="small" width={4} showSpinner bind:value={$editor3DSettings.clipZ} />
<hr />
<Input labelWidth="3" label="H" type="number" size="small" width={4} showSpinner bind:value={$editor3DSettings.clipH} />
<Input labelWidth="3" label="W" type="number" size="small" width={4} showSpinner bind:value={$editor3DSettings.clipW} />
<Input labelWidth="3" label="D" type="number" size="small" width={4} showSpinner bind:value={$editor3DSettings.clipD} />
</main>
16 changes: 16 additions & 0 deletions frontend/src/stores/editor3d.ts
Original file line number Diff line number Diff line change
@@ -19,6 +19,14 @@ type Editor3DSettings = {
showCursor: boolean
// Voxels
hoverScale: boolean
// Clipping
useClipping: boolean
clipX: number
clipY: number
clipZ: number
clipW: number
clipH: number
clipD: number
}

export const editor3DSettings = makeLocalStorageStore<Editor3DSettings>('editor3d', {
@@ -40,4 +48,12 @@ export const editor3DSettings = makeLocalStorageStore<Editor3DSettings>('editor3
showCursor: true,
// Voxels
hoverScale: true,
// Clipping
useClipping: false,
clipX: 0,
clipY: 0,
clipZ: 0,
clipW: 0,
clipH: 0,
clipD: 0,
})

0 comments on commit 1091603

Please sign in to comment.