-
-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(Billboard): add component, playground, docs (#527)
Co-authored-by: alvarosabu <[email protected]>
- Loading branch information
1 parent
7a23019
commit 418e6ae
Showing
8 changed files
with
157 additions
and
0 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
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,26 @@ | ||
<script setup lang="ts"> | ||
import { Billboard, Box, OrbitControls } from '@tresjs/cientos' | ||
import { TresCanvas } from '@tresjs/core' | ||
import { Vector3 } from 'three' | ||
const COUNT = 5 * 5 | ||
const positions = Array.from({ length: COUNT }).fill(0).map((_, i) => { | ||
return new Vector3( | ||
i % 5 - 2, | ||
Math.floor(i / 5) - 2, | ||
0, | ||
) | ||
}) | ||
</script> | ||
|
||
<template> | ||
<TresCanvas clear-color="#333333"> | ||
<OrbitControls /> | ||
<TresPerspectiveCamera :position="[0, 0, 10]" /> | ||
<Billboard v-for="position, i of positions" :key="i" :position="position"> | ||
<Box :scale="[0.5, 0.5, 0.001]"> | ||
<TresMeshNormalMaterial /> | ||
</Box> | ||
</Billboard> | ||
</TresCanvas> | ||
</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
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,20 @@ | ||
# Billboard | ||
|
||
<DocsDemo> | ||
<BillboardDemo /> | ||
</DocsDemo> | ||
|
||
Adds a `THREE.Group` that faces the camera. | ||
|
||
## Usage | ||
|
||
<<< @/.vitepress/theme/components/BillboardDemo.vue | ||
|
||
## Props | ||
|
||
| Prop | Description | Default | | ||
| :--------------- | :--------------------------------------------------- | ------------- | | ||
| `autoUpdate` | Whether the `<Billboard />` should face the camera automatically on every frame. | `true` | | ||
| `lockX` | Whether to lock the x-axis. | `false` | | ||
| `lockY` | Whether to lock the y-axis. | `false` | | ||
| `lockZ` | Whether to lock the z-axis. | `false` | |
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,27 @@ | ||
<script setup lang="ts"> | ||
import { Billboard, Box, OrbitControls } from '@tresjs/cientos' | ||
import { TresCanvas } from '@tresjs/core' | ||
import { Vector3 } from 'three' | ||
import '@tresjs/leches/styles' | ||
const COUNT = 5 * 5 | ||
const positions = Array.from({ length: COUNT }).fill(0).map((_, i) => { | ||
return new Vector3( | ||
i % 5 - 2, | ||
Math.floor(i / 5) - 2, | ||
0, | ||
) | ||
}) | ||
</script> | ||
|
||
<template> | ||
<TresCanvas clear-color="#333333"> | ||
<OrbitControls /> | ||
<TresPerspectiveCamera :position="[0, 0, 10]" /> | ||
<Billboard v-for="position, i of positions" :key="i" :position="position"> | ||
<Box :scale="[0.5, 0.5, 0.001]"> | ||
<TresMeshNormalMaterial /> | ||
</Box> | ||
</Billboard> | ||
</TresCanvas> | ||
</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
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,75 @@ | ||
<script setup lang="ts"> | ||
import type { Camera } from 'three' | ||
import { Euler, Group, Quaternion } from 'three' | ||
import { shallowRef } from 'vue' | ||
import { useLoop, useTres } from '@tresjs/core' | ||
export interface BillboardProps { | ||
/** | ||
* Whether the Billboard should face the camera automatically on every frame. | ||
*/ | ||
autoUpdate?: boolean | ||
/** | ||
* Whether to lock the x-axis. | ||
*/ | ||
lockX?: boolean | ||
/** | ||
* Whether to lock the y-axis. | ||
*/ | ||
lockY?: boolean | ||
/** | ||
* Whether to lock the z-axis. | ||
*/ | ||
lockZ?: boolean | ||
} | ||
const props = withDefaults(defineProps<BillboardProps>(), { | ||
autoUpdate: true, | ||
lockX: false, | ||
lockY: false, | ||
lockZ: false, | ||
}) | ||
const outerRef = shallowRef(new Group()) | ||
const innerRef = shallowRef(new Group()) | ||
const q = new Quaternion() | ||
const r = new Euler() | ||
function update(camera?: Camera) { | ||
if (!outerRef.value) { return } | ||
if (!camera) { | ||
const t = useTres() | ||
camera = t.camera.value | ||
if (!camera) { return } | ||
} | ||
// NOTE: Save current rotation in case we're locking an axis | ||
innerRef.value.rotation.copy(r) | ||
// NOTE: Face the camera | ||
outerRef.value.updateMatrix() | ||
outerRef.value.updateWorldMatrix(false, false) | ||
outerRef.value.getWorldQuaternion(q) | ||
camera.getWorldQuaternion(innerRef.value.quaternion).premultiply(q.invert()) | ||
// NOTE: Overwrite locked axes | ||
if (props.lockX) { innerRef.value.rotation.x = r.x } | ||
if (props.lockY) { innerRef.value.rotation.y = r.y } | ||
if (props.lockZ) { innerRef.value.rotation.z = r.z } | ||
} | ||
useLoop().onBeforeRender(({ camera }) => { | ||
if (props.autoUpdate) { update(camera) } | ||
}) | ||
defineExpose({ instance: outerRef, update }) | ||
</script> | ||
|
||
<template> | ||
<TresGroup ref="outerRef"> | ||
<TresGroup ref="innerRef"> | ||
<slot></slot> | ||
</TresGroup> | ||
</TresGroup> | ||
</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