Explorar o código

feat(core): useTexture and useTres test and jsdocs

alvarosabu %!s(int64=2) %!d(string=hai) anos
pai
achega
672e8adb95

+ 6 - 0
packages/tres/src/core/useScene/index.ts

@@ -3,6 +3,12 @@ import { shallowRef } from 'vue'
 
 const scene = shallowRef(new Scene())
 
+/**
+ * Composable for accessing the scene.
+ *
+ * @export
+ * @return {*} {ShallowRef<Scene>}
+ */
 export function useScene() {
   return {
     scene,

+ 44 - 22
packages/tres/src/core/useTexture/index.ts

@@ -2,7 +2,19 @@ import { isArray } from '@alvarosabu/utils'
 import { LoadingManager, Texture, TextureLoader } from 'three'
 
 export interface PBRMaterialOptions {
+  /**
+   * List of texture maps to load.
+   *
+   * @type {string[]}
+   * @memberof PBRMaterialOptions
+   */
   maps: string[]
+  /**
+   * Path to the texture maps.
+   *
+   * @type {('png' | 'jpg')}
+   * @memberof PBRMaterialOptions
+   */
   ext: 'png' | 'jpg'
 }
 
@@ -10,12 +22,44 @@ export interface PBRTextureMaps {
   [key: string]: Texture | null
 }
 // eslint-disable-next-line require-await
+/**
+ * Composable for loading textures.
+ *
+ * @see https://tresjs.org/examples/load-textures.html
+ *
+ * ```ts
+ * import { useTexture } from 'tres'
+ *
+ * const pbrTexture = await useTexture({
+ *  map: 'path/to/texture.png',
+ *  displacementMap: 'path/to/displacement-map.png',
+ *  roughnessMap: 'path/to/roughness-map.png',
+ *  normalMap: 'path/to/normal-map.png',
+ *  ambientOcclusionMap: 'path/to/ambient-occlusion-map.png',
+ * })
+ * ```
+ * Then you can use the texture in your material.
+ *
+ * ```vue
+ * <TresMeshStandardMaterial v-bind="pbrTexture" />
+ * ```
+ *
+ * @export
+ * @param {(Array<string> | { [key: string]: string })} paths
+ * @return {*}  {(Promise<Texture | Array<Texture> | PBRTextureMaps>)}
+ */
 export async function useTexture(
   paths: Array<string> | { [key: string]: string },
 ): Promise<Texture | Array<Texture> | PBRTextureMaps> {
   const loadingManager = new LoadingManager()
   const textureLoader = new TextureLoader(loadingManager)
 
+  /**
+   * Load a texture.
+   *
+   * @param {string} url
+   * @return {*}  {Promise<Texture>}
+   */
   const loadTexture = (url: string): Promise<Texture> => {
     return new Promise((resolve, reject) => {
       textureLoader.load(
@@ -47,26 +91,4 @@ export async function useTexture(
       aoMap: aoMap ? await loadTexture(aoMap) : null,
     }
   }
-
-  /*   const getPbrTextures = async (path: string, options: PBRMaterialOptions = { maps: ['albedo'], ext: 'png' }) => {
-    const [albedoMap, normalMap, roughnessMap, metalnessMap] = await Promise.all(
-      options.maps.map(map => loadTexture(`${path}${map}.${options.ext}`)),
-    )
-
-    return {
-      map: albedoMap,
-      normalMap,
-      roughnessMap,
-      metalnessMap,
-    }
-  } */
-
-  /*  return new MeshStandardMaterial({
-      map: albedoMap,
-      normalMap,
-      roughnessMap,
-      metalnessMap,
-    })
-  } */
-  /*   return { textureLoader, loadTexture, getPbrMaterial } */
 }

+ 19 - 0
packages/tres/src/core/useTexture/useTexture.test.ts

@@ -0,0 +1,19 @@
+import { LoadingManager, Texture, TextureLoader } from 'three'
+import { useTexture } from '.'
+
+describe('useTexture', () => {
+  afterEach(() => {
+    vi.restoreAllMocks()
+  })
+  // TODO: Add tests, maybe mock the texture loader?
+  it.todo('should load a single texture', async () => {
+    const loadingManager = new LoadingManager()
+    const textureLoader = new TextureLoader(loadingManager)
+
+    const spy = vi.spyOn(textureLoader, 'load').mockImplementation(() => {})
+    const texture = await useTexture([
+      'https://github.com/Tresjs/assets/blob/main/textures/stylized-grass/stylized-grass1_albedo.png?raw=true',
+    ])
+    expect(spy).toHaveBeenCalledTimes(1)
+  })
+})

+ 95 - 0
packages/tres/src/core/useTres/index.ts

@@ -3,15 +3,89 @@ import { ComputedRef, shallowReactive, toRefs } from 'vue'
 import { Camera } from '/@/core'
 
 export interface TresState {
+  /**
+   * The active camera used for rendering the scene.
+   *
+   * @see https://threejs.org/docs/index.html?q=camera#api/en/cameras/Camera
+   *
+   * @type {Camera}
+   * @memberof TresState
+   */
   camera?: Camera
+  /**
+   * All cameras available in the scene.
+   *
+   * @see https://threejs.org/docs/index.html?q=camera#api/en/cameras/Camera
+   *
+   * @type {Camera[]}
+   * @memberof TresState
+   */
   cameras?: Camera[]
+  /**
+   * The aspect ratio of the scene.
+   *
+   * @type {ComputedRef<number>}
+   * @memberof TresState
+   */
   aspectRatio?: ComputedRef<number>
+  /**
+   * The WebGLRenderer used to display the scene using WebGL.
+   *
+   * @see https://threejs.org/docs/index.html?q=webglren#api/en/renderers/WebGLRenderer
+   *
+   * @type {WebGLRenderer}
+   * @memberof TresState
+   */
   renderer?: WebGLRenderer
+  /**
+   * The scene. This is the place where you place objects, lights and cameras.
+   *
+   * @see https://threejs.org/docs/index.html?q=scene#api/en/scenes/Scene
+   *
+   * @type {Scene}
+   * @memberof TresState
+   */
   scene?: Scene
+  /**
+   * The raycaster.
+   *
+   * @see https://threejs.org/docs/index.html?q=raycas#api/en/core/Raycaster
+   *
+   * @type {Raycaster}
+   * @memberof TresState
+   */
   raycaster?: Raycaster
+
+  /**
+   * Object for keeping track of time. This uses `performance.now` if it is available,
+   * otherwise it reverts to the less accurate `Date.now`.
+   *
+   * @see https://threejs.org/docs/index.html?q=clock#api/en/core/Clock
+   *
+   * @type {Clock}
+   * @memberof TresState
+   */
   clock?: Clock
+  /**
+   * The current mouse position.
+   *
+   * @type {Vector2}
+   * @memberof TresState
+   */
   pointer?: Vector2
+  /**
+   * The current instance of the component.
+   *
+   * @type {*}
+   * @memberof TresState
+   */
   currentInstance?: any
+  /**
+   *  The current active scene control
+   *
+   * @type {((EventDispatcher & { enabled: boolean }) | null)}
+   * @memberof TresState
+   */
   controls?: (EventDispatcher & { enabled: boolean }) | null
   [key: string]: any
 }
@@ -21,11 +95,32 @@ const state: TresState = shallowReactive({
   cameras: [],
 })
 
+/**
+ * The Tres state.
+ *
+ * @see https://threejs.org/docs/index.html?q=scene#api/en/scenes/Scene
+ *
+ * @export
+ * @return {*} {TresState, getState, setState}
+ */
 export function useTres() {
+  /**
+   * Get a state value.
+   *
+   *
+   * @param {string} key
+   * @return {*}
+   */
   function getState(key: string) {
     return state[key]
   }
 
+  /**
+   * Set a state value.
+   *
+   * @param {string} key
+   * @param {*} value
+   */
   function setState(key: string, value: any) {
     state[key] = value
   }

+ 14 - 0
packages/tres/src/core/useTres/useTres.test.ts

@@ -0,0 +1,14 @@
+import { useTres } from '.'
+
+describe('useTres', () => {
+  it('should set the state', () => {
+    const { state, setState } = useTres()
+    setState('foo', 'bar')
+    expect(state.foo).toBe('bar')
+  })
+  it('should get the state', () => {
+    const { setState, getState } = useTres()
+    setState('foo', 'bar')
+    expect(getState('foo')).toBe('bar')
+  })
+})