Skip to content

Commit

Permalink
feat: visually highlight element selected
Browse files Browse the repository at this point in the history
  • Loading branch information
alvarosabu committed Jan 7, 2024
1 parent 69d5edc commit 86476c5
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 3 deletions.
1 change: 1 addition & 0 deletions plugins/vite-plugin-tres/client/.nuxt/imports.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export { computedAsync, asyncComputed, computedEager, eagerComputed, computedInj
export { createGenericProjection, createProjection, logicAnd, logicNot, logicOr, useAbs, useAverage, useCeil, useClamp, useFloor, useMath, useMax, useMin, usePrecision, useProjection, useRound, useSum, useTrunc } from '@vueuse/math';
export { injectHead, useHead, useSeoMeta, useHeadSafe, useServerHead, useServerSeoMeta, useServerHeadSafe } from '@unhead/vue';
export { useDevtoolsHook } from '../composables/useDevtoolsHook';
export { HightlightMesh } from '../utils/highlightedMesh';
export { calculateMemoryUsage, bytesToKB, bytesToMB, bytesToGB } from '../utils/perf';
export { ShortcutConfig, ShortcutsConfig, ShortcutsOptions } from '../../../../node_modules/.pnpm/@nuxt+ui@2.11.1_nuxt@3.9.0_rollup@3.29.4_vite@5.0.10_vue@3.4.3/node_modules/@nuxt/ui/dist/runtime/composables/defineShortcuts.d';
export { defineShortcuts } from '../../../../node_modules/.pnpm/@nuxt+ui@2.11.1_nuxt@3.9.0_rollup@3.29.4_vite@5.0.10_vue@3.4.3/node_modules/@nuxt/ui/dist/runtime/composables/defineShortcuts';
Expand Down
3 changes: 3 additions & 0 deletions plugins/vite-plugin-tres/client/.nuxt/types/imports.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Generated by auto imports
export {}
declare global {
const HightlightMesh: typeof import('../../utils/highlightedMesh')['HightlightMesh']
const _useShortcuts: typeof import('../../../../../node_modules/.pnpm/@nuxt+ui@2.11.1_nuxt@3.9.0_rollup@3.29.4_vite@5.0.10_vue@3.4.3/node_modules/@nuxt/ui/dist/runtime/composables/useShortcuts')['_useShortcuts']
const abortNavigation: typeof import('../../../../../node_modules/.pnpm/nuxt@3.9.0_eslint@8.56.0_rollup@3.29.4_typescript@5.3.3_vite@5.0.10/node_modules/nuxt/dist/app/composables/router')['abortNavigation']
const addRouteMiddleware: typeof import('../../../../../node_modules/.pnpm/nuxt@3.9.0_eslint@8.56.0_rollup@3.29.4_typescript@5.3.3_vite@5.0.10/node_modules/nuxt/dist/app/composables/router')['addRouteMiddleware']
Expand Down Expand Up @@ -401,6 +402,7 @@ declare global {
import { UnwrapRef } from 'vue'
declare module 'vue' {
interface ComponentCustomProperties {
readonly HightlightMesh: UnwrapRef<typeof import('../../utils/highlightedMesh')['HightlightMesh']>
readonly _useShortcuts: UnwrapRef<typeof import('../../../../../node_modules/.pnpm/@nuxt+ui@2.11.1_nuxt@3.9.0_rollup@3.29.4_vite@5.0.10_vue@3.4.3/node_modules/@nuxt/ui/dist/runtime/composables/useShortcuts')['_useShortcuts']>
readonly abortNavigation: UnwrapRef<typeof import('../../../../../node_modules/.pnpm/nuxt@3.9.0_eslint@8.56.0_rollup@3.29.4_typescript@5.3.3_vite@5.0.10/node_modules/nuxt/dist/app/composables/router')['abortNavigation']>
readonly addRouteMiddleware: UnwrapRef<typeof import('../../../../../node_modules/.pnpm/nuxt@3.9.0_eslint@8.56.0_rollup@3.29.4_typescript@5.3.3_vite@5.0.10/node_modules/nuxt/dist/app/composables/router')['addRouteMiddleware']>
Expand Down Expand Up @@ -791,6 +793,7 @@ declare module 'vue' {
}
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
readonly HightlightMesh: UnwrapRef<typeof import('../../utils/highlightedMesh')['HightlightMesh']>
readonly _useShortcuts: UnwrapRef<typeof import('../../../../../node_modules/.pnpm/@nuxt+ui@2.11.1_nuxt@3.9.0_rollup@3.29.4_vite@5.0.10_vue@3.4.3/node_modules/@nuxt/ui/dist/runtime/composables/useShortcuts')['_useShortcuts']>
readonly abortNavigation: UnwrapRef<typeof import('../../../../../node_modules/.pnpm/nuxt@3.9.0_eslint@8.56.0_rollup@3.29.4_typescript@5.3.3_vite@5.0.10/node_modules/nuxt/dist/app/composables/router')['abortNavigation']>
readonly addRouteMiddleware: UnwrapRef<typeof import('../../../../../node_modules/.pnpm/nuxt@3.9.0_eslint@8.56.0_rollup@3.29.4_typescript@5.3.3_vite@5.0.10/node_modules/nuxt/dist/app/composables/router')['addRouteMiddleware']>
Expand Down
12 changes: 10 additions & 2 deletions plugins/vite-plugin-tres/client/components/SceneGraphItem.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<script setup lang="ts">
import { useDevtoolsHook } from '../composables/useDevtoolsHook'
import type { SceneGraphObject } from '../types'
withDefaults(defineProps<{
const props = withDefaults(defineProps<{
item: SceneGraphObject
depth?: number
}>(), {
Expand All @@ -10,9 +11,16 @@ withDefaults(defineProps<{
const isExpanded = ref(false)
const { internal, highlightObject } = useDevtoolsHook()
function roundNumber(num: number) {
return Math.round((num + Number.EPSILON) * 100) / 100
}
function handleClick() {
isExpanded.value = !isExpanded.value
highlightObject(props.item)
}
</script>

<template>
Expand All @@ -21,7 +29,7 @@ function roundNumber(num: number) {
>
<div
class="flex gap-2 items-end cursor-pointer pt2 mb2"
@click="isExpanded = !isExpanded"
@click="handleClick"
>
<span
v-if="depth > 0"
Expand Down
43 changes: 42 additions & 1 deletion plugins/vite-plugin-tres/client/composables/useDevtoolsHook.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import type { TresContext, TresObject } from '@tresjs/core'
import type { Scene, WebGLRenderer } from 'three'
import { DoubleSide, MeshBasicMaterial } from 'three'
import type { Mesh, Object3D, type Scene, type WebGLRenderer } from 'three'
import { reactive } from 'vue'
import type { SceneGraphObject } from '../types'
import { HightlightMesh } from '../utils/highlightedMesh'

interface FPSState {
value: number
Expand Down Expand Up @@ -45,6 +48,7 @@ interface DevtoolsHookReturn {
fps: FPSState
memory: MemoryState
renderer: RendererState
highlightObject: (object: TresObject) => void
}

const scene = reactive<{
Expand All @@ -58,6 +62,11 @@ const scene = reactive<{
})

const gl = {
internal: reactive<{}>({
selectedObject: null,
prevInstance: null,
highlightMesh: null,
}),
fps: reactive<FPSState>({
value: 0,
accumulator: [],
Expand Down Expand Up @@ -108,6 +117,7 @@ const icons: Record<string, string> = {

function createNode(object: TresObject) {
const node: SceneGraphObject = {
uuid: object.uuid,
name: object.name,
type: object.type,
icon: icons[object.type.toLowerCase()] || 'i-carbon-cube',
Expand Down Expand Up @@ -170,6 +180,36 @@ function countObjectsInScene(scene: Scene) {
return count
}

function createHighlightMesh(object: Object3D): Mesh {
const highlightMaterial = new MeshBasicMaterial({
color: 0xa7e6d7, // Highlight color, e.g., yellow
transparent: true,
opacity: 0.2,
depthTest: false, // So the highlight is always visible
side: DoubleSide, // To e
})
// Clone the geometry of the object. You might need a more complex approach
// if the object's geometry is not straightforward.
const highlightMesh = new HightlightMesh(object.geometry.clone(), highlightMaterial)

return highlightMesh
}

function highlightObject(object: TresObject) {
const [instance] = scene.value.getObjectsByProperty('uuid', object.uuid)
if (gl.internal.prevInstance && gl.internal.highlightMesh && gl.internal.highlightMesh.parent) {
gl.internal.prevInstance.remove(gl.internal.highlightMesh)
}

if (instance.isMesh) {
const newHighlightMesh = createHighlightMesh(instance)
instance.add(newHighlightMesh)

gl.internal.highlightMesh = newHighlightMesh
gl.internal.prevInstance = instance
}
}

export function useDevtoolsHook(): DevtoolsHookReturn {
// Connect with Core
const tresGlobalHook = {
Expand All @@ -196,5 +236,6 @@ export function useDevtoolsHook(): DevtoolsHookReturn {
fps: gl.fps,
memory: gl.memory,
renderer: gl.renderer,
highlightObject,
}
}
24 changes: 24 additions & 0 deletions plugins/vite-plugin-tres/client/utils/highlightedMesh.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import * as THREE from 'three'

export class HightlightMesh extends THREE.Mesh {
type = 'HightlightMesh'
createTime: number
constructor(...args: THREE.Mesh['args']) {
super(...args)
this.createTime = Date.now()
}

onBeforeRender() {
const currentTime = Date.now()
const time = (currentTime - this.createTime) / 1000
// Pulsing effect parameters
const scaleAmplitude = 0.07 // Amplitude of the scale pulsation
const pulseSpeed = 2.5 // Speed of the pulsation

// Calculate the scale factor with a sine function for pulsing effect
const scaleFactor = 1 + scaleAmplitude * Math.sin(pulseSpeed * time)

// Apply the scale factor
this.scale.set(scaleFactor, scaleFactor, scaleFactor)
}
}

0 comments on commit 86476c5

Please sign in to comment.