Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 178 v distance to #220

Merged
merged 9 commits into from
Oct 7, 2023
1 change: 1 addition & 0 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ export default defineConfig({
{ text: 'v-log', link: '/guide/directives/v-log' },
{ text: 'v-light-helper', link: '/guide/directives/v-light-helper' },
{ text: 'v-always-look-at', link: '/guide/directives/v-always-look-at' },
{ text: 'v-distance-to', link: '/guide/directives/v-distance-to' },
],
},
],
Expand Down
36 changes: 36 additions & 0 deletions docs/guide/directives/v-distance-to.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# v-distance-to

Have you tried to calculate the distance between two Object3Ds?

With the new directive `v-distance-to` it's easier than ever, you should only indicate the target object to perform the measure and the result will appear in your console.

In addition, an arrow will be created to indicate which objects you're measuring.

```vue{2,8,13}
<script setup lang="ts">
import { OrbitControls, Sphere, vLog } from '@tresjs/cientos'
</script>
<template>
<TresCanvas v-bind="gl">
<TresPerspectiveCamera :position="[0, 2, 5]" />
<Sphere
ref="sphere1Ref"
:position="[-2, slider, 0]"
:scale="0.5"
/>
<Sphere
v-distance-to="sphere1Ref"
:position="[2, 0, 0]"
:scale="0.5"
/>
<TresGridHelper :args="[10, 10]" />
<OrbitControls />
</TresCanvas>
</template>
```

The use of `v-distance-to` is reactive, so it works perfectly with @tres/leches 🍰.

::: warning
`v-distance-to` will not measure an object in movement within the renderLoop.
:::
44 changes: 44 additions & 0 deletions playground/src/pages/directives/vDistanceTo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<script setup lang="ts">
import { shallowRef } from 'vue'
import { TresCanvas } from '@tresjs/core'
import { OrbitControls, Sphere, vDistanceTo } from '@tresjs/cientos'
import { SRGBColorSpace, NoToneMapping } from 'three'
import { useControls, TresLeches } from '@tresjs/leches'
import '@tresjs/leches/styles'

const gl = {
clearColor: '#333',
outputColorSpace: SRGBColorSpace,
toneMapping: NoToneMapping,
}

const sphere1Ref = shallowRef()

const { value: slider } = useControls({
slider: {
value: -2,
min: -4,
max: 2,
step: 0.1,
},
})
</script>

<template>
<TresLeches class="top-0 important-left-4" />
<TresCanvas v-bind="gl">
<TresPerspectiveCamera :position="[0, 2, 5]" />
<Sphere
ref="sphere1Ref"
:position="[-2, slider, 0]"
:scale="0.5"
/>
<Sphere
v-distance-to="sphere1Ref"
:position="[2, 0, 0]"
:scale="0.5"
/>
<TresGridHelper :args="[10, 10]" />
<OrbitControls />
</TresCanvas>
</template>
5 changes: 5 additions & 0 deletions playground/src/router/routes/directives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,9 @@ export const directivesRoutes = [
name: 'vAlwaysLookAt',
component: () => import('../../pages/directives/vAlwaysLookAt.vue'),
},
{
path: '/directives/v-distance-to',
name: 'vDistanceTo',
component: () => import('../../pages/directives/vDistanceTo.vue'),
},
]
3 changes: 2 additions & 1 deletion src/core/directives/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { vLog } from './vLog'
import { vLightHelper } from './vLightHelper'
import { vAlwaysLookAt } from './vAlwaysLookAt'
import { vDistanceTo } from './vDistanceTo'

export { vLog, vLightHelper, vAlwaysLookAt }
export { vLog, vLightHelper, vAlwaysLookAt, vDistanceTo }
16 changes: 8 additions & 8 deletions src/core/directives/vAlwaysLookAt.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { useRenderLoop } from '@tresjs/core'
import { Vector3 } from 'three'
import { useRenderLoop, useLogger } from '@tresjs/core'
import type { Object3D } from 'three'
import { extractBindingPosition } from '../../utils/index'

const { logWarning } = useLogger()

export const vAlwaysLookAt = {
updated: (el: Object3D, binding: any) => {
let observer = binding.value
if (binding.value && binding.value?.value?.isMesh) {
observer = binding.value.value.position
}
if (Array.isArray(binding.value)) {
observer = new Vector3(...observer)
const observer = extractBindingPosition(binding)
if (!observer) {
logWarning(`v-always-look-at: problem with binding value: ${binding.value}`)
return
}
const { onLoop } = useRenderLoop()
onLoop(() => {
Expand Down
35 changes: 35 additions & 0 deletions src/core/directives/vDistanceTo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { useLogger } from '@tresjs/core'
import { ArrowHelper } from 'three'
import { extractBindingPosition } from '../../utils/index'

const { logWarning } = useLogger()

export const vDistanceTo = {
updated: (el: any, binding: any) => {
const observer = extractBindingPosition(binding)
andretchen0 marked this conversation as resolved.
Show resolved Hide resolved
if (!observer) {
logWarning(`v-distance-to: problem with binding value: ${binding.value}`)
return
}
if (arrowHelper) {
arrowHelper.dispose()
el.parent.remove(arrowHelper)
}
const dir = observer.clone().sub(el.position)
dir.normalize()
arrowHelper = new ArrowHelper( dir, el.position, el.position.distanceTo(observer) / 1.5, 0xffff00 )
el.parent.add( arrowHelper )
// eslint-disable-next-line no-console
console.table([
['Distance:', el.position.distanceTo(observer)],
[`origin: ${el.name || el.type}`, `x:${el.position.x}, y:${el.position.y}, z:${el.position?.z}`],
[`Destiny: ${el.name || el.type}`, `x:${observer.x}, y:${observer.y}, z:${observer?.z}`],
],
)
},
unmounted: (el: any) => {
arrowHelper?.dispose()
el.parent.remove(arrowHelper)
},
}
let arrowHelper: ArrowHelper | null = null
2 changes: 1 addition & 1 deletion src/core/directives/vLog.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export const vLog = {
updated: (el: any, binding: any) => {
mounted: (el: any, binding: any) => {
if (binding.arg) {
// eslint-disable-next-line no-console
console.log(`v-log:${binding.arg}`, el[binding.arg])
Expand Down
11 changes: 11 additions & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Vector3 } from 'three'

/**
* Update the function signature to explicitly specify the type of the props parameter
*
Expand Down Expand Up @@ -29,4 +31,13 @@ export function pick<T extends object, K extends keyof T>(obj: T, props: K[]): P
export function hasSetter(obj: any, prop: string): boolean {
const setterName = `set${prop[0].toUpperCase()}${prop.slice(1)}`
return obj[setterName] !== undefined
}

export function extractBindingPosition(binding: any): Vector3 {
let observer = binding.value
if (binding.value && binding.value?.value?.isMesh) {
observer = binding.value.value.position
}
if (Array.isArray(binding.value)) observer = new Vector3(...observer)
return observer
}