Skip to content
This repository was archived by the owner on Feb 1, 2026. It is now read-only.

Commit e057a6d

Browse files
committed
feat(inspector): add support for copying Quaternion values and enhance handling in Props and Tree components
1 parent 8333146 commit e057a6d

4 files changed

Lines changed: 48 additions & 6 deletions

File tree

client/components/inspector/Props.vue

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script setup lang="ts">
22
import type { TresObject } from '@tresjs/core'
33
import { computed, watch } from 'vue'
4-
import { copyPath, copyProp, copyPropAsArray, copyValue, copyValueAsArray, copyValueAsJSON, copyValueAsVector3, copyValueAsEuler } from '~/utils/clipboard'
4+
import { copyPath, copyProp, copyPropAsArray, copyValue, copyValueAsArray, copyValueAsJSON, copyValueAsVector3, copyValueAsEuler, copyValueAsQuaternion } from '~/utils/clipboard'
55
66
import { iconsMap } from '../../utils/graph'
77
import MaterialBadge from './MaterialBadge.vue'
@@ -298,6 +298,18 @@ function getValueClass(value: unknown): string {
298298
})),
299299
}),
300300
},
301+
prop.displayValue === 'vector' && prop.key === 'quaternion'
302+
&& { label: 'Copy as Quaternion',
303+
icon: 'i-lucide:rotate-3d',
304+
onSelect: () => copyValueAsQuaternion({
305+
children: [
306+
{ label: 'x', value: prop.value.x },
307+
{ label: 'y', value: prop.value.y },
308+
{ label: 'z', value: prop.value.z },
309+
{ label: 'w', value: prop.value.w || 1 },
310+
],
311+
}),
312+
},
301313
302314
].filter(Boolean)"
303315
:ui="{

client/components/inspector/Tree.vue

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script setup lang="ts">
22
import { computed, ref, watch } from 'vue'
33
import type { InspectorNode } from '~/client/types'
4-
import { copyPath, copyProp, copyPropAsArray, copyValue, copyValueAsArray, copyValueAsJSON, copyValueAsVector3, copyValueAsEuler } from '~/utils/clipboard'
4+
import { copyPath, copyProp, copyPropAsArray, copyValue, copyValueAsArray, copyValueAsJSON, copyValueAsVector3, copyValueAsEuler, copyValueAsQuaternion } from '~/utils/clipboard'
55
66
interface Props {
77
node: InspectorNode
@@ -168,8 +168,9 @@ const indentStyle = computed(() => ({ paddingLeft: `${props.level * 16}px` }))
168168
{ label: 'Copy value as Array', icon: 'i-material-symbols:data-array', onSelect: () => copyValueAsArray(node) },
169169
node.value === '_Vector3' ? { label: 'Copy value as Vector3', icon: 'i-lucide:pen-line', onSelect: () => copyValueAsVector3(node) } : null,
170170
node.value === '_Euler' ? { label: 'Copy as Euler', icon: 'i-lucide:rotate-3d', onSelect: () => copyValueAsEuler(node) } : null,
171+
node.value === '_Quaternion' ? { label: 'Copy as Quaternion', icon: 'i-lucide:rotate-3d', onSelect: () => copyValueAsQuaternion(node) } : null,
171172
{ label: 'Copy value as JSON', icon: 'i-material-symbols:data-object', onSelect: () => copyValueAsJSON(node) },
172-
node.value === '_Vector3' || node.value === '_Euler' ? { label: 'Copy as Prop', icon: 'i-lucide:code', onSelect: () => copyPropAsArray(node) } : null,
173+
node.value === '_Vector3' || node.value === '_Euler' || node.value === '_Quaternion' ? { label: 'Copy as Prop', icon: 'i-lucide:code', onSelect: () => copyPropAsArray(node) } : null,
173174
].filter(Boolean)"
174175
:ui="{
175176
content: 'w-48',

client/utils/clipboard.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,22 @@ export const copyValueAsEuler = async (node: InspectorNode): Promise<void> => {
9797
console.error('Failed to copy value as Euler:', error)
9898
}
9999
}
100+
101+
export const copyValueAsQuaternion = async (node: InspectorNode): Promise<void> => {
102+
try {
103+
const xChild = node.children?.find(child => child.label === 'x')
104+
const yChild = node.children?.find(child => child.label === 'y')
105+
const zChild = node.children?.find(child => child.label === 'z')
106+
const wChild = node.children?.find(child => child.label === 'w')
107+
108+
const x = xChild?.value || 0
109+
const y = yChild?.value || 0
110+
const z = zChild?.value || 0
111+
const w = wChild?.value || 1
112+
113+
await navigator.clipboard.writeText(`new Quaternion(${x}, ${y}, ${z}, ${w})`)
114+
}
115+
catch (error) {
116+
console.error('Failed to copy value as Quaternion:', error)
117+
}
118+
}

client/utils/graph.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ export function getInspectorGraph(obj: unknown, label = 'root', path = 'root', s
125125
// Handle objects
126126
const children: InspectorNode[] = []
127127
const objectName = (obj as object).constructor?.name || 'Object'
128-
128+
129129
// Special handling for Three.js Euler objects
130130
if (objectName === '_Euler') {
131131
console.log('Processing _Euler object:', obj, 'Constructor name:', objectName)
@@ -138,7 +138,17 @@ export function getInspectorGraph(obj: unknown, label = 'root', path = 'root', s
138138
children.push(getInspectorGraph(val, key, childPath, seen))
139139
}
140140
}
141-
// Special handling for Three.js Vector3 objects
141+
// Special handling for Three.js Quaternion objects
142+
else if (objectName === 'Quaternion') {
143+
const quaternionObj = obj as { x: number, y: number, z: number, w: number }
144+
const quaternionProps = ['x', 'y', 'z', 'w']
145+
for (const key of quaternionProps) {
146+
const val = quaternionObj[key as keyof typeof quaternionObj]
147+
const childPath = path === 'root' ? key : `${path}.${key}`
148+
children.push(getInspectorGraph(val, key, childPath, seen))
149+
}
150+
}
151+
// Special handling for Three.js Vector3 objects
142152
else if (objectName === '_Vector3') {
143153
const vectorObj = obj as { x: number, y: number, z: number }
144154
const vectorProps = ['x', 'y', 'z']
@@ -167,7 +177,7 @@ export function getInspectorGraph(obj: unknown, label = 'root', path = 'root', s
167177
label,
168178
type: 'object',
169179
path,
170-
value: objectName === '_Euler' ? '_Euler' : objectName === '_Vector3' ? '_Vector3' : objectName,
180+
value: objectName === 'Euler' ? 'Euler' : objectName === 'Quaternion' ? 'Quaternion' : objectName === 'Vector3' ? 'Vector3' : objectName,
171181
defaultExpanded: path === 'root',
172182
children,
173183
}

0 commit comments

Comments
 (0)