Tino Koch hace 5 meses
padre
commit
cf2917a013

+ 24 - 4
playground/vue/src/pages/composables/useTexture/ObjectASyncMultipleTexture.vue

@@ -1,14 +1,29 @@
 <script setup lang="ts">
 /* eslint-disable no-console */
 import { Html } from '@tresjs/cientos'
-import { useTexture } from '@tresjs/core'
+import { useTexture2 } from '@tresjs/core'
 
-const { data: texture } = await useTexture([
+const [texture1, texture2] = useTexture2([
   'https://raw.githubusercontent.com/Tresjs/assets/main/textures/black-rock/Rock035_2K_Color.jpg',
   'https://raw.githubusercontent.com/Tresjs/assets/main/textures/black-rock/Rock035_2K_Displacement.jpg',
 ])
 
-watch(texture, (newVal) => {
+const { state: texture1State, isLoading: texture1IsLoading, then } = texture1
+const { state: texture2State, isLoading: texture2IsLoading } = texture2
+
+then(() => {
+  console.log('texture1 loaded')
+})
+
+const promise = new Promise(then) // TODO remove
+
+await promise // TODO remove
+
+const isLoading = computed(() => texture1IsLoading.value || texture2IsLoading.value) // TODO remove
+
+const textures = computed(() => [texture1State.value, texture2State.value]) // TODO remove
+
+watch(textures, (newVal) => {
   console.log('Multiple texture Async', newVal)
 }, { immediate: true })
 
@@ -23,6 +38,11 @@ watch(texture, (newVal) => {
       </span>
     </Html>
     <TresSphereGeometry :args="[1, 32, 32]" />
-    <TresMeshStandardMaterial v-if="texture" :map="texture[0]" :displacement-map="texture[1]" :displacement-scale="0.1" />
+    <TresMeshStandardMaterial
+      v-if="textures.length && textures[0] && textures[1]"
+      :map="textures[0]"
+      :displacement-map="textures[1]"
+      :displacement-scale="0.1"
+    />
   </TresMesh>
 </template>

+ 1 - 3
playground/vue/src/pages/composables/useTexture/index.vue

@@ -32,9 +32,7 @@ const gl = {
     <Suspense>
       <ObjectAsyncSimpleTexture />
     </Suspense>
-    <Suspense>
-      <ObjectAsyncMultipleTexture />
-    </Suspense>
+    <ObjectAsyncMultipleTexture />
     <ObjectUseTextureComponent />
     <ObjectSyncLoadSimpleTexture />
     <ObjectSyncLoadMultipleTexture />

+ 29 - 0
src/composables/useTexture/index.ts

@@ -1,6 +1,8 @@
 import { ref, type Ref, shallowRef } from 'vue'
 import type { LoadingManager, Texture } from 'three'
 import { TextureLoader } from 'three'
+import type { UseAsyncStateReturn } from '@vueuse/core'
+import { useAsyncState } from '@vueuse/core'
 
 export interface UseTextureReturn<T> {
   /**
@@ -54,6 +56,33 @@ export interface UseTextureReturn<T> {
  * @param path - Path or paths to texture(s)
  * @param manager - Optional THREE.js LoadingManager
  */
+
+export function useTexture2<T extends string | string[]>(path: T, manager?: LoadingManager):
+T extends string ? UseAsyncStateReturn<Texture, [], true> : UseAsyncStateReturn<Texture, [], true>[] {
+  const textureLoader = new TextureLoader(manager)
+
+  const makeComposable = (path: string) => useAsyncState(
+    () =>
+      new Promise<Texture>((resolve, reject) => textureLoader.load(
+        path,
+        loadedTexture => resolve(loadedTexture),
+        undefined,
+        err => reject(err),
+      )),
+    null,
+    {
+      // TODO make argument
+      immediate: true,
+    },
+  )
+
+  if (Array.isArray(path)) {
+    return path.map(path => makeComposable(path)) as T extends string ? never : UseAsyncStateReturn<Texture, [], true>[]
+  }
+
+  return makeComposable(path) as T extends string ? UseAsyncStateReturn<Texture, [], true> : never
+}
+
 export function useTexture(path: string, manager?: LoadingManager): UseTextureReturn<Texture> & Promise<UseTextureReturn<Texture>>
 export function useTexture(paths: string[], manager?: LoadingManager): UseTextureReturn<Texture[]> & Promise<UseTextureReturn<Texture[]>>
 export function useTexture(