Skip to content

Commit

Permalink
Merge branch 'main' into blog/tresjs-nuxt-module-announcement
Browse files Browse the repository at this point in the history
  • Loading branch information
alvarosabu committed Jun 22, 2023
2 parents 0858701 + 6d46188 commit 677765e
Show file tree
Hide file tree
Showing 24 changed files with 306 additions and 247 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@


## [2.2.0](https://github.com/Tresjs/tres/compare/2.1.3...2.2.0) (2023-06-19)


### Features

* removed `useCamera` logic from nodeOps ([#308](https://github.com/Tresjs/tres/issues/308)) ([e9509ba](https://github.com/Tresjs/tres/commit/e9509bab177a7a23f802ad2716f42d1f36f7654b))


### Bug Fixes

* banner image link ([b793c77](https://github.com/Tresjs/tres/commit/b793c77a2b456ddac0fdd4cf18ad4d94f19db439))
* main button colors ([3aab827](https://github.com/Tresjs/tres/commit/3aab8273dace80ba6e5ee210b0e17f0b8bc61449))
* raycaster does not work properly when scene is not in full screen ([#304](https://github.com/Tresjs/tres/issues/304)) ([20a5b9e](https://github.com/Tresjs/tres/commit/20a5b9eee94755ca58ff4936aef20a070f920a7e))

### [2.1.3](https://github.com/Tresjs/tres/compare/2.1.2...2.1.3) (2023-06-14)


Expand Down
30 changes: 12 additions & 18 deletions docs/api/events.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,25 @@
# Events

**TresJS** Mesh objects emit pointer events when they are interacted with using `raycaster` and `pointer` objects under the hood.
**TresJS** components emit pointer events when they are interacted with. This is the case for the components that represent Three.js classes that derive from [THREE.Object3D](https://threejs.org/docs/index.html?q=object#api/en/core/Object3D) (like meshes, groups,...).

<StackBlitzEmbed project-id="tresjs-events" />

## Pointer Events

```html
<TresMesh
@click="(ev) => console.log('click', ev)"
@pointer-move="(ev) => console.log('click', ev)"
@pointer-enter="(ev) => console.log('click', ev)"
@pointer-leave="(ev) => console.log('click', ev)"
@click="(intersection, pointerEvent) => console.log('click', intersection, pointerEvent)"
@pointer-move="(intersection, pointerEvent) => console.log('pointer-move', intersection, pointerEvent)"
@pointer-enter="(intersection, pointerEvent) => console.log('pointer-enter', intersection, pointerEvent)"
@pointer-leave="(intersection, pointerEvent) => console.log('pointer-leave', pointerEvent)"
/>
```

## Event Data
| Event | fires when ... | Event Handler Parameter Type(s) |
| ------------- | ------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| click   | ... the events pointerdown and pointerup fired on the same object one after the other | [Intersection](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/three/src/core/Raycaster.d.ts#L16), [PointerEvent](https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent) |
| pointer-move | ... the pointer is moving above the object | [Intersection](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/three/src/core/Raycaster.d.ts#L16), [PointerEvent](https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent) |
| pointer-enter | ... the pointer is entering the object | [Intersection](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/three/src/core/Raycaster.d.ts#L16), [PointerEvent](https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent) |
| pointer-leave | ... the pointer is leaves the object | [PointerEvent](https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent) |

The event data is a `TresEvent` object that contains the following properties:

```ts
;({
object: Object3D, // The mesh object that emitted the event
distance: number, // The distance between the camera and the mesh
point: Vector3, // The intersection point between the ray and the mesh
uv: Vector2, // The uv coordinates of the intersection point
face: Face3, // The face of the mesh that was intersected
faceIndex: number, // The index of the face that was intersected
})
```
The returned [Intersection](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/three/src/core/Raycaster.d.ts#L16) includes the [Object3D](https://threejs.org/docs/index.html?q=object#api/en/core/Object3D) that triggered the event. You can access it via `intersection.object`.
6 changes: 3 additions & 3 deletions docs/guide/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ TresJS is written in Typescript and it's fully typed. If you are using Typescrip
::: code-group

```bash [npm]
npm install @three/types -D
npm install @types/three -D
```

```bash [yarn]
yarn add @three/types -D
yarn add @types/three -D
```

```bash [pnpm]
pnpm add @three/types -D
pnpm add @types/three -D
```

:::
Expand Down
6 changes: 3 additions & 3 deletions docs/guide/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ TresJS is written in Typescript and it's fully typed. If you are using Typescrip
::: code-group

```bash [npm]
npm install @three/types -D
npm install @types/three -D
```

```bash [yarn]
yarn add @three/types -D
yarn add @types/three -D
```

```bash [pnpm]
pnpm add @three/types -D
pnpm add @types/three -D
```

:::
Expand Down
2 changes: 0 additions & 2 deletions docs/guide/migration-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,6 @@ watch(modelRef, model => {

The `TresOrbitControls` component needs to be after the camera in the tree. This is because the controls need to know the camera to work.

Read more about it here: [Troubleshooting](/guide/troubleshooting.md)

Change this:

```vue {3,5}
Expand Down
21 changes: 0 additions & 21 deletions docs/guide/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,6 @@ You followed the [Getting started guide](/guide/getting-started.md) but you stil

These are the most common reasons why you might not be able to see your scene:

### Make sure you have a camera 🎥

The first thing you need to do is to make sure you have a camera in your scene. If you don't have a camera, you won't be able to see anything.

![No camera found](/no-camera-found.png)

```vue
<!-- Wrong ❌ -->
<TresCanvas>
<TresOrbitControls />
</TresCanvas>
```

```vue
<!-- Correct ✅ -->
<TresCanvas>
<TresPerspectiveCamera />
<TresOrbitControls />
</TresCanvas>
```

### Check the height of your canvas 📏

Another common issue is that the `TresCanvas` component is creating by default a `canvas` element takes the `width` and `height` of the parent element. If the parent element has no height, the canvas will have no height either.
Expand Down
2 changes: 1 addition & 1 deletion docs/guide/your-first-scene.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ Then you can add a [**PerspectiveCamera**](https://threejs.org/docs/index.html?q
```

::: warning
A common issue is that the camera default position is the origin of the scene (0,0,0), if you still can see your scene try adding a position to the camera `<TresPerspectiveCamera :position="[3, 3, 3]" />`
A common issue is that the camera default position is the origin of the scene (0,0,0), TresJS will automatically set the position of your camera to `[3,3,3]` if the prop `position`. If no camera is defined in you scene, a perspective camera is added automatically.`
:::

## Adding a 🍩
Expand Down
2 changes: 1 addition & 1 deletion docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@
"devDependencies": {
"unocss": "^0.53.0",
"vite-svg-loader": "^4.0.0",
"vitepress": "1.0.0-beta.1"
"vitepress": "1.0.0-beta.2"
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@tresjs/core",
"description": "Declarative ThreeJS using Vue Components",
"version": "2.1.3",
"version": "2.2.0",
"type": "module",
"packageManager": "[email protected]",
"author": "Alvaro Saburido <[email protected]> (https://github.com/alvarosabu/)",
Expand Down
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' {
AnimatedModel: typeof import('./src/components/AnimatedModel.vue')['default']
Cameras: typeof import('./src/components/Cameras.vue')['default']
DanielTest: typeof import('./src/components/DanielTest.vue')['default']
DeleteMe: typeof import('./src/components/DeleteMe.vue')['default']
FBXModels: typeof import('./src/components/FBXModels.vue')['default']
Gltf: typeof import('./src/components/gltf/index.vue')['default']
MeshWobbleMaterial: typeof import('./src/components/meshWobbleMaterial/index.vue')['default']
Expand Down
9 changes: 7 additions & 2 deletions playground/src/components/TheEvents.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,15 @@ function onPointerMove(ev) {
console.log(ev)
}
}
const visible = ref(true)
</script>

<template>
<TresCanvas v-bind="gl">
<TresPerspectiveCamera :position="[11, 11, 11]" :fov="45" :near="0.1" :far="1000" :look-at="[0, 0, 0]" />
<button @click="visible = !visible"></button>
<div v-if="visible">
<TresCanvas window-size v-bind="gl">

<OrbitControls />

<template v-for="x in [-2.5, 0, 2.5]">
Expand All @@ -62,4 +66,5 @@ function onPointerMove(ev) {
<TresDirectionalLight :intensity="1" />
<TresAmbientLight :intensity="1" />
</TresCanvas>
</div>
</template>
47 changes: 2 additions & 45 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

78 changes: 27 additions & 51 deletions src/components/TresScene.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { App, defineComponent, h, onMounted, onUnmounted, ref, watch, watchEffect, VNode } from 'vue'
import { App, defineComponent, h, onMounted, onUnmounted, ref, watch } from 'vue'
import * as THREE from 'three'
import { ColorSpace, ShadowMapType, ToneMapping } from 'three'
import { useEventListener } from '@vueuse/core'
import { isString } from '@alvarosabu/utils'
import { createTres } from '../core/renderer'
import { TresCamera } from '../types/'
import {
Expand All @@ -12,11 +10,12 @@ import {
useCamera,
useRenderer,
useRenderLoop,
useRaycaster,
useTres,
usePointerEventHandler,
} from '../composables'
import { extend } from '../core/catalogue'
import { type RendererPresetsType } from '../composables/useRenderer/const'
import { OBJECT_3D_USER_DATA_KEYS } from '../keys'

export interface TresSceneProps {
shadows?: boolean
Expand Down Expand Up @@ -67,24 +66,18 @@ export const TresScene = defineComponent<TresSceneProps>({

const container = ref<HTMLElement>()
const canvas = ref<HTMLElement>()

const scene = new THREE.Scene()

const pointerEventHandler = usePointerEventHandler()
const { setState } = useTres()

scene.userData[OBJECT_3D_USER_DATA_KEYS.REGISTER_AT_POINTER_EVENT_HANDLER] = pointerEventHandler.registerObject

setState('scene', scene)
setState('canvas', canvas)
setState('container', container)

const isCameraAvailable = ref()

const internal = slots && slots.default && slots.default()

if (internal && internal?.length > 0) {
isCameraAvailable.value =
internal.some((node: VNode) => isString(node.type) && node.type.includes('Camera')) || props.camera
if (!isCameraAvailable.value) {
logWarning('No camera found in the scene, please add one!')
}
}
setState('pointerEventHandler', pointerEventHandler)

const { onLoop, resume } = useRenderLoop()

Expand All @@ -98,48 +91,31 @@ export const TresScene = defineComponent<TresSceneProps>({

const { activeCamera, pushCamera, clearCameras } = useCamera()

function setCamera() {
const camera = scene.getObjectByProperty('isCamera', true)

if (!camera) {
// eslint-disable-next-line max-len
logWarning('No camera found. Creating a default perspective camera. To have full control over a camera, please add one to the scene.')
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.set(3,3,3)
camera.lookAt(0,0,0)
pushCamera(camera)
} else {

pushCamera(camera as TresCamera)
}
}

function initRenderer() {
const { renderer } = useRenderer(props)

if (props.camera) {
pushCamera(props.camera as any)
}

const { raycaster, pointer } = useRaycaster()

// TODO: Type raycasting events correctly
let prevInstance: any = null
let currentInstance: any = null

watchEffect(() => {
if (activeCamera.value) raycaster.value.setFromCamera(pointer.value, activeCamera.value)
})

onLoop(() => {
if (activeCamera.value && props.disableRender !== true) renderer.value?.render(scene, activeCamera.value)

if (raycaster.value) {
const intersects = raycaster.value.intersectObjects(scene.children)

if (intersects.length > 0) {
currentInstance = intersects[0]
if (prevInstance === null) {
currentInstance.object?.events?.onPointerEnter?.(currentInstance)
}
currentInstance.object?.events?.onPointerMove?.(currentInstance)
} else {
if (prevInstance !== null) {
currentInstance?.object?.events?.onPointerLeave?.(prevInstance)
currentInstance = null
}
}
prevInstance = currentInstance
}
})

useEventListener(canvas.value, 'click', () => {
if (currentInstance === null) return
currentInstance.object?.events?.onClick?.(currentInstance)
})
}

Expand All @@ -152,6 +128,7 @@ export const TresScene = defineComponent<TresSceneProps>({
app.provide(TRES_CONTEXT_KEY, tres)
app.provide('extend', extend)
app.mount(scene as unknown)
setCamera()
}
mountApp()

Expand All @@ -165,8 +142,7 @@ export const TresScene = defineComponent<TresSceneProps>({
app = createTres(slots)
app.provide('extend', extend)
app.mount(scene as unknown)
const camera = scene.children.find((child: any) => child.isCamera)
pushCamera(camera as TresCamera)
setCamera()
resume()
}

Expand Down
Loading

0 comments on commit 677765e

Please sign in to comment.