|
@@ -1,34 +1,85 @@
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
-/* import { useRenderLoop } from '@tresjs/core' */
|
|
|
|
import { Camera, Object3D, Scene, WebGLRenderer } from 'three'
|
|
import { Camera, Object3D, Scene, WebGLRenderer } from 'three'
|
|
import { TransformControls as TransformControlsImp } from 'three-stdlib'
|
|
import { TransformControls as TransformControlsImp } from 'three-stdlib'
|
|
-import { inject, type Ref, unref, watch, useSlots } from 'vue'
|
|
|
|
|
|
+import { inject, computed, type Ref, unref, watch, shallowRef, ShallowRef } from 'vue'
|
|
|
|
+import { pick } from '../utils'
|
|
|
|
|
|
-let controls: TransformControlsImp
|
|
|
|
|
|
+const props = withDefaults(
|
|
|
|
+ defineProps<{
|
|
|
|
+ object: Object3D
|
|
|
|
+ mode?: string
|
|
|
|
+ enabled?: boolean
|
|
|
|
+ axis?: 'X' | 'Y' | 'Z' | 'XY' | 'YZ' | 'XZ' | 'XYZ'
|
|
|
|
+ translationSnap?: number
|
|
|
|
+ rotationSnap?: number
|
|
|
|
+ scaleSnap?: number
|
|
|
|
+ space?: 'local' | 'world'
|
|
|
|
+ size?: number
|
|
|
|
+ showX?: boolean
|
|
|
|
+ showY?: boolean
|
|
|
|
+ showZ?: boolean
|
|
|
|
+ }>(),
|
|
|
|
+ {
|
|
|
|
+ enabled: true,
|
|
|
|
+ },
|
|
|
|
+)
|
|
|
|
+
|
|
|
|
+let controls: ShallowRef<TransformControlsImp | undefined> = shallowRef()
|
|
|
|
|
|
-const props = defineProps<{
|
|
|
|
- object: Ref<Object3D>
|
|
|
|
- mode: 'translate' | 'rotate' | 'scale' | 'scaleUniform'
|
|
|
|
-}>()
|
|
|
|
|
|
+const transformOnlyProps = [
|
|
|
|
+ 'enabled',
|
|
|
|
+ 'axis',
|
|
|
|
+ 'mode',
|
|
|
|
+ 'translationSnap',
|
|
|
|
+ 'rotationSnap',
|
|
|
|
+ 'scaleSnap',
|
|
|
|
+ 'space',
|
|
|
|
+ 'size',
|
|
|
|
+ 'showX',
|
|
|
|
+ 'showY',
|
|
|
|
+ 'showZ',
|
|
|
|
+]
|
|
|
|
|
|
const camera = inject<Ref<Camera>>('camera')
|
|
const camera = inject<Ref<Camera>>('camera')
|
|
const renderer = inject<Ref<WebGLRenderer>>('renderer')
|
|
const renderer = inject<Ref<WebGLRenderer>>('renderer')
|
|
const scene = inject<Ref<Scene>>('local-scene')
|
|
const scene = inject<Ref<Scene>>('local-scene')
|
|
|
|
|
|
|
|
+const transformProps = computed(() => pick(props, transformOnlyProps))
|
|
|
|
+
|
|
watch(
|
|
watch(
|
|
[camera, renderer],
|
|
[camera, renderer],
|
|
() => {
|
|
() => {
|
|
if (camera?.value && renderer?.value && scene?.value) {
|
|
if (camera?.value && renderer?.value && scene?.value) {
|
|
- controls = new TransformControlsImp(camera.value, unref(renderer).domElement)
|
|
|
|
|
|
+ controls.value = new TransformControlsImp(camera.value, unref(renderer).domElement)
|
|
|
|
|
|
- controls.attach(unref(props.object))
|
|
|
|
- scene.value.add(controls)
|
|
|
|
|
|
+ controls.value.attach(unref(props.object))
|
|
|
|
+ scene.value.add(unref(controls) as TransformControlsImp)
|
|
}
|
|
}
|
|
},
|
|
},
|
|
{
|
|
{
|
|
deep: true,
|
|
deep: true,
|
|
},
|
|
},
|
|
)
|
|
)
|
|
|
|
+
|
|
|
|
+watch(
|
|
|
|
+ [transformProps, controls],
|
|
|
|
+ // TODO: properly type this
|
|
|
|
+ ([value, controlsValue]: [any, any]) => {
|
|
|
|
+ console.log([value, controlsValue])
|
|
|
|
+ if (value && controlsValue) {
|
|
|
|
+ for (const key in value) {
|
|
|
|
+ const methodName = `set${key[0].toUpperCase()}${key.slice(1)}`
|
|
|
|
+
|
|
|
|
+ if (typeof controlsValue[methodName] === 'function' && value[key] !== undefined) {
|
|
|
|
+ ;(controlsValue[methodName] as (param: any) => void)(value[key])
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ immediate: true,
|
|
|
|
+ },
|
|
|
|
+)
|
|
</script>
|
|
</script>
|
|
<template>
|
|
<template>
|
|
<slot />
|
|
<slot />
|