Skip to content

Commit

Permalink
feat: devtools scene graph and cb injection
Browse files Browse the repository at this point in the history
  • Loading branch information
alvarosabu committed Dec 5, 2023
1 parent 67932a7 commit 0cc3e31
Show file tree
Hide file tree
Showing 20 changed files with 1,210 additions and 691 deletions.
1 change: 1 addition & 0 deletions client/.nuxtrc
@@ -0,0 +1 @@
imports.autoImport=true
5 changes: 5 additions & 0 deletions client/app.vue
@@ -0,0 +1,5 @@
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>
28 changes: 28 additions & 0 deletions client/components/ModuleAuthorNote.vue
@@ -0,0 +1,28 @@
<script setup lang="ts">
</script>

<template>
<NTip
n="teal"
class="py-4"
>
<p class="font-bold">
Note for module authors:
</p>
Nuxt DevTools is in early preview and the API is subject to change.
Which means the setup in this template is only presenting the current state of the API.
We suggest following closely to the changes in the <NLink
href="https://github.com/nuxt/devtools"
target="_blank"
>
nuxt/devtools
</NLink> repository.<br>
The UI components are coming from <NLink
href="https://github.com/nuxt/devtools/tree/main/packages/devtools-ui-kit"
target="_blank"
>
@nuxt/devtools-ui-kit
</NLink>.
</NTip>
</template>
57 changes: 57 additions & 0 deletions client/components/TreeItem.vue
@@ -0,0 +1,57 @@
<script setup lang="ts">
interface SceneGraphObject {
name: string
type: string
material: string
geometry: string
position: {
x: number
y: number
z: number
}
rotation: {
x: number
y: number
z: number
}
children: SceneGraphObject[]
}
withDefaults(defineProps<{
item: SceneGraphObject
depth?: number
}>(), {
depth: 0,
})
const isExpanded = ref(false)
</script>

<template>
<div
:class="{ 'text-sm text-gray-400 font-mono': depth > 0 }"
>
<div
class="flex gap-2 items-end cursor-pointer pt2 mb2"
@click="isExpanded = !isExpanded"
>
<span
v-if="depth > 0"
class="h-1 border-b border-gray-300 w-4"
/>
<div class="flex gap-2 items-center -mb2.5">
<i :class="item.icon" />{{ item.type }} {{ item.name ? `(${item.name})` : '' }}
</div>
</div>
<div
v-if="isExpanded"
class="border-l border-gray-300 ml2.5"
>
<TreeItem
v-for="(child, index) in item.children"
:key="index"
:depth="depth + 1"
:item="child"
/>
</div>
</div>
</template>
17 changes: 17 additions & 0 deletions client/nuxt.config.ts
@@ -0,0 +1,17 @@
import { resolve } from 'pathe'

export default defineNuxtConfig({
ssr: false,
modules: [
'@nuxt/devtools-ui-kit',
'@unocss/nuxt',
],
nitro: {
output: {
publicDir: resolve(__dirname, '../dist/client'),
},
},
app: {
baseURL: '/__tres_nuxt_devtools',
},
})
4 changes: 4 additions & 0 deletions client/package.json
@@ -0,0 +1,4 @@
{
"private": true,
"name": "tres-nuxt-module"
}
140 changes: 140 additions & 0 deletions client/pages/index.vue
@@ -0,0 +1,140 @@
<script setup lang="ts">
import { useDevtoolsClient } from '@nuxt/devtools-kit/iframe-client'
const client = useDevtoolsClient()
const tres = reactive({})
const scene = reactive({
objects: 0,
graph: {},
})
/* window.addEventListener('message', (event) => {
switch (event.data.type) {
case 'tresjs:devtools':
tres.value = JSON.parse(event.data.payload)
break
default:
break
}
}) */
const icons: Record<string, string> = {
scene: 'i-carbon-web-services-container',
perspectivecamera: 'i-carbon-video',
mesh: 'i-carbon-cube',
group: 'i-carbon-group',
}
function createNode(object) {
return {
name: object.name,
type: object.type,
icon: icons[object.type.toLowerCase()] || 'i-carbon-cube',
material: object.material ? object.material.type : 'None',
geometry: object.geometry ? object.geometry.type : 'None',
position: {
x: object.position.x,
y: object.position.y,
z: object.position.z,
},
rotation: {
x: object.rotation.x,
y: object.rotation.y,
z: object.rotation.z,
},
children: [],
}
}
function getSceneGraph(scene) {
function buildGraph(object, node) {
object.children.forEach((child) => {
const childNode = createNode(child)
node.children.push(childNode)
buildGraph(child, childNode)
})
}
const root = createNode(scene)
buildGraph(scene, root)
return root
}
function countObjectsInScene(scene) {
let count = 0
scene.traverse((object) => {
// Check if the object is a 3D object
if (object.isObject3D) {
count++
}
})
return count
}
const tresGlobalHook = {
cb(context) {
Object.assign(tres, context)
scene.objects = countObjectsInScene(context.scene.value)
scene.graph = getSceneGraph(context.scene.value)
console.log('tresGlobalHook', scene.graph )
},
}
window.parent.parent.__TRES__DEVTOOLS__ = tresGlobalHook
</script>

