Skip to content
This repository was archived by the owner on Feb 1, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
c48bada
feat!: new devtools
alvarosabu Jul 8, 2025
d7fd1b5
chore: playground update with nuxt ui and fixed nuxt devtools client
alvarosabu Jul 11, 2025
16ac1a2
feat(client): devtools client with nuxt ui
alvarosabu Jul 12, 2025
8fa083c
refactor: graph utils and inspector graph
alvarosabu Jul 18, 2025
0817504
feat(client): enhance scene graph inspector with inline editing and c…
alvarosabu Jul 18, 2025
d5caab3
feat(client): enhance scene graph component with improved state manag…
alvarosabu Jul 19, 2025
e5574ec
feat(client): add highlight mesh functionality and improve scene grap…
alvarosabu Jul 19, 2025
44af00d
feat(client): add TreeInspector component for enhanced object inspection
alvarosabu Jul 25, 2025
e718574
feat(client): add TreeGraph component for hierarchical object represe…
alvarosabu Jul 25, 2025
1f31877
feat(client): enhance PerformanceMonitor component with improved UX a…
alvarosabu Jul 25, 2025
c7f98de
feat: performance tab
alvarosabu Jul 26, 2025
d1b13e4
feat(client): add AssetsMonitor component for asset management and vi…
alvarosabu Jul 26, 2025
5f43d80
refactor(client): clean up AssetsMonitor and asset utility functions
alvarosabu Jul 26, 2025
f281565
feat(client): enhanced asset monitor
alvarosabu Aug 1, 2025
00b0141
feat(inspector): add GeometryBadge and MaterialBadge components for e…
alvarosabu Sep 3, 2025
eb3c65d
refactor(devtools): clean up unused asset handling and update core de…
alvarosabu Sep 3, 2025
c9f8132
fix(inspector): update value class color from green to primary for co…
alvarosabu Sep 4, 2025
e0acab7
feat(inspector): integrate EditableNumber component for enhanced valu…
alvarosabu Sep 5, 2025
aefcdbd
fix(workflow): change build command from prepack to build for consist…
alvarosabu Sep 5, 2025
dd28d44
refactor(devtools): remove unused imports and clean up code in variou…
alvarosabu Sep 5, 2025
a136fe5
refactor(components): update input variants to 'soft' for consistency…
alvarosabu Sep 5, 2025
6a3284e
feat(inspector): add button for toggling boolean property values in P…
alvarosabu Sep 5, 2025
307e1d2
feat(inspector): enhance copy functionality in Props and Tree components
alvarosabu Sep 5, 2025
2937cf5
fix(inspector): simplify copy functionality by removing unnecessary t…
alvarosabu Sep 5, 2025
9ba7494
feat(inspector): implement clipboard copy functionality for Props and…
alvarosabu Sep 12, 2025
8333146
feat(inspector): add support for copying values as Euler and enhance …
alvarosabu Sep 12, 2025
e057a6d
feat(inspector): add support for copying Quaternion values and enhanc…
alvarosabu Sep 12, 2025
4201c7c
refactor(inspector): clean up unused code and simplify clipboard func…
alvarosabu Sep 12, 2025
adc6c34
feat(components): add EditableColor component for color editing and e…
alvarosabu Sep 17, 2025
fd5cbd9
refactor(inspector): remove unused import in Tree component and impro…
alvarosabu Sep 17, 2025
642756f
chore(package): add @nuxt/devtools-kit to dependencies for improved d…
alvarosabu Sep 17, 2025
803e638
chore(workflow): add NUXT_UI_PRO_LICENSE secret to GitHub Actions env…
alvarosabu Sep 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/pkg.pr.new.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ on:
env:
PNPM_CACHE_FOLDER: .pnpm-store
HUSKY: 0 # Bypass husky commit hook for CI
NUXT_UI_PRO_LICENSE: ${{ secrets.NUXT_UI_PRO_LICENSE }}

permissions: {}

Expand All @@ -34,5 +35,5 @@ jobs:
- name: Install dependencies
run: pnpm install
- name: Build
run: pnpm prepack
run: pnpm build
- run: pnpx pkg-pr-new publish --compact --pnpm
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ dist
.env
.netlify

**/.env

# Env
.env

