Browse Source

feat: removed `useCamera` logic from nodeOps (#308)

* feat: removed `useCamera` logic from nodeOps

* docs: update docs/guide/your-first-scene.md

Co-authored-by: Tino Koch <17991193+Tinoooo@users.noreply.github.com>

* docs: update src/components/TresScene.ts

Co-authored-by: Tino Koch <17991193+Tinoooo@users.noreply.github.com>

* feat: use `getObjectByProperty` to get the camera

* docs: remove camera troubleshooting

* chore: removed unused scene imports

---------

Co-authored-by: Tino Koch <17991193+Tinoooo@users.noreply.github.com>
Alvaro Saburido 1 year ago
parent
commit
e9509bab17

+ 0 - 2
docs/guide/migration-guide.md

@@ -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}

+ 0 - 21
docs/guide/troubleshooting.md

@@ -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.

+ 1 - 1
docs/guide/your-first-scene.md

@@ -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 🍩

+ 7 - 2
playground/src/components/TheEvents.vue

@@ -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]">
@@ -62,4 +66,5 @@ function onPointerMove(ev) {
     <TresDirectionalLight :intensity="1" />
     <TresAmbientLight :intensity="1" />
   </TresCanvas>
+  </div>
 </template>

+ 19 - 16
src/components/TresScene.ts

@@ -1,7 +1,6 @@
-import { App, defineComponent, h, onMounted, onUnmounted, ref, watch, 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 { isString } from '@alvarosabu/utils'
 import { createTres } from '../core/renderer'
 import { TresCamera } from '../types/'
 import {
@@ -80,18 +79,6 @@ export const TresScene = defineComponent<TresSceneProps>({
     setState('container', container)
     setState('pointerEventHandler', pointerEventHandler)
 
-    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!')
-      }
-    }
-
     const { onLoop, resume } = useRenderLoop()
 
     onMounted(() => {
@@ -104,6 +91,22 @@ 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)
 
@@ -125,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()
 
@@ -138,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()
     }
 

+ 2 - 6
src/core/nodeOps.ts

@@ -1,7 +1,7 @@
 import { RendererOptions } from 'vue'
 import { BufferAttribute, Scene } from 'three'
-import { useCamera, useLogger } from '../composables'
 import { isFunction } from '@alvarosabu/utils'
+import {  useLogger } from '../composables'
 import { catalogue } from './catalogue'
 import { TresObject } from '../types'
 import { isHTMLTag, kebabToCamel } from '../utils'
@@ -20,7 +20,6 @@ let scene: Scene | null = null
 
 const { logError } = useLogger()
 
-let firstCamera = true
 export const nodeOps: RendererOptions<TresObject, TresObject> = {
   createElement(tag, _isSVG, _anchor, props) {
     if (!props) props = {}
@@ -46,16 +45,13 @@ export const nodeOps: RendererOptions<TresObject, TresObject> = {
       instance = new target(...props.args)
     }
 
-    if (instance.isCamera && firstCamera) {
+    if (instance.isCamera) {
       if (!props?.position) {
         instance.position.set(3, 3, 3)
       }
       if (!props?.lookAt) {
         instance.lookAt(0, 0, 0)
       }
-      const { setFirstCamera } = useCamera()
-      setFirstCamera(instance)
-      firstCamera = false
     }
 
     if (props?.attach === undefined) {