Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: use devtool cb and perf stats from core
- Loading branch information
1 parent
29ff44d
commit e35d546
Showing
11 changed files
with
782 additions
and
434 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
<script setup lang="ts"> | ||
import { computed, ref, watchEffect } from 'vue' | ||
const props = withDefaults(defineProps<{ | ||
points: Array<number> // Array of y-values | ||
value: number | ||
unit: string | ||
label: string | ||
color: string | ||
}>(), | ||
{ | ||
points: () => [], | ||
value: 0, | ||
unit: '', | ||
label: '', | ||
color: 'green', | ||
}) | ||
const width = 160 | ||
const height = 40 | ||
const strokeWidth = 2 | ||
// Determine the maximum value for scaling the graph | ||
const maxValue = ref(140) | ||
// Update maxValue to accommodate the range of y-values in points | ||
watchEffect(() => { | ||
const highestValue = Math.max(...props.points, 30) // Ensure at least 30 | ||
maxValue.value = Math.max(highestValue, maxValue.value) | ||
}) | ||
const pointsF = computed(() => props.points.map( | ||
(point, index) => | ||
`${index * strokeWidth},${height - (point * height / maxValue.value)}`, | ||
).join(' ')) | ||
</script> | ||
|
||
<template> | ||
<div | ||
class=" | ||
graph | ||
relative | ||
p-1 | ||
rounded | ||
text-right | ||
text-xs | ||
outline-none | ||
border-none | ||
font-sans | ||
" | ||
> | ||
<div class="absolute bottom-0.5 right-0.5 font-mono text-xs"> | ||
{{ Math.round(value) }} {{ unit }} | ||
</div> | ||
<svg | ||
width="100%" | ||
:height="height" | ||
xmlns="http://www.w3.org/2000/svg" | ||
> | ||
<polyline | ||
:points="pointsF" | ||
fill="none" | ||
:stroke="color" | ||
:stroke-width="strokeWidth" | ||
stroke-linecap="round" | ||
stroke-linejoin="round" | ||
/> | ||
</svg> | ||
</div> | ||
</template> | ||
|
||
<style> | ||
.graph { | ||
background-color: rgba(var(--nui-c-context), 0.1); | ||
color: rgba(var(--nui-c-context), 1); | ||
} | ||
.graph polyline { | ||
stroke: rgba(var(--nui-c-context), 1); | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<script setup lang="ts"> | ||
defineProps<{ | ||
title: string | ||
}>() | ||
</script> | ||
|
||
<template> | ||
<div | ||
class="relative | ||
px-4 | ||
py-6 | ||
border | ||
border-solid | ||
border-gray-200 | ||
rounded | ||
my-4" | ||
> | ||
<span | ||
class="absolute | ||
bg-white | ||
text-xs | ||
dark:bg-[#151515] | ||
text-gray-400 | ||
px-2 | ||
rounded | ||
-top-2 | ||
left-2" | ||
>{{ title }}</span> | ||
<slot /> | ||
</div> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
<script setup lang="ts"> | ||
import { bytesToKB } from '../utils' | ||
const { fps, memory, gl } = useDevtoolsHook() | ||
</script> | ||
|
||
<template> | ||
<div class="grid grid-cols-2 gap-4"> | ||
<NCard | ||
class="col-span-1" | ||
n="green" | ||
> | ||
<Graph | ||
:points="fps.accumulator" | ||
:value="fps.value" | ||
color="green" | ||
n="green" | ||
unit="FPS" | ||
label="FPS" | ||
/> | ||
</NCard> | ||
<NCard | ||
class="col-span-1" | ||
n="green" | ||
> | ||
<Graph | ||
:points="memory.accumulator" | ||
:value="memory.currentMem" | ||
color="yellow" | ||
n="yellow" | ||
unit="MB" | ||
label="memory" | ||
/> | ||
</NCard> | ||
<Pane :title="`Memory ${bytesToKB(memory.allocatedMem)}KB`"> | ||
<div class="flex p4 justify-around w-full"> | ||
<div class="flex flex-col items-center gap-2"> | ||
<div class="flex items-center font-mono gap-2"> | ||
{{ gl.renderer.info?.memory?.geometries || 0 }} | ||
<i class="i-iconoir-box-3d-three-points" /> | ||
</div> | ||
<span class="text-xs text-gray-500">Geometries</span> | ||
</div> | ||
<div class="flex flex-col items-center gap-2"> | ||
<div class="flex items-center font-mono gap-2"> | ||
{{ gl.renderer.info?.memory?.textures || 0 }} | ||
<i class="i-iconoir-select-face-3d" /> | ||
</div> | ||
<span class="text-xs text-gray-500">Textures</span> | ||
</div> | ||
</div> | ||
</Pane> | ||
<Pane title="Render"> | ||
<div class="grid grid-cols-2 p4 justify-around w-full"> | ||
<div class="flex flex-col items-center gap-2 mb4"> | ||
<div class="flex items-center font-mono gap-2"> | ||
{{ gl.renderer.info?.render?.calls || 0 }} | ||
<i class="i-iconoir-comp-align-left" /> | ||
</div> | ||
<span class="text-xs text-gray-500">Calls</span> | ||
</div> | ||
<div class="flex flex-col items-center gap-2 mb4"> | ||
<div class="flex items-center font-mono gap-2"> | ||
{{ gl.renderer.info?.render?.triangles || 0 }} | ||
<i class="i-iconoir-triangle" /> | ||
</div> | ||
<span class="text-xs text-gray-500">Triangles</span> | ||
</div> | ||
<div class="flex flex-col items-center gap-2 mb4"> | ||
<div class="flex items-center font-mono gap-2"> | ||
{{ gl.renderer.info?.render?.points || 0 }} | ||
<i class="i-iconoir-one-point-circle" /> | ||
</div> | ||
<span class="text-xs text-gray-500">Points</span> | ||
</div> | ||
<div class="flex flex-col items-center gap-2 mb4"> | ||
<div class="flex items-center font-mono gap-2"> | ||
{{ gl.renderer.info?.render?.lines || 0 }} | ||
<i class="i-iconoir-linear" /> | ||
</div> | ||
<span class="text-xs text-gray-500">Lines</span> | ||
</div> | ||
</div> | ||
</Pane> | ||
</div> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
import type { TresObject } from '@tresjs/core' | ||
import type { Scene, WebGLRenderer } from 'three' | ||
import { useTresContextProvider } from '@tresjs/core' | ||
import type { SceneGraphObject } from '../types' | ||
import { calculateMemoryUsage } from '../utils' | ||
import { iants } from './../.nuxt/tailwind.config.d' | ||
|
||
const scene = reactive({ | ||
objects: 0, | ||
graph: {}, | ||
value: undefined as Scene | undefined, | ||
}) | ||
|
||
const gl = { | ||
fps: reactive({ | ||
value: 0, | ||
accumulator: [], | ||
lastLoggedTime: Date.now(), | ||
logInterval: 1000, | ||
}), | ||
memory: reactive({ | ||
currentMem: 0, | ||
averageMem: 0, | ||
maxMemory: 0, | ||
allocatedMem: 0, | ||
accumulator: [], | ||
lastLoggedTime: Date.now(), | ||
logInterval: 1000, | ||
}), | ||
renderer: undefined as WebGLRenderer | undefined, | ||
} | ||
|
||
const icons: Record<string, string> = { | ||
scene: 'i-carbon-web-services-container', | ||
perspectivecamera: 'i-carbon-video', | ||
mesh: 'i-carbon-cube', | ||
group: 'i-carbon-group', | ||
ambientlight: 'i-carbon-light', | ||
directionallight: 'i-carbon-light', | ||
spotlight: 'i-iconoir-project-curve-3d', | ||
position: 'i-iconoir-axes', | ||
rotation: 'i-carbon-rotate-clockwise', | ||
scale: 'i-iconoir-ellipse-3d-three-points', | ||
} | ||
|
||
function createNode(object: TresObject) { | ||
const node: SceneGraphObject = { | ||
name: object.name, | ||
type: object.type, | ||
icon: icons[object.type.toLowerCase()] || 'i-carbon-cube', | ||
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: [], | ||
} | ||
|
||
if (object.type === 'Mesh') { | ||
node.material = object.material | ||
node.geometry = object.geometry | ||
node.scale = { | ||
x: object.scale.x, | ||
y: object.scale.y, | ||
z: object.scale.z, | ||
} | ||
} | ||
|
||
if (object.type.includes('Light')) { | ||
node.color = object.color.getHexString() | ||
node.intensity = object.intensity | ||
} | ||
return node | ||
} | ||
|
||
function getSceneGraph(scene: TresObject) { | ||
|
||
function buildGraph(object: TresObject, node: SceneGraphObject) { | ||
object.children.forEach((child: TresObject) => { | ||
const childNode = createNode(child) | ||
node.children.push(childNode) | ||
buildGraph(child, childNode) | ||
}) | ||
} | ||
|
||
const root = createNode(scene) | ||
buildGraph(scene, root) | ||
|
||
return root | ||
} | ||
|
||
function countObjectsInScene(scene: Scene) { | ||
let count = 0 | ||
|
||
scene.traverse((object) => { | ||
// Check if the object is a 3D object | ||
if (object.isObject3D) { | ||
count++ | ||
} | ||
}) | ||
|
||
return count | ||
} | ||
|
||
export function useDevtoolsHook() { | ||
/* const updateInterval = 100 // Update interval in milliseconds | ||
const fps = useFps({ every: updateInterval }) | ||
const { isSupported, memory } = useMemory({ interval: updateInterval }) | ||
const maxFrames = 160 */ | ||
|
||
// Connect with Core | ||
const tresGlobalHook = { | ||
cb(context: { renderer: Ref<WebGLRenderer>; scene: Ref<Scene> }) { | ||
scene.value = context.scene.value | ||
scene.objects = countObjectsInScene(context.scene.value) | ||
gl.renderer = context.renderer.value | ||
Object.assign(gl.fps, context.perf.fps) | ||
gl.fps.accumulator = [...context.perf.fps.accumulator] | ||
Object.assign(gl.memory, context.perf.memory) | ||
gl.memory.accumulator = [...context.perf.memory.accumulator] | ||
scene.graph = getSceneGraph(context.scene.value as unknown as TresObject) | ||
}, | ||
} | ||
|
||
window.parent.parent.__TRES__DEVTOOLS__ = tresGlobalHook | ||
|
||
/* let lastUpdateTime = performance.now() | ||
const updatePerformanceData = ({ timestamp }: { timestamp: number }) => { | ||
// Update WebGL Memory Usage (Placeholder for actual logic) | ||
// perf.memory.value = calculateMemoryUsage(gl) | ||
if (scene.value) { | ||
gl.memory.allocatedMem = calculateMemoryUsage(scene.value as unknown as TresObject) | ||
} | ||
// Update memory usage | ||
if (timestamp - lastUpdateTime >= updateInterval) { | ||
lastUpdateTime = timestamp | ||
// Update FPS | ||
gl.fps.accumulator.push(fps.value as never) | ||
if (gl.fps.accumulator.length > maxFrames) { | ||
gl.fps.accumulator.shift() | ||
} | ||
gl.fps.value = fps.value | ||
// Update memory | ||
if (isSupported.value && memory.value) { | ||
gl.memory.accumulator.push(memory.value.usedJSHeapSize / 1024 / 1024 as never) | ||
if (gl.memory.accumulator.length > maxFrames) { | ||
gl.memory.accumulator.shift() | ||
} | ||
gl.memory.currentMem = gl.memory.accumulator.reduce((a, b) => a + b, 0) / gl.memory.accumulator.length | ||
} | ||
} | ||
} | ||
const { pause, resume } = useRafFn(updatePerformanceData, { immediate: true }) | ||
onUnmounted(() => { | ||
pause() | ||
}) */ | ||
|
||
return { | ||
scene, | ||
gl, | ||
fps: gl.fps, | ||
memory: gl.memory, | ||
} | ||
} |
Oops, something went wrong.