Expand Down
34 changes: 34 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "client: chrome",
"url": "http://localhost:3000",
"webRoot": "${workspaceFolder}"
},
{
"type": "node",
"request": "launch",
"name": "server: nuxt",
"outputCapture": "std",
"program": "${workspaceFolder}/node_modules/nuxt/bin/nuxt.mjs",
"args": [
"dev playground"
],
}
],
"compounds": [
{
"name": "fullstack: nuxt",
"configurations": [
"server: nuxt",
"client: chrome"
]
}
]
}
1 change: 1 addition & 0 deletions client/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
shamefully-hoist=true
15 changes: 15 additions & 0 deletions client/app.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export default defineAppConfig({
ui: {
colors: {
primary: 'teal',
accent: 'yellow',
neutral: 'zinc',
},
card: {
slots: {
root: 'hover:bg-linear-[115deg,#272727 .06%,#171717]',
body: 'p-2 sm:p-3',
},
},
},
})
4 changes: 2 additions & 2 deletions client/app.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<NuxtLayout>
<UApp>
<NuxtPage />
</NuxtLayout>
</UApp>
</template>
61 changes: 61 additions & 0 deletions client/assets/css/main.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
@import "tailwindcss";
@import "@nuxt/ui-pro";

@theme static {
--font-display: 'Manrope', sans-serif;
--font-sans: 'Inter', sans-serif;
--font-mono: 'Fira Code', monospace;
--breakpoint-3xl: 1920px;
--ui-pattern-fg: color-mix(in oklab,var(--ui-text)5%,transparent);
--ui-pattern-bg: repeating-linear-gradient(315deg,var(--ui-pattern-fg)0,var(--ui-pattern-fg)1px,transparent 0,transparent 50%);

/* Technical blueprint styles */
--ui-line-gap: 5px;
--ui-line-width: 1px;
--ui-line-offset: 172px;
--ui-line-color: var(--color-gray-200);

/* Teal Palette */
--color-teal-50: #f2fbf8;
--color-teal-100: #d3f4ea;
--color-teal-200: #a6e9d6;
--color-teal-300: #82dbc5;
--color-teal-400: #44bda2;
--color-teal-500: #2ba189;
--color-teal-600: #20816f;
--color-teal-700: #1d685b;
--color-teal-800: #1c534b;
--color-teal-900: #1b463f;
--color-teal-950: #0a2925;

/* Yellow/Brown Palette */
--color-yellow-50: #fff8eb;
--color-yellow-100: #feeac7;
--color-yellow-200: #fdd48a;
--color-yellow-300: #fbb03b;
--color-yellow-400: #fa9e25;
--color-yellow-500: #f47a0c;
--color-yellow-600: #b85607;
--color-yellow-700: #b3390a;
--color-yellow-800: #922b0e;
--color-yellow-900: #78250f;
--color-yellow-950: #451003;
}

:root {
--ui-header-height: 49px;
}

.dark {
--ui-line-color: var(--color-gray-800);
}

.pattern-bg {
background-image: var(--ui-pattern-bg);
background-size: 10px 10px;
background-attachment: fixed;
}

.noise-bg {
background-image: url("data:image/svg+xml,%3C!-- svg: first layer --%3E%3Csvg viewBox='0 0 250 250' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='4' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E");
}
246 changes: 246 additions & 0 deletions client/components/AssetsMonitor.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
<script setup lang="ts">
import { computed } from '#imports'
import { useDevtoolsHook } from '../composables/useDevtoolsHook'

const { scene } = useDevtoolsHook()

// Store geometry previews

// Group assets by type
const groupedAssets = computed(() => {
const assets = scene.assets || []
return {
textures: assets.filter(asset => asset.type === 'texture'),
materials: assets.filter(asset => asset.type === 'material'),
models: assets.filter(asset => asset.type === 'model'),
}
})

// Asset statistics
const assetStats = computed(() => {
const assets = scene.assets || []
const totalMemory = assets.reduce((sum, asset) => sum + (asset.usage || 0), 0)

return {
total: assets.length,
textures: groupedAssets.value.textures.length,
materials: groupedAssets.value.materials.length,
models: groupedAssets.value.models.length,
totalMemory: Math.round(totalMemory),
}
})

// Get icon for asset type
const getAssetIcon = (type: string) => {
switch (type) {
case 'texture':
return 'i-tabler:photo'
case 'geometry':
return 'i-tabler:box'
case 'material':
return 'i-tabler:palette'
case 'model':
return 'i-tabler:burger'
default:
return 'i-tabler:file'
}
}

