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: 423 enable render modes usage on abstractions #430

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 40 additions & 6 deletions docs/guide/controls/map-controls.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<MapControlsDemo />
</DocsDemo>

[MapControls](https://threejs.org/docs/index.html?q=controls#examples/en/controls/MapControls) similar to OrbitControls, this control is intended for transforming a camera over a map from bird's eye perspective, but uses a specific preset for mouse/touch interaction and disables screen space panning by default.
[MapControls](https://threejs.org/docs/index.html?q=controls#examples/en/controls/MapControls) similar to MapControls, this control is intended for transforming a camera over a map from bird's eye perspective, but uses a specific preset for mouse/touch interaction and disables screen space panning by default.

However, as it is not part of the core of ThreeJS, to use it you would need to import it from the `three/examples/jsm/controls/MapControls` module.

Expand All @@ -24,8 +24,42 @@ Is really important that the Perspective camera is set first in the canvas. Othe

## Props

| Prop | Description | Default |
| :---------------- | :--------------------------------------------------------------------------------------------------------------- | ----------- |
| **makeDefault** | If `true`, the controls will be set as the default controls for the scene. | `false` |
| **camera** | The camera to control. | `undefined` |
| **domElement** | The dom element to listen to. | `undefined` |
| Prop | Description | Default |
| :------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| **makeDefault** | If `true`, the controls will be set as the default controls for the scene. | `false` |
| **camera** | The camera to control. | `undefined` |
| **domElement** | The dom element to listen to. | `undefined` |
| **target** | The target to Map around. | `undefined` |
| **enableDamping** | If `true`, the controls will use damping (inertia), which can be used to give a sense of weight to the controls. | `false` |
| **dampingFactor** | The damping inertia used if `.enableDamping` is set to true. | `0.05` |
| **autoRotate** | Set to true to automatically rotate around the target. | `false` |
| **autoRotateSpeed** | How fast to rotate around the target if `.autoRotate` is true. | `2` |
| **enablePan** | Whether to enable panning. | `true` |
| **keyPanSpeed** | How fast to pan the camera when the keyboard is used. Default is 7.0 pixels per keypress. | `7.0` |
| **keys** | This object contains references to the keycodes for controlling camera panning. Default is the 4 arrow keys. | `{ LEFT: 'ArrowLeft', UP: 'ArrowUp', RIGHT: 'ArrowRight', BOTTOM: 'ArrowDown' }` |
| **maxAzimuthAngle** | How far you can Map horizontally, upper limit. If set, the interval [ min, max ] must be a sub-interval of [ - 2 PI, 2 PI ], with ( max - min < 2 PI ). Default is Infinity. | `Infinity` |
| **minAzimuthAngle** | How far you can Map horizontally, lower limit. If set, the interval [ min, max ] must be a sub-interval of [ - 2 PI, 2 PI ], with ( max - min < 2 PI ). Default is - Infinity. | `-Infinity` |
| **maxPolarAngle** | How far you can Map vertically, upper limit. Range is 0 to Math.PI radians, and default is Math.PI. | `Math.PI` |
| **minPolarAngle** | How far you can Map vertically, lower limit. Range is 0 to Math.PI radians, and default is 0. | `0` |
| **minDistance** | The minimum distance of the camera to the target. Default is 0. | `0` |
| **maxDistance** | The maximum distance of the camera to the target. Default is Infinity. | `Infinity` |
| **minZoom** | The minimum field of view angle, in radians. Default is 0. | `0` |
| **maxZoom** | The maximum field of view angle, in radians. ( OrthographicCamera only ). Default is Infinity. | `Infinity` |
| **touches** | This object contains references to the touch actions used by the controls. | `{ ONE: TOUCH.ROTATE, TWO: TOUCH.DOLLY_PAN }` |
| - | - |
| **enableZoom** | Whether to enable zooming. | `true` |
| **zoomSpeed** | How fast to zoom in and out. Default is 1. | `1` |
| **enableRotate** | Whether to enable rotating. | `true` |
| **rotateSpeed** | How fast to rotate around the target. Default is 1. | `1` |

## Events

```vue
<MapControls @change="onChange" @start="onStart" @end="onEnd" />
```

| Event | Description |
| :--------- | :-------------------------------------------- |
| **start** | Dispatched when the control starts to change. |
| **change** | Dispatched when the control changes. |
| **end** | Dispatched when the control ends to change. |
30 changes: 15 additions & 15 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,39 +58,39 @@
"vue": ">=3.3"
},
"dependencies": {
"@vueuse/core": "^10.7.2",
"camera-controls": "^2.7.4",
"@vueuse/core": "^10.10.0",
"camera-controls": "^2.8.4",
"stats-gl": "^2.0.1",
"stats.js": "^0.17.0",
"three-custom-shader-material": "^5.4.0",
"three-stdlib": "^2.29.11"
"three-stdlib": "^2.30.3"
},
"devDependencies": {
"@release-it/conventional-changelog": "^8.0.1",
"@tresjs/core": "4.0.0-next.1",
"@tresjs/core": "4.0.2",
"@tresjs/eslint-config": "^1.1.0",
"@types/node": "^20.12.10",
"@types/three": "^0.164.0",
"@typescript-eslint/eslint-plugin": "^7.8.0",
"@typescript-eslint/parser": "^7.8.0",
"@vitejs/plugin-vue": "^5.0.4",
"eslint": "^9.1.1",
"@types/node": "^20.14.2",
"@types/three": "^0.165.0",
"@typescript-eslint/eslint-plugin": "^7.12.0",
"@typescript-eslint/parser": "^7.12.0",
"@vitejs/plugin-vue": "^5.0.5",
"eslint": "^9.4.0",
"eslint-plugin-vue": "^9.25.0",
"gsap": "^3.12.5",
"husky": "^9.0.11",
"kolorist": "^1.8.0",
"pathe": "^1.1.2",
"release-it": "^17.2.1",
"release-it": "^17.3.0",
"rollup-plugin-analyzer": "^4.0.0",
"rollup-plugin-visualizer": "^5.12.0",
"three": "^0.164.1",
"three": "^0.165.0",
"typescript": "^5.4.5",
"unocss": "^0.59.4",
"vite": "^5.2.11",
"unocss": "^0.60.4",
"vite": "^5.2.12",
"vite-plugin-banner": "^0.7.1",
"vite-plugin-dts": "3.9.1",
"vite-plugin-glsl": "^1.3.0",
"vite-svg-loader": "^5.1.0",
"vitepress": "1.1.4"
"vitepress": "1.2.3"
}
}
1 change: 1 addition & 0 deletions playground/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ declare module 'vue' {
AkuAku: typeof import('./src/components/AkuAku.vue')['default']
FboCube: typeof import('./src/components/FboCube.vue')['default']
Gltf: typeof import('./src/components/gltf/index.vue')['default']
GraphPane: typeof import('./src/components/GraphPane.vue')['default']
ModelsDemo: typeof import('./src/components/ModelsDemo.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
Expand Down
2 changes: 1 addition & 1 deletion playground/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"preview": "vite preview"
},
"dependencies": {
"@tresjs/core": "4.0.0-rc.1",
"@tresjs/core": "4.0.2",
"vue-router": "^4.2.5"
},
"devDependencies": {
Expand Down
101 changes: 101 additions & 0 deletions playground/src/components/GraphPane.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<script lang="ts" setup>
import { ref } from 'vue'
import { useRafFn } from '@vueuse/core'
import { useState } from '../composables/state'

const width = 160
const height = 40
const strokeWidth = 2
const updateInterval = 100 // Update interval in milliseconds
const topOffset = 0 // Offset from the top

const points = ref('')
const frameTimes = ref([])
const maxFrames = ref(width / strokeWidth)

let lastUpdateTime = performance.now()

const { renderingTimes } = useState()

useRafFn(({ timestamp }) => {
if (timestamp - lastUpdateTime >= updateInterval) {
lastUpdateTime = timestamp

frameTimes.value.push(renderingTimes?.value)
renderingTimes.value = 0

if (frameTimes.value.length > maxFrames.value) {
frameTimes.value.shift()
}

points.value = frameTimes.value
.map(
(value, index) =>
`${index * strokeWidth},${
height + topOffset - strokeWidth / 2 - (value * (height + topOffset - strokeWidth)) / 2
}`,
)
.join(' ')
}
})
</script>

<template>
<div
class="absolute
right-2
top-2
flex
px-4
py-1
justify-between
gap-4
items-center
mb-2
z-10
bg-white
dark:bg-dark
shadow-xl
rounded
border-4
border-solid
bg-primary
border-primary
pointer-events-none
overflow-hidden"
>
<label class="text-secondary text-xs w-1/3">Rendering Activity</label>

<div
class="
bg-gray-100
dark:bg-gray-600
relative
w-2/3
p-1
rounded
text-right
text-xs
focus:border-gray-200
outline-none
border-none
font-sans
"
>
<svg
:width="width"
:height="height"
xmlns="http://www.w3.org/2000/svg"
fill="none"
>
<polyline
:points="points"
stroke="lightgray"
:stroke-width="strokeWidth"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
</div>
</template>
10 changes: 10 additions & 0 deletions playground/src/composables/state.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { reactive, toRefs } from 'vue'

const state = reactive({
renderingTimes: 0,
})
export function useState() {
return {
...toRefs(state),
}
}
26 changes: 18 additions & 8 deletions playground/src/pages/controls/CameraControlsDemo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { CameraControls } from '@tresjs/cientos'
import { BasicShadowMap, MathUtils, NoToneMapping, SRGBColorSpace } from 'three'
import { TresLeches, useControls } from '@tresjs/leches'
import '@tresjs/leches/styles'
import { useState } from '../../composables/state'

const gl = {
clearColor: '#82DBC5',
Expand Down Expand Up @@ -70,14 +71,14 @@ useControls(
dollyInc: {
type: 'button',
onClick: () => {
controlsRef?.value?.value?.dolly(1, true)
controlsRef?.value?.instance?.dolly(1, true)
},
label: 'Increment (+1)',
},
dollyDec: {
type: 'button',
onClick: () => {
controlsRef?.value?.value?.dolly(-1, true)
controlsRef?.value?.instance?.dolly(-1, true)
},
label: 'Increment (-1)',
},
Expand All @@ -91,28 +92,28 @@ useControls(
type: 'button',
label: 'Rotate theta 45°',
onClick: () => {
controlsRef?.value?.value?.rotate(45 * MathUtils.DEG2RAD, 0, true)
controlsRef?.value?.instance.rotate(45 * MathUtils.DEG2RAD, 0, true)
},
},
rotateTheta90: {
type: 'button',
label: 'Rotate theta -90°',
onClick: () => {
controlsRef?.value?.value?.rotate(-90 * MathUtils.DEG2RAD, 0, true)
controlsRef?.value?.instance.rotate(-90 * MathUtils.DEG2RAD, 0, true)
},
},
rotateTheta360: {
type: 'button',
label: 'Rotate theta 360°',
onClick: () => {
controlsRef?.value?.value?.rotate(360 * MathUtils.DEG2RAD, 0, true)
controlsRef?.value?.instance.rotate(360 * MathUtils.DEG2RAD, 0, true)
},
},
rotatePhi20: {
type: 'button',
label: 'Rotate phi 20°',
onClick: () => {
controlsRef?.value?.value?.rotate(0, 20 * MathUtils.DEG2RAD, true)
controlsRef?.value?.instance.rotate(0, 20 * MathUtils.DEG2RAD, true)
},
},
},
Expand All @@ -125,16 +126,25 @@ useControls(
type: 'button',
label: 'Fit to the bounding box of the mesh',
onClick: () => {
controlsRef?.value?.value?.fitToBox(boxMeshRef.value, true)
controlsRef?.value?.instance.fitToBox(boxMeshRef.value, true)
},
},
},
)

// For testing render mode on-demand,

const { renderingTimes } = useState()

function onRender() {
renderingTimes.value = 1
}
</script>

<template>
<TresLeches />
<TresCanvas v-bind="gl">
<GraphPane />
<TresCanvas render-mode="on-demand" v-bind="gl" @render="onRender">
<TresPerspectiveCamera :position="[5, 5, 5]" />
<CameraControls
v-bind="controlsState"
Expand Down
18 changes: 14 additions & 4 deletions playground/src/pages/controls/KeyboardControls.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { TresCanvas } from '@tresjs/core'
import { BasicShadowMap, NoToneMapping } from 'three'
import { Box, KeyboardControls, StatsGl } from '@tresjs/cientos'
import { useState } from '../../composables/state'

const gl = {
clearColor: '#82DBC5',
Expand All @@ -15,14 +16,23 @@ const isActive = (state: boolean) => {
// eslint-disable-next-line no-console
console.log(state)
}
const hasChange = (state: any) => {
// eslint-disable-next-line no-console
console.log('change', state)
const hasChange = () => {

/* console.log('change', state) */
}

// For testing render mode on-demand,

const { renderingTimes } = useState()

function onRender() {
renderingTimes.value = 1
}
</script>

<template>
<TresCanvas v-bind="gl">
<GraphPane />
<TresCanvas render-mode="on-demand" v-bind="gl" @render="onRender">
<TresPerspectiveCamera :position="[0, 3, 10]" />
<StatsGl />
<!-- <Sky /> -->
Expand Down
10 changes: 9 additions & 1 deletion playground/src/pages/controls/OrbitControlsDemo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { OrbitControls } from '@tresjs/cientos'
import { reactive } from 'vue'
import { TresLeches, useControls } from '@tresjs/leches'
import '@tresjs/leches/styles'
import { useState } from '../../composables/state'

const gl = {
clearColor: '#82DBC5',
Expand Down Expand Up @@ -174,11 +175,18 @@ function onStart() {
function onEnd() {
/* console.log('end') */
}
// For testing render mode on-demand,
const { renderingTimes } = useState()

function onRender() {
renderingTimes.value = 1
}
</script>

<template>
<TresLeches />
<TresCanvas v-bind="gl">
<GraphPane />
<TresCanvas render-mode="on-demand" v-bind="gl" @render="onRender">
<TresPerspectiveCamera :position="[3, 3, 3]" />
<OrbitControls
v-bind="controlsState"
Expand Down
Loading
Loading