<template>
<div class="relative n-bg-base flex flex-col h-screen">
<header
class="p4 flex items-center justify-between hover:bg-active"
border="b base"
>
<div class="flex items-center gap-4">
<img

src="/logo.svg"
alt="tres logo"
>
<h2 class="text-xl opacity-60 font-bold">
TresJS DevTools
</h2>
</div>
<NTip
n="green"
icon="carbon-checkmark"
>
Nuxt DevTools is connected
</NTip>
</header>

<div
v-if="client"
class="flex flex-col gap-2"
>
<NSectionBlock
icon="i-carbon-web-services-container"
text="Scene Graph"
border="b base"
:description="`Total Objects ${scene.objects}`"
>
<TreeItem :item="scene.graph" />
</NSectionBlock>
<NSectionBlock
icon="i-iconoir-dashboard-speed"
text="Performance"
>
Awiwi
</NSectionBlock>
</div>
<div v-else>
<NTip n="yellow">
Failed to connect to the client. Did you open this page inside Nuxt DevTools?
</NTip>
</div>
</div>
</template>
5 changes: 5 additions & 0 deletions client/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions client/public/logo-dark.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions client/public/logo.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions package.json
Expand Up @@ -24,6 +24,8 @@
],
"scripts": {
"prepack": "nuxt-module-build",
"client:build": "nuxi generate client",
"client:dev": "nuxi dev client --port 3300",
"dev": "nuxi dev playground",
"dev:build": "nuxi build playground",
"dev:prepare": "nuxt-module-build --stub && nuxi prepare playground",
Expand All @@ -36,16 +38,22 @@
"three": ">=0.133"
},
"dependencies": {
"@nuxt/devtools-kit": "^1.0.4",
"@nuxt/kit": "^3.8.2",
"@tresjs/core": "3.5.1",
"@types/three": "^0.159.0",
"@unocss/nuxt": "^0.57.7",
"defu": "^6.1.3",
"mlly": "^1.4.2",
"pkg-types": "^1.0.3",
"sirv": "^2.0.3",
"typescript": "^5.3.2"
},
"devDependencies": {
"@alvarosabu/eslint-config-vue": "^0.4.0",
"@iconify-json/carbon": "^1.1.24",
"@iconify-json/iconoir": "^1.1.36",
"@nuxt/devtools-ui-kit": "^1.0.4",
"@nuxt/eslint-config": "^0.2.0",
"@nuxt/module-builder": "^0.5.4",
"@nuxt/schema": "^3.8.2",
Expand Down
15 changes: 3 additions & 12 deletions playground/app.vue
Expand Up @@ -10,32 +10,23 @@ const gl = reactive({
toneMapping: NoToneMapping,
})
const bloomParams = reactive({
luminanceThreshold: 0.2,
luminanceSmoothing: 0.3,
mipmapBlur: true,
intensity: 0.5,
})
const showScene = ref(false)
setTimeout(() => {
showScene.value = true
}, 5000)
}, 500)
</script>

<template>
<div style="height: 100vh">
<TresCanvas v-bind="gl">
<CtxExposer />
<TresPerspectiveCamera
:position="[-5.3, 8.3, 10.6]"
:look-at="[0, 0, 0]"
/>
<OrbitControls />
<Suspense>
<EffectComposer>
<Bloom v-bind="bloomParams" />
</EffectComposer>
</Suspense>

<Suspense>
<NuxtStones />
</Suspense>
Expand Down
36 changes: 36 additions & 0 deletions playground/components/CtxExposer.vue
@@ -0,0 +1,36 @@
<script setup lang="ts">
const { renderer, scene } = useTresContext()
const { onLoop } = useRenderLoop()
onMounted(() => {
window.__TRES__ = {
renderer,
scene,
}
setTimeout(() => {
window.__TRES__DEVTOOLS__.cb({
renderer,
scene,
})
}, 3000)
})
/*
/* onLoop(({ elapsed }) => {
const iframe = document.querySelector('iframe[id*="devtools"]')
const internalIframe = iframe?.contentWindow.document.querySelector('iframe')
if (internalIframe) {
internalIframe.contentWindow.postMessage({
type: 'tresjs:devtools',
payload: JSON.stringify({
renderer: renderer.value,
}),
}, '*')
}
}) */
</script>

<template>
</template>
4 changes: 2 additions & 2 deletions playground/nuxt.config.ts
@@ -1,8 +1,8 @@
export default defineNuxtConfig({
modules: ['../src/module'],
devtools: { enabled: true },
modules: ['../src/module', '@nuxt/devtools'],
tres: {
// for testing purposes, and so we test both deduplication + auto-detection capabilities
modules: ['@tresjs/cientos'],
devtools: true,
},
})

0 comments on commit 0cc3e31

Please sign in to comment.