// Get color for asset type
const getAssetColor = (type: string) => {
switch (type) {
case 'texture':
return 'purple'
case 'geometry':
return 'blue'
case 'material':
return 'orange'
default:
return 'gray'
}
}
</script>

<template>
<div class="pb-6">
<!-- Assets Overview Stats -->
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 pb-4">
<UCard>
<div class="text-center">
<div class="font-bold text-gray-900 dark:text-white">
{{ assetStats.total }}
</div>
<div class="text-sm">
Total Assets
</div>
</div>
</UCard>

<UCard>
<div class="text-center">
<div class="flex items-center justify-center gap-2 mb-1">
<UIcon
name="i-tabler:photo"
class="w-5 h-5"
/>
<div class="font-bold ">
{{ assetStats.textures }}
</div>
</div>
<div class="text-sm">
Textures
</div>
</div>
</UCard>

<UCard>
<div class="text-center">
<div class="flex items-center justify-center gap-2 mb-1">
<UIcon
name="i-tabler:burger"
class="w-5 h-5"
/>
<div class="font-bold">
{{ assetStats.models }}
</div>
</div>
<div class="text-sm">
Models
</div>
</div>
</UCard>

<UCard>
<div class="text-center">
<div class="flex items-center justify-center gap-2 mb-1">
<UIcon
name="i-tabler:database"
class="w-5 h-5"
/>
<!-- <div class="font-bold">
{{ formatMemorySize(assetStats.totalMemory) }}
</div> -->
</div>
<div class="text-sm text-gray-600 dark:text-gray-400">
Memory Used
</div>
</div>
</UCard>
</div>

<!-- Assets Grid -->
<div v-if="scene.assets && scene.assets.length > 0">
<!-- Textures -->
<div
v-if="groupedAssets.textures.length > 0"
class="pb-4"
>
<div class="flex items-center gap-2 my-2 mb-4">
<UIcon
name="i-tabler:photo"
class="w-5 h-5"
/>
<h3 class="font-semibold">
Textures
</h3>
</div>

<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
<TextureAssetCard
v-for="asset in groupedAssets.textures"
:key="asset.id"
:asset="asset"
/>
</div>
</div>

<!-- Models -->

<div
v-if="groupedAssets.models.length > 0"
class="pb-4"
>
<div class="flex items-center gap-2 my-2 mb-4">
<UIcon
name="i-tabler:burger"
class="w-5 h-5"
/>
<h3 class="text-lg font-semibold">
Models
</h3>
</div>

<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
<ModelAssetCard
v-for="asset in groupedAssets.models"
:key="asset.id"
:asset="asset"
/>
</div>
</div>

<!-- Materials -->
<div
v-if="groupedAssets.materials.length > 0"
class="pb-4"
>
<div class="flex items-center gap-2 my-2 mb-4">
<UIcon
name="i-tabler:palette"
class="w-5 h-5"
/>
<h3 class="text-lg font-semibold">
Materials
</h3>
</div>

<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
<UCard
v-for="asset in groupedAssets.materials"
:key="asset.id"
class="hover:shadow-md transition-shadow"
>
<template #header>
<div class="flex items-center gap-2">
<UIcon
:name="getAssetIcon(asset.type)"
class="w-4 h-4"
:class="`text-${getAssetColor(asset.type)}-500`"
/>
<div class="text-sm font-medium truncate">
{{ asset.name }}
</div>
</div>
</template>

<div class="pb-2 text-sm">
<div
v-if="asset.format"
class="flex justify-between"
>
<span class="text-gray-600 dark:text-gray-400">Type:</span>
<span>{{ asset.format }}</span>
</div>
</div>
</UCard>
</div>
</div>
</div>

<!-- Empty State -->
<UCard v-else>
<div class="text-center py-8">
<UIcon
name="i-tabler:file-x"
class="w-12 h-12 text-gray-400 mx-auto mb-4"
/>
<h3 class="text-lg font-semibold text-gray-900 dark:text-white mb-2">
No Assets Found
</h3>
<p class="text-gray-600 dark:text-gray-400">
No textures, geometries, or materials detected in the current scene.
</p>
</div>
</UCard>
</div>
</template>
Loading
